| @@ -0,0 +1,70 @@ | ||
| //--- OBJECT WRITE BEGIN --- | ||
| new Root(BotTree) { | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new Parallel() { | ||
| returnPolicy = "REQUIRE_ALL"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new Ticker() { | ||
| frequencyMs = "1000"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new Loop() { | ||
| numLoops = "0"; | ||
| terminationPolicy = "ON_FAILURE"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new ScriptedBehavior() { | ||
| preconditionMode = "ONCE"; | ||
| internalName = "look for enemy"; | ||
| class = "pickTargetTask"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| }; | ||
| }; | ||
| new Loop() { | ||
| numLoops = "0"; | ||
| terminationPolicy = "ON_FAILURE"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new ActiveSelector() { | ||
| recheckFrequency = "1000"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new SubTree() { | ||
| subTreeName = "getHealthTree"; | ||
| internalName = "get health"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| new SubTree() { | ||
| subTreeName = "combatTree"; | ||
| internalName = "combat"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| new SubTree() { | ||
| subTreeName = "PatrolTree"; | ||
| internalName = "patrol"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| new SubTree() { | ||
| subTreeName = "WanderTree"; | ||
| internalName = "wander"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
| //--- OBJECT WRITE END --- |
| @@ -0,0 +1,99 @@ | ||
| //--- OBJECT WRITE BEGIN --- | ||
| new Root(CombatTree) { | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new Sequence() { | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new ScriptEval() { | ||
| behaviorScript = "if (isObject(%obj.targetObject) && %obj.targetObject.isEnabled()) return SUCCESS;"; | ||
| defaultReturnStatus = "FAILURE"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| new Parallel() { | ||
| returnPolicy = "REQUIRE_ALL"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new Loop() { | ||
| numLoops = "0"; | ||
| terminationPolicy = "ON_FAILURE"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new Sequence() { | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new ScriptedBehavior() { | ||
| preconditionMode = "ONCE"; | ||
| internalName = "combatMoveTask"; | ||
| class = "combatMoveTask"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| new RandomWait() { | ||
| waitMinMs = "500"; | ||
| waitMaxMs = "1000"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| }; | ||
| }; | ||
| new Loop() { | ||
| numLoops = "0"; | ||
| terminationPolicy = "ON_FAILURE"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new Ticker() { | ||
| frequencyMs = "500"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new ScriptedBehavior() { | ||
| preconditionMode = "TICK"; | ||
| internalName = "aim"; | ||
| class = "aimAtTargetTask"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| }; | ||
| }; | ||
| new Loop() { | ||
| numLoops = "0"; | ||
| terminationPolicy = "ON_FAILURE"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new SucceedAlways() { | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new Sequence() { | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new ScriptedBehavior() { | ||
| preconditionMode = "ONCE"; | ||
| internalName = "fire"; | ||
| class = "shootAtTargetTask"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| new RandomWait() { | ||
| waitMinMs = "500"; | ||
| waitMaxMs = "1000"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
| //--- OBJECT WRITE END --- |
| @@ -0,0 +1,33 @@ | ||
| //--- OBJECT WRITE BEGIN --- | ||
| new Root(getHealthTree) { | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new Sequence() { | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
|
|
||
| new ScriptEval() { | ||
| behaviorScript = "if (%obj.getDamagePercent() > 0.75) return SUCCESS;"; | ||
| defaultReturnStatus = "FAILURE"; | ||
| internalName = "need health?"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| new ScriptedBehavior() { | ||
| preconditionMode = "ONCE"; | ||
| internalName = "look for health"; | ||
| class = "findHealthTask"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| new ScriptedBehavior() { | ||
| preconditionMode = "TICK"; | ||
| internalName = "get health"; | ||
| class = "getHealthTask"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| }; | ||
| }; | ||
| }; | ||
| //--- OBJECT WRITE END --- |
| @@ -0,0 +1,50 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| $BotMatchTickFrequency = 250; | ||
|
|
||
| // start a bot match | ||
| function botMatch(%numBots) | ||
| { | ||
| // Avoid having lots of dead bodies lying around. | ||
| $CorpseTimeoutValue = 2000; | ||
|
|
||
| // script object to attach the BT to | ||
| if(!isObject(BotMatch)) | ||
| new ScriptObject(botMatch); | ||
|
|
||
| // number of bots that will be spawned | ||
| botMatch.numBots = %numBots; | ||
|
|
||
| // set the behavior tree | ||
| botMatch.setBehavior(botMatchTree, $BotMatchTickFrequency); | ||
| } | ||
|
|
||
|
|
||
| // cancel the match | ||
| function cancelBotmatch() | ||
| { | ||
| // post the signal to the behavior tree | ||
| if(isObject(botMatch)) | ||
| botMatch.behaviorTree.postSignal("onBotmatchCancel"); | ||
| } | ||
|
|
| @@ -0,0 +1,25 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| exec("./behaviorTreeManager.cs"); | ||
| exec("./BadBot.cs"); | ||
| exec("./botMatch.cs"); |
| @@ -0,0 +1,217 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| //--- OBJECT WRITE BEGIN --- | ||
| %guiContent = new GuiControl(BTEditorCreatePrompt,EditorGuiGroup) { | ||
| position = "0 0"; | ||
| extent = "1024 768"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiDefaultProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| fixedAspectRatio = "0"; | ||
|
|
||
| new GuiWindowCtrl() { | ||
| text = "Create New Tree"; | ||
| resizeWidth = "0"; | ||
| resizeHeight = "0"; | ||
| canMove = "0"; | ||
| canClose = "1"; | ||
| canMinimize = "0"; | ||
| canMaximize = "0"; | ||
| canCollapse = "0"; | ||
| closeCommand = "canvas.popDialog(DatablockEditorCreatePrompt);"; | ||
| edgeSnap = "0"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "389 252"; | ||
| extent = "207 145"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiWindowProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiTextCtrl() { | ||
| text = "Your new tree must have a name"; | ||
| maxLength = "1024"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "7 26"; | ||
| extent = "190 15"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiTextProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "0"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
| }; | ||
| new GuiTextEditCtrl() { | ||
| historySize = "0"; | ||
| tabComplete = "0"; | ||
| sinkAllKeyEvents = "0"; | ||
| password = "0"; | ||
| passwordMask = "*"; | ||
| text = "Name"; | ||
| maxLength = "1024"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "7 45"; | ||
| extent = "191 18"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiTextEditProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "0"; | ||
| internalName = "CreateTreeName"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
| }; | ||
| new GuiButtonCtrl() { | ||
| text = "Create"; | ||
| groupNum = "-1"; | ||
| buttonType = "PushButton"; | ||
| useMouseEvents = "0"; | ||
| position = "7 114"; | ||
| extent = "122 22"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiButtonProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| Command = "BTEditor.createPromptNameCheck();"; | ||
| accelerator = "return"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "0"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
| }; | ||
| new GuiButtonCtrl() { | ||
| text = "Cancel"; | ||
| groupNum = "-1"; | ||
| buttonType = "PushButton"; | ||
| useMouseEvents = "0"; | ||
| position = "135 114"; | ||
| extent = "63 22"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiButtonProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| Command = "canvas.popDialog(BTEditorCreatePrompt);"; | ||
| accelerator = "escape"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "0"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
| }; | ||
| new GuiTextCtrl() { | ||
| text = "Copy tree from"; | ||
| maxLength = "1024"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "7 66"; | ||
| extent = "100 17"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiTextProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "0"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
| }; | ||
| new GuiPopUpMenuCtrl() { | ||
| maxPopupHeight = "200"; | ||
| sbUsesNAColor = "0"; | ||
| reverseTextList = "0"; | ||
| bitmapBounds = "16 16"; | ||
| maxLength = "1024"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "7 87"; | ||
| extent = "191 19"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "GuiPopUpMenuProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "0"; | ||
| internalName = "CopySourceDropdown"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
| }; | ||
| }; | ||
| }; | ||
| //--- OBJECT WRITE END --- |
| @@ -0,0 +1,321 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| //--- OBJECT WRITE BEGIN --- | ||
| %guiContent = new GuiControl(BTEditor) { | ||
| position = "0 0"; | ||
| extent = "1024 768"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "width"; | ||
| vertSizing = "height"; | ||
| profile = "ToolsGuiDefaultProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "1"; | ||
| lastContent = "1663"; | ||
|
|
||
| new GuiControl() { | ||
| position = "0 0"; | ||
| extent = "1024 32"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "width"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiDefaultProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| internalName = "top bar"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiContainer(BTToolBar) { | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "0 0"; | ||
| extent = "16000 32"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "menubarProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiControl() { | ||
| position = "5 0"; | ||
| extent = "695 32"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "width"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiDefaultProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiPopUpMenuCtrl(BTEditorContentList) { | ||
| maxPopupHeight = "200"; | ||
| sbUsesNAColor = "0"; | ||
| reverseTextList = "0"; | ||
| bitmapBounds = "16 16"; | ||
| text = "BotBehavior"; | ||
| maxLength = "1024"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "8 7"; | ||
| extent = "145 18"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiPopUpMenuProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "ToolsGuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "0"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
| new GuiControl() { | ||
| position = "0 32"; | ||
| extent = "1024 719"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "width"; | ||
| vertSizing = "height"; | ||
| profile = "ToolsGuiDefaultProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| internalName = "middle bar"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiFrameSetCtrl() { | ||
| columns = "0 514"; | ||
| rows = "0"; | ||
| borderWidth = "4"; | ||
| borderColor = "48 32 48 32"; | ||
| borderEnable = "alwaysOn"; | ||
| borderMovable = "alwaysOn"; | ||
| autoBalance = "0"; | ||
| fudgeFactor = "0"; | ||
| docking = "None"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "0 0"; | ||
| extent = "1024 719"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "width"; | ||
| vertSizing = "height"; | ||
| profile = "ToolsGuiFrameSetProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiContainer() { | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "0 0"; | ||
| extent = "510 719"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "width"; | ||
| vertSizing = "height"; | ||
| profile = "GuiDefaultProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiTabBookCtrl(BTEditorTabBook) { | ||
| tabPosition = "Top"; | ||
| tabMargin = "7"; | ||
| minTabWidth = "48"; | ||
| tabHeight = "20"; | ||
| allowReorder = "1"; | ||
| defaultPage = "0"; | ||
| selectedPage = "0"; | ||
| frontTabPadding = "0"; | ||
| docking = "Client"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "0 0"; | ||
| extent = "510 719"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "width"; | ||
| vertSizing = "height"; | ||
| profile = "ToolsGuiTabBookProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| }; | ||
| }; | ||
| new GuiScrollCtrl() { | ||
| willFirstRespond = "1"; | ||
| hScrollBar = "alwaysOn"; | ||
| vScrollBar = "alwaysOn"; | ||
| lockHorizScroll = "0"; | ||
| lockVertScroll = "0"; | ||
| constantThumbHeight = "0"; | ||
| childMargin = "0 0"; | ||
| mouseWheelScrollSpeed = "-1"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "514 0"; | ||
| extent = "510 719"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiScrollProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiInspector(BehaviorTreeInspector) { | ||
| dividerMargin = "5"; | ||
| showCustomFields = "1"; | ||
| stackingType = "Vertical"; | ||
| horizStacking = "Left to Right"; | ||
| vertStacking = "Top to Bottom"; | ||
| padding = "1"; | ||
| dynamicSize = "1"; | ||
| dynamicNonStackExtent = "0"; | ||
| dynamicPos = "0"; | ||
| changeChildSizeToFit = "1"; | ||
| changeChildPosition = "1"; | ||
| position = "1 1"; | ||
| extent = "493 328"; | ||
| minExtent = "16 16"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "GuiInspectorProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
| new GuiControl() { | ||
| position = "0 751"; | ||
| extent = "1024 17"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "width"; | ||
| vertSizing = "top"; | ||
| profile = "menubarProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| internalName = "bottom bar"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiTextCtrl(BTEditorStatusBar) { | ||
| text = "Status"; | ||
| maxLength = "1024"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "5 0"; | ||
| extent = "1019 17"; | ||
| minExtent = "64 17"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "ToolsGuiTextProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "1"; | ||
| canSaveDynamicFields = "0"; | ||
| }; | ||
| }; | ||
| }; | ||
| //--- OBJECT WRITE END --- |
| @@ -0,0 +1,31 @@ | ||
| function reloadBTE() | ||
| { | ||
| if(isObject(BehaviorTreeEditorGui)) | ||
| BehaviorTreeEditorGui.delete(); | ||
|
|
||
| initializeBehaviorTreeEditor(); | ||
| } | ||
|
|
||
| function initializeBehaviorTreeEditor() | ||
| { | ||
| echo( " % - Initializing Behavior Tree Editor" ); | ||
|
|
||
| // exec the scripts and gui | ||
| exec("./scripts/behaviorTreeEditorProfiles.ed.cs"); | ||
| exec("./gui/behaviorTreeEditor.ed.gui"); | ||
| exec("./gui/BTEditorCreatePrompt.ed.gui"); | ||
| exec("./scripts/guiBehaviorTreeViewCtrl.ed.cs"); | ||
| exec("./scripts/behaviorTreeEditorCanvas.ed.cs"); | ||
| exec("./scripts/behaviorTreeEditor.ed.cs"); | ||
| exec("./scripts/behaviorTreeEditorUndo.ed.cs"); | ||
| exec("./scripts/behaviorTreeEditorStatusBar.ed.cs"); | ||
| exec("./scripts/behaviorTreeEditorContentList.ed.cs"); | ||
| exec("./scripts/behaviorTreeEditorInspector.ed.cs"); | ||
|
|
||
| // register the class icons | ||
| EditorIconRegistry::loadFromPath("tools/behaviorTreeEditor/images/classIcons/"); | ||
| } | ||
|
|
||
| function destroyBehaviorTreeEditor() | ||
| { | ||
| } |
| @@ -0,0 +1,390 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| $inBehaviorTreeEditor = false; | ||
|
|
||
| //============================================================================== | ||
| // INIT | ||
| //============================================================================== | ||
| function BTEdit() | ||
| { | ||
| if (!$InBehaviorTreeEditor) | ||
| { | ||
| if(!isObject(BTEditCanvas)) | ||
| new GuiControl(BTEditCanvas, EditorGuiGroup); | ||
|
|
||
| BTEditor.startUp(Canvas.getContent()); | ||
|
|
||
| $InBehaviorTreeEditor = true; | ||
| BehaviorTreeManager.onBehaviorTreeEditor(true); | ||
| } | ||
| else | ||
| { | ||
| BTEditCanvas.quit(); | ||
| } | ||
| } | ||
|
|
||
| function toggleBehaviorTreeEditor( %make ) | ||
| { | ||
| if( %make ) | ||
| { | ||
| BTEdit(); | ||
| cancel($Game::Schedule); | ||
| } | ||
| } | ||
|
|
||
| GlobalActionMap.bind( keyboard, "ctrl f9", toggleBehaviorTreeEditor ); | ||
|
|
||
|
|
||
| function BTEditor::startUp(%this, %content) | ||
| { | ||
| %this.lastContent=%content; | ||
| Canvas.setContent( BTEditor ); | ||
|
|
||
| if(!isObject(BehaviorTreeManager)) | ||
| // This isn't pretty, but we need to load up existing trees | ||
| exec("scripts/server/BadBehavior/behaviorTreeManager.cs"); | ||
|
|
||
| if(BehaviorTreeGroup.getCount() == 0) | ||
| { | ||
| %this.createTree(); | ||
| } | ||
| else | ||
| { | ||
| BTEditorContentList.refresh(); | ||
| if(BTEditorTabBook.getCount() == 0) | ||
| BTEditorContentList.setFirstSelected(); | ||
| } | ||
|
|
||
| %this.updateUndoMenu(); | ||
| %this.updateNodeTypes(); | ||
| } | ||
|
|
||
|
|
||
| function BTEditor::updateNodeTypes(%this) | ||
| { | ||
| if(isObject(BTNodeTypes)) | ||
| BTNodeTypes.delete(); | ||
|
|
||
| new SimSet(BTNodeTypes); | ||
| %set = new SimSet() { | ||
| internalName = "Composite"; | ||
| }; | ||
| %set.add( new ScriptObject() { nodeType = "ActiveSelector"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "Parallel"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "RandomSelector"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "Selector"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "Sequence"; } ); | ||
| BTNodeTypes.add(%set); | ||
|
|
||
| %set = new SimSet() { | ||
| internalName = "Decorator"; | ||
| }; | ||
| %set.add( new ScriptObject() { nodeType = "FailAlways"; }); | ||
| %set.add( new ScriptObject() { nodeType = "Inverter"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "Loop"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "Monitor"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "SucceedAlways"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "Ticker"; } ); | ||
| BTNodeTypes.add(%set); | ||
|
|
||
| %set = new SimSet() { | ||
| internalName = "Leaf"; | ||
| }; | ||
| %set.add( new ScriptObject() { nodeType = "RandomWait"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "ScriptedBehavior"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "ScriptEval"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "ScriptFunc"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "SubTree"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "Wait"; } ); | ||
| %set.add( new ScriptObject() { nodeType = "WaitForSignal"; } ); | ||
| BTNodeTypes.add(%set); | ||
| } | ||
|
|
||
| function BTEditor::getBaseNodeType(%this, %type) | ||
| { | ||
| foreach(%baseType in BTNodeTypes) | ||
| { | ||
| if(%baseType.internalName $= %type) // supplied basetype | ||
| return %type; | ||
|
|
||
| foreach(%derivedType in %baseType) // supplied derived type | ||
| { | ||
| if(%derivedType.nodeType $= %type) | ||
| return %baseType.internalName; | ||
| } | ||
| } | ||
| return ""; | ||
| } | ||
|
|
||
| function BTEditor::viewTree(%this, %tree) | ||
| { | ||
| %viewPage = -1; | ||
| foreach(%page in BTEditorTabBook) | ||
| { | ||
| if(%page.rootNode == %tree) | ||
| { | ||
| %viewPage = %page; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if(isObject(%viewPage)) | ||
| { | ||
| %viewPage.select(); | ||
| } | ||
| else | ||
| { | ||
| %newPage = BTEditor::newPage(); | ||
| %newPage.setText(%tree.name); | ||
| %newPage.rootNode = %tree; | ||
| BTEditorTabBook.addGuiControl(%newPage); | ||
| %newPage-->BTView.open(%tree); | ||
| %newPage-->BTView.refresh(); | ||
| } | ||
| %this.updateUndoMenu(); | ||
| } | ||
|
|
||
| function BTEditor::createTree(%this) | ||
| { | ||
| %list = BTEditorCreatePrompt-->CopySourceDropdown; | ||
| %list.clear(); | ||
| foreach (%tree in BehaviorTreeGroup) | ||
| %list.add(%tree.getName(), %tree); | ||
| Canvas.pushDialog(BTEditorCreatePrompt); | ||
| } | ||
|
|
||
| function BTEditor::getCurrentViewCtrl(%this) | ||
| { | ||
| %pageId = BTEditorTabBook.getSelectedPage(); | ||
| if(%pageId >= 0) | ||
| return BTEditorTabBook.getObject(%pageId)-->BTView; | ||
|
|
||
| return %pageId; | ||
| } | ||
|
|
||
|
|
||
| function BTEditor::getTreeRoot(%this, %node) | ||
| { | ||
| %current = %node; | ||
| while(%current.getClassName() !$= "Root" && isObject(%current)) | ||
| { | ||
| %current = %current.getGroup(); | ||
| } | ||
| return %current; | ||
| } | ||
|
|
||
| function BTEditor::getCurrentRootNode(%this) | ||
| { | ||
| return %this.getCurrentViewCtrl().getRootNode(); | ||
| } | ||
|
|
||
|
|
||
| function BTEditor::createPromptNameCheck(%this) | ||
| { | ||
| %name = BTEditorCreatePrompt-->CreateTreeName.getText(); | ||
| if( !Editor::validateObjectName( %name, true ) ) | ||
| return; | ||
|
|
||
| // Fetch the copy source and clear the list. | ||
|
|
||
| %copySource = BTEditorCreatePrompt-->copySourceDropdown.getText(); | ||
| BTEditorCreatePrompt-->copySourceDropdown.clear(); | ||
|
|
||
| // Remove the dialog and create the tree. | ||
|
|
||
| canvas.popDialog( BTEditorCreatePrompt ); | ||
| %this.createTreeFinish( %name, %copySource ); | ||
| } | ||
|
|
||
| function BTEditor::createTreeFinish( %this, %name, %copySource ) | ||
| { | ||
| %newTree = -1; | ||
| pushInstantGroup(BehaviorTreeGroup); | ||
| if(%copySource !$= "") | ||
| { | ||
| %newTree = %copySource.deepClone(); | ||
| } | ||
| else | ||
| { | ||
| %newTree = new Root(); | ||
| } | ||
| popInstantGroup(); | ||
|
|
||
| %newTree.setName(%name); | ||
| %newTree.setFilename(""); | ||
|
|
||
| BTEditorContentList.refresh(); | ||
| BTEditorContentList.setSelected(BTEditorContentList.findText(%newTree.name)); | ||
| } | ||
|
|
||
| function BTEditor::saveTree(%this, %tree, %prompt) | ||
| { | ||
| // check we actually have something to save | ||
| if(!isObject(%tree)) | ||
| return; | ||
|
|
||
| if((%file = %tree.getFileName()) !$= "") | ||
| { | ||
| %path = filePath(%file); | ||
| } | ||
| else | ||
| { | ||
| %path = "scripts/server/BadBehavior/behaviorTrees"; | ||
| %file = %path @ "/" @ %tree.name; | ||
|
|
||
| if(!isDirectory(%path)) | ||
| createPath(%path @ "/"); | ||
|
|
||
| %prompt = true; | ||
| } | ||
|
|
||
| if(%prompt || !isFile(%file)) | ||
| { | ||
| %dlg = new SaveFileDialog() | ||
| { | ||
| filters = "Torque script files (*.cs)|*.cs|"; | ||
| defaultPath = %path; | ||
| defaultFile = %file; | ||
| changePath = true; | ||
| overwritePrompt = true; | ||
| }; | ||
|
|
||
| if(%dlg.execute()) | ||
| { | ||
| %file = %dlg.fileName; | ||
| %dlg.delete(); | ||
| } | ||
| else | ||
| { | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| %tree.save(%file); | ||
| %tree.setFileName(collapseFilename(%file)); | ||
| BTEditorStatusBar.setText("Saved '" @ %tree.name @ "' to file" SPC %tree.getFileName()); | ||
| } | ||
|
|
||
| //============================================================================== | ||
| // VIEW | ||
| //============================================================================== | ||
|
|
||
| function BTEditor::expandAll(%this) | ||
| { | ||
| %this.getCurrentViewCtrl().expandAll(); | ||
| } | ||
|
|
||
| function BTEditor::collapseAll(%this) | ||
| { | ||
| %this.getCurrentViewCtrl().collapseAll(); | ||
| } | ||
|
|
||
|
|
||
| function BTEditorTabBook::onTabClose(%this, %index) | ||
| { | ||
| if(%index == %this.selectedPage) | ||
| { | ||
| BehaviorTreeInspector.inspect(-1); | ||
| if(%this.getCount() > 1) | ||
| %this.getObject(0).select(); | ||
| else | ||
| BTEditor.ResetUndoMenu(); | ||
| } | ||
|
|
||
| %this.getObject(%index).delete(); | ||
| } | ||
|
|
||
| function BTEditorTabBook::onTabSelected(%this, %text, %index) | ||
| { | ||
| //echo("onTabSelected" TAB %text); | ||
| BTEditor.updateUndoMenu(); | ||
| BehaviorTreeInspector.inspect(BTEditor.getCurrentViewCtrl().getSelectedObject()); | ||
| } | ||
|
|
||
| function BTEditorTabBook::onTabRightClick(%this, %text, %index) | ||
| { | ||
| if(isObject(BTEditorTabBookPopup)) | ||
| BTEditorTabBookPopup.delete(); | ||
|
|
||
| %popup = new PopupMenu( BTEditorTabBookPopup ) | ||
| { | ||
| superClass = "MenuBuilder"; | ||
| isPopup = true; | ||
| item[ 0 ] = "Close" SPC %text SPC "tab" TAB "" TAB "BTEditorTabBook.onTabClose(" SPC %index SPC ");"; | ||
| }; | ||
|
|
||
| %popup.showPopup( Canvas ); | ||
| } | ||
|
|
||
| //============================================================================== | ||
| // UNDO | ||
| //============================================================================== | ||
| function BTEditor::getUndoManager( %this ) | ||
| { | ||
| return %this.getCurrentViewCtrl().getUndoManager(); | ||
| } | ||
|
|
||
|
|
||
| function BTEditor::updateUndoMenu(%this) | ||
| { | ||
| %uman = %this.getUndoManager(); | ||
| %nextUndo = %uman.getNextUndoName(); | ||
| %nextRedo = %uman.getNextRedoName(); | ||
|
|
||
| %editMenu = BTEditCanvas.menuBar->editMenu; | ||
|
|
||
| %editMenu.setItemName( 0, "Undo " @ %nextUndo ); | ||
| %editMenu.setItemName( 1, "Redo " @ %nextRedo ); | ||
|
|
||
| %editMenu.enableItem( 0, %nextUndo !$= "" ); | ||
| %editMenu.enableItem( 1, %nextRedo !$= "" ); | ||
| } | ||
|
|
||
| function BTEditor::ResetUndoMenu(%this) | ||
| { | ||
| %editMenu = BTEditCanvas.menuBar->editMenu; | ||
| %editMenu.setItemName( 0, "Undo" ); | ||
| %editMenu.setItemName( 1, "Redo" ); | ||
| %editMenu.enableItem( 0, false ); | ||
| %editMenu.enableItem( 1, false ); | ||
| } | ||
|
|
||
| function BTEditor::undo(%this) | ||
| { | ||
| %action = %this.getUndoManager().getNextUndoName(); | ||
|
|
||
| %this.getUndoManager().undo(); | ||
| %this.updateUndoMenu(); | ||
|
|
||
| BTEditorStatusBar.print( "Undid '" @ %action @ "'" ); | ||
| } | ||
|
|
||
| function BTEditor::redo(%this) | ||
| { | ||
| %action = %this.getUndoManager().getNextRedoName(); | ||
|
|
||
| %this.getUndoManager().redo(); | ||
| %this.updateUndoMenu(); | ||
|
|
||
| BTEditorStatusBar.print( "Redid '" @ %action @ "'" ); | ||
| } |
| @@ -0,0 +1,152 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| //============================================================================== | ||
| // INIT | ||
| //============================================================================== | ||
| function BTEditCanvas::onAdd( %this ) | ||
| { | ||
| %this.onCreateMenu(); | ||
|
|
||
| // close any invalid tab book pages | ||
| for( %i=0; %i < BTEditorTabBook.getCount(); %i++) | ||
| { | ||
| %page = BTEditorTabBook.getObject(%i); | ||
| if(!isObject(%page.rootNode) || %page.rootNode.getClassName() !$= "Root") | ||
| { | ||
| BTEditorTabBook.remove(%page); | ||
| %page.delete(); | ||
| %i--; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| function BTEditCanvas::onRemove( %this ) | ||
| { | ||
| if( isObject( BehaviorTreeEditorGui.menuGroup ) ) | ||
| BehaviorTreeEditorGui.delete(); | ||
|
|
||
| // cleanup | ||
| %this.onDestroyMenu(); | ||
|
|
||
| //BTEditorTabBook.deleteAllObjects(); | ||
| } | ||
|
|
||
| function BTEditCanvas::quit( %this ) | ||
| { | ||
| // we must not delete a window while in its event handler, or we foul the event dispatch mechanism | ||
| %this.schedule(10, delete); | ||
|
|
||
| Canvas.setContent(BTEditor.lastContent); | ||
| $InBehaviorTreeEditor = false; | ||
| BehaviorTreeManager.onBehaviorTreeEditor(false); | ||
| } | ||
|
|
||
| //============================================================================== | ||
| // MENU | ||
| //============================================================================== | ||
| function BTEditCanvas::onCreateMenu(%this) | ||
| { | ||
| if(isObject(%this.menuBar)) | ||
| return; | ||
|
|
||
| //set up %cmdctrl variable so that it matches OS standards | ||
| if( $platform $= "macos" ) | ||
| { | ||
| %cmdCtrl = "cmd"; | ||
| %redoShortcut = "Cmd-Shift Z"; | ||
| } | ||
| else | ||
| { | ||
| %cmdCtrl = "Ctrl"; | ||
| %redoShortcut = "Ctrl Y"; | ||
| } | ||
|
|
||
| // Menu bar | ||
| %this.menuBar = new MenuBar() | ||
| { | ||
| dynamicItemInsertPos = 3; | ||
|
|
||
| new PopupMenu() | ||
| { | ||
| superClass = "MenuBuilder"; | ||
| barTitle = "File"; | ||
| internalName = "FileMenu"; | ||
|
|
||
| item[0] = "New Tree..." TAB %cmdCtrl SPC "N" TAB "BTEditor.createTree();"; | ||
| item[1] = "Open..." TAB %cmdCtrl SPC "O" TAB %this @ ".open();"; | ||
| item[2] = "Save Tree" TAB %cmdCtrl SPC "S" TAB "BTEditor.saveTree( BTEditor.getCurrentRootNode(), false );"; | ||
| item[3] = "Save Tree As..." TAB %cmdCtrl @ "-Shift S" TAB "BTEditor.saveTree( BTEditor.getCurrentRootNode(), true );"; | ||
| item[4] = "-"; | ||
| item[5] = "Close Editor" TAB "F9" TAB %this @ ".quit();"; | ||
| item[6] = "Quit" TAB %cmdCtrl SPC "Q" TAB "quit();"; | ||
| }; | ||
|
|
||
| new PopupMenu() | ||
| { | ||
| superClass = "MenuBuilder"; | ||
| barTitle = "Edit"; | ||
| internalName = "EditMenu"; | ||
|
|
||
| item[0] = "Undo" TAB %cmdCtrl SPC "Z" TAB "BTEditor.undo();"; | ||
| item[1] = "Redo" TAB %redoShortcut TAB "BTEditor.redo();"; | ||
| item[2] = "-"; | ||
| item[3] = "Delete node" TAB "" TAB "BTEditor.getCurrentViewCtrl().deleteSelection();"; | ||
| item[4] = "Excise node" TAB "" TAB "BTEditor.getCurrentViewCtrl().exciseSelection();"; | ||
| }; | ||
|
|
||
| new PopupMenu() | ||
| { | ||
| superClass = "MenuBuilder"; | ||
| barTitle = "View"; | ||
| internalName = "ViewMenu"; | ||
|
|
||
| item[0] = "Expand All" TAB %cmdCtrl SPC "=" TAB "BTEditor.expandAll();"; | ||
| item[1] = "Collapse All" TAB %cmdCtrl SPC "-" TAB "BTEditor.collapseAll();"; | ||
| }; | ||
|
|
||
| new PopupMenu() | ||
| { | ||
| superClass = "MenuBuilder"; | ||
| internalName = "HelpMenu"; | ||
|
|
||
| barTitle = "Help"; | ||
|
|
||
| Item[0] = "Help will arrive soon......"; | ||
| }; | ||
| }; | ||
| %this.menuBar.attachToCanvas(Canvas, 0); | ||
| } | ||
|
|
||
| function BTEditCanvas::onDestroyMenu(%this) | ||
| { | ||
| if( !isObject( %this.menuBar ) ) | ||
| return; | ||
|
|
||
| // Destroy menus | ||
| while( %this.menuBar.getCount() != 0 ) | ||
| %this.menuBar.getObject( 0 ).delete(); | ||
|
|
||
| %this.menuBar.removeFromCanvas(); | ||
| %this.menuBar.delete(); | ||
| } | ||
|
|
| @@ -0,0 +1,133 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| function BTEditorContentList::refresh(%this) | ||
| { | ||
| %this.clear(); | ||
| foreach(%tree in BehaviorTreeGroup) | ||
| %this.add(%tree.name, %tree); | ||
| } | ||
|
|
||
| function BTEditorContentList::onSelect( %this, %tree ) | ||
| { | ||
| BTEditor.viewTree( %tree ); | ||
| } | ||
|
|
||
|
|
||
|
|
||
| function BTEditor::newPage() | ||
| { | ||
| %page = new GuiTabPageCtrl() { | ||
| fitBook = "1"; | ||
| maxLength = "1024"; | ||
| docking = "client"; | ||
| margin = "-1 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "0 0 "; | ||
| extent = "200 200"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "width"; | ||
| vertSizing = "height"; | ||
| profile = "GuiTabPageProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "0"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiScrollCtrl() { | ||
| willFirstRespond = "1"; | ||
| hScrollBar = "dynamic"; | ||
| vScrollBar = "alwaysOn"; | ||
| lockHorizScroll = "0"; | ||
| lockVertScroll = "0"; | ||
| constantThumbHeight = "0"; | ||
| childMargin = "1 1"; | ||
| mouseWheelScrollSpeed = "-1"; | ||
| margin = "0 0 0 0"; | ||
| padding = "0 0 0 0"; | ||
| anchorTop = "1"; | ||
| anchorBottom = "0"; | ||
| anchorLeft = "1"; | ||
| anchorRight = "0"; | ||
| position = "0 0"; | ||
| extent = "400 400"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "width"; | ||
| vertSizing = "height"; | ||
| profile = "GuiScrollProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "0"; | ||
| docking="client"; | ||
| canSaveDynamicFields = "0"; | ||
|
|
||
| new GuiBehaviorTreeViewCtrl() { | ||
| internalName="BTView"; | ||
| tabSize = "17"; | ||
| textOffset = "8"; | ||
| fullRowSelect = "0"; | ||
| itemHeight = "21"; | ||
| destroyTreeOnSleep = "0"; | ||
| mouseDragging = "1"; | ||
| multipleSelections = "0"; | ||
| deleteObjectAllowed = "1"; | ||
| dragToItemAllowed = "1"; | ||
| clearAllOnSingleSelection = "1"; | ||
| showRoot = "1"; | ||
| useInspectorTooltips = "0"; | ||
| tooltipOnWidthOnly = "0"; | ||
| showObjectIds = "0"; | ||
| showClassNames = "1"; | ||
| showObjectNames = "1"; | ||
| showInternalNames = "1"; | ||
| showClassNameForUnnamedObjects = "0"; | ||
| compareToObjectID = "1"; | ||
| canRenameObjects = "1"; | ||
| renameInternal = "0"; | ||
| position = "1 1"; | ||
| extent = "267 231"; | ||
| minExtent = "8 2"; | ||
| horizSizing = "right"; | ||
| vertSizing = "bottom"; | ||
| profile = "GuiBehaviorTreeViewProfile"; | ||
| visible = "1"; | ||
| active = "1"; | ||
| tooltipProfile = "GuiToolTipProfile"; | ||
| hovertime = "1000"; | ||
| isContainer = "1"; | ||
| canSave = "0"; | ||
| canSaveDynamicFields = ""; | ||
| }; | ||
| }; | ||
| }; | ||
| return %page; | ||
| } |
| @@ -0,0 +1,50 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| //============================================================================== | ||
| // inspector field changed | ||
| //============================================================================== | ||
| function BehaviorTreeInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) | ||
| { | ||
| //echo("onInspectorFieldModified" SPC %object SPC %fieldName SPC %arrayIndex SPC %oldValue SPC %newValue); | ||
|
|
||
| // select the correct page | ||
| %treeRoot = BTEditor.getTreeRoot(%object); | ||
| %targetView = -1; | ||
| foreach(%page in BTEditorTabBook) | ||
| { | ||
| %view = %page-->BTView; | ||
| if(%view.getRootNode() == %treeRoot) | ||
| %targetView = %view; | ||
| } | ||
|
|
||
| if(!isObject(%targetView)) | ||
| { | ||
| warn("OOPS - something went wrong with the inspector!"); | ||
| return; | ||
| } | ||
|
|
||
| %action = BTInspectorUndoAction::create(%object, %fieldName, %arrayIndex, %oldValue, %newValue); | ||
| %action.addToManager( %targetView.getUndoManager() ); | ||
|
|
||
| BTEditor.updateUndoMenu(); | ||
| } |
| @@ -0,0 +1,26 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| singleton GuiControlProfile(GuiBehaviorTreeViewProfile : ToolsGuiTreeViewProfile) | ||
| { | ||
| bitmap = "tools/behaviorTreeEditor/images/BehaviorTreeView.png"; | ||
| }; |
| @@ -0,0 +1,41 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| function BTEditorStatusBar::print( %this, %message ) | ||
| { | ||
| %this.setText( %message ); | ||
|
|
||
| %sequenceNum = %this.sequenceNum + 1; | ||
| %this.sequenceNum = %sequenceNum; | ||
|
|
||
| %this.schedule( 4 * 1000, "clearMessage", %sequenceNum ); | ||
| } | ||
|
|
||
| //--------------------------------------------------------------------------------------------- | ||
|
|
||
| function BTEditorStatusBar::clearMessage( %this, %sequenceNum ) | ||
| { | ||
| // If we had no newer message in the meantime, clear | ||
| // out the current text. | ||
|
|
||
| %this.setText( "" ); | ||
| } |
| @@ -0,0 +1,174 @@ | ||
| //----------------------------------------------------------------------------- | ||
| // Copyright (c) 2014 Guy Allard | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to | ||
| // deal in the Software without restriction, including without limitation the | ||
| // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
| // sell copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| // IN THE SOFTWARE. | ||
| //----------------------------------------------------------------------------- | ||
|
|
||
| function BTEditorUndoManager::onAddUndo( %this ) | ||
| { | ||
| echo("Undo Added"); | ||
| BTEditor.updateUndoMenu(); | ||
| } | ||
|
|
||
| //============================================================================== | ||
| // create a node | ||
| //============================================================================== | ||
| function BTCreateUndoAction::submit( %undoObject ) | ||
| { | ||
| // The instant group will try to add our | ||
| // UndoAction if we don't disable it. | ||
| pushInstantGroup(); | ||
|
|
||
| // Create the undo action. | ||
| %action = new MECreateUndoAction() | ||
| { | ||
| className = "BTCreateUndoAction"; | ||
| actionName = "Create " @ %undoObject.getClassName(); | ||
| }; | ||
|
|
||
| // Restore the instant group. | ||
| popInstantGroup(); | ||
|
|
||
| // Set the object to undo. | ||
| %action.addObject( %undoObject ); | ||
|
|
||
| // Submit it. | ||
| %action.addToManager( BTEditor.getUndoManager() ); | ||
| } | ||
|
|
||
| function BTCreateUndoAction::onUndone( %this ) | ||
| { | ||
| //EWorldEditor.syncGui(); | ||
| } | ||
|
|
||
| function BTCreateUndoAction::onRedone( %this ) | ||
| { | ||
| //EWorldEditor.syncGui(); | ||
| } | ||
|
|
||
|
|
||
|
|
||
| //============================================================================== | ||
| // delete a node | ||
| //============================================================================== | ||
|
|
||
| /// A helper for submitting a delete undo action. | ||
| function BTDeleteUndoAction::submit( %deleteObject ) | ||
| { | ||
| // The instant group will try to add our | ||
| // UndoAction if we don't disable it. | ||
| pushInstantGroup(); | ||
|
|
||
| // Create the undo action. | ||
| %action = new BTDeleteUndoAction() | ||
| { | ||
| actionName = "delete node"; | ||
| }; | ||
|
|
||
| // Restore the instant group. | ||
| popInstantGroup(); | ||
|
|
||
| %action.deleteObject( %deleteObject ); | ||
|
|
||
| // Submit it. | ||
| %action.addToManager( BTEditor.getUndoManager() ); | ||
| } | ||
|
|
||
| function BTDeleteUndoAction::onUndone( %this ) | ||
| { | ||
| // for some reason this doesn't restore the correct order | ||
| //BTEditor.getCurrentViewCtrl().buildVisibleTree(true); | ||
| // so re-open the tree instead | ||
| BTEditor.getCurrentViewCtrl().refresh(); | ||
| } | ||
|
|
||
| function BTDeleteUndoAction::onRedone( %this ) | ||
| { | ||
| BTEditor.getCurrentViewCtrl().buildVisibleTree(true); | ||
| } | ||
|
|
||
| //============================================================================== | ||
| // reparent a node | ||
| //============================================================================== | ||
| function BTReparentUndoAction::create( %treeView ) | ||
| { | ||
| pushInstantGroup(); | ||
| %action = new UndoScriptAction() | ||
| { | ||
| class = "BTReparentUndoAction"; | ||
| actionName = "move node"; | ||
| control = %treeView; | ||
| }; | ||
| popInstantGroup(); | ||
|
|
||
| return %action; | ||
| } | ||
|
|
||
| function BTReparentUndoAction::undo(%this) | ||
| { | ||
| if(%this.newParent.isMember(%this.node)) | ||
| %this.newParent.remove(%this.node); | ||
|
|
||
| %this.oldParent.add(%this.node); | ||
|
|
||
| if(%this.oldPosition < %this.oldParent.getCount() - 1) | ||
| %this.oldParent.reorderChild(%this.node, %this.oldParent.getObject(%this.oldPosition)); | ||
|
|
||
| %this.control.refresh(); | ||
| } | ||
|
|
||
| function BTReparentUndoAction::redo(%this) | ||
| { | ||
| if(%this.oldParent.isMember(%this.node)) | ||
| %this.oldParent.remove(%this.node); | ||
|
|
||
| %this.newParent.add(%this.node); | ||
|
|
||
| if(%this.newPosition < %this.newParent.getCount() - 1) | ||
| %this.newParent.reorderChild(%this.node, %this.newParent.getObject(%this.newPosition)); | ||
|
|
||
| %this.control.refresh(); | ||
| } | ||
|
|
||
| //============================================================================== | ||
| // Inspector field modified | ||
| //============================================================================== | ||
| function BTInspectorUndoAction::create(%object, %fieldName, %arrayIndex, %oldValue, %newValue ) | ||
| { | ||
| %nameOrClass = %object.getName(); | ||
| if ( %nameOrClass $= "" ) | ||
| %nameOrClass = %object.getClassname(); | ||
|
|
||
| pushInstantGroup(); | ||
| %action = new InspectorFieldUndoAction() | ||
| { | ||
| class = "BTInspectorUndoAction"; | ||
| actionName = %nameOrClass @ "." @ %fieldName @ " Change"; | ||
|
|
||
| objectId = %object.getId(); | ||
| fieldName = %fieldName; | ||
| fieldValue = %oldValue; | ||
| arrayIndex = %arrayIndex; | ||
|
|
||
| inspectorGui = BehaviorTreeInspector; | ||
| }; | ||
| popInstantGroup(); | ||
|
|
||
| return %action; | ||
| } |