diff --git a/editor/CastagneEditor.gd b/editor/CastagneEditor.gd index 735d77d..3e0b739 100644 --- a/editor/CastagneEditor.gd +++ b/editor/CastagneEditor.gd @@ -230,6 +230,13 @@ func GetCurrentlySelectedBattleInitData(): else: return configData.GetModuleSlot(Castagne.MODULE_SLOTS_BASE.FLOW).EditorGetCurrentBattleInitData(self, $MainMenu/FlowPanel/Custom/VBox) +func StartBattle(battleInitData = null): + if(battleInitData == null): + battleInitData = GetCurrentlySelectedBattleInitData() + queue_free() + var ce = Castagne.InstanceCastagneEngine(battleInitData, configData) + get_tree().get_root().add_child(ce) + func _on_CharacterEditNew_pressed(): EnterSubmenu("CharacterSet", null, "CharAdd") @@ -253,6 +260,10 @@ func _on_Characters_item_activated(_index): # Just copied from the started, a bit of a code smell lol func _on_StartGame_pressed(): call_deferred("LoadLevel", configData.Get("PathMainMenu")) +func _on_StartGameMatch_pressed(): + pass # Replace with function body. +func _on_StartGameTraining_pressed(): + StartBattle() func LoadLevel(path): var ps = load(path) var s = ps.instance() @@ -281,3 +292,7 @@ func FlowCreateAdvancedWindow(flowRoot): func _on_FlowNewBID_pressed(): EnterSubmenu("FlowSetup") + + + + diff --git a/editor/CastagneEditor.tscn b/editor/CastagneEditor.tscn index 6088e8a..741e560 100644 --- a/editor/CastagneEditor.tscn +++ b/editor/CastagneEditor.tscn @@ -75,7 +75,7 @@ __meta__ = { [node name="GameIcon" type="TextureRect" parent="MainMenu/Header"] margin_right = 128.0 -margin_bottom = 71.0 +margin_bottom = 120.0 rect_min_size = Vector2( 128, 0 ) texture = ExtResource( 7 ) expand = true @@ -86,29 +86,29 @@ __meta__ = { [node name="GameTitle" type="Label" parent="MainMenu/Header"] margin_left = 132.0 -margin_top = 20.0 -margin_right = 470.0 -margin_bottom = 51.0 +margin_top = 44.0 +margin_right = 758.0 +margin_bottom = 75.0 size_flags_horizontal = 3 text = "GAME NAME GAME VERSION" valign = 1 [node name="CastagneTitle" type="Label" parent="MainMenu/Header"] -margin_left = 474.0 -margin_top = 20.0 -margin_right = 812.0 -margin_bottom = 51.0 +margin_left = 762.0 +margin_top = 44.0 +margin_right = 1388.0 +margin_bottom = 75.0 size_flags_horizontal = 3 -text = "Castagne v0.0 +text = "Castagne v0.0 2022-00-00 [MAIN]" align = 2 valign = 1 [node name="CastagneLogo" type="TextureRect" parent="MainMenu/Header"] -margin_left = 816.0 -margin_right = 1072.0 -margin_bottom = 71.0 +margin_left = 1392.0 +margin_right = 1648.0 +margin_bottom = 120.0 rect_min_size = Vector2( 256, 0 ) texture = ExtResource( 8 ) expand = true @@ -131,56 +131,56 @@ __meta__ = { } [node name="Label" type="Label" parent="MainMenu/Menu"] -margin_top = 114.0 -margin_right = 508.0 -margin_bottom = 128.0 +margin_top = 240.0 +margin_right = 796.0 +margin_bottom = 254.0 text = "---- Castagne ----" align = 1 [node name="Tutorials" type="Button" parent="MainMenu/Menu"] -margin_top = 132.0 -margin_right = 508.0 -margin_bottom = 150.0 +margin_top = 258.0 +margin_right = 796.0 +margin_bottom = 276.0 text = "Castagne Tutorials" [node name="Documentation" type="Button" parent="MainMenu/Menu"] -margin_top = 154.0 -margin_right = 508.0 -margin_bottom = 172.0 +margin_top = 280.0 +margin_right = 796.0 +margin_bottom = 298.0 size_flags_stretch_ratio = 0.5 text = "Documentation" [node name="Updater" type="Button" parent="MainMenu/Menu"] -margin_top = 176.0 -margin_right = 508.0 -margin_bottom = 194.0 +margin_top = 302.0 +margin_right = 796.0 +margin_bottom = 320.0 size_flags_horizontal = 3 text = "Updater" [node name="Label2" type="Label" parent="MainMenu/Menu"] -margin_top = 198.0 -margin_right = 508.0 -margin_bottom = 229.0 +margin_top = 324.0 +margin_right = 796.0 +margin_bottom = 355.0 text = " ---- Settings ----" align = 1 [node name="Config" type="HBoxContainer" parent="MainMenu/Menu"] -margin_top = 233.0 -margin_right = 508.0 -margin_bottom = 251.0 +margin_top = 359.0 +margin_right = 796.0 +margin_bottom = 377.0 size_flags_horizontal = 3 alignment = 1 [node name="Config" type="Button" parent="MainMenu/Menu/Config"] -margin_right = 426.0 +margin_right = 714.0 margin_bottom = 18.0 size_flags_horizontal = 3 text = "Config Editor" [node name="ConfigAdv" type="Button" parent="MainMenu/Menu/Config"] -margin_left = 430.0 -margin_right = 508.0 +margin_left = 718.0 +margin_right = 796.0 margin_bottom = 18.0 text = "Advanced" __meta__ = { @@ -188,43 +188,62 @@ __meta__ = { } [node name="Label3" type="Label" parent="MainMenu/Menu"] -margin_top = 255.0 -margin_right = 508.0 -margin_bottom = 286.0 +margin_top = 381.0 +margin_right = 796.0 +margin_bottom = 412.0 text = " ---- Game ----" align = 1 [node name="CharacterEdit" type="Button" parent="MainMenu/Menu"] -margin_top = 290.0 -margin_right = 508.0 -margin_bottom = 322.0 +margin_top = 416.0 +margin_right = 796.0 +margin_bottom = 448.0 rect_min_size = Vector2( 0, 32 ) size_flags_horizontal = 3 text = "Character Editor" [node name="CharEditOptions" type="HBoxContainer" parent="MainMenu/Menu"] -margin_top = 326.0 -margin_right = 508.0 -margin_bottom = 344.0 +margin_top = 452.0 +margin_right = 796.0 +margin_bottom = 470.0 [node name="CharacterEditNew" type="Button" parent="MainMenu/Menu/CharEditOptions"] -margin_right = 252.0 +margin_right = 396.0 margin_bottom = 18.0 size_flags_horizontal = 3 text = "New Character" [node name="CharacterEditSafe" type="Button" parent="MainMenu/Menu/CharEditOptions"] -margin_left = 256.0 -margin_right = 508.0 +margin_left = 400.0 +margin_right = 796.0 margin_bottom = 18.0 size_flags_horizontal = 3 text = "Character Editor (Safemode)" +[node name="StartGameModes" type="HBoxContainer" parent="MainMenu/Menu"] +margin_top = 474.0 +margin_right = 796.0 +margin_bottom = 492.0 + +[node name="StartGameTraining" type="Button" parent="MainMenu/Menu/StartGameModes"] +margin_right = 396.0 +margin_bottom = 18.0 +size_flags_horizontal = 3 +text = "Start Training Mode" + +[node name="StartGameMatch" type="Button" parent="MainMenu/Menu/StartGameModes"] +margin_left = 400.0 +margin_right = 796.0 +margin_bottom = 18.0 +size_flags_horizontal = 3 +disabled = true +text = "Start Normal Match" + [node name="StartGame" type="Button" parent="MainMenu/Menu"] -margin_top = 348.0 -margin_right = 508.0 -margin_bottom = 366.0 +margin_top = 496.0 +margin_right = 796.0 +margin_bottom = 514.0 size_flags_horizontal = 3 disabled = true text = "Start Game Normally (Locked until v0.55)" @@ -367,9 +386,9 @@ align = 1 valign = 1 [node name="TmpOut" type="Label" parent="MainMenu/FlowPanel"] -margin_top = 211.0 -margin_right = 508.0 -margin_bottom = 225.0 +margin_top = 348.0 +margin_right = 796.0 +margin_bottom = 362.0 size_flags_horizontal = 3 size_flags_vertical = 6 text = "Disabled at the moment." @@ -377,17 +396,17 @@ align = 1 valign = 1 [node name="HSeparator" type="HSeparator" parent="MainMenu/FlowPanel"] -margin_top = 440.0 -margin_right = 508.0 -margin_bottom = 444.0 +margin_top = 715.0 +margin_right = 796.0 +margin_bottom = 719.0 __meta__ = { "_edit_use_anchors_": false } [node name="FlowAdvanced" type="Button" parent="MainMenu/FlowPanel"] -margin_top = 448.0 -margin_right = 508.0 -margin_bottom = 480.0 +margin_top = 723.0 +margin_right = 796.0 +margin_bottom = 755.0 rect_min_size = Vector2( 0, 32 ) toggle_mode = true text = "Advanced Flow Setup" @@ -1041,8 +1060,8 @@ margin_right = -8.0 margin_bottom = -8.0 [node name="VBox" type="VBoxContainer" parent="FlowSetup/BID"] -margin_right = 598.4 -margin_bottom = 528.0 +margin_right = 905.6 +margin_bottom = 816.0 size_flags_horizontal = 3 size_flags_vertical = 3 @@ -1286,6 +1305,8 @@ __meta__ = { [connection signal="pressed" from="MainMenu/Menu/CharacterEdit" to="." method="_on_CharacterEdit_pressed"] [connection signal="pressed" from="MainMenu/Menu/CharEditOptions/CharacterEditNew" to="." method="_on_CharacterEditNew_pressed"] [connection signal="pressed" from="MainMenu/Menu/CharEditOptions/CharacterEditSafe" to="." method="_on_CharacterEditSafe_pressed"] +[connection signal="pressed" from="MainMenu/Menu/StartGameModes/StartGameTraining" to="." method="_on_StartGameTraining_pressed"] +[connection signal="pressed" from="MainMenu/Menu/StartGameModes/StartGameMatch" to="." method="_on_StartGameMatch_pressed"] [connection signal="pressed" from="MainMenu/Menu/StartGame" to="." method="_on_StartGame_pressed"] [connection signal="pressed" from="MainMenu/FlowPanel/Generic/VBox/Setup/FlowNewBID" to="." method="_on_FlowNewBID_pressed"] [connection signal="toggled" from="MainMenu/FlowPanel/FlowAdvanced" to="." method="_on_FlowAdvanced_toggled"] diff --git a/editor/CastagneEditorCharacterEdit.gd b/editor/CastagneEditorCharacterEdit.gd index 355bfce..93f6465 100644 --- a/editor/CastagneEditorCharacterEdit.gd +++ b/editor/CastagneEditorCharacterEdit.gd @@ -951,7 +951,8 @@ func _on_Code_cursor_changed(): func CompileGizmos(): if(get_node("BottomPanel/BMiniPanel/HBox/Middle/TopBar/Other/HideGizmos").pressed): - engine.editorModule.currentGizmos = [] + if(engine != null): + engine.editorModule.currentGizmos = [] return # Temporary, but good enough for now diff --git a/engine/CastagneEngine.gd b/engine/CastagneEngine.gd index 05e3a40..61d29b0 100644 --- a/engine/CastagneEngine.gd +++ b/engine/CastagneEngine.gd @@ -93,7 +93,6 @@ func EngineTick(previousMemory, playerInputs): memory.GlobalSet("_TrueFrameID", memory.GlobalGet("_TrueFrameID")+1) memory.GlobalSet("_SkipFrame", false) - var previousGameStateHandle = CreateStateHandle(previousMemory) var gameStateHandle = CreateStateHandle(memory) gameStateHandle.GlobalSet("_InputsRaw", playerInputs) @@ -114,6 +113,8 @@ func EngineTick(previousMemory, playerInputs): var activeEIDs = gameStateHandle.GlobalGet("_ActiveEntities") for module in modules: module.ResetVariables(gameStateHandle, activeEIDs) + #var inputPhaseFunction = funcref(configData.GetModuleSlot(Castagne.MODULE_SLOTS_BASE.INPUT), "InputPhase") + #ExecuteInternalPhase("Input", activeEIDs, gameStateHandle, inputPhaseFunction) ExecuteScriptPhase("Freeze", activeEIDs, gameStateHandle) return memory @@ -144,7 +145,7 @@ func EngineTick(previousMemory, playerInputs): # 3. Input Internal Phase var inputPhaseFunction = funcref(configData.GetModuleSlot(Castagne.MODULE_SLOTS_BASE.INPUT), "InputPhase") - ExecuteInternalPhase("Input", activeEIDs, gameStateHandle, previousGameStateHandle, inputPhaseFunction) + ExecuteInternalPhase("Input", activeEIDs, gameStateHandle, inputPhaseFunction) # 4. Action Script Phase for module in modules: @@ -153,7 +154,7 @@ func EngineTick(previousMemory, playerInputs): # 5. Physics Internal Phase var physicsPhaseFunction = funcref(configData.GetModuleSlot(Castagne.MODULE_SLOTS_BASE.PHYSICS), "PhysicsPhase") - ExecuteInternalPhase("Physics", activeEIDs, gameStateHandle, previousGameStateHandle, physicsPhaseFunction) + ExecuteInternalPhase("Physics", activeEIDs, gameStateHandle, physicsPhaseFunction) # 6. Resolution Script Phase @@ -180,14 +181,14 @@ func ExecuteScriptPhase(phaseName, eids, gameStateHandle): funcref(m, phaseName+"PhaseEndEntity").call_func(gameStateHandle) funcref(m, phaseName+"PhaseEnd").call_func(gameStateHandle) -func ExecuteInternalPhase(phaseName, activeEIDs, gameStateHandle, previousGameStateHandle, phaseFunction): +func ExecuteInternalPhase(phaseName, activeEIDs, gameStateHandle, phaseFunction): # :TODO:Panthavma:20220126:Optimize this by making the funcrefs beforehand for m in modules: funcref(m, phaseName+"PhaseStart").call_func(gameStateHandle) for eid in activeEIDs: gameStateHandle.PointToEntity(eid) funcref(m, phaseName+"PhaseStartEntity").call_func(gameStateHandle) - phaseFunction.call_func(gameStateHandle, previousGameStateHandle, activeEIDs) + phaseFunction.call_func(gameStateHandle, activeEIDs) for m in modules: for eid in activeEIDs: gameStateHandle.PointToEntity(eid) @@ -500,6 +501,16 @@ var _memories = [] var MAX_MEMORIES_IN_MEMORY = 16 var _nextMemoryID = 0 func CreateMemory(copyFrom = null): + if(_memories.empty()): + var newMemory = Node.new() + newMemory.set_script(_prefabMemory) + newMemory.InitMemory() + add_child(newMemory) + _memories.push_back(newMemory) + return _memories[0] + + + # :TODO:Panthavma:20230617:Put back actual memory management back in when we go faster for rollback if(_memories.size() < MAX_MEMORIES_IN_MEMORY): var newMemory = Node.new() newMemory.set_script(_prefabMemory) diff --git a/engine/CastagneGlobal.gd b/engine/CastagneGlobal.gd index c8902cd..6a5a25f 100644 --- a/engine/CastagneGlobal.gd +++ b/engine/CastagneGlobal.gd @@ -357,9 +357,11 @@ func AreDictionariesEqual(a, b): return false if(typeA == TYPE_DICTIONARY): - var r = AreDictionariesEqual(a[k], b[k]) + if(!AreDictionariesEqual(a[k], b[k])): + return false elif(typeA == TYPE_ARRAY): - var r = AreArraysEqual(a[k], b[k]) + if(!AreArraysEqual(a[k], b[k])): + return false else: return false return true @@ -378,9 +380,11 @@ func AreArraysEqual(a, b): return false if(typeA == TYPE_DICTIONARY): - var r = AreDictionariesEqual(a[i], b[i]) + if(!AreDictionariesEqual(a[i], b[i])): + return false elif(typeA == TYPE_ARRAY): - var r = AreArraysEqual(a[i], b[i]) + if(!AreArraysEqual(a[i], b[i])): + return false else: return false return true diff --git a/engine/CastagneParser.gd b/engine/CastagneParser.gd index cb71153..615687e 100644 --- a/engine/CastagneParser.gd +++ b/engine/CastagneParser.gd @@ -90,25 +90,25 @@ func _StartParsing(filePath, configData, resetErrors = true): _files = [] _filePaths = [] _curFile = 0 - + _metadata = {} _variables = {} _states = {} - + _aborting = false _invalidFile = false if(resetErrors): ResetErrors() - + # Helpers _moduleVariables = {} for m in _configData.GetModules(): m.CopyVariablesEntityParsing(_moduleVariables) - + _branchFunctions = {} for l in _letters: _branchFunctions[l] = funcref(self, "Instruction"+l) - + _OpenFile(filePath) func _AbortParsing(): @@ -121,10 +121,10 @@ func _AbortParsing(): func _EndParsing(_sendDataEvenIfError = false): if(_aborting or _invalidFile): return null - + for f in _files: f.close() - + return { "Character":_metadata, "Variables":_variables, @@ -133,13 +133,13 @@ func _EndParsing(_sendDataEvenIfError = false): func _OpenFile(filePath): _Log("Opening file " + filePath) - + var file = File.new() _lineIDs.append(0) _filePaths.append(filePath) _currentLines.append("") _files.append(file) - + if(!file.file_exists(filePath)): _FatalError("File " + filePath + " does not exist.") else: @@ -148,8 +148,8 @@ func _OpenFile(filePath): func _ParseFullFile(): if(_aborting): return - - + + # 1. Get the metadata and character skeletons var profiling = [OS.get_ticks_usec()] _Log(">>> Starting to parse the full file.") @@ -159,12 +159,12 @@ func _ParseFullFile(): fileID += 1 if(_aborting): return - + if(md.has("Skeleton")): _OpenFile(md["Skeleton"]) if(_aborting): return - + # 2. Parse the variables profiling.push_back(OS.get_ticks_usec()) _Log(">>> Parsing the variables...") @@ -174,7 +174,7 @@ func _ParseFullFile(): fileID -= 1 if(_aborting): return - + # Pass the variables from the metadata block to the variables block var characterVariables = {} for mName in _metadata: @@ -190,7 +190,7 @@ func _ParseFullFile(): characterVariables[mName] = v for entityName in _variables: Castagne.FuseDataNoOverwrite(_variables[entityName], characterVariables) - + # 3. Parse the states profiling.push_back(OS.get_ticks_usec()) _Log(">>> Parsing the states...") @@ -200,7 +200,7 @@ func _ParseFullFile(): fileID -= 1 if(_aborting): return - + # 4-5. Optimize the code profiling.push_back(OS.get_ticks_usec()) _Log(">>> Optimizing...") @@ -213,13 +213,13 @@ func _ParseFullFile(): variablesList_OptimPhase2 = {} for sName in _states: _OptimizeActionListPhase2(sName) - + # 6. Tag states correctly profiling.push_back(OS.get_ticks_usec()) _Log(">>> State Tagging") for sName in _states: _RuntimeStateTagging(sName) - + # 7. Adjusting the variables profiling.push_back(OS.get_ticks_usec()) var variables = {} @@ -231,7 +231,7 @@ func _ParseFullFile(): continue variables[entity][vName] = v["Value"] _variables = variables - + profiling.push_back(OS.get_ticks_usec()) _PrintProfilingData("["+str(_filePaths[0])+"] GameParse", profiling) @@ -249,18 +249,18 @@ func _OptimizeActionList(stateName): return _optimizedStates += [stateName] var state = _states[stateName] - + var parentLevel = 0 var subName = stateName while(subName.begins_with("Parent:")): parentLevel += 1 subName = subName.right(7) var entity = _GetEntityNameFromStateName(subName) - + for p in PHASES: var actionList = _OptimizeActionList_Sublist(state[p], parentLevel, p, state) state[p] = actionList - + # TODO Set function not on defines ? _states[stateName] = state @@ -268,9 +268,9 @@ var _optimizeActionList_parentWarnings = [] func _OptimizeActionList_Sublist(actionList, baseParentLevel, p, state): var callFuncref = _configData.GetModuleFunctions()["Call"]["ActionFunc"] var callParentFuncref = _configData.GetModuleFunctions()["CallParent"]["ActionFunc"] - + var branchFuncrefs = _branchFunctions.values() - + var loopAgain = true while(loopAgain): loopAgain = false @@ -292,31 +292,31 @@ func _OptimizeActionList_Sublist(actionList, baseParentLevel, p, state): actionList.remove(i) loopAgain = true break - + elif(a[0] in branchFuncrefs): a[1][0] = _OptimizeActionList_Sublist(a[1][0], parentLevel, p, state) a[1][1] = _OptimizeActionList_Sublist(a[1][1], parentLevel, p, state) - + if(a[1][0].empty() and a[1][1].empty()): actionList.remove(i) loopAgain = true break - + if(calledState != null and calledState in _states): if(calledState == state["Name"]): _Warning("CastagneParser: State " + calledState + " is calling itself. Recursion has a fair chance of not going well.") continue - + _OptimizeActionList(calledState) var calledActionList = _states[calledState][p] actionList.remove(i) for j in range(calledActionList.size()): actionList.insert(i+j, calledActionList[j].duplicate(true)) loopAgain = true - + # Variables Castagne.FuseDataNoOverwrite(state["Variables"], _states[calledState]["Variables"].duplicate(true)) - + break return actionList @@ -326,14 +326,14 @@ func _OptimizeActionListPhase2(stateName): return _optimizedStates += [stateName] var state = _states[stateName] - + var _parentLevel = 0 var subName = stateName while(subName.begins_with("Parent:")): _parentLevel += 1 subName = subName.right(7) var entity = _GetEntityNameFromStateName(subName) - + #if(!variablesList_OptimPhase2.has(entity)): #var variablesList = state["Variables"].duplicate() if(!_variables.has(entity)): @@ -341,18 +341,18 @@ func _OptimizeActionListPhase2(stateName): #Castagne.FuseDataNoOverwrite(variablesList, _variables[entity].duplicate(true)) #variablesList_OptimPhase2[entity] = newVariablesList #var variablesList = variablesList_OptimPhase2[entity] - + for p in PHASES: var actionList = state[p] - + actionList = _OptimizeActionList_Defines(actionList, state["Variables"], _variables[entity]) - + state[p] = actionList _states[stateName] = state func _OptimizeActionList_Defines(actionList, variablesList, entityVariablesList): var branchFuncrefs = _branchFunctions.values() - + for i in range(actionList.size()): var a = actionList[i] var arguments = a[1] @@ -360,7 +360,7 @@ func _OptimizeActionList_Defines(actionList, variablesList, entityVariablesList) a[1][0] = _OptimizeActionList_Defines(a[1][0], variablesList, entityVariablesList) a[1][1] = _OptimizeActionList_Defines(a[1][1], variablesList, entityVariablesList) a[1][2] = _OptimizeActionList_Defines_BranchArgs(a[0], a[1][2], variablesList, entityVariablesList) - + for j in range(arguments.size()): arguments[j] = _OptimizeActionList_Defines_ReplaceSymbol(arguments[j], variablesList, entityVariablesList) return actionList @@ -371,7 +371,7 @@ func _OptimizeActionList_Defines_ReplaceSymbol(symbol, variablesList, entityVari v = variablesList[symbol] elif(symbol in entityVariablesList): v = entityVariablesList[symbol] - + if(v != null): if(v["Mutability"] == Castagne.VARIABLE_MUTABILITY.Define): return v["Value"] @@ -379,7 +379,7 @@ func _OptimizeActionList_Defines_ReplaceSymbol(symbol, variablesList, entityVari func _OptimizeActionList_Defines_BranchArgs(branchFuncref, letterArgs, variablesList, entityVariablesList): letterArgs = str(letterArgs) - + if(branchFuncref == _branchFunctions["F"]): var frameRange = _Instruction_GetRange(letterArgs) frameRange[0] = _OptimizeActionList_Defines_ReplaceSymbol(frameRange[0], variablesList, entityVariablesList) @@ -398,7 +398,7 @@ func _OptimizeActionList_Defines_BranchArgs(branchFuncref, letterArgs, variables letterArgs = str(parsedCondition[0]) + comparaisonSymbols[parsedCondition[1]] + str(parsedCondition[2]) else: letterArgs = _OptimizeActionList_Defines_ReplaceSymbol(letterArgs, variablesList, entityVariablesList) - + if(letterArgs.is_valid_integer()): letterArgs = int(letterArgs) return letterArgs @@ -411,21 +411,21 @@ func _RuntimeStateTagging(stateName): parentLevel += 1 subName = subName.right(7) var entity = _GetEntityNameFromStateName(subName) - + var metadata = { "ParentLevel":parentLevel, "Entity":entity, "NameShort":subName, "AttackNotations":[], "AttackType":null, } var flags = [] - + for p in PHASES: var actionList = state[p] var newFlags = _ExtractFlagsFromActionList(actionList, metadata) for f in newFlags: if(!flags.has(f)): flags.push_back(f) - + metadata["Flags"] = flags state["Metadata"] = metadata @@ -437,7 +437,7 @@ func _ExtractFlagsFromActionList(actionList, metadata, level = 0): _configData.GetModuleFunctions()["AttackRegisterNoNotation"]["ActionFunc"], _configData.GetModuleFunctions()["AttackAddNotation"]["ActionFunc"], ] - + for i in range(actionList.size()): var a = actionList[i] var arguments = a[1] @@ -448,11 +448,11 @@ func _ExtractFlagsFromActionList(actionList, metadata, level = 0): var nff = _ExtractFlagsFromActionList(arguments[1], metadata, level+1) for flag in nff: f.push_back(flag) - + elif(a[0] in attackRegisterFuncrefs and level == 0): var atkType = null var atkNotation = null - + if(a[0] == attackRegisterFuncrefs[0]): atkType = arguments[0] atkNotation = metadata["NameShort"] @@ -462,17 +462,17 @@ func _ExtractFlagsFromActionList(actionList, metadata, level = 0): atkType = arguments[0] else: atkNotation = arguments[0] - + if(atkType != null): f.push_back("Attack") f.push_back("AttackType-"+arguments[0]) if(!(metadata["AttackNotations"].empty()) and metadata["AttackType"] != atkType): _Error("Found several AttackRegister calls in one state ! "+metadata["NameShort"] + "(Parent level "+str(metadata["ParentLevel"])+", entity "+metadata["Entity"]+")") metadata["AttackType"] = atkType - + if(atkNotation != null): metadata["AttackNotations"] += [atkNotation] - + return f func _ParseMetadata(fileID): @@ -483,21 +483,21 @@ func _ParseMetadata(fileID): if(_GetNextBlock(fileID) != ":Character:"): _FatalError("Expected a :Character: block.") return md - + md = _ParseBlockData(fileID) md["Filepath"] = filepath - + for mdVarName in md: if(mdVarName in _moduleVariables): _Error("Character define " + mdVarName + " shares its name with an internal variable. Please use another one.") - + Castagne.FuseDataNoOverwrite(_metadata, md) - + var baseFilesList = _configData.GetBaseCaspFilePaths() var skeletonsList = Castagne.SplitStringToArray(_configData.Get("Skeletons")) var idInBaseFiles = baseFilesList.find(filepath) var idInSkeletons = skeletonsList.find(filepath) - + # Skeleton management # Default behaviour: # If a base file, default to base (will be managed later) @@ -510,7 +510,7 @@ func _ParseMetadata(fileID): md["Skeleton"] = skeletonsList[0] else: md["Skeleton"] = "base" - + while(md.has("Skeleton") and !md["Skeleton"].ends_with(".casp")): var skeletonName = str(md["Skeleton"]).strip_edges() if(skeletonName == "none"): @@ -537,33 +537,33 @@ func _ParseMetadata(fileID): md.erase("Skeleton") #else: # md["Skeleton"] = _configData.Get("Skeleton-"+skeletonName) - + if(md.has("Skeleton") and md["Skeleton"] in _filePaths): _Error("Skeleton "+md["Skeleton"] + " has already been loaded. Do you have a cyclical dependancy?") md.erase("Skeleton") - + _LogD("Found " + str(md.size()) + " entries. " + ("Has a skeleton : " + md["Skeleton"] if md.has("Skeleton") else "No Skeleton")) return md func _ParseVariables(fileID): _curFile = fileID _LogD("Parsing Variables of " + _filePaths[fileID]) - + var nbBlocks = 0 var nbVariables = 0 - + var line = _GetNextBlock(fileID) - + var variablesFound = {} - + while(line != null and line.begins_with(":Variables")): line = line.left(line.length()-1).right(1) nbBlocks += 1 - + var entity = _GetEntityNameFromStateName(line) if(!variablesFound.has(entity)): variablesFound[entity] = [] - + line = _GetNextLine(fileID) while(line != null and !_IsLineBlock(line)): if(!_IsLineVariable(line)): @@ -572,26 +572,26 @@ func _ParseVariables(fileID): var variableData = _ExtractVariable(line) if(variableData == null): return null - + if(!_variables.has(entity)): _variables[entity] = {} - + var variableName = variableData["Name"] - + if(variableName in variablesFound[entity]): _Error("Variable " + str(variableName) + " is defined twice in the same file and entity.") else: variablesFound[entity] += [variableName] - + _variables[entity][variableName] = variableData nbVariables += 1 - + line = _GetNextLine(fileID) - + if(nbBlocks == 0): _LogD("Didn't find variables.") return null - + _LogD("Found " + str(nbVariables) + " variables over "+str(nbBlocks)+" blocks.") return nbVariables @@ -605,7 +605,7 @@ func _ParseStates(fileID): if(s == null or _aborting): return null states[s["Name"]] = s - + _ParseStates_OverwriteStates(states) _LogD("Found " + str(states.size()) + " states.") return states @@ -626,10 +626,10 @@ func _ParseStates_OverwriteStates_MoveToParentIfExists(stateName): func _ParseForEdition(): var result = {} result["NbFiles"] = 0 - + if(_aborting): return result - + _parseForEditionPostProcessed = [] # 1. Parse the character skeleton var profiling = [OS.get_ticks_usec()] @@ -640,7 +640,7 @@ func _ParseForEdition(): var md = _ParseMetadata(fileID) result["NbFiles"] = _files.size() var cName = _filePaths[fileID].right(_filePaths[fileID].find_last("/")) - + var defaultStateData = { "Text":"", "LineStart":0, @@ -650,7 +650,7 @@ func _ParseForEdition(): "TagLocal": false, "Variables":{}, "FileID": -1, - + "Categories": [], "StateFlags":[], "StateDoc":"", @@ -661,24 +661,24 @@ func _ParseForEdition(): "BaseStateDistance":-1, "StateType":Castagne.STATE_TYPE.Normal, "CalledStates": [], - + "Warnings": [], "ParseFlags": [], } - + var fileData = { "States":{"Character":defaultStateData.duplicate(true)}, "Name": cName, "Path": _filePaths[fileID], } - + for i in range(fileID-1, -1, -1): result[i+1] = result[i] result[0] = fileData - + if(_aborting): return result - + # Parse states of the file var fileStates = {} _files[fileID].seek(0) @@ -707,7 +707,7 @@ func _ParseForEdition(): fscs["LineEnd"] = lineID # Tag extraction line = line.strip_edges() - + if(line.begins_with("##")): var doccontents = line.right(2).strip_edges() fscs["StateFullDoc"] += doccontents + "\n" @@ -745,9 +745,9 @@ func _ParseForEdition(): # fscs["StateDoc"] = f[1][0].strip_edges() if(f[0] == "_StateFlag" and f[1].size() > 0): fscs["StateFlags"] += [f[1][0].strip_edges()] - + # Bonus state flags, should get a better way in v0.7 - if(f[0] == "AttackRegister"): + if(f[0] == "AttackRegister" or f[0] == "AttackRegisterNoNotation"): fscs["StateFlags"] += ["Attack"] if(f[1].size() >= 1): fscs["StateFlags"] += ["AttackType-"+str(f[1][0])] @@ -768,24 +768,24 @@ func _ParseForEdition(): fscs["Variables"][v["Name"]] = v elif(!curState.begins_with("Variables")): fscs["Warnings"] += ["Trying to declare a variable inside a state! You can either use a constant (with def), or declare your variable in a 'Variables' block."] - - + + #if(curState != null): # fileStates[curState]["LineEnd"] = _lineIDs[fileID] - + result[0]["States"] = fileStates - + fileID += 1 if(md.has("Skeleton")): _OpenFile(md["Skeleton"]) if(_aborting): return result - + profiling.push_back(OS.get_ticks_usec()) for i in range(_files.size()): for stateName in result[i]["States"]: ParseForEditionPostProcess(i, stateName, result) - + profiling.push_back(OS.get_ticks_usec()) _PrintProfilingData("["+str(_filePaths[0])+"] EditParse", profiling) return result @@ -799,14 +799,14 @@ func ParseForEditionPostProcess(fileID, stateName, result): _parseForEditionPostProcessed[fileID] += [stateName] var state = result[fileID]["States"][stateName] state["FileID"] = fileID - + var UNHERITED_FLAGS = ["Overridable", "Overriding", "TODO", "CASTTODO", "Warning", "Error", "Attack"] - + var calledStates = state["CalledStates"] var forceInheritParentTag = true var inheritFromCalledStates = !(stateName in ["Character"]) var inheritDocFromParent = !(stateName in ["Character"]) - + # Check if overriding a state var _pFID = fileID - 1 var parentState = null @@ -817,14 +817,14 @@ func ParseForEditionPostProcess(fileID, stateName, result): state["StateFlags"] += ["Overriding"] if(state["StateType"] == Castagne.STATE_TYPE.Normal and parentState["StateType"] == Castagne.STATE_TYPE.Helper): state["StateType"] = parentState["StateType"] - + if(forceInheritParentTag): # :TODO:Panthavma:20220514:Add option to not inherit states automatically calledStates += [[stateName, _pFID]] break _pFID -= 1 - - + + # Inherit data from called states var baseStateRef = null if(inheritFromCalledStates): @@ -845,15 +845,15 @@ func ParseForEditionPostProcess(fileID, stateName, result): for f in inheritedFlags: if(f.begins_with("AttackType-")): inheritedFlags.erase(f) - + state["StateFlags"].append_array(inheritedFlags) - - if(calledState["StateType"] == Castagne.STATE_TYPE.BaseState and + + if(calledState["StateType"] == Castagne.STATE_TYPE.BaseState and (state["BaseStateDistance"] == -1 or state["BaseStateDistance"] > calledState["BaseStateDistance"]+1)): state["BaseStateDistance"] = calledState["BaseStateDistance"] state["BaseState"] = calledState["BaseState"] baseStateRef = calledState - + # Additional checks and inheritance if(state["Categories"].empty()): var attackType = null @@ -868,56 +868,56 @@ func ParseForEditionPostProcess(fileID, stateName, result): state["Categories"] = parentState["Categories"] elif(baseStateRef != null): state["Categories"] = baseStateRef["Categories"] - + if(parentState != null and inheritDocFromParent): if(state["StateFullDoc"] == ""): state["StateFullDoc"] = parentState["StateFullDoc"] if(state["StateDoc"] == ""): state["StateDoc"] = parentState["StateDoc"] - + var entityName = _GetEntityNameFromStateName(stateName) if(entityName != "Main" and state["Categories"].empty()): state["Categories"] = ["Entities/"+entityName] - + if(stateName == "Character"): state["StateType"] = Castagne.STATE_TYPE.Special state["StateFlags"].erase("Overriding") - + if(stateName.begins_with("Variables")): state["StateType"] = Castagne.STATE_TYPE.Special if(state["Categories"].empty()): state["Categories"] = ["Variables"] if(stateName.begins_with("Init-")): state["StateType"] = Castagne.STATE_TYPE.Special - - + + if(state["StateType"] == Castagne.STATE_TYPE.BaseState): state["BaseStateDistance"] = 0 state["BaseState"] = state["Name"] - + if(stateName.begins_with("StateTemplate-")): state["Categories"] = ["Templates/State Templates"] if(stateName.begins_with("EntityTemplate-")): state["Categories"] = ["Templates/Entity Templates"] if(stateName.ends_with("-Init") or stateName.ends_with("-Variables")): state["StateType"] = Castagne.STATE_TYPE.Special - + state["StateDoc"] = state["StateFullDoc"] var fdFirstLine = state["StateFullDoc"].find("\n") if(fdFirstLine >= 0): state["StateDoc"] = state["StateFullDoc"].left(fdFirstLine) - + if(!state["Variables"].empty() or stateName.begins_with("Variables")): state["StateFlags"] += ["CustomEditor"] - + # Code Quality Checks if(state["StateType"] == Castagne.STATE_TYPE.Normal and state["BaseStateDistance"] == -1 and !state["StateFlags"].has("Attack")): state["Warnings"] += ["State doesn't lead back to a base state, and isn't itself a base state, helper, or registered attack."] - + if(!state["Warnings"].empty()): state["StateFlags"] += ["Warning"] - - + + # Remove double flags state["StateFlags"].sort() var flags = [] @@ -925,7 +925,7 @@ func ParseForEditionPostProcess(fileID, stateName, result): if(flags.empty() or flags.back() != f): flags += [f] state["StateFlags"] = flags - + return true # ------------------------------------------------------------------------------ @@ -936,16 +936,16 @@ func ParseForEditionPostProcess(fileID, stateName, result): func _GetNextLine(fileID): if(_aborting): return null - + while(true): if(_files[fileID].eof_reached()): _currentLines[fileID] = null return null - + var l = _files[fileID].get_line() l = l.strip_edges() _lineIDs[fileID] += 1 - + if(_IsValidLine(l)): _currentLines[fileID] = l return l @@ -994,7 +994,7 @@ func _IsLineBlock(line): func _IsLineInstruction(line): return (!line.begins_with(":")) and line.ends_with(":") func _IsLineFunction(line): - return (line.find("(") > 0) and line.ends_with(")") + return (line.find("(") > 0) and line.ends_with(")") func _IsLineVariable(line): return (line.begins_with("var ") or line.begins_with("def ") or line.begins_with("internal ")) @@ -1023,15 +1023,15 @@ var _currentState = {} func _ParseBlockState(fileID): var stateName = _GetCurrentLine(fileID) stateName = stateName.left(stateName.length()-1).right(1) - + if(stateName.begins_with("Variables")): _Error("Found a variables block after variables are handled.") return null - + var entity = _GetEntityNameFromStateName(stateName) if(!_variables.has(entity)): _variables[entity] = {} - + _currentState = { "Name": stateName, "Type": null, @@ -1039,10 +1039,10 @@ func _ParseBlockState(fileID): "Entity":entity, "Variables":{}, } - - + + var line = _GetNextLine(fileID) - + var stateActions = {} for p in PHASES: stateActions[p] = [] @@ -1080,7 +1080,7 @@ func _ParseBlockState(fileID): action = StandardParseFunction(f[0], f[1]) else: action = fData["ParseFunc"].call_func(self, f[1], parseData) - + if(action != null): var d = [action["Func"], action["Args"]] for p in PHASES: @@ -1110,30 +1110,30 @@ func _ParseBlockState(fileID): else: var letter = line.left(1) var letterArgs = line.left(line.length()-1).right(1) - + if(line == "endif"): var branch = currentSubblock if(currentSubblock == null): _Error("Endif found without a branch!") line = _GetNextLine(fileID) continue - + if(branch["Letter"] == "S"): pass - + currentSubblock = reserveSubblocks.pop_back() currentSubblockList = reserveSubblocksList.pop_back() for p in PHASES: var phaseToGet = p if(branch["Letter"] == "P"): phaseToGet = "Manual" - + var args = [branch["True"][phaseToGet], branch["False"][phaseToGet], branch["LetterArgs"]] var d = [branch["Func"], args] - + if(args[0].empty() and args[1].empty()): continue - + if(currentSubblock == null): stateActions[p] += [d] else: @@ -1152,7 +1152,7 @@ func _ParseBlockState(fileID): reserveSubblocks.push_back(currentSubblock) reserveSubblocksList.push_back(currentSubblockList) currentSubblockList = "True" - + currentSubblock = { "Func": _branchFunctions[letter], "FuncName":"Instruction " + letter, @@ -1164,12 +1164,12 @@ func _ParseBlockState(fileID): for p in PHASES: currentSubblock["True"][p] = [] currentSubblock["False"][p] = [] - + else: _Error("Branch type not recognized: " + letter) - + line = _GetNextLine(fileID) - + if(_aborting): return null for p in PHASES: @@ -1180,14 +1180,14 @@ func _ExtractFunction(line): var splitID = line.find("(") var functionName = line.left(splitID) var splitVars = line.left(line.length()-1).right(splitID+1).split(",") - + var args = [] for v in splitVars: args += [v.strip_edges()] - + if(args.size() == 1 and args[0] == ""): args = [] - + return [functionName, args] func _GetEntityNameFromStateName(stateName): @@ -1212,7 +1212,7 @@ func _ExtractVariable(line): var variableName = null var variableType = null var variableSubtype = null - + if(line.begins_with("var ")): line = line.right(4) variableMutability = Castagne.VARIABLE_MUTABILITY.Variable @@ -1225,7 +1225,7 @@ func _ExtractVariable(line): else: _Error("Couldn't find variable mutability.") return null - + line = line.strip_edges() var sep = line.find("=") if(variableMutability == Castagne.VARIABLE_MUTABILITY.Internal): @@ -1238,15 +1238,15 @@ func _ExtractVariable(line): if(variableValue.empty()): _Error("Variable declaration has an '=' sign but no assignation.") return null - - + + var splits = line.split(" ", false) var nbSplits = splits.size() if(nbSplits != 1 and nbSplits != 2): _Error("Too many words in variable declaration. Please keep your variable names as one word.") return null variableName = splits[0] - + # Internal var check var hasInternalName = (variableName in _moduleVariables) if(hasInternalName and variableMutability != Castagne.VARIABLE_MUTABILITY.Internal): @@ -1259,8 +1259,8 @@ func _ExtractVariable(line): else: _Error("Variable " + str(variableName) + " is marked as internal but no internal variable of the name exists.") return null - - + + # Type check if(variableMutability == Castagne.VARIABLE_MUTABILITY.Internal): if(nbSplits == 2): @@ -1275,34 +1275,34 @@ func _ExtractVariable(line): variableSubtype = lineType.left(lineType.length()-1).right(sep+1) lineType = lineType.left(sep) # TODO parse / use the subtype - - + + if(!lineType in KnownVariableTypes): _Error("Unknown variable type: "+lineType+".") return null variableType = KnownVariableTypes[lineType] - - + + # Default behaviors if(variableType == null): if(variableValue != null and !variableValue.is_valid_integer()): variableType = Castagne.VARIABLE_TYPE.Str else: variableType = Castagne.VARIABLE_TYPE.Int - + if(variableValue == null): if(variableType == Castagne.VARIABLE_TYPE.Int): variableValue = "0" else: variableValue = "" - + if(variableType == Castagne.VARIABLE_TYPE.Int): if(variableValue.is_valid_integer()): variableValue = variableValue.to_int() else: variableValue = 0 _Error("Int variable but the value isn't a valid integer.") - + return { "Name": variableName, "Mutability": variableMutability, @@ -1327,21 +1327,21 @@ func StandardParseFunction(functionName, args): func InstructionI(args, stateHandle): var inputName = ArgStr(args, stateHandle, 2) var inputs = stateHandle.EntityGet("_Inputs") - + if(!inputName in inputs): Castagne.Error("I"+inputName+" : Input not found !") return - + InstructionBranch(args, stateHandle, inputs[inputName]) func InstructionF(args, stateHandle): var letterArgs = str(args[2]) - + var frameID = stateHandle.GlobalGet("_FrameID") - stateHandle.EntityGet("_StateStartFrame") var validFrames = [] - + var frameRange = _Instruction_GetRange(letterArgs) - + if(frameRange.size() == 1): validFrames += [ArgInt([frameRange[0]], stateHandle, 0)] elif(frameRange[1] == "+"): @@ -1353,7 +1353,7 @@ func InstructionF(args, stateHandle): var end = ArgInt([frameRange[1]], stateHandle, 0) for i in range(start, end+1): validFrames += [i] - + letterArgs = validFrames InstructionBranch(args, stateHandle, frameID in validFrames) func InstructionS(args, stateHandle): @@ -1388,28 +1388,28 @@ func InstructionP(args, stateHandle): func InstructionBranch(args, stateHandle, condition): var actionListTrue = args[0] var actionListFalse = args[1] - + var actionList = actionListFalse if(condition): actionList = actionListTrue - + var phase = stateHandle.GetPhase() - + stateHandle.Engine().ExecuteFighterScript({"Name":"Branch", phase:actionList}, stateHandle) - + func _Instruction_ParseCondition(s): var firstPart = s var secondPart = 0 var condition = 2 - + var inferiorPos = s.find("<") var superiorPos = s.find(">") var equalPos = s.find("=") var splitPos = max(inferiorPos, superiorPos) if(splitPos < 0): splitPos = equalPos - + if(inferiorPos >= 0 and superiorPos >= 0): condition = null elif(splitPos >= 0): @@ -1418,25 +1418,25 @@ func _Instruction_ParseCondition(s): condition = 0 condition += (2 if superiorPos>=0 else 0) condition -= (2 if inferiorPos>=0 else 0) - + if(secondPart.begins_with("=")): secondPart = secondPart.right(1) condition -= sign(condition) - + return [firstPart, condition, secondPart] func _Instruction_ComputeCondition(letterArgs, stateHandle): var parsedCondition = _Instruction_ParseCondition(letterArgs) - + if(parsedCondition[1] == null): ModuleError("_Instruction_ComputeCondition: Found both < and > in the same condition", stateHandle) return false - + var firstPart = ArgInt([parsedCondition[0]], stateHandle, 0, 0) var condition = parsedCondition[1] var secondPart = ArgInt([parsedCondition[2]], stateHandle, 0, 0) var diff = firstPart - secondPart - + if(diff == 0): return (abs(condition) <= 1) return (sign(condition) == sign(diff)) diff --git a/menus/starter/CastagneStarter.tscn b/menus/starter/CastagneStarter.tscn index 1d86b8d..3006c7f 100644 --- a/menus/starter/CastagneStarter.tscn +++ b/menus/starter/CastagneStarter.tscn @@ -26,15 +26,15 @@ __meta__ = { } [node name="Editor" type="Button" parent="Buttons"] -margin_top = 182.0 -margin_right = 768.0 -margin_bottom = 202.0 +margin_top = 290.0 +margin_right = 1152.0 +margin_bottom = 310.0 text = "Castagne Editor" [node name="MainMenu" type="Button" parent="Buttons"] -margin_top = 206.0 -margin_right = 768.0 -margin_bottom = 226.0 +margin_top = 314.0 +margin_right = 1152.0 +margin_bottom = 334.0 text = "Start Game Normally" [node name="Training" type="Button" parent="Buttons"] @@ -52,9 +52,9 @@ margin_bottom = 130.0 text = "Battle" [node name="DevTools" type="Button" parent="Buttons"] -margin_top = 230.0 -margin_right = 768.0 -margin_bottom = 250.0 +margin_top = 338.0 +margin_right = 1152.0 +margin_bottom = 358.0 text = "Dev Tools" [node name="Characters" type="Control" parent="."] diff --git a/modules/coreset/Base-Attacks.casp b/modules/coreset/Base-Attacks.casp index 273f62c..58796ca 100644 --- a/modules/coreset/Base-Attacks.casp +++ b/modules/coreset/Base-Attacks.casp @@ -377,17 +377,13 @@ Flag(Attacking) Call(StandardState) F1: Set(_AttackDuration, 180) - AttackRearm() + AttackRearm(1) endif Unflag(FaceTarget) F_AttackDuration+: - LCrouching: - Transition(Crouching) - else - Transition(Stand) - endif + Call(TransitionToNeutralState) endif ## CASTDO Find a way to remove the warning diff --git a/modules/coreset/CMAttacks.gd b/modules/coreset/CMAttacks.gd index 3426e0f..76b2562 100644 --- a/modules/coreset/CMAttacks.gd +++ b/modules/coreset/CMAttacks.gd @@ -32,10 +32,11 @@ func ModuleSetup(): "Flags":["Basic"], "Types":["int",], }) - RegisterFunction("AttackRearm", [0], null, { + RegisterFunction("AttackRearm", [0, 1], null, { "Description":"Sets the variables to be able to hit with another attack, and should be used between multihits. Resets the hit detection.", "Flags":["Intermediate"], - "Types":[], + "Arguments":["(Optional) Treat as a new attack instead of a multihit (reapplies proration and resets hit/block/clash flags) (Default: False)"], + "Types":["bool"], }) RegisterFunction("AttackParam", [2], null, { "Description":"Sets a generic attack parameter directly. This is an advanced function and should be used either when you need some really specific adjustment, or when you want to add functionality without a module.", @@ -86,13 +87,13 @@ func ModuleSetup(): "Types":["int","int"], }) RegisterFunction("AttackFrameAdvantageHit", [1], null, { - "Description":"Sets an attack's frame advantage automatically on hit. This is based on the total duration of the attack and the last use of the multihit flag. Same functionality as AttackSetHitstunBlockstun, but in an easier way.", + "Description":"Sets an attack's frame advantage automatically on hit. This is based on the total duration of the attack and the last use of the AttackRearm function. Same functionality as AttackSetHitstunBlockstun, but in an easier way.", "Arguments":["Frame advantage on hit"], "Flags":["Basic"], "Types":["int",], }) RegisterFunction("AttackFrameAdvantageBlock", [1], null, { - "Description":"Sets an attack's frame advantage automatically on block. This is based on the total duration of the attack and the last use of the multihit flag. Same functionality as AttackSetHitstunBlockstun, but in an easier way.", + "Description":"Sets an attack's frame advantage automatically on block. This is based on the total duration of the attack and the last use of the AttackRearm function. Same functionality as AttackSetHitstunBlockstun, but in an easier way.", "Arguments":["Frame advantage on block"], "Flags":["Basic"], "Types":["int",], @@ -165,6 +166,28 @@ func ModuleSetup(): "Flags":["Intermediate"], "Types":["int","int","int","int"], }) + RegisterFunction("AttackInheritMomentum", [0, 1, 2, 4], null, { + "Description":"Makes an attack inherit the momentum of the attacker, in permil. Happens on hit and block.", + "Arguments":["Ratio of Ground X Momentum conserved in permil", "Ratio of Ground Y Momentum conserved in permil", + "Ratio of Air X Momentum conserved in permil", "Ratio of Air Y Momentum conserved in permil"], + "Flags":["Intermediate"], + "Types":["int", "int", "int", "int"], + }) + RegisterFunction("AttackInheritMomentumHit", [0, 1, 2, 4], null, { + "Description":"Makes an attack inherit the momentum of the attacker, in permil. Happens on hit.", + "Arguments":["Ratio of Ground X Momentum conserved in permil", "Ratio of Ground Y Momentum conserved in permil", + "Ratio of Air X Momentum conserved in permil", "Ratio of Air Y Momentum conserved in permil"], + "Flags":["Intermediate"], + "Types":["int", "int", "int", "int"], + }) + RegisterFunction("AttackInheritMomentumBlock", [0, 1, 2, 4], null, { + "Description":"Makes an attack inherit the momentum of the attacker, in permil. Happens on block.", + "Arguments":["Ratio of Ground X Momentum conserved in permil", "Ratio of Ground Y Momentum conserved in permil", + "Ratio of Air X Momentum conserved in permil", "Ratio of Air Y Momentum conserved in permil"], + "Flags":["Intermediate"], + "Types":["int", "int", "int", "int"], + }) + RegisterFunction("AttackFloat", [1], null, { "Description":"Sets the opponent's gravity on hit to the specified value until the next attack.", "Arguments":["New Gravity"], @@ -214,10 +237,10 @@ func ModuleSetup(): RegisterVariableEntity("_AttackMomentumX", 0) RegisterVariableEntity("_AttackMomentumY", 0) - #RegisterFlag("Multihit", {"Description":"Allow an attack to hit again."}) RegisterFlag("AFLow", {"Description":"Makes an attack unblockable while standing up."}) RegisterFlag("AFOverhead", {"Description":"Makes an attack unblockable while crouching."}) - RegisterFlag("AFInheritMomentum", {"Description":"Makes it so that the attack inherits the attacker's momentum."}) + RegisterFlag("AFInheritMomentumHit", {"Description":"Makes it so that the attack inherits the attacker's momentum on hit, ratio determined by attack data."}) + RegisterFlag("AFInheritMomentumBlock", {"Description":"Makes it so that the attack inherits the attacker's momentum on block, ratio determined by attack data."}) RegisterFlag("AFFloat", {"Description":"Set by the AttackFloat function. Tells the opponent to override the usual gravity for the next hit."}) RegisterFlag("Invul-All", {"Description":"Can't by hit by any attacks, they will count as whiffed."}) @@ -366,6 +389,15 @@ func ModuleSetup(): RegisterConfig("AttackDefault-MaxGroundbounces", 3) RegisterConfig("AttackDefault-FloatGravity", 0) + + RegisterConfig("AttackDefault-InheritMomentumHitGroundX", 1000) + RegisterConfig("AttackDefault-InheritMomentumHitGroundY", 1000) + RegisterConfig("AttackDefault-InheritMomentumHitAirX", 1000) + RegisterConfig("AttackDefault-InheritMomentumHitAirY", 1000) + RegisterConfig("AttackDefault-InheritMomentumBlockGroundX", 1000) + RegisterConfig("AttackDefault-InheritMomentumBlockGroundY", 1000) + RegisterConfig("AttackDefault-InheritMomentumBlockAirX", 1000) + RegisterConfig("AttackDefault-InheritMomentumBlockAirY", 1000) var _defaultAttackData = {} var _knockdownDefaultTimeDiff = 0 @@ -407,10 +439,6 @@ func ActionPhaseStartEntity(stateHandle): var attackData = _defaultAttackData.duplicate(true) stateHandle.EntitySet("_AttackData", attackData) -func ActionPhaseEndEntity(stateHandle): - if(stateHandle.EntityHasFlag("Multihit")): - AttackRearm(null, stateHandle) - func PhysicsPhaseEndEntity(stateHandle): # :TODO:Panthavma:20220314:Optim: Maybe replace the string check by a int var hitconfirmState = stateHandle.EntityGet("_AttackHitconfirm_State") @@ -572,6 +600,10 @@ func ApplyAttackToDefender(hitconfirm, attackData, attackerHandle, hitbox, defen var physicsModule = attackerHandle.ConfigData().GetModuleSlot(Castagne.MODULE_SLOTS_BASE.PHYSICS) var attackerFacing = physicsModule.GetFacingHV(attackerHandle) var defenderFacing = physicsModule.GetFacingHV(defenderHandle) + var defenderGrounded = defenderHandle.EntityHasFlag("PFGrounded") + var defenderGroundAir = ("Ground" if defenderGrounded else "Air") + var defenderNoGroundAir = ("" if defenderGrounded else "Air") + # :TODO:Panthavma:20230513:Momentum here is physics dependant, should move it there I think @@ -594,16 +626,16 @@ func ApplyAttackToDefender(hitconfirm, attackData, attackerHandle, hitbox, defen defenderHandle.EntityAdd("HP", -attackData["ChipDamage"]) defenderHandle.EntitySet("_BlockstunDuration", max(1,attackData["Blockstun"])) - if(defenderHandle.EntityHasFlag("PFGrounded")): - defenderHandle.EntitySet("_AttackMomentumX", attackerFacing[0] * defenderFacing[0] * attackData[hitBlock+"MomentumX"]) - defenderHandle.EntitySet("_AttackMomentumY", attackData[hitBlock+"MomentumY"]) - else: - defenderHandle.EntitySet("_AttackMomentumX", attackerFacing[0] * defenderFacing[0] * attackData[hitBlock+"MomentumAirX"]) - defenderHandle.EntitySet("_AttackMomentumY", attackData[hitBlock+"MomentumAirY"]) + defenderHandle.EntitySet("_AttackMomentumX", attackerFacing[0] * defenderFacing[0] * attackData[hitBlock+"Momentum"+defenderNoGroundAir+"X"]) + defenderHandle.EntitySet("_AttackMomentumY", attackData[hitBlock+"Momentum"+defenderNoGroundAir+"Y"]) - if(HasFlag(attackData, "InheritMomentum")): - defenderHandle.EntityAdd("AttackMomentumX", attackerHandle.EntityGet("_MomentumX")) - defenderHandle.EntityAdd("AttackMomentumY", attackerHandle.EntityGet("_MomentumY")) + var inheritMomentum = (hit and HasFlag(attackData, "InheritMomentumHit")) or (!hit and HasFlag(attackData, "InheritMomentumBlock")) + if(inheritMomentum): + var inheritMomentumX = attackData["InheritMomentum"+hitBlock+defenderGroundAir+"X"] + var inheritMomentumY = attackData["InheritMomentum"+hitBlock+defenderGroundAir+"Y"] + + defenderHandle.EntityAdd("_AttackMomentumX", defenderFacing[0] * attackerHandle.EntityGet("_MomentumX") * inheritMomentumX / 1000) + defenderHandle.EntityAdd("_AttackMomentumY", attackerHandle.EntityGet("_MomentumY") * inheritMomentumY / 1000) if(HasFlag(attackData, "Float")): defenderHandle.EntitySet("_HitstunGravityFloat", attackData["FloatGravity"]) @@ -695,20 +727,23 @@ func AttackDuration(args, stateHandle): if(stateHandle.EntityGet("_AttackData")["Blockstun"] <= 0): AttackFrameAdvantageBlock([0], stateHandle) -func AttackRearm(_args, stateHandle): - stateHandle.EntitySet("_AttackHitconfirm_State", null) +func AttackRearm(args, stateHandle): + var newAttack = ArgBool(args, stateHandle, 0, false) + # :TODO:Panthavma:20230617:Manage Proration stateHandle.EntitySet("_AttackInitialFrame", -1) stateHandle.EntitySet("_AttackHitEntities", []) - stateHandle.EntitySet("_AttackHasHit", false) - stateHandle.EntitySet("_AttackWasBlocked", false) - stateHandle.EntitySet("_AttackHasWhiffed", false) - stateHandle.EntitySet("_AttackHasTouched", false) + if(newAttack): + stateHandle.EntitySet("_AttackHitconfirm_State", null) + stateHandle.EntitySet("_AttackHasHit", false) + stateHandle.EntitySet("_AttackWasBlocked", false) + stateHandle.EntitySet("_AttackHasWhiffed", false) + stateHandle.EntitySet("_AttackHasTouched", false) func AttackParam(args, stateHandle): var paramName = ArgStr(args, stateHandle, 0) var value = ArgInt(args, stateHandle, 1) - stateHandle.EntityGet("_AttackData")[paramName] = value + _SetInPrepareAttackData(stateHandle, paramName, value) @@ -732,7 +767,7 @@ func AttackRecievedUnflag(args, stateHandle): stateHandle.EntitySetFlag("AF"+flagName, false) func AttackAttribute(args, stateHandle): - stateHandle.EntityGet("_AttackData")["Attribute"] = ArgStr(args, stateHandle, 0, "Auto") + _SetInPrepareAttackData(stateHandle, "Attribute", ArgStr(args, stateHandle, 0, "Auto")) func AttackFrameAdvantage(args, stateHandle): @@ -749,28 +784,28 @@ func AttackFrameAdvantageBlock(args, stateHandle): _AttackFrameAdvantage(ArgInt(args, stateHandle, 0), stateHandle, "Blockstun") func _AttackFrameAdvantage(FA, stateHandle, stunType): var neutralFA = stateHandle.EntityGet("_AttackDuration") - stateHandle.EntityGet("_AttackInitialFrame") - stateHandle.EntityGet("_AttackData")[stunType] = max(neutralFA + FA, 1) + _SetInPrepareAttackData(stateHandle, stunType, max(neutralFA + FA, 1)) func AttackHitstunBlockstun(args, stateHandle): - stateHandle.EntityGet("_AttackData")["Hitstun"] = max(ArgInt(args, stateHandle, 0),1) - stateHandle.EntityGet("_AttackData")["Blockstun"] = max(ArgInt(args, stateHandle, 1),1) + _SetInPrepareAttackData(stateHandle, "Hitstun", max(ArgInt(args, stateHandle, 0),1)) + _SetInPrepareAttackData(stateHandle, "Blockstun", max(ArgInt(args, stateHandle, 1),1)) func AttackHitstun(args, stateHandle): - stateHandle.EntityGet("_AttackData")["Hitstun"] = max(ArgInt(args, stateHandle, 0),1) + _SetInPrepareAttackData(stateHandle, "Hitstun", max(ArgInt(args, stateHandle, 0),1)) func AttackBlockstun(args, stateHandle): - stateHandle.EntityGet("_AttackData")["Blockstun"] = max(ArgInt(args, stateHandle, 0),1) + _SetInPrepareAttackData(stateHandle, "Blockstun", max(ArgInt(args, stateHandle, 0),1)) func AttackProrationHitstun(args, stateHandle): - stateHandle.EntityGet("_AttackData")["StarterProrationHitstun"] = ArgInt(args, stateHandle, 0) - stateHandle.EntityGet("_AttackData")["ProrationHitstun"] = ArgInt(args, stateHandle, 1) + _SetInPrepareAttackData(stateHandle, "StarterProrationHitstun", ArgInt(args, stateHandle, 0)) + _SetInPrepareAttackData(stateHandle, "ProrationHitstun", ArgInt(args, stateHandle, 1)) func AttackProrationDamage(args, stateHandle): - stateHandle.EntityGet("_AttackData")["StarterProrationDamage"] = ArgInt(args, stateHandle, 0) - stateHandle.EntityGet("_AttackData")["ProrationDamage"] = ArgInt(args, stateHandle, 1) + _SetInPrepareAttackData(stateHandle, "StarterProrationDamage", ArgInt(args, stateHandle, 0)) + _SetInPrepareAttackData(stateHandle, "ProrationDamage", ArgInt(args, stateHandle, 1)) func AttackChipDamage(args, stateHandle): - stateHandle.EntityGet("_AttackData")["ChipDamage"] = ArgInt(args, stateHandle, 0) + _SetInPrepareAttackData(stateHandle, "ChipDamage", ArgInt(args, stateHandle, 0)) func AttackMinDamage(args, stateHandle): - stateHandle.EntityGet("_AttackData")["MinDamage"] = ArgInt(args, stateHandle, 0) + _SetInPrepareAttackData(stateHandle, "MinDamage", ArgInt(args, stateHandle, 0)) @@ -780,19 +815,36 @@ func AttackMomentum(args, stateHandle): func AttackMomentumHit(args, stateHandle): var mh = ArgInt(args, stateHandle, 0) var mv = ArgInt(args, stateHandle, 1, 0) - stateHandle.EntityGet("_AttackData")["HitMomentumX"] = mh - stateHandle.EntityGet("_AttackData")["HitMomentumY"] = mv - stateHandle.EntityGet("_AttackData")["HitMomentumAirX"] = ArgInt(args, stateHandle, 2, mh) - stateHandle.EntityGet("_AttackData")["HitMomentumAirY"] = ArgInt(args, stateHandle, 3, mv) + _SetInPrepareAttackData(stateHandle, "HitMomentumX", mh) + _SetInPrepareAttackData(stateHandle, "HitMomentumY", mv) + _SetInPrepareAttackData(stateHandle, "HitMomentumAirX", ArgInt(args, stateHandle, 2, mh)) + _SetInPrepareAttackData(stateHandle, "HitMomentumAirY", ArgInt(args, stateHandle, 3, mv)) func AttackMomentumBlock(args, stateHandle): var mh = ArgInt(args, stateHandle, 0) var mv = ArgInt(args, stateHandle, 1, 0) - stateHandle.EntityGet("_AttackData")["BlockMomentumX"] = mh - stateHandle.EntityGet("_AttackData")["BlockMomentumY"] = mv - stateHandle.EntityGet("_AttackData")["BlockMomentumAirX"] = ArgInt(args, stateHandle, 2, mh) - stateHandle.EntityGet("_AttackData")["BlockMomentumAirY"] = ArgInt(args, stateHandle, 3, mv) + _SetInPrepareAttackData(stateHandle, "BlockMomentumX", mh) + _SetInPrepareAttackData(stateHandle, "BlockMomentumY", mv) + _SetInPrepareAttackData(stateHandle, "BlockMomentumAirX", ArgInt(args, stateHandle, 2, mh)) + _SetInPrepareAttackData(stateHandle, "BlockMomentumAirY", ArgInt(args, stateHandle, 3, mv)) +func AttackInheritMomentum(args, stateHandle): + AttackInheritMomentumHit(args, stateHandle) + AttackInheritMomentumBlock(args, stateHandle) +func AttackInheritMomentumHit(args, stateHandle, situation = "Hit"): + AttackFlag(["InheritMomentum"+situation], stateHandle) + if(args.size() > 0): + var imGroundX = ArgInt(args, stateHandle, 0) + var imGroundY = ArgInt(args, stateHandle, 1, imGroundX) + var imAirX = ArgInt(args, stateHandle, 2, imGroundX) + var imAirY = ArgInt(args, stateHandle, 3, imGroundY) + + _SetInPrepareAttackData(stateHandle, "InheritMomentum"+situation+"GroundX", imGroundX) + _SetInPrepareAttackData(stateHandle, "InheritMomentum"+situation+"GroundY", imGroundY) + _SetInPrepareAttackData(stateHandle, "InheritMomentum"+situation+"AirX", imAirX) + _SetInPrepareAttackData(stateHandle, "InheritMomentum"+situation+"AirY", imAirY) +func AttackInheritMomentumBlock(args, stateHandle): + AttackInheritMomentumHit(args, stateHandle, "Block") func AttackFloat(args, stateHandle): - stateHandle.EntityGet("_AttackData")["FloatGravity"] = -ArgInt(args, stateHandle, 0) + _SetInPrepareAttackData(stateHandle, "FloatGravity", -ArgInt(args, stateHandle, 0)) AttackFlag(["Float"], stateHandle) func AttackKnockdown(args, stateHandle): @@ -804,14 +856,14 @@ func AttackKnockdown(args, stateHandle): kdMin = max(1, ArgInt(args, stateHandle, 0, kdMin)) kdMax = max(kdMin, ArgInt(args, stateHandle, 1, kdMin+_knockdownDefaultTimeDiff)) - stateHandle.EntityGet("_AttackData")["KnockdownTimeMin"] = kdMin - stateHandle.EntityGet("_AttackData")["KnockdownTimeMax"] = kdMax + _SetInPrepareAttackData(stateHandle, "KnockdownTimeMin", kdMin) + _SetInPrepareAttackData(stateHandle, "KnockdownTimeMax", kdMax) func AttackGroundbounce(args, stateHandle): AttackFlag(["Groundbounce"], stateHandle) - stateHandle.EntityGet("_AttackData")["GroundbounceTime"] = ArgInt(args, stateHandle, 0, stateHandle.ConfigData().Get("AttackDefault-GroundbounceTime")) - stateHandle.EntityGet("_AttackData")["GroundbounceMomentum"] = ArgInt(args, stateHandle, 1, stateHandle.ConfigData().Get("AttackDefault-GroundbounceMomentum")) - stateHandle.EntityGet("_AttackData")["MaxGroundbounces"] = ArgInt(args, stateHandle, 2, stateHandle.ConfigData().Get("AttackDefault-MaxGroundbounces")) + _SetInPrepareAttackData(stateHandle, "GroundbounceTime", ArgInt(args, stateHandle, 0, stateHandle.ConfigData().Get("AttackDefault-GroundbounceTime"))) + _SetInPrepareAttackData(stateHandle, "GroundbounceMomentum", ArgInt(args, stateHandle, 1, stateHandle.ConfigData().Get("AttackDefault-GroundbounceMomentum"))) + _SetInPrepareAttackData(stateHandle, "MaxGroundbounces", ArgInt(args, stateHandle, 2, stateHandle.ConfigData().Get("AttackDefault-MaxGroundbounces"))) @@ -895,3 +947,10 @@ func _AttackAllCancelRegister(args, stateHandle, lists): for i in range(1, 10): var notation = prefix+str(i)+button stateHandle.EntityGet("_AttackPossibleCancels"+l)[notation] = notation + + +# ---- +# Helpers + +func _SetInPrepareAttackData(stateHandle, fieldName, value): + stateHandle.EntityGet("_AttackData")[fieldName] = value diff --git a/modules/coreset/CMInput.gd b/modules/coreset/CMInput.gd index 80d0c31..534582e 100644 --- a/modules/coreset/CMInput.gd +++ b/modules/coreset/CMInput.gd @@ -31,7 +31,7 @@ func ModuleSetup(): {"Name":"TrainingButton2", "Type":Castagne.PHYSICALINPUT_TYPES.BUTTON, "KeyboardInputs":[[[]]], "ControllerInputs":[[[JOY_R3]]]}, ], {"Flags":["Hidden"], "Description":"The complete InputLayout to use."}) - RegisterCustomConfig("Define Input Layout", "InputConfig", {"Flags":["LockBack"]}) + RegisterCustomConfig("Define Input Layout", "InputConfig", {"Flags":["ReloadFull", "LockBack"]}) RegisterConfig("NumberOfKeyboardPlayers", 2, {"Description":"Number of keyboard devices to setup."}) RegisterConfig("NumberOfKeyboardLayouts", 2, {"Description":"Number of keyboard default bindings to make available."}) @@ -103,6 +103,7 @@ func FrameStart(stateHandle): var inputsProcessed = [] var inputsRaw = stateHandle.GlobalGet("_InputsRaw") var castagneInput = stateHandle.Input() + var frozenFrame = stateHandle.GlobalGet("_FrozenFrame") for pid in range(stateHandle.GlobalGet("_NbPlayers")): var raw = null @@ -113,12 +114,15 @@ func FrameStart(stateHandle): var inputData = castagneInput.CreateInputDataFromRawInput(raw) inputsProcessed.push_back(inputData) - + + + # :TODO:Panthavma:20230228:This is kind of a shortcut, can be improved in v0.7 with a second buffer. Good enough for now var previousProcessed = stateHandle.GlobalGet("_InputsProcessedPrevious") if(previousProcessed.size() >= stateHandle.ConfigData().Get("InputBufferSizePress")): previousProcessed.pop_back() - previousProcessed.push_front(stateHandle.GlobalGet("_InputsProcessed")) + if(!frozenFrame): + previousProcessed.push_front(stateHandle.GlobalGet("_InputsProcessed")) stateHandle.GlobalSet("_InputsProcessedPrevious", previousProcessed) stateHandle.GlobalSet("_InputsProcessed", inputsProcessed) @@ -144,10 +148,11 @@ func InitPhaseEndEntity(stateHandle): stateHandle.EntitySet("_Inputs", inputData) -func InputPhase(stateHandle, _previousStateHandle, activeEIDs): +func InputPhase(stateHandle, activeEIDs): var castagneInput = stateHandle.Input() var inputSchema = castagneInput.GetInputSchema() - + + for eid in activeEIDs: stateHandle.PointToEntity(eid) @@ -161,13 +166,6 @@ func InputPhase(stateHandle, _previousStateHandle, activeEIDs): var diType = derivedInput["DerivedType"] var diValue = false - if(derivedInputName == "ForwardPress"): - pass - if(derivedInputName == "ForwardRelease"): - pass - if(derivedInputName == "APress"): - pass - if(diType == Castagne.GAMEINPUT_DERIVED_TYPES.BUTTON_PRESS): var diTarget = derivedInput["Target"] if(inputs[diTarget]): diff --git a/modules/graphics/Base-Graphics.casp b/modules/graphics/Base-Graphics.casp index b17b2c7..4f62858 100644 --- a/modules/graphics/Base-Graphics.casp +++ b/modules/graphics/Base-Graphics.casp @@ -367,38 +367,6 @@ VANIMS_UseStandardAnims: Anim(ANIM_Movement_Basic_WalkF) AnimLoop(ANIM_Movement_Basic_WalkF_Loop) endif -:BlockVFX: -## Temporary block vfx function -## CASTDO - -def VFXPath str() = res://castagne/assets/fx/TempBlockVFX.tscn -def VFXPosX int() = 3000 -def VFXPosY int() = 10000 -def VFXScale int() = 1000 -def VFXTime int() = 10 -def VFXAnimation str() = default -def VFXAnimPlayer str() = AnimationPlayer - -VFXPrepare(VFXPath, VFXTime, VFXPosX, VFXPosY) -VFXScale(VFXScale) -VFXAnimation(VFXAnimation, VFXAnimPlayer) -VFXCreate() -:HitVFX: -## Temporary hit vfx function -## CASTDO - -def VFXPath str() = res://castagne/assets/fx/TempHitVFX.tscn -def VFXPosX int() = 5000 -def VFXPosY int() = 10000 -def VFXScale int() = 600 -def VFXTime int() = 10 -def VFXAnimation str() = default -def VFXAnimPlayer str() = AnimationPlayer - -VFXPrepare(VFXPath, VFXTime, VFXPosX, VFXPosY) -VFXScale(VFXScale) -VFXAnimation(VFXAnimation, VFXAnimPlayer) -VFXCreate() :Init-LightGraphicsInit: ## Simple helper to create a model or sprite quickly for subentities _Helper() @@ -469,8 +437,40 @@ RegisterSpritesheet(GRAPHICS_Spritesheet_DefaultName, GRAPHICS_Spritesheet_Path, :OnBlock: CallParent(OnBlock) -Call(BlockVFX) +Call(VFXBlock) :OnHit: CallParent(OnHit) -Call(HitVFX) +Call(VFXHit) +:VFXBlock: +## Temporary block vfx function +## CASTDO + +def VFXPath str() = res://castagne/assets/fx/TempBlockVFX.tscn +def VFXPosX int() = 3000 +def VFXPosY int() = 10000 +def VFXScale int() = 1000 +def VFXTime int() = 10 +def VFXAnimation str() = default +def VFXAnimPlayer str() = AnimationPlayer + +VFXPrepare(VFXPath, VFXTime, VFXPosX, VFXPosY) +VFXScale(VFXScale) +VFXAnimation(VFXAnimation, VFXAnimPlayer) +VFXCreate() +:VFXHit: +## Temporary hit vfx function +## CASTDO + +def VFXPath str() = res://castagne/assets/fx/TempHitVFX.tscn +def VFXPosX int() = 5000 +def VFXPosY int() = 10000 +def VFXScale int() = 600 +def VFXTime int() = 10 +def VFXAnimation str() = default +def VFXAnimPlayer str() = AnimationPlayer + +VFXPrepare(VFXPath, VFXTime, VFXPosX, VFXPosY) +VFXScale(VFXScale) +VFXAnimation(VFXAnimation, VFXAnimPlayer) +VFXCreate() diff --git a/modules/graphics/CMGraphics2D.gd b/modules/graphics/CMGraphics2D.gd index 8923c80..c3c38eb 100644 --- a/modules/graphics/CMGraphics2D.gd +++ b/modules/graphics/CMGraphics2D.gd @@ -80,15 +80,23 @@ func _UpdateCamera(_stateHandle, camera, cameraPos): camera.set_position(cameraPos) -func _ModelApplyTransform(stateHandle, modelRoot, modelPosition, modelRotation, modelScale): +func _ModelApplyTransformDirect(modelRoot, modelPosition, modelRotation, modelScale, facingH): + modelPosition = IngameToGodotPos(modelPosition) + modelRotation *= 0.1 + modelScale /= 1000.0 + if(pixelArtMode): modelPosition = modelPosition.round() + if(!modelRoot.has_method("set_position")): + ModuleError("Graphics2D: Trying to set the position of a 3D asset!") + return + modelRoot.set_position(modelPosition) modelRoot.set_rotation_degrees(modelRotation) - var spriteData = _GetCurrentSpriteData(stateHandle) + #var spriteData = _GetCurrentSpriteData(stateHandle) #modelScale *= spriteData["PixelSize"] - modelRoot.set_scale(Vector2(stateHandle.EntityGet("_FacingHModel") * modelScale, modelScale)) + modelRoot.set_scale(Vector2(facingH * modelScale, modelScale)) func _CreateRootNode(): return Node2D.new() diff --git a/modules/graphics/CMGraphicsBase.gd b/modules/graphics/CMGraphicsBase.gd index 7c62cfe..10c5a4f 100644 --- a/modules/graphics/CMGraphicsBase.gd +++ b/modules/graphics/CMGraphicsBase.gd @@ -230,6 +230,12 @@ func UpdateGraphics(stateHandle): if(sprite != null): _UpdateSprite(sprite, stateHandle) +func InitPhaseStartEntity(stateHandle): + var spriteData = { + "Null": _CreateSpriteData() + } + stateHandle.IDEntitySet("SpriteData", spriteData) + func InitPhaseEndEntity(stateHandle): SetPalette(stateHandle, stateHandle.GetPlayer()) @@ -320,14 +326,10 @@ func CreateSprite(args, stateHandle): stateHandle.EntitySet("_SpriteUseSpritesheets", (1 if spriteFramesPath == null else 0)) var sprite = _CreateSprite_Instance(spriteFramesPath) - var spriteData = { - "Null": _CreateSpriteData() - } _EnsureRootIsSet(stateHandle) stateHandle.IDEntityGet("Root").add_child(sprite) stateHandle.IDEntitySet("Sprite", sprite) - stateHandle.IDEntitySet("SpriteData", spriteData) func _CreateSpriteData(): return { diff --git a/modules/physics/CMPhysics2D.gd b/modules/physics/CMPhysics2D.gd index 64bffc0..868f199 100644 --- a/modules/physics/CMPhysics2D.gd +++ b/modules/physics/CMPhysics2D.gd @@ -89,6 +89,8 @@ func ModuleSetup(): RegisterVariableEntity("_PositionX", 0) RegisterVariableEntity("_PositionY", 0) + RegisterVariableEntity("_PrevPositionX", 0) + RegisterVariableEntity("_PrevPositionY", 0) RegisterVariableEntity("_MovementX", 0, ["ResetEachFrame"]) RegisterVariableEntity("_MovementY", 0, ["ResetEachFrame"]) @@ -399,6 +401,8 @@ func ActionPhaseEndEntity(stateHandle): func PhysicsPhaseStart(_stateHandle): pass func PhysicsPhaseStartEntity(stateHandle): + stateHandle.EntitySet("_PrevPositionX", stateHandle.EntityGet("_PositionX")) + stateHandle.EntitySet("_PrevPositionY", stateHandle.EntityGet("_PositionY")) for pf in _physicsFlagList: if(stateHandle.EntityHasFlag(pf)): stateHandle.EntityAdd("_PhysicsFlagBuffer", [pf]) @@ -932,20 +936,20 @@ func GetTargetPositionRelativeToSelf(args, stateHandle): # -------------------------------------------------------------------------------------------------- # Physics code -func PhysicsPhase(stateHandle, prevStateHandle, activeEIDs): +func PhysicsPhase(stateHandle, activeEIDs): # 1. Colbox and Environment Collisions - PhysicsPhaseEnvironment(stateHandle, prevStateHandle, activeEIDs) + PhysicsPhaseEnvironment(stateHandle, activeEIDs) # 2. Attack collisions PhysicsPhaseAttack(stateHandle, activeEIDs) -func PhysicsPhaseEnvironment(stateHandle, prevStateHandle, activeEIDs): +func PhysicsPhaseEnvironment(stateHandle, activeEIDs): # Checks environment collisions for each entity separately var nbBuckets = stateHandle.ConfigData().Get("PhysicsNbBuckets") # Gather colboxes and env constraints - var envConstraints = GetEnvironmentConstraints(stateHandle, prevStateHandle) + var envConstraints = GetEnvironmentConstraints(stateHandle) var colboxes = [] for eid in activeEIDs: stateHandle.PointToEntity(eid) @@ -1010,7 +1014,7 @@ func PhysicsPhaseEnvironment(stateHandle, prevStateHandle, activeEIDs): for colboxCol in validColboxCollisions: var colboxA = colboxes[colboxCol[0]] var colboxB = colboxes[colboxCol[1]] - PhysicsEnv_ColboxColbox(stateHandle, prevStateHandle, colboxA, colboxB) + PhysicsEnv_ColboxColbox(stateHandle, colboxA, colboxB) # Do environment constraints for envCol in validEnvironmentCollisions: @@ -1072,18 +1076,14 @@ func PhysicsEnv_ApplyEnvConstraint(stateHandle, colbox, envc): else: ModuleError("PhysicsEnv: Env Constraint of unknown type: "+ str(envcType)) -func PhysicsEnv_ColboxColbox(stateHandle, prevStateHandle, colboxA, colboxB): +func PhysicsEnv_ColboxColbox(stateHandle, colboxA, colboxB): stateHandle.PointToEntity(colboxA["Owner"]) var colposA = GetBoxPosition(stateHandle, colboxA) - var prevXA = stateHandle.EntityGet("_PositionX") - if(prevStateHandle.PointToEntity(colboxA["Owner"])): - prevXA = prevStateHandle.EntityGet("_PositionX") + var prevXA = stateHandle.EntityGet("_PrevPositionX") stateHandle.PointToEntity(colboxB["Owner"]) var colposB = GetBoxPosition(stateHandle, colboxB) - var prevXB = stateHandle.EntityGet("_PositionX") - if(prevStateHandle.PointToEntity(colboxB["Owner"])): - prevXB = prevStateHandle.EntityGet("_PositionX") + var prevXB = stateHandle.EntityGet("_PrevPositionX") # Check collision if(!AreBoxesOverlapping(colposA, colposB)): @@ -1244,12 +1244,12 @@ func PhysicsAtk_HandleAttackDefend(stateHandle, attackerEID, defenderEID, attack return true return false -func GetEnvironmentConstraints(stateHandle, prevStateHandle): +func GetEnvironmentConstraints(stateHandle): if(stateHandle.ConfigData().Get("UseFightingArena")): - return CreateFightingArena(stateHandle, prevStateHandle) + return CreateFightingArena(stateHandle) return [] -func CreateFightingArena(stateHandle, prevStateHandle): +func CreateFightingArena(stateHandle): # Ground # If two player: special walls and camera # If other count: normal walls @@ -1267,11 +1267,13 @@ func CreateFightingArena(stateHandle, prevStateHandle): var eid1 = stateHandle.PlayerGet("MainEntity") stateHandle.PointToEntity(eid1) var p1Pos = stateHandle.EntityGet("_PositionX") + var p1OldPos = stateHandle.EntityGet("_PrevPositionX") stateHandle.PointToPlayer(1) var eid2 = stateHandle.PlayerGet("MainEntity") stateHandle.PointToEntity(eid2) var p2Pos = stateHandle.EntityGet("_PositionX") + var p2OldPos = stateHandle.EntityGet("_PrevPositionX") var centerPos = (p1Pos+p2Pos)/2 var p1Left = (p1Pos <= p2Pos) @@ -1280,13 +1282,6 @@ func CreateFightingArena(stateHandle, prevStateHandle): # Just giving priority to the player below would be janky too if(p1Pos == p2Pos): - var p1OldPos = p1Pos - var p2OldPos = p2Pos - - if(prevStateHandle.PointToEntity(eid1)): - p1OldPos = prevStateHandle.EntityGet("_PositionX") - if(prevStateHandle.PointToEntity(eid2)): - p2OldPos = prevStateHandle.EntityGet("_PositionX") p1Left = (p1OldPos <= p2OldPos) envConstraints.push_back({"Type":ENVC_TYPES.AAPlane, "Dir":ENVC_AAPLANE_DIR.Right,