@@ -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");
@@ -320,6 +320,9 @@ function createAndConnectToLocalServer( %serverType, %level, %missionType )
}
}

// setup the behavior tree framework
exec("./BadBehavior/main.cs");

//Entity/Component stuff
if(isFile("./components/game/camera.cs"))
exec("./components/game/camera.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 ---
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -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;
}

Large diffs are not rendered by default.