mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-25 17:43:44 +00:00
BadBehavior added
This commit is contained in:
parent
b16f99d51c
commit
eaa28844c9
63 changed files with 5698 additions and 0 deletions
132
Engine/source/BadBehavior/composite/ActiveSelector.cpp
Normal file
132
Engine/source/BadBehavior/composite/ActiveSelector.cpp
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "ActiveSelector.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Active selector node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(ActiveSelector);
|
||||
|
||||
ActiveSelector::ActiveSelector()
|
||||
: mRecheckFrequency(0)
|
||||
{
|
||||
}
|
||||
|
||||
Task *ActiveSelector::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new ActiveSelectorTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
void ActiveSelector::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addField( "recheckFrequency", TypeS32, Offset(mRecheckFrequency, ActiveSelector),
|
||||
"@brief The minimum time period in milliseconds to wait between re-evaluations of higher priority branches.");
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Active selector task
|
||||
//------------------------------------------------------------------------------
|
||||
ActiveSelectorTask::ActiveSelectorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner),
|
||||
mRecheckTime(0)
|
||||
{
|
||||
}
|
||||
|
||||
void ActiveSelectorTask::onInitialize()
|
||||
{
|
||||
Parent::onInitialize();
|
||||
|
||||
if(mBranches.empty())
|
||||
{
|
||||
for (VectorPtr<Task*>::iterator i = mChildren.begin(); i != mChildren.end(); ++i)
|
||||
{
|
||||
mBranches.push_back(BehaviorTreeBranch(*i));
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentBranch = mBranches.begin();
|
||||
mRunningBranch = mBranches.end();
|
||||
mRecheckTime = 0;
|
||||
}
|
||||
|
||||
|
||||
Task* ActiveSelectorTask::update()
|
||||
{
|
||||
// empty node, bail
|
||||
if(mBranches.empty())
|
||||
{
|
||||
mStatus = INVALID;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// is it time to re-check higher priority branches?
|
||||
if(Sim::getCurrentTime() >= mRecheckTime)
|
||||
{
|
||||
// pick highest priority branch
|
||||
mCurrentBranch = mBranches.begin();
|
||||
|
||||
// determine the next recheck time
|
||||
mRecheckTime = Sim::getCurrentTime() + static_cast<ActiveSelector *>(mNodeRep)->getRecheckFrequency();
|
||||
}
|
||||
|
||||
// run a branch, if it fails move on to the next
|
||||
for(mCurrentBranch; mCurrentBranch != mBranches.end(); ++mCurrentBranch)
|
||||
{
|
||||
// reset the branch if it's not the current running branch
|
||||
if(mCurrentBranch != mRunningBranch)
|
||||
mCurrentBranch->reset();
|
||||
|
||||
mStatus = mCurrentBranch->update();
|
||||
|
||||
if(mStatus == FAILURE) // move on to next
|
||||
continue;
|
||||
|
||||
if(mStatus == RUNNING || mStatus == SUSPENDED) // track the current running branch
|
||||
mRunningBranch = mCurrentBranch;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if( (mStatus != RUNNING && mStatus != SUSPENDED) || mCurrentBranch == mBranches.end() )
|
||||
mIsComplete = true;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Status ActiveSelectorTask::getStatus()
|
||||
{
|
||||
if(mStatus == SUSPENDED && mCurrentBranch != mBranches.end())
|
||||
return mCurrentBranch->getStatus(); // suspended branch may have resumed
|
||||
|
||||
return mStatus;
|
||||
}
|
||||
92
Engine/source/BadBehavior/composite/ActiveSelector.h
Normal file
92
Engine/source/BadBehavior/composite/ActiveSelector.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_ACTIVESELECTOR_H_
|
||||
#define _BB_ACTIVESELECTOR_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Composite.h"
|
||||
#endif
|
||||
#ifndef _BB_BRANCH_H_
|
||||
#include "BadBehavior/core/Branch.h"
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// Active Selector
|
||||
// Re-evaluates its children from the beginning each tick. Lower priority
|
||||
// children which previously returned RUNNING are resumed if re-selected
|
||||
//
|
||||
// ***** TODO - This runs OK, but may need a bit more work
|
||||
// -- abort previously running branches?
|
||||
//
|
||||
//==============================================================================
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Active selector Node
|
||||
//---------------------------------------------------------------------------
|
||||
class ActiveSelector : public CompositeNode
|
||||
{
|
||||
typedef CompositeNode Parent;
|
||||
|
||||
protected:
|
||||
U32 mRecheckFrequency;
|
||||
|
||||
public:
|
||||
ActiveSelector();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
U32 getRecheckFrequency() const { return mRecheckFrequency; }
|
||||
|
||||
DECLARE_CONOBJECT(ActiveSelector);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Active selector Task
|
||||
//---------------------------------------------------------------------------
|
||||
class ActiveSelectorTask : public CompositeTask
|
||||
{
|
||||
typedef CompositeTask Parent;
|
||||
|
||||
protected:
|
||||
Vector<BehaviorTreeBranch>::iterator mRunningBranch;
|
||||
Vector<BehaviorTreeBranch>::iterator mCurrentBranch;
|
||||
Vector<BehaviorTreeBranch> mBranches;
|
||||
|
||||
U32 mRecheckTime;
|
||||
|
||||
virtual void onInitialize();
|
||||
virtual Task* update();
|
||||
|
||||
public:
|
||||
ActiveSelectorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
Status getStatus();
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
175
Engine/source/BadBehavior/composite/Parallel.cpp
Normal file
175
Engine/source/BadBehavior/composite/Parallel.cpp
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Parallel.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Parallel node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(Parallel);
|
||||
|
||||
Parallel::Parallel()
|
||||
: mReturnPolicy(REQUIRE_ALL)
|
||||
{
|
||||
}
|
||||
|
||||
ImplementEnumType( ParallelReturnPolicy,
|
||||
"@brief The policy to use when determining the return status of a parallel node.\n\n"
|
||||
"@ingroup AI\n\n")
|
||||
{ Parallel::REQUIRE_ALL, "REQUIRE_ALL", "Will return success if all children succeed.\n"
|
||||
"Will terminate and return failure if one child fails \n"},
|
||||
{ Parallel::REQUIRE_NONE, "REQUIRE_NONE", "Will return success even if all children fail.\n" },
|
||||
{ Parallel::REQUIRE_ONE, "REQUIRE_ONE", "Will terminate and return success when one child succeeds.\n" },
|
||||
EndImplementEnumType;
|
||||
|
||||
void Parallel::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addField( "returnPolicy", TYPEID< Parallel::ParallelPolicy >(), Offset(mReturnPolicy, Parallel),
|
||||
"@brief The policy to use when deciding the return status for the parallel sequence.");
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
Task *Parallel::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new ParallelTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Parallel Task
|
||||
//------------------------------------------------------------------------------
|
||||
ParallelTask::ParallelTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner),
|
||||
mHasSuccess(false),
|
||||
mHasFailure(false)
|
||||
{
|
||||
}
|
||||
|
||||
void ParallelTask::onInitialize()
|
||||
{
|
||||
Parent::onInitialize();
|
||||
|
||||
mHasSuccess = mHasFailure = false;
|
||||
|
||||
if(mBranches.empty())
|
||||
{
|
||||
for (VectorPtr<Task*>::iterator i = mChildren.begin(); i != mChildren.end(); ++i)
|
||||
{
|
||||
mBranches.push_back(BehaviorTreeBranch(*i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Vector<BehaviorTreeBranch>::iterator it = mBranches.begin(); it != mBranches.end(); ++it)
|
||||
{
|
||||
it->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Task* ParallelTask::update()
|
||||
{
|
||||
bool hasRunning = false, hasSuspended = false, hasResume = false;
|
||||
for (Vector<BehaviorTreeBranch>::iterator it = mBranches.begin(); it != mBranches.end(); ++it)
|
||||
{
|
||||
Status s = it->getStatus();
|
||||
if(s == INVALID || s == RUNNING || s == RESUME)
|
||||
{
|
||||
s = it->update();
|
||||
|
||||
switch(it->getStatus())
|
||||
{
|
||||
case SUCCESS:
|
||||
mHasSuccess = true;
|
||||
break;
|
||||
case FAILURE:
|
||||
mHasFailure = true;
|
||||
break;
|
||||
case RUNNING:
|
||||
hasRunning = true;
|
||||
break;
|
||||
case SUSPENDED:
|
||||
hasSuspended = true;
|
||||
break;
|
||||
case RESUME:
|
||||
hasResume = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(static_cast<Parallel *>(mNodeRep)->getReturnPolicy())
|
||||
{
|
||||
// REQUIRE_NONE
|
||||
// returns SUCCESS when all children have finished irrespective of their return status.
|
||||
case Parallel::REQUIRE_NONE:
|
||||
mStatus = hasResume ? RESUME : ( hasRunning ? RUNNING : ( hasSuspended ? SUSPENDED : SUCCESS ) );
|
||||
break;
|
||||
|
||||
// REQUIRE_ONE
|
||||
// terminates and returns SUCCESS when any of its children succeed
|
||||
// returns FAILURE if no children succeed
|
||||
case Parallel::REQUIRE_ONE:
|
||||
mStatus = mHasSuccess ? SUCCESS : ( hasResume ? RESUME : ( hasRunning ? RUNNING : ( hasSuspended ? SUSPENDED : FAILURE ) ) );
|
||||
break;
|
||||
|
||||
// REQUIRE_ALL
|
||||
// returns SUCCESS if all of its children succeed.
|
||||
// terminates and returns failure if any of its children fail
|
||||
case Parallel::REQUIRE_ALL:
|
||||
mStatus = mHasFailure ? FAILURE : ( hasResume ? RESUME : ( hasRunning ? RUNNING : ( hasSuspended ? SUSPENDED : SUCCESS ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
mIsComplete = (mStatus != RUNNING && mStatus != SUSPENDED && mStatus != RESUME);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Status ParallelTask::getStatus()
|
||||
{
|
||||
if(mStatus == SUSPENDED)
|
||||
{
|
||||
// need to check if the parallel is still suspended.
|
||||
// A parallel will only report SUSPENDED when all of its children are suspended
|
||||
for(Vector<BehaviorTreeBranch>::iterator it = mBranches.begin(); it != mBranches.end(); ++it)
|
||||
{
|
||||
switch(it->getStatus())
|
||||
{
|
||||
case RUNNING:
|
||||
return RUNNING;
|
||||
case RESUME:
|
||||
return RESUME;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mStatus;
|
||||
}
|
||||
97
Engine/source/BadBehavior/composite/Parallel.h
Normal file
97
Engine/source/BadBehavior/composite/Parallel.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_PARALLEL_H_
|
||||
#define _BB_PARALLEL_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Composite.h"
|
||||
#endif
|
||||
|
||||
#ifndef _BB_BRANCH_H_
|
||||
#include "BadBehavior/core/Branch.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Parallel sequence node
|
||||
// Runs all of its children irrespective of their return status
|
||||
// The final return status depends on the chosen policy
|
||||
// (not a true parallel, as branches are actually evaluated sequentially)
|
||||
//---------------------------------------------------------------------------
|
||||
class Parallel: public CompositeNode
|
||||
{
|
||||
typedef CompositeNode Parent;
|
||||
|
||||
public:
|
||||
// parallel return policies
|
||||
enum ParallelPolicy
|
||||
{
|
||||
REQUIRE_NONE,
|
||||
REQUIRE_ONE,
|
||||
REQUIRE_ALL,
|
||||
};
|
||||
|
||||
protected:
|
||||
ParallelPolicy mReturnPolicy;
|
||||
|
||||
public:
|
||||
Parallel();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
ParallelPolicy getReturnPolicy() const { return mReturnPolicy; }
|
||||
|
||||
DECLARE_CONOBJECT(Parallel);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Parallel Task
|
||||
//---------------------------------------------------------------------------
|
||||
class ParallelTask: public CompositeTask
|
||||
{
|
||||
typedef CompositeTask Parent;
|
||||
|
||||
protected:
|
||||
Vector<BehaviorTreeBranch> mBranches;
|
||||
|
||||
bool mHasSuccess, mHasFailure;
|
||||
|
||||
virtual void onInitialize();
|
||||
virtual Task* update();
|
||||
|
||||
public:
|
||||
ParallelTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
virtual Status getStatus();
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
// make the return policy enum accessible from script
|
||||
typedef BadBehavior::Parallel::ParallelPolicy ParallelReturnPolicy;
|
||||
DefineEnumType( ParallelReturnPolicy );
|
||||
|
||||
#endif
|
||||
68
Engine/source/BadBehavior/composite/RandomSelector.cpp
Normal file
68
Engine/source/BadBehavior/composite/RandomSelector.cpp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "RandomSelector.h"
|
||||
|
||||
#include "math/mMathFn.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Random selector node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(RandomSelector);
|
||||
|
||||
Task *RandomSelector::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new RandomSelectorTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Random selector task
|
||||
//------------------------------------------------------------------------------
|
||||
RandomSelectorTask::RandomSelectorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
void RandomSelectorTask::onInitialize()
|
||||
{
|
||||
Parent::onInitialize();
|
||||
|
||||
// randomize the order of our child tasks
|
||||
VectorPtr<Task *> randomChildren;
|
||||
|
||||
while(mChildren.size() > 0)
|
||||
{
|
||||
U32 index = mRandI(0, mChildren.size() - 1);
|
||||
Task* child = mChildren[index];
|
||||
randomChildren.push_back(child);
|
||||
mChildren.erase_fast(index);
|
||||
}
|
||||
|
||||
mChildren = randomChildren;
|
||||
|
||||
// normal init
|
||||
mCurrentChild = mChildren.begin();
|
||||
if(mCurrentChild != mChildren.end())
|
||||
(*mCurrentChild)->reset();
|
||||
}
|
||||
62
Engine/source/BadBehavior/composite/RandomSelector.h
Normal file
62
Engine/source/BadBehavior/composite/RandomSelector.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_RANDOMSELECTOR_H_
|
||||
#define _BB_RANDOMSELECTOR_H_
|
||||
|
||||
#ifndef _BB_SELECTOR_H_
|
||||
#include "Selector.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Random selector node
|
||||
// selects its children in a random order until one of them succeeds
|
||||
//---------------------------------------------------------------------------
|
||||
class RandomSelector : public Selector
|
||||
{
|
||||
typedef Selector Parent;
|
||||
|
||||
public:
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
DECLARE_CONOBJECT(RandomSelector);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Random selector task
|
||||
//---------------------------------------------------------------------------
|
||||
class RandomSelectorTask : public SelectorTask
|
||||
{
|
||||
typedef SelectorTask Parent;
|
||||
|
||||
protected:
|
||||
virtual void onInitialize();
|
||||
|
||||
public:
|
||||
RandomSelectorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
54
Engine/source/BadBehavior/composite/Selector.cpp
Normal file
54
Engine/source/BadBehavior/composite/Selector.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Selector.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Selector node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(Selector);
|
||||
|
||||
Task *Selector::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new SelectorTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Selector task
|
||||
//------------------------------------------------------------------------------
|
||||
SelectorTask::SelectorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
void SelectorTask::onChildComplete(Status s)
|
||||
{
|
||||
mStatus = s;
|
||||
|
||||
// if child failed, move on to the next child
|
||||
if(mStatus == FAILURE)
|
||||
++mCurrentChild;
|
||||
else
|
||||
mIsComplete = true;
|
||||
}
|
||||
60
Engine/source/BadBehavior/composite/Selector.h
Normal file
60
Engine/source/BadBehavior/composite/Selector.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_SELECTOR_H_
|
||||
#define _BBSELECTOR_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Composite.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Selector Node
|
||||
//---------------------------------------------------------------------------
|
||||
class Selector : public CompositeNode
|
||||
{
|
||||
typedef CompositeNode Parent;
|
||||
|
||||
public:
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
DECLARE_CONOBJECT(Selector);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Selector Task
|
||||
//---------------------------------------------------------------------------
|
||||
class SelectorTask : public CompositeTask
|
||||
{
|
||||
typedef CompositeTask Parent;
|
||||
|
||||
public:
|
||||
SelectorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
virtual void onChildComplete(Status);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
55
Engine/source/BadBehavior/composite/Sequence.cpp
Normal file
55
Engine/source/BadBehavior/composite/Sequence.cpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Sequence.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Sequence node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(Sequence);
|
||||
|
||||
Task *Sequence::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new SequenceTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Sequence Task
|
||||
//------------------------------------------------------------------------------
|
||||
SequenceTask::SequenceTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
void SequenceTask::onChildComplete(Status s)
|
||||
{
|
||||
mStatus = s;
|
||||
|
||||
// if child succeeded, move on to the next child
|
||||
if(mStatus == SUCCESS)
|
||||
++mCurrentChild;
|
||||
else
|
||||
mIsComplete = true;
|
||||
}
|
||||
|
||||
60
Engine/source/BadBehavior/composite/Sequence.h
Normal file
60
Engine/source/BadBehavior/composite/Sequence.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_SEQUENCE_H_
|
||||
#define _BB_SEQUENCE_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Composite.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Sequence Node
|
||||
//---------------------------------------------------------------------------
|
||||
class Sequence : public CompositeNode
|
||||
{
|
||||
typedef CompositeNode Parent;
|
||||
|
||||
public:
|
||||
virtual Task* createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
DECLARE_CONOBJECT(Sequence);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Sequence Task
|
||||
//---------------------------------------------------------------------------
|
||||
class SequenceTask : public CompositeTask
|
||||
{
|
||||
typedef CompositeTask Parent;
|
||||
|
||||
public:
|
||||
SequenceTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
virtual void onChildComplete(Status);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
66
Engine/source/BadBehavior/core/Branch.cpp
Normal file
66
Engine/source/BadBehavior/core/Branch.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Branch.h"
|
||||
#include "Stepper.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
BehaviorTreeBranch::BehaviorTreeBranch()
|
||||
: mRootTask(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
BehaviorTreeBranch::BehaviorTreeBranch(Task *root)
|
||||
: mRootTask(root),
|
||||
mStatus(INVALID)
|
||||
{
|
||||
}
|
||||
|
||||
Status BehaviorTreeBranch::getStatus()
|
||||
{
|
||||
if(!mTasks.empty())
|
||||
return mTasks.back()->getStatus();
|
||||
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
Status BehaviorTreeBranch::update()
|
||||
{
|
||||
if(mRootTask)
|
||||
{
|
||||
if(mTasks.empty())
|
||||
{
|
||||
mRootTask->setup();
|
||||
mTasks.push_back(mRootTask);
|
||||
}
|
||||
}
|
||||
mStatus = BehaviorTreeStepper::stepThrough(mTasks);
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
void BehaviorTreeBranch::reset()
|
||||
{
|
||||
mStatus = INVALID;
|
||||
mRootTask->reset();
|
||||
mTasks.clear();
|
||||
}
|
||||
53
Engine/source/BadBehavior/core/Branch.h
Normal file
53
Engine/source/BadBehavior/core/Branch.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_BRANCH_H_
|
||||
#define _BB_BRANCH_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "Core.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
// The branch class handles a single execution path in the tree
|
||||
// Typically used for the tree root and for handling suspension and concurrency
|
||||
class BehaviorTreeBranch
|
||||
{
|
||||
private:
|
||||
Status mStatus;
|
||||
Task *mRootTask;
|
||||
VectorPtr<Task *> mTasks;
|
||||
|
||||
public:
|
||||
BehaviorTreeBranch();
|
||||
BehaviorTreeBranch(Task *root);
|
||||
|
||||
Status getStatus();
|
||||
Status update();
|
||||
void reset();
|
||||
};
|
||||
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
110
Engine/source/BadBehavior/core/Composite.cpp
Normal file
110
Engine/source/BadBehavior/core/Composite.cpp
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Composite.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Base composite node
|
||||
// override addObject to only allow behavior tree nodes to be added
|
||||
//------------------------------------------------------------------------------
|
||||
void CompositeNode::addObject(SimObject *object)
|
||||
{
|
||||
if(dynamic_cast<Node*>(object))
|
||||
Parent::addObject(object);
|
||||
}
|
||||
|
||||
bool CompositeNode::acceptsAsChild( SimObject *object ) const
|
||||
{
|
||||
return (dynamic_cast<Node*>(object));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Base composite task
|
||||
//------------------------------------------------------------------------------
|
||||
CompositeTask::CompositeTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
CompositeTask::~CompositeTask()
|
||||
{
|
||||
while(mChildren.size())
|
||||
{
|
||||
Task *child = mChildren.back();
|
||||
mChildren.pop_back();
|
||||
if(child)
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
|
||||
void CompositeTask::onInitialize()
|
||||
{
|
||||
if(mChildren.empty())
|
||||
{
|
||||
CompositeNode *node = static_cast<CompositeNode *>(mNodeRep);
|
||||
for(SimSet::iterator i = node->begin(); i != node->end(); ++i)
|
||||
{
|
||||
Task *task = static_cast<Node*>(*i)->createTask(*mOwner, *mRunner);
|
||||
if(task)
|
||||
{
|
||||
task->setParent(this);
|
||||
mChildren.push_back(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mStatus = INVALID;
|
||||
mCurrentChild = mChildren.begin();
|
||||
if(mCurrentChild != mChildren.end())
|
||||
(*mCurrentChild)->reset();
|
||||
}
|
||||
|
||||
void CompositeTask::onTerminate()
|
||||
{
|
||||
mStatus = INVALID;
|
||||
}
|
||||
|
||||
Task* CompositeTask::update()
|
||||
{
|
||||
// reached the end of child list, we are complete
|
||||
if (mCurrentChild == mChildren.end())
|
||||
mIsComplete = true;
|
||||
|
||||
// task has finished
|
||||
if( mIsComplete )
|
||||
{
|
||||
// are we latent?
|
||||
if(mStatus == RUNNING || mStatus == SUSPENDED)
|
||||
mIsComplete = false;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// reset the child ready for the next tick
|
||||
if(mStatus != RUNNING && mStatus != SUSPENDED)
|
||||
(*mCurrentChild)->reset();
|
||||
|
||||
// return child
|
||||
return (*mCurrentChild);
|
||||
}
|
||||
70
Engine/source/BadBehavior/core/Composite.h
Normal file
70
Engine/source/BadBehavior/core/Composite.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_COMPOSITE_H_
|
||||
#define _BB_COMPOSITE_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "Core.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Composite node base class - for nodes with children
|
||||
//---------------------------------------------------------------------------
|
||||
class CompositeNode : public Node
|
||||
{
|
||||
typedef Node Parent;
|
||||
|
||||
public:
|
||||
// override addObject and acceptsAsChild to only allow behavior tree nodes to be added as children
|
||||
virtual void addObject(SimObject *obj);
|
||||
virtual bool acceptsAsChild( SimObject *object ) const;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Composite task base class
|
||||
//---------------------------------------------------------------------------
|
||||
class CompositeTask : public Task
|
||||
{
|
||||
typedef Task Parent;
|
||||
|
||||
protected:
|
||||
// vector of pointers to child tasks
|
||||
VectorPtr<Task*> mChildren;
|
||||
|
||||
// the current child task
|
||||
VectorPtr<Task*>::iterator mCurrentChild;
|
||||
|
||||
virtual void onInitialize();
|
||||
virtual void onTerminate();
|
||||
virtual Task* update();
|
||||
|
||||
public:
|
||||
CompositeTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
virtual ~CompositeTask();
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
161
Engine/source/BadBehavior/core/Core.cpp
Normal file
161
Engine/source/BadBehavior/core/Core.cpp
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Core.h"
|
||||
#include "Runner.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
bool gInBtEditor = false;
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// script enum for return type
|
||||
//------------------------------------------------------------------------------
|
||||
ImplementEnumType( BehaviorReturnType,
|
||||
"@brief The return status for a behavior.\n\n"
|
||||
"@ingroup AI\n\n")
|
||||
// not needed script side
|
||||
//{ BadBehavior::INVALID, "INVALID", "The behavior could not be evaluated.\n" },
|
||||
{ BadBehavior::SUCCESS, "SUCCESS", "The behavior succeeded.\n" },
|
||||
{ BadBehavior::FAILURE, "FAILURE", "The behavior failed.\n" },
|
||||
{ BadBehavior::RUNNING, "RUNNING", "The behavior is still running.\n" },
|
||||
// not needed script side
|
||||
//{ BadBehavior::SUSPENDED, "SUSPENDED", "The behavior has been suspended.\n" },
|
||||
//{ BadBehavior::RESUME, "RESUME", "The behavior is resuming from suspended.\n" }
|
||||
EndImplementEnumType;
|
||||
|
||||
|
||||
//================================LeafNode======================================
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// don't allow objects to be added
|
||||
//------------------------------------------------------------------------------
|
||||
void LeafNode::addObject(SimObject *object)
|
||||
{
|
||||
}
|
||||
|
||||
bool LeafNode::acceptsAsChild( SimObject *object ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//==================================Task========================================
|
||||
|
||||
Task::Task(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: mStatus(INVALID),
|
||||
mIsComplete(false),
|
||||
mNodeRep(&node),
|
||||
mOwner(&owner),
|
||||
mRunner(&runner),
|
||||
mParent(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Task::~Task()
|
||||
{
|
||||
}
|
||||
|
||||
void Task::onInitialize()
|
||||
{
|
||||
}
|
||||
|
||||
void Task::onTerminate()
|
||||
{
|
||||
}
|
||||
|
||||
Task* Task::tick()
|
||||
{
|
||||
PROFILE_SCOPE(Task_Tick);
|
||||
|
||||
return update();
|
||||
}
|
||||
|
||||
void Task::setup()
|
||||
{
|
||||
PROFILE_SCOPE(Task_setup);
|
||||
|
||||
if(mStatus != RUNNING && mStatus != SUSPENDED)
|
||||
onInitialize();
|
||||
|
||||
mIsComplete = false;
|
||||
}
|
||||
|
||||
void Task::finish()
|
||||
{
|
||||
if(mIsComplete)
|
||||
onTerminate();
|
||||
}
|
||||
|
||||
void Task::reset()
|
||||
{
|
||||
mStatus = INVALID;
|
||||
}
|
||||
|
||||
Status Task::getStatus()
|
||||
{
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
void Task::setStatus(Status newStatus)
|
||||
{
|
||||
mStatus = newStatus;
|
||||
}
|
||||
|
||||
void Task::setParent(Task *parent)
|
||||
{
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
Task *Task::getParent()
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
void Task::onChildComplete(Status)
|
||||
{
|
||||
}
|
||||
|
||||
void Task::onResume()
|
||||
{
|
||||
if(mStatus == SUSPENDED)
|
||||
mStatus = RESUME;
|
||||
|
||||
//Con::warnf("onResume %s",
|
||||
// mNodeRep->getIdString());
|
||||
}
|
||||
|
||||
DefineEngineFunction(onBehaviorTreeEditorStart, void, (),,
|
||||
"@brief Notify the engine that the behavior tree editor is active")
|
||||
{
|
||||
gInBtEditor = true;
|
||||
}
|
||||
|
||||
|
||||
DefineEngineFunction(onBehaviorTreeEditorStop, void, (),,
|
||||
"@brief Notify the engine that the behavior tree editor has finished")
|
||||
{
|
||||
gInBtEditor = false;
|
||||
}
|
||||
151
Engine/source/BadBehavior/core/Core.h
Normal file
151
Engine/source/BadBehavior/core/Core.h
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BBCORE_H_
|
||||
#define _BBCORE_H_
|
||||
|
||||
#ifndef _SIMSET_H_
|
||||
#include "console/simSet.h"
|
||||
#endif
|
||||
#ifndef _SIMOBJECT_H_
|
||||
#include "console/simObject.h"
|
||||
#endif
|
||||
|
||||
extern bool gInBtEditor;
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// return status values
|
||||
//---------------------------------------------------------------------------
|
||||
enum Status
|
||||
{
|
||||
INVALID = -1,
|
||||
FAILURE,
|
||||
SUCCESS,
|
||||
RUNNING,
|
||||
SUSPENDED,
|
||||
RESUME
|
||||
};
|
||||
|
||||
class Task;
|
||||
class BehaviorTreeRunner;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// node base class
|
||||
// derived from SimGroup for easy editor integration
|
||||
//---------------------------------------------------------------------------
|
||||
class Node : public SimGroup
|
||||
{
|
||||
typedef SimGroup Parent;
|
||||
|
||||
public:
|
||||
// create a runtime task for this node
|
||||
virtual Task* createTask(SimObject &owner, BehaviorTreeRunner &runner) = 0;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Leaf node base class - for nodes without children
|
||||
//---------------------------------------------------------------------------
|
||||
class LeafNode : public Node
|
||||
{
|
||||
typedef Node Parent;
|
||||
|
||||
public:
|
||||
virtual void addObject(SimObject *obj);
|
||||
virtual bool acceptsAsChild( SimObject *object ) const;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// base class for all behavior tree tasks
|
||||
//---------------------------------------------------------------------------
|
||||
class Task
|
||||
{
|
||||
protected:
|
||||
|
||||
// the current status
|
||||
Status mStatus;
|
||||
|
||||
// has the task finished
|
||||
bool mIsComplete;
|
||||
|
||||
// the node associated with this task
|
||||
Node *mNodeRep;
|
||||
|
||||
// the object that owns us
|
||||
SimObjectPtr<SimObject> mOwner;
|
||||
|
||||
// the object running us
|
||||
BehaviorTreeRunner *mRunner;
|
||||
|
||||
// the parent of this task
|
||||
Task *mParent;
|
||||
|
||||
// update
|
||||
virtual Task* update() = 0;
|
||||
|
||||
// initialize
|
||||
virtual void onInitialize();
|
||||
|
||||
// terminate
|
||||
virtual void onTerminate();
|
||||
|
||||
public:
|
||||
// tasks are instantiated with a reference to their associated node
|
||||
Task(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
virtual ~Task();
|
||||
|
||||
// status sets and gets
|
||||
virtual Status getStatus();
|
||||
void setStatus(Status newStatus);
|
||||
|
||||
// parent sets and gets
|
||||
void setParent(Task *parent);
|
||||
Task *getParent();
|
||||
|
||||
// run the task
|
||||
Task* tick();
|
||||
|
||||
// called when child task finishes
|
||||
virtual void onChildComplete(Status);
|
||||
|
||||
// called when a suspended task becomes active
|
||||
virtual void onResume();
|
||||
|
||||
// prepare the task
|
||||
void setup();
|
||||
|
||||
// finish the task
|
||||
void finish();
|
||||
|
||||
// reset the task
|
||||
void reset();
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
// make the return status enum accessible from script
|
||||
typedef BadBehavior::Status BehaviorReturnType;
|
||||
DefineEnumType( BehaviorReturnType );
|
||||
|
||||
#endif
|
||||
106
Engine/source/BadBehavior/core/Decorator.cpp
Normal file
106
Engine/source/BadBehavior/core/Decorator.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Decorator.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Base decorator node
|
||||
// overrides for decorators to only allow 1 child
|
||||
//------------------------------------------------------------------------------
|
||||
void DecoratorNode::addObject(SimObject *obj)
|
||||
{
|
||||
if(empty())
|
||||
Parent::addObject(obj);
|
||||
}
|
||||
|
||||
bool DecoratorNode::acceptsAsChild( SimObject *object ) const
|
||||
{
|
||||
return (dynamic_cast<Node *>(object) && empty());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Base decorator task
|
||||
//------------------------------------------------------------------------------
|
||||
DecoratorTask::DecoratorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner),
|
||||
mChild(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
DecoratorTask::~DecoratorTask()
|
||||
{
|
||||
if(mChild)
|
||||
{
|
||||
delete mChild;
|
||||
mChild = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void DecoratorTask::onInitialize()
|
||||
{
|
||||
if(!mChild)
|
||||
{
|
||||
if(mNodeRep->size() > 0)
|
||||
{
|
||||
Node *childNode = static_cast<Node*>(*mNodeRep->begin());
|
||||
if(childNode)
|
||||
{
|
||||
mChild = childNode->createTask(*mOwner, *mRunner);
|
||||
if(mChild)
|
||||
{
|
||||
mChild->setParent(this);
|
||||
mChild->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mStatus = INVALID;
|
||||
}
|
||||
|
||||
void DecoratorTask::onTerminate()
|
||||
{
|
||||
mStatus = INVALID;
|
||||
}
|
||||
|
||||
Task* DecoratorTask::update()
|
||||
{
|
||||
// first time through, return child
|
||||
if(!mIsComplete)
|
||||
return mStatus != SUSPENDED ? mChild : NULL;
|
||||
|
||||
// child has completed, are we latent?
|
||||
if(mStatus == RUNNING || mStatus == SUSPENDED)
|
||||
mIsComplete = false;
|
||||
|
||||
// no more children
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DecoratorTask::onChildComplete(Status s)
|
||||
{
|
||||
// set our status to the child status and flag completed
|
||||
mStatus = s;
|
||||
mIsComplete = true;
|
||||
}
|
||||
68
Engine/source/BadBehavior/core/Decorator.h
Normal file
68
Engine/source/BadBehavior/core/Decorator.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_DECORATOR_H_
|
||||
#define _BB_DECORATOR_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Core.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Decorator node base class
|
||||
//---------------------------------------------------------------------------
|
||||
class DecoratorNode : public Node
|
||||
{
|
||||
typedef Node Parent;
|
||||
|
||||
public:
|
||||
// only allow 1 child node to be added
|
||||
virtual void addObject(SimObject *obj);
|
||||
virtual bool acceptsAsChild( SimObject *object ) const;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Decorator task base class
|
||||
//---------------------------------------------------------------------------
|
||||
class DecoratorTask : public Task
|
||||
{
|
||||
typedef Task Parent;
|
||||
|
||||
protected:
|
||||
Task* mChild;
|
||||
|
||||
virtual Task* update();
|
||||
virtual void onInitialize();
|
||||
virtual void onTerminate();
|
||||
|
||||
public:
|
||||
DecoratorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
virtual ~DecoratorTask();
|
||||
|
||||
virtual void onChildComplete(Status s);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
278
Engine/source/BadBehavior/core/Runner.cpp
Normal file
278
Engine/source/BadBehavior/core/Runner.cpp
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Runner.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
IMPLEMENT_CONOBJECT(BehaviorTreeRunner);
|
||||
|
||||
BehaviorTreeRunner::BehaviorTreeRunner()
|
||||
: mOwner(NULL),
|
||||
mRootNode(NULL),
|
||||
mRootTask(NULL),
|
||||
mIsRunning(0),
|
||||
mTickEvent(0),
|
||||
mTickFrequency(100)
|
||||
{}
|
||||
|
||||
|
||||
BehaviorTreeRunner::~BehaviorTreeRunner()
|
||||
{
|
||||
delete mRootTask;
|
||||
|
||||
if(Sim::isEventPending(mTickEvent))
|
||||
{
|
||||
Sim::cancelEvent(mTickEvent);
|
||||
mTickEvent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BehaviorTreeRunner::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addProtectedField("rootNode", TYPEID< SimObject >(), Offset(mRootNode, BehaviorTreeRunner),
|
||||
&_setRootNode, &defaultProtectedGetFn, "@brief The root node of the tree to be run.");
|
||||
|
||||
addProtectedField("ownerObject", TYPEID< SimObject >(), Offset(mOwner, BehaviorTreeRunner),
|
||||
&_setOwner, &defaultProtectedGetFn, "@brief The object that owns the tree to be run.");
|
||||
|
||||
addField("frequency", TypeS32, Offset(mTickFrequency, BehaviorTreeRunner),
|
||||
"@brief The frequency in ms that the tree is ticked at.");
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void BehaviorTreeRunner::onDeleteNotify(SimObject *object)
|
||||
{
|
||||
// delete ourselves nicely
|
||||
// - this takes care of any events registered to this runner
|
||||
if(object == mOwner.getObject())
|
||||
safeDeleteObject();
|
||||
}
|
||||
|
||||
|
||||
// processTick is where the magic happens :)
|
||||
void BehaviorTreeRunner::onTick()
|
||||
{
|
||||
PROFILE_SCOPE(BehaviorTreeRunner_processTick);
|
||||
|
||||
// check that we are setup to run
|
||||
if(mOwner.isNull() || mRootNode.isNull())
|
||||
return;
|
||||
|
||||
if(gInBtEditor)
|
||||
{
|
||||
if(mRootTask)
|
||||
reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!mRootTask)
|
||||
{
|
||||
if((mRootTask = mRootNode->createTask(*mOwner, *this)) == NULL)
|
||||
{
|
||||
Con::errorf("BehaviorTreeTicker::processTick, no task for root node");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// dispatch any signals
|
||||
mSignalHandler.dispatchSignals();
|
||||
|
||||
// Evaluate the tree
|
||||
mRootTask->setup();
|
||||
mRootTask->tick();
|
||||
//Con::warnf("Tree returned %s", EngineMarshallData(mRootTask->getStatus()));
|
||||
mRootTask->finish();
|
||||
}
|
||||
|
||||
// schedule the next tick
|
||||
if(Sim::isEventPending(mTickEvent))
|
||||
Sim::cancelEvent(mTickEvent);
|
||||
|
||||
mTickEvent = Sim::postEvent(this, new BehaviorTreeTickEvent(), Sim::getCurrentTime() + mTickFrequency);
|
||||
|
||||
mIsRunning = true;
|
||||
}
|
||||
|
||||
void BehaviorTreeRunner::onReactivateEvent(Task *task)
|
||||
{
|
||||
if(task)
|
||||
task->onResume();
|
||||
}
|
||||
|
||||
bool BehaviorTreeRunner::_setRootNode( void *object, const char *index, const char *data )
|
||||
{
|
||||
BehaviorTreeRunner *runner = static_cast<BehaviorTreeRunner *>( object );
|
||||
Node* root = NULL;
|
||||
Sim::findObject( data, root );
|
||||
if(root)
|
||||
runner->setRootNode(root);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BehaviorTreeRunner::_setOwner( void *object, const char *index, const char *data )
|
||||
{
|
||||
BehaviorTreeRunner *runner = static_cast<BehaviorTreeRunner *>( object );
|
||||
SimObject* owner = NULL;
|
||||
Sim::findObject( data, owner );
|
||||
if(owner)
|
||||
runner->setOwner(owner);
|
||||
return false;
|
||||
}
|
||||
|
||||
void BehaviorTreeRunner::setOwner(SimObject *owner)
|
||||
{
|
||||
reset();
|
||||
mOwner = owner;
|
||||
deleteNotify(mOwner);
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
void BehaviorTreeRunner::setRootNode(Node *root)
|
||||
{
|
||||
reset();
|
||||
mRootNode = root;
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
void BehaviorTreeRunner::stop()
|
||||
{
|
||||
if(Sim::isEventPending(mTickEvent))
|
||||
{
|
||||
Sim::cancelEvent(mTickEvent);
|
||||
mTickEvent = 0;
|
||||
}
|
||||
mIsRunning = false;
|
||||
}
|
||||
|
||||
|
||||
void BehaviorTreeRunner::start()
|
||||
{
|
||||
if(Sim::isEventPending(mTickEvent))
|
||||
{
|
||||
Sim::cancelEvent(mTickEvent);
|
||||
mTickEvent = 0;
|
||||
}
|
||||
|
||||
mIsRunning = true;
|
||||
if(mRootTask)
|
||||
mRootTask->reset();
|
||||
|
||||
mTickEvent = Sim::postEvent(this, new BehaviorTreeTickEvent(), -1);
|
||||
}
|
||||
|
||||
|
||||
void BehaviorTreeRunner::reset()
|
||||
{
|
||||
//stop();
|
||||
if(mRootTask)
|
||||
{
|
||||
delete mRootTask;
|
||||
mRootTask = 0;
|
||||
}
|
||||
mSignalHandler.reset();
|
||||
}
|
||||
|
||||
|
||||
void BehaviorTreeRunner::clear()
|
||||
{
|
||||
reset();
|
||||
mRootNode = 0;
|
||||
}
|
||||
|
||||
|
||||
bool BehaviorTreeRunner::isRunning()
|
||||
{
|
||||
return mIsRunning;
|
||||
}
|
||||
|
||||
|
||||
void BehaviorTreeRunner::subscribeToSignal(const char *signal, SignalSubscriber *subscriber)
|
||||
{
|
||||
mSignalHandler.registerSubscriber(signal, subscriber);
|
||||
}
|
||||
|
||||
|
||||
void BehaviorTreeRunner::unsubscribeFromSignal(const char *signal, SignalSubscriber *subscriber)
|
||||
{
|
||||
mSignalHandler.unregisterSubscriber(signal, subscriber);
|
||||
}
|
||||
|
||||
|
||||
void BehaviorTreeRunner::postSignal(const char *signal)
|
||||
{
|
||||
mSignalHandler.postSignal(signal);
|
||||
}
|
||||
|
||||
|
||||
DefineEngineMethod( BehaviorTreeRunner, stop, void, (), ,
|
||||
"Halt the execution of the behavior tree.\n\n"
|
||||
"@note The internal task status is retained, allowing execution to be resumed.")
|
||||
{
|
||||
object->stop();
|
||||
}
|
||||
|
||||
|
||||
DefineEngineMethod( BehaviorTreeRunner, start, void, (), ,
|
||||
"Resume execution of the (stopped) behavior tree.")
|
||||
{
|
||||
object->start();
|
||||
}
|
||||
|
||||
|
||||
DefineEngineMethod( BehaviorTreeRunner, reset, void, (), ,
|
||||
"Reset the behavior tree. Any internal state is lost.")
|
||||
{
|
||||
object->reset();
|
||||
}
|
||||
|
||||
|
||||
DefineEngineMethod( BehaviorTreeRunner, clear, void, (), ,
|
||||
"Clear the behavior tree.")
|
||||
{
|
||||
object->clear();
|
||||
}
|
||||
|
||||
|
||||
DefineEngineMethod( BehaviorTreeRunner, isRunning, bool, (), ,
|
||||
"Is the behavior tree running")
|
||||
{
|
||||
return object->isRunning();
|
||||
}
|
||||
|
||||
|
||||
DefineEngineMethod(BehaviorTreeRunner, postSignal, void, (const char *signal),,
|
||||
"@brief Posts a signal to the behavior tree.\n\n")
|
||||
{
|
||||
object->postSignal( signal );
|
||||
}
|
||||
140
Engine/source/BadBehavior/core/Runner.h
Normal file
140
Engine/source/BadBehavior/core/Runner.h
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_RUNNER_H_
|
||||
#define _BB_RUNNER_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "Core.h"
|
||||
#endif
|
||||
#ifndef _BB_SIGNAL_H_
|
||||
#include "Signal.h"
|
||||
#endif
|
||||
#ifndef _SIMOBJECT_H_
|
||||
#include "console/simObject.h"
|
||||
#endif
|
||||
#ifndef _SIMBASE_H_
|
||||
#include "console/simBase.h"
|
||||
#endif
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "util/tVector.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// BehaviorTreeRunner - handles the evaluation of the tree
|
||||
//---------------------------------------------------------------------------
|
||||
class BehaviorTreeRunner : public SimObject
|
||||
{
|
||||
typedef SimObject Parent;
|
||||
|
||||
private:
|
||||
// is this tree running?
|
||||
bool mIsRunning;
|
||||
|
||||
// event ID of the tick event
|
||||
U32 mTickEvent;
|
||||
|
||||
// frequency of ticks in ms
|
||||
U32 mTickFrequency;
|
||||
|
||||
// the root node of the tree
|
||||
SimObjectPtr<Node> mRootNode;
|
||||
|
||||
// the task associated with the root node
|
||||
Task *mRootTask;
|
||||
|
||||
// the game object that is using this tree
|
||||
SimObjectPtr<SimObject> mOwner;
|
||||
|
||||
// signal handler for throwing signals around
|
||||
SignalHandler mSignalHandler;
|
||||
|
||||
// setters for the script interface
|
||||
static bool _setRootNode( void *object, const char *index, const char *data );
|
||||
static bool _setOwner( void *object, const char *index, const char *data );
|
||||
|
||||
public:
|
||||
/*Ctor*/ BehaviorTreeRunner();
|
||||
/*Dtor*/ ~BehaviorTreeRunner();
|
||||
|
||||
// public setters for the script interface
|
||||
void setOwner(SimObject *owner);
|
||||
void setRootNode(Node *root);
|
||||
|
||||
// notification if our owner is deleted
|
||||
virtual void onDeleteNotify(SimObject *object);
|
||||
|
||||
// for script control
|
||||
void stop();
|
||||
void start();
|
||||
void reset();
|
||||
void clear();
|
||||
bool isRunning();
|
||||
|
||||
// tick
|
||||
void onTick();
|
||||
|
||||
// signal handling
|
||||
void subscribeToSignal(const char *signal, SignalSubscriber *subscriber);
|
||||
void unsubscribeFromSignal(const char *signal, SignalSubscriber *subscriber);
|
||||
void postSignal(const char *signal);
|
||||
|
||||
// task reactivation
|
||||
void onReactivateEvent(Task *task);
|
||||
|
||||
// script interface
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(BehaviorTreeRunner);
|
||||
};
|
||||
|
||||
|
||||
class BehaviorTreeTickEvent : public SimEvent
|
||||
{
|
||||
public:
|
||||
void process( SimObject *object )
|
||||
{
|
||||
((BehaviorTreeRunner*)object)->onTick();
|
||||
}
|
||||
};
|
||||
|
||||
class TaskReactivateEvent : public SimEvent
|
||||
{
|
||||
Task *mTask;
|
||||
public:
|
||||
TaskReactivateEvent(Task &task)
|
||||
{
|
||||
mTask = &task;
|
||||
}
|
||||
|
||||
void process( SimObject *object )
|
||||
{
|
||||
((BehaviorTreeRunner*)object)->onReactivateEvent(mTask);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
168
Engine/source/BadBehavior/core/Signal.cpp
Normal file
168
Engine/source/BadBehavior/core/Signal.cpp
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Signal.h"
|
||||
|
||||
#include "core/stringTable.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
// clean up
|
||||
SignalHandler::~SignalHandler()
|
||||
{
|
||||
clearSignalQueue();
|
||||
clearSubscribers();
|
||||
}
|
||||
|
||||
void SignalHandler::clearSignalQueue()
|
||||
{
|
||||
while(!mSignalQueue.empty())
|
||||
{
|
||||
Signal *sig = mSignalQueue.back();
|
||||
mSignalQueue.pop_back();
|
||||
delete sig;
|
||||
sig = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SignalHandler::clearSubscribers()
|
||||
{
|
||||
for( Vector<StringTableEntry>::const_iterator it = mSignals.begin(); it != mSignals.end(); ++it )
|
||||
{
|
||||
// Delete the subscriber list.
|
||||
VectorPtr<SignalSubscriber*>* subscribers = mSubscribers.remove( *it );
|
||||
if(subscribers)
|
||||
delete subscribers;
|
||||
}
|
||||
}
|
||||
|
||||
void SignalHandler::reset()
|
||||
{
|
||||
// empty out the signal queue
|
||||
clearSignalQueue();
|
||||
|
||||
// clear out the subscribers table
|
||||
clearSubscribers();
|
||||
|
||||
// reset the vector of registered signals
|
||||
mSignals.clear();
|
||||
}
|
||||
|
||||
// check if the specified signal is registered
|
||||
bool SignalHandler::isSignalRegistered(const char *signal)
|
||||
{
|
||||
StringTableEntry signalName = StringTable->insert( signal );
|
||||
return mSignals.contains(signalName);
|
||||
}
|
||||
|
||||
// register a signal
|
||||
void SignalHandler::registerSignal(const char *signal)
|
||||
{
|
||||
// check signal has a name
|
||||
if(!signal || !signal[0])
|
||||
return;
|
||||
|
||||
// Make sure the signal has not been registered yet.
|
||||
if(!isSignalRegistered( signal ) )
|
||||
{
|
||||
// Add to the signal list.
|
||||
mSignals.push_back( StringTable->insert( signal ) );
|
||||
|
||||
// Create a list of subscribers for this event.
|
||||
mSubscribers.insert( new VectorPtr<SignalSubscriber*>, signal );
|
||||
}
|
||||
}
|
||||
|
||||
// register a subscriber to a signal
|
||||
void SignalHandler::registerSubscriber(const char *signal, SignalSubscriber *subscriber)
|
||||
{
|
||||
// must have a subscriber
|
||||
if(!subscriber)
|
||||
return;
|
||||
|
||||
// and an signal name
|
||||
if(!signal || !signal[0])
|
||||
return;
|
||||
|
||||
// register a new event if this one hasn't already been registered
|
||||
if(!isSignalRegistered(signal))
|
||||
registerSignal(signal);
|
||||
|
||||
// add the subscriber if it's not already registered for this signal
|
||||
VectorPtr<SignalSubscriber*>* subscribers = mSubscribers.retreive( signal );
|
||||
|
||||
if(!subscribers->contains(subscriber))
|
||||
subscribers->push_back(subscriber);
|
||||
}
|
||||
|
||||
// unregister a subscriber
|
||||
void SignalHandler::unregisterSubscriber(const char *signal, SignalSubscriber *subscriber)
|
||||
{
|
||||
// check if the subscriber exists and that the signal is actually registered
|
||||
if(!subscriber || !isSignalRegistered(signal))
|
||||
return;
|
||||
|
||||
// find the subscriber and remove it
|
||||
VectorPtr<SignalSubscriber*>* subscribers = mSubscribers.retreive( signal );
|
||||
|
||||
for( VectorPtr<SignalSubscriber *>::iterator iter = subscribers->begin(); iter != subscribers->end(); ++iter )
|
||||
{
|
||||
if( *iter == subscriber )
|
||||
{
|
||||
subscribers->erase_fast( iter );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// post a signal
|
||||
void SignalHandler::postSignal(const char *signal)
|
||||
{
|
||||
// signal must be registered
|
||||
if(!isSignalRegistered(signal))
|
||||
return;
|
||||
|
||||
// dispatch a signal to each of the subscribers
|
||||
VectorPtr<SignalSubscriber*>* subscribers = mSubscribers.retreive( signal );
|
||||
|
||||
for( VectorPtr<SignalSubscriber *>::iterator iter = subscribers->begin(); iter != subscribers->end(); ++iter )
|
||||
{
|
||||
mSignalQueue.push_back(new Signal((*iter)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// dispatch queued signals
|
||||
void SignalHandler::dispatchSignals()
|
||||
{
|
||||
if(mSignalQueue.empty())
|
||||
return;
|
||||
|
||||
while(!mSignalQueue.empty())
|
||||
{
|
||||
Signal *sig = mSignalQueue.back();
|
||||
mSignalQueue.pop_back();
|
||||
sig->send();
|
||||
delete sig;
|
||||
sig = NULL;
|
||||
}
|
||||
}
|
||||
97
Engine/source/BadBehavior/core/Signal.h
Normal file
97
Engine/source/BadBehavior/core/Signal.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_SIGNAL_H_
|
||||
#define _BB_SIGNAL_H_
|
||||
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
#ifndef _TSIMPLEHASHTABLE_H
|
||||
#include "core/tSimpleHashTable.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Signal subscriber interface
|
||||
//---------------------------------------------------------------------------
|
||||
class SignalSubscriber
|
||||
{
|
||||
protected:
|
||||
virtual void subscribe() = 0;
|
||||
virtual void unsubscribe() = 0;
|
||||
|
||||
public:
|
||||
virtual void onSignal() = 0;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Signal class
|
||||
//---------------------------------------------------------------------------
|
||||
class Signal
|
||||
{
|
||||
private:
|
||||
SignalSubscriber *mSubscriber;
|
||||
public:
|
||||
Signal(SignalSubscriber *subscriber) : mSubscriber(subscriber) {}
|
||||
void send() { if(mSubscriber) mSubscriber->onSignal(); }
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// SignalHandler
|
||||
// Simple handler to pass signals to tree task listeners
|
||||
//---------------------------------------------------------------------------
|
||||
class SignalHandler
|
||||
{
|
||||
private:
|
||||
SimpleHashTable<VectorPtr<SignalSubscriber*> > mSubscribers;
|
||||
Vector<StringTableEntry> mSignals;
|
||||
|
||||
VectorPtr<Signal*> mSignalQueue;
|
||||
|
||||
void registerSignal(const char *signal);
|
||||
bool isSignalRegistered(const char *signal);
|
||||
void clearSignalQueue();
|
||||
void clearSubscribers();
|
||||
|
||||
public:
|
||||
SignalHandler() {}
|
||||
~SignalHandler();
|
||||
|
||||
// reset
|
||||
void reset();
|
||||
|
||||
// register a scubscriber
|
||||
void registerSubscriber(const char *signal, SignalSubscriber *subscriber);
|
||||
|
||||
// unregister a subscriber
|
||||
void unregisterSubscriber(const char *signal, SignalSubscriber *subscriber);
|
||||
|
||||
// post an signal
|
||||
void postSignal(const char *signal);
|
||||
|
||||
// dispatch queued signals
|
||||
void dispatchSignals();
|
||||
};
|
||||
} // namespace BadBehavior
|
||||
#endif
|
||||
71
Engine/source/BadBehavior/core/Stepper.cpp
Normal file
71
Engine/source/BadBehavior/core/Stepper.cpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Stepper.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
Status BehaviorTreeStepper::stepThrough(VectorPtr<Task *> &taskVector)
|
||||
{
|
||||
if(taskVector.empty()) return INVALID;
|
||||
|
||||
if(taskVector.back()->getStatus() == SUSPENDED)
|
||||
return SUSPENDED;
|
||||
|
||||
Status status = INVALID;
|
||||
|
||||
// loop through the tasks in the task list
|
||||
while(!taskVector.empty())
|
||||
{
|
||||
// get a task
|
||||
Task *currentTask = taskVector.back();
|
||||
|
||||
// tick the task
|
||||
Task *nextTask = currentTask->tick();
|
||||
|
||||
// if task returned no children, it has completed
|
||||
if(!nextTask)
|
||||
{
|
||||
// stop if it's RUNNING or SUSPENED
|
||||
status = currentTask->getStatus();
|
||||
if(status == RUNNING || status == SUSPENDED)
|
||||
break;
|
||||
|
||||
// otherwise, remove it from the list
|
||||
taskVector.pop_back();
|
||||
if(!taskVector.empty())
|
||||
// and tell its parent that it completed
|
||||
taskVector.back()->onChildComplete(currentTask->getStatus());
|
||||
|
||||
// complete the task
|
||||
currentTask->finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
// add the child as a task
|
||||
nextTask->setup();
|
||||
taskVector.push_back(nextTask);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
43
Engine/source/BadBehavior/core/Stepper.h
Normal file
43
Engine/source/BadBehavior/core/Stepper.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_STEPPER_H_
|
||||
#define _BB_STEPPER_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "Core.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// helper class for stepping through a tree
|
||||
//---------------------------------------------------------------------------
|
||||
class BehaviorTreeStepper
|
||||
{
|
||||
public:
|
||||
static Status stepThrough(VectorPtr<Task *> &taskVector);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
106
Engine/source/BadBehavior/core/behavior.cpp
Normal file
106
Engine/source/BadBehavior/core/behavior.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "behavior.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// script enum for precondition mode
|
||||
//------------------------------------------------------------------------------
|
||||
ImplementEnumType( BehaviorPreconditionType,
|
||||
"@brief When should the precondition function be evaluated.\n\n"
|
||||
"@ingroup AI\n\n")
|
||||
{ ONCE, "ONCE", "The first time the node is executed.\n" },
|
||||
{ TICK, "TICK", "Each time the node is executed.\n" },
|
||||
EndImplementEnumType;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Behavior node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(Behavior);
|
||||
|
||||
Behavior::Behavior()
|
||||
: mPreconditionMode(ONCE)
|
||||
{
|
||||
}
|
||||
|
||||
void Behavior::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addField( "preconditionMode", TYPEID< BadBehavior::PreconditionMode >(), Offset(mPreconditionMode, Behavior),
|
||||
"@brief When to evaluate the precondition function.");
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
Task *Behavior::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new BehaviorTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ScriptedBehavior task
|
||||
//------------------------------------------------------------------------------
|
||||
BehaviorTask::BehaviorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
Task* BehaviorTask::update()
|
||||
{
|
||||
PROFILE_SCOPE(BehaviorTask_update);
|
||||
|
||||
Behavior *node = static_cast<Behavior*>(mNodeRep);
|
||||
|
||||
// first check preconditions are valid
|
||||
bool precondition = true;
|
||||
if( (node->getPreconditionMode() == ONCE && mStatus == INVALID) || (node->getPreconditionMode() == TICK) )
|
||||
precondition = node->precondition( mOwner );
|
||||
|
||||
if(precondition)
|
||||
{
|
||||
// run onEnter if this is the first time the node is ticked
|
||||
if(mStatus == INVALID)
|
||||
node->onEnter(mOwner);
|
||||
|
||||
// execute the main behavior and get its return value
|
||||
mStatus = node->behavior(mOwner);
|
||||
}
|
||||
else
|
||||
{
|
||||
mStatus = FAILURE;
|
||||
}
|
||||
|
||||
mIsComplete = mStatus != RUNNING && mStatus != SUSPENDED;
|
||||
|
||||
if(mIsComplete)
|
||||
node->onExit(mOwner);
|
||||
|
||||
return NULL; // leaves don't have children
|
||||
}
|
||||
87
Engine/source/BadBehavior/core/behavior.h
Normal file
87
Engine/source/BadBehavior/core/behavior.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_BEHAVIOR_H_
|
||||
#define _BB_BEHAVIOR_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "Core.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
// specify when the precondition function should be executed
|
||||
enum PreconditionMode
|
||||
{
|
||||
ONCE, // the first time the behavior is evaluated
|
||||
TICK // every tick
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Behavior - Base class for structured behavior leaf nodes
|
||||
//---------------------------------------------------------------------------
|
||||
class Behavior : public LeafNode
|
||||
{
|
||||
typedef LeafNode Parent;
|
||||
|
||||
protected:
|
||||
// how often should we valuate the precondition
|
||||
PreconditionMode mPreconditionMode;
|
||||
|
||||
public:
|
||||
Behavior();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
const PreconditionMode &getPreconditionMode() const { return mPreconditionMode; }
|
||||
|
||||
virtual bool precondition( SimObject *owner ) { return true; }
|
||||
virtual void onEnter( SimObject *owner ) {}
|
||||
virtual void onExit( SimObject *owner ) {}
|
||||
virtual Status behavior( SimObject *owner ) { return SUCCESS; }
|
||||
|
||||
DECLARE_CONOBJECT(Behavior);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Behavior task
|
||||
//---------------------------------------------------------------------------
|
||||
class BehaviorTask : public Task
|
||||
{
|
||||
typedef Task Parent;
|
||||
|
||||
protected:
|
||||
virtual Task* update();
|
||||
|
||||
public:
|
||||
BehaviorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
// make the return precondition mode accessible from script
|
||||
typedef BadBehavior::PreconditionMode BehaviorPreconditionType;
|
||||
DefineEnumType( BehaviorPreconditionType );
|
||||
|
||||
#endif
|
||||
51
Engine/source/BadBehavior/decorator/FailAlways.cpp
Normal file
51
Engine/source/BadBehavior/decorator/FailAlways.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "FailAlways.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// FailAlways decorator node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(FailAlways);
|
||||
|
||||
Task *FailAlways::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new FailAlwaysTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// FailAlways decorator task
|
||||
//------------------------------------------------------------------------------
|
||||
FailAlwaysTask::FailAlwaysTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
void FailAlwaysTask::onChildComplete(Status s)
|
||||
{
|
||||
Parent::onChildComplete(s);
|
||||
if(mStatus == SUCCESS)
|
||||
mStatus = FAILURE;
|
||||
}
|
||||
|
||||
61
Engine/source/BadBehavior/decorator/FailAlways.h
Normal file
61
Engine/source/BadBehavior/decorator/FailAlways.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_FAILALWAYS_H_
|
||||
#define _BB_FAILALWAYS_H_
|
||||
|
||||
#ifndef _BB_DECORATOR_H_
|
||||
#include "BadBehavior/core/Decorator.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// FailAlways decorator
|
||||
// Returns FAILURE if child returns SUCCESS or FAILURE. RUNNING and INVALID are unchanged
|
||||
//---------------------------------------------------------------------------
|
||||
class FailAlways : public DecoratorNode
|
||||
{
|
||||
typedef DecoratorNode Parent;
|
||||
|
||||
public:
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
DECLARE_CONOBJECT(FailAlways);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// FailAlways task
|
||||
//---------------------------------------------------------------------------
|
||||
class FailAlwaysTask : public DecoratorTask
|
||||
{
|
||||
typedef DecoratorTask Parent;
|
||||
|
||||
public:
|
||||
FailAlwaysTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
virtual void onChildComplete(Status s);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
54
Engine/source/BadBehavior/decorator/Inverter.cpp
Normal file
54
Engine/source/BadBehavior/decorator/Inverter.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Inverter.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Inverter decorator node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(Inverter);
|
||||
|
||||
Task *Inverter::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new InverterTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Inverter decorator task
|
||||
//------------------------------------------------------------------------------
|
||||
InverterTask::InverterTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
void InverterTask::onChildComplete(Status s)
|
||||
{
|
||||
Parent::onChildComplete(s);
|
||||
|
||||
// invert SUCCESS or FAILURE, leave INVALID and RUNNING unchanged
|
||||
if (mStatus == SUCCESS)
|
||||
mStatus = FAILURE;
|
||||
else if (mStatus == FAILURE)
|
||||
mStatus = SUCCESS;
|
||||
}
|
||||
62
Engine/source/BadBehavior/decorator/Inverter.h
Normal file
62
Engine/source/BadBehavior/decorator/Inverter.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_INVERTER_H_
|
||||
#define _BB_INVERTER_H_
|
||||
|
||||
#ifndef _BB_DECORATOR_H_
|
||||
#include "BadBehavior/core/Decorator.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// inverter decorator
|
||||
// invert the return value of the child,
|
||||
// SUCCESS becomes FAILURE, FAILURE becomes SUCCESS, INVALID and RUNNING are unmodified
|
||||
//---------------------------------------------------------------------------
|
||||
class Inverter : public DecoratorNode
|
||||
{
|
||||
typedef DecoratorNode Parent;
|
||||
|
||||
public:
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
DECLARE_CONOBJECT(Inverter);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// inverter decorator task
|
||||
//---------------------------------------------------------------------------
|
||||
class InverterTask : public DecoratorTask
|
||||
{
|
||||
typedef DecoratorTask Parent;
|
||||
|
||||
public:
|
||||
InverterTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
virtual void onChildComplete(Status s);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
120
Engine/source/BadBehavior/decorator/Loop.cpp
Normal file
120
Engine/source/BadBehavior/decorator/Loop.cpp
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Loop.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Loop decorator node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(Loop);
|
||||
|
||||
ImplementEnumType( LoopTerminationPolicy,
|
||||
"@brief The policy to use when determining if the loop should terminate early.\n\n"
|
||||
"@ingroup AI\n\n")
|
||||
{ Loop::ON_FAILURE, "ON_FAILURE", "Will terminate and return FAILURE if child fails.\n" },
|
||||
{ Loop::ON_SUCCESS, "ON_SUCCESS", "Will terminate and return SUCCESS if child succeeds.\n" },
|
||||
EndImplementEnumType;
|
||||
|
||||
Loop::Loop()
|
||||
: mNumLoops(0),
|
||||
mTerminationPolicy(ON_FAILURE)
|
||||
{
|
||||
}
|
||||
|
||||
void Loop::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addProtectedField( "numLoops", TypeS32, Offset(mNumLoops, Loop), &_setNumLoops, &defaultProtectedGetFn,
|
||||
"The number of times to repeat the child behavior. 0 = infinite." );
|
||||
|
||||
addField( "terminationPolicy", TYPEID< Loop::TerminationPolicy >(), Offset(mTerminationPolicy, Loop),
|
||||
"@brief The policy to use when deciding if the loop should terminate before completion.");
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool Loop::_setNumLoops(void *object, const char *index, const char *data)
|
||||
{
|
||||
Loop *node = static_cast<Loop *>( object );
|
||||
node->mNumLoops = getMax(0, dAtoi( data ));
|
||||
return false;
|
||||
}
|
||||
|
||||
Task *Loop::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new LoopTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Loop decorator task
|
||||
//------------------------------------------------------------------------------
|
||||
LoopTask::LoopTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner),
|
||||
mCurrentLoop(0)
|
||||
{
|
||||
}
|
||||
|
||||
void LoopTask::onInitialize()
|
||||
{
|
||||
Parent::onInitialize();
|
||||
mCurrentLoop = 0;
|
||||
}
|
||||
|
||||
Task* LoopTask::update()
|
||||
{
|
||||
if(Parent::update())
|
||||
return mChild;
|
||||
|
||||
if(mStatus == RUNNING || mStatus == SUSPENDED)
|
||||
mIsComplete = false;
|
||||
|
||||
// child has terminated with SUCCESS or FAILURE
|
||||
if( mIsComplete )
|
||||
{
|
||||
// check if we should continue looping or reset
|
||||
Loop *nodeRep = static_cast<Loop *>(mNodeRep);
|
||||
Loop::TerminationPolicy policy = nodeRep->getTerminationPolicy();
|
||||
S32 numLoops = nodeRep->getNumLoops();
|
||||
|
||||
// termination policy not met?
|
||||
if( ((policy == Loop::ON_FAILURE) && (mStatus != FAILURE)) ||
|
||||
((policy == Loop::ON_SUCCESS) && (mStatus != SUCCESS)) )
|
||||
{
|
||||
// more looping to be done
|
||||
if ( (++mCurrentLoop < numLoops) || (numLoops == 0) )
|
||||
{
|
||||
mIsComplete = false;
|
||||
mStatus = RUNNING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no children to return
|
||||
return NULL;
|
||||
}
|
||||
90
Engine/source/BadBehavior/decorator/Loop.h
Normal file
90
Engine/source/BadBehavior/decorator/Loop.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_LOOP_H_
|
||||
#define _BB_LOOP_H_
|
||||
|
||||
#ifndef _BB_DECORATOR_H_
|
||||
#include "BadBehavior/core/Decorator.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// loop decorator
|
||||
// repeats the child behaviour for n times, or until it fails
|
||||
// returns RUNNING until it completes
|
||||
//---------------------------------------------------------------------------
|
||||
class Loop : public DecoratorNode
|
||||
{
|
||||
typedef DecoratorNode Parent;
|
||||
|
||||
public:
|
||||
// loop termination policies
|
||||
enum TerminationPolicy
|
||||
{
|
||||
ON_FAILURE,
|
||||
ON_SUCCESS,
|
||||
};
|
||||
|
||||
protected:
|
||||
static bool _setNumLoops(void *object, const char *index, const char *data);
|
||||
S32 mNumLoops;
|
||||
TerminationPolicy mTerminationPolicy;
|
||||
|
||||
public:
|
||||
Loop();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
S32 getNumLoops() const { return mNumLoops; }
|
||||
TerminationPolicy getTerminationPolicy() const { return mTerminationPolicy; }
|
||||
|
||||
DECLARE_CONOBJECT(Loop);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// loop task
|
||||
//---------------------------------------------------------------------------
|
||||
class LoopTask : public DecoratorTask
|
||||
{
|
||||
typedef DecoratorTask Parent;
|
||||
|
||||
protected:
|
||||
S32 mCurrentLoop;
|
||||
|
||||
virtual void onInitialize();
|
||||
virtual Task *update();
|
||||
|
||||
public:
|
||||
LoopTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
// make the loop termination policy enum accessible from script
|
||||
typedef BadBehavior::Loop::TerminationPolicy LoopTerminationPolicy;
|
||||
DefineEnumType( LoopTerminationPolicy );
|
||||
|
||||
#endif
|
||||
54
Engine/source/BadBehavior/decorator/Monitor.cpp
Normal file
54
Engine/source/BadBehavior/decorator/Monitor.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Monitor.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Monitor decorator node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(Monitor);
|
||||
|
||||
Task *Monitor::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new MonitorTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Logger decorator task
|
||||
//------------------------------------------------------------------------------
|
||||
MonitorTask::MonitorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
void MonitorTask::onChildComplete(Status s)
|
||||
{
|
||||
Parent::onChildComplete(s);
|
||||
|
||||
Con::printf("%s (%s) child returning %s", static_cast<Monitor *>(mNodeRep)->getInternalName(),
|
||||
static_cast<Monitor *>(mNodeRep)->getIdString(),
|
||||
EngineMarshallData< BehaviorReturnType > (mStatus));
|
||||
}
|
||||
61
Engine/source/BadBehavior/decorator/Monitor.h
Normal file
61
Engine/source/BadBehavior/decorator/Monitor.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_MONITOR_H_
|
||||
#define _BB_MONITOR_H_
|
||||
|
||||
#ifndef _BB_DECORATOR_H_
|
||||
#include "BadBehavior/core/Decorator.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Monitor decorator
|
||||
// outputs the return status to the console,
|
||||
//---------------------------------------------------------------------------
|
||||
class Monitor : public DecoratorNode
|
||||
{
|
||||
typedef DecoratorNode Parent;
|
||||
|
||||
public:
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
DECLARE_CONOBJECT(Monitor);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Monitor decorator task
|
||||
//---------------------------------------------------------------------------
|
||||
class MonitorTask : public DecoratorTask
|
||||
{
|
||||
typedef DecoratorTask Parent;
|
||||
|
||||
public:
|
||||
MonitorTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
virtual void onChildComplete(Status s);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
75
Engine/source/BadBehavior/decorator/Root.cpp
Normal file
75
Engine/source/BadBehavior/decorator/Root.cpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Root.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Root decorator node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(Root);
|
||||
|
||||
Task *Root::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new RootTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Root decorator task
|
||||
//------------------------------------------------------------------------------
|
||||
RootTask::RootTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner),
|
||||
mBranch(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
RootTask::~RootTask()
|
||||
{
|
||||
if(mBranch)
|
||||
delete mBranch;
|
||||
}
|
||||
|
||||
void RootTask::onInitialize()
|
||||
{
|
||||
Parent::onInitialize();
|
||||
if(!mBranch)
|
||||
mBranch = new BehaviorTreeBranch(mChild);
|
||||
else
|
||||
mBranch->reset();
|
||||
}
|
||||
|
||||
Task *RootTask::update()
|
||||
{
|
||||
mStatus = mBranch->update();
|
||||
|
||||
mIsComplete = mStatus != RUNNING && mStatus != SUSPENDED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Status RootTask::getStatus()
|
||||
{
|
||||
if(mStatus == SUSPENDED)
|
||||
return mBranch->getStatus();
|
||||
|
||||
return mStatus;
|
||||
}
|
||||
73
Engine/source/BadBehavior/decorator/Root.h
Normal file
73
Engine/source/BadBehavior/decorator/Root.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_ROOT_H_
|
||||
#define _BB_ROOT_H_
|
||||
|
||||
#ifndef _BB_BRANCH_H_
|
||||
#include "BadBehavior/core/Branch.h"
|
||||
#endif
|
||||
#ifndef _BB_DECORATOR_H_
|
||||
#include "BadBehavior/core/Decorator.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Root decorator
|
||||
// A placeholder node to mark the start of a tree.
|
||||
// Used by the editor, bypassed during tree evaluation.
|
||||
//---------------------------------------------------------------------------
|
||||
class Root : public DecoratorNode
|
||||
{
|
||||
typedef DecoratorNode Parent;
|
||||
|
||||
public:
|
||||
virtual Task* createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
DECLARE_CONOBJECT(Root);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Root task
|
||||
//---------------------------------------------------------------------------
|
||||
class RootTask : public DecoratorTask
|
||||
{
|
||||
typedef DecoratorTask Parent;
|
||||
|
||||
protected:
|
||||
BehaviorTreeBranch *mBranch;
|
||||
|
||||
virtual Task* update();
|
||||
virtual void onInitialize();
|
||||
//virtual void onTerminate();
|
||||
|
||||
public:
|
||||
RootTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
virtual ~RootTask();
|
||||
|
||||
virtual Status getStatus();
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
51
Engine/source/BadBehavior/decorator/SucceedAlways.cpp
Normal file
51
Engine/source/BadBehavior/decorator/SucceedAlways.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "SucceedAlways.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// SucceedAlways decorator node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(SucceedAlways);
|
||||
|
||||
Task *SucceedAlways::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new SucceedAlwaysTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// SucceedAlways decorator task
|
||||
//------------------------------------------------------------------------------
|
||||
SucceedAlwaysTask::SucceedAlwaysTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
void SucceedAlwaysTask::onChildComplete(Status s)
|
||||
{
|
||||
Parent::onChildComplete(s);
|
||||
if(mStatus == FAILURE)
|
||||
mStatus = SUCCESS;
|
||||
}
|
||||
|
||||
61
Engine/source/BadBehavior/decorator/SucceedAlways.h
Normal file
61
Engine/source/BadBehavior/decorator/SucceedAlways.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_SUCCEEDALWAYS_H_
|
||||
#define _BB_SUCCEEDALWAYS_H_
|
||||
|
||||
#ifndef _BB_DECORATOR_H_
|
||||
#include "BadBehavior/core/Decorator.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// SucceedAlways decorator
|
||||
// Returns SUCCESS if child returns SUCCESS or FAILURE. RUNNING and INVALID are unchanged
|
||||
//---------------------------------------------------------------------------
|
||||
class SucceedAlways : public DecoratorNode
|
||||
{
|
||||
typedef DecoratorNode Parent;
|
||||
|
||||
public:
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
DECLARE_CONOBJECT(SucceedAlways);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// SucceedAlways task
|
||||
//---------------------------------------------------------------------------
|
||||
class SucceedAlwaysTask : public DecoratorTask
|
||||
{
|
||||
typedef DecoratorTask Parent;
|
||||
|
||||
public:
|
||||
SucceedAlwaysTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
virtual void onChildComplete(Status s);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
136
Engine/source/BadBehavior/decorator/Ticker.cpp
Normal file
136
Engine/source/BadBehavior/decorator/Ticker.cpp
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "Ticker.h"
|
||||
#include "BadBehavior/core/Runner.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Ticker decorator node
|
||||
// **** EXPERIMENTAL ****
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(Ticker);
|
||||
|
||||
Ticker::Ticker()
|
||||
: mFrequencyMs(100)
|
||||
{
|
||||
}
|
||||
|
||||
void Ticker::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addProtectedField( "frequencyMs", TypeS32, Offset(mFrequencyMs, Ticker), &_setFrequency, &defaultProtectedGetFn,
|
||||
"The time to wait between evaluations of this nodes child." );
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool Ticker::_setFrequency(void *object, const char *index, const char *data)
|
||||
{
|
||||
Ticker *node = static_cast<Ticker *>( object );
|
||||
node->mFrequencyMs = getMax(0, dAtoi( data ));
|
||||
return false;
|
||||
}
|
||||
|
||||
Task *Ticker::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new TickerTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Ticker decorator task
|
||||
//------------------------------------------------------------------------------
|
||||
TickerTask::TickerTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner),
|
||||
mNextTimeMs(0),
|
||||
mEventId(0),
|
||||
mBranch(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
TickerTask::~TickerTask()
|
||||
{
|
||||
cancelEvent();
|
||||
|
||||
if(mBranch)
|
||||
delete mBranch;
|
||||
}
|
||||
|
||||
void TickerTask::cancelEvent()
|
||||
{
|
||||
if(Sim::isEventPending(mEventId))
|
||||
{
|
||||
Sim::cancelEvent(mEventId);
|
||||
mEventId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TickerTask::onInitialize()
|
||||
{
|
||||
Parent::onInitialize();
|
||||
cancelEvent();
|
||||
if(!mBranch)
|
||||
mBranch = new BehaviorTreeBranch(mChild);
|
||||
else
|
||||
mBranch->reset();
|
||||
}
|
||||
|
||||
void TickerTask::onTerminate()
|
||||
{
|
||||
Parent::onTerminate();
|
||||
cancelEvent();
|
||||
}
|
||||
|
||||
Task* TickerTask::update()
|
||||
{
|
||||
if(Sim::getCurrentTime() < mNextTimeMs)
|
||||
{
|
||||
if(!Sim::isEventPending(mEventId))
|
||||
mEventId = Sim::postEvent(mRunner, new TaskReactivateEvent(*this), mNextTimeMs);
|
||||
|
||||
mStatus = SUSPENDED;
|
||||
}
|
||||
else if(mStatus != SUSPENDED)
|
||||
{
|
||||
mNextTimeMs = Sim::getCurrentTime() + static_cast<Ticker *>(mNodeRep)->getFrequencyMs();
|
||||
Status s = mBranch->update();
|
||||
mStatus = s != SUSPENDED ? s : RUNNING;
|
||||
}
|
||||
|
||||
mIsComplete = mStatus != SUSPENDED && mStatus != RUNNING;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Status TickerTask::getStatus()
|
||||
{
|
||||
if(mStatus != SUSPENDED && mStatus != RESUME)
|
||||
return mBranch->getStatus();
|
||||
|
||||
return mStatus;
|
||||
}
|
||||
89
Engine/source/BadBehavior/decorator/Ticker.h
Normal file
89
Engine/source/BadBehavior/decorator/Ticker.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_TICKER_H_
|
||||
#define _BB_TICKER_H_
|
||||
|
||||
#ifndef _BB_DECORATOR_H_
|
||||
#include "BadBehavior/core/Decorator.h"
|
||||
#endif
|
||||
#ifndef _BB_BRANCH_H_
|
||||
#include "BadBehavior/core/Branch.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Ticker decorator
|
||||
// Limits the frequency at which it's children are updated.
|
||||
//---------------------------------------------------------------------------
|
||||
class Ticker : public DecoratorNode
|
||||
{
|
||||
typedef DecoratorNode Parent;
|
||||
|
||||
protected:
|
||||
static bool _setFrequency(void *object, const char *index, const char *data);
|
||||
|
||||
// time between ticks (in ms)
|
||||
S32 mFrequencyMs;
|
||||
|
||||
public:
|
||||
Ticker();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
S32 getFrequencyMs() const { return mFrequencyMs; }
|
||||
|
||||
DECLARE_CONOBJECT(Ticker);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ticker decorator task
|
||||
//---------------------------------------------------------------------------
|
||||
class TickerTask : public DecoratorTask
|
||||
{
|
||||
typedef DecoratorTask Parent;
|
||||
|
||||
protected:
|
||||
U32 mNextTimeMs;
|
||||
U32 mEventId;
|
||||
|
||||
BehaviorTreeBranch *mBranch;
|
||||
|
||||
virtual void onInitialize();
|
||||
virtual void onTerminate();
|
||||
virtual Task* update();
|
||||
|
||||
void cancelEvent();
|
||||
|
||||
public:
|
||||
TickerTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
virtual ~TickerTask();
|
||||
|
||||
virtual Status getStatus();
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
125
Engine/source/BadBehavior/leaf/RandomWait.cpp
Normal file
125
Engine/source/BadBehavior/leaf/RandomWait.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "RandomWait.h"
|
||||
#include "BadBehavior/core/Runner.h"
|
||||
|
||||
#include "math/mMathFn.h"
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RandomWait leaf node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(RandomWait);
|
||||
|
||||
RandomWait::RandomWait()
|
||||
: mWaitMinMs(0),
|
||||
mWaitMaxMs(99999)
|
||||
{
|
||||
}
|
||||
|
||||
void RandomWait::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addProtectedField( "waitMinMs", TypeS32, Offset(mWaitMinMs, RandomWait), &_setWaitMin, &defaultProtectedGetFn,
|
||||
"The minimum time period in ms to wait before completion." );
|
||||
|
||||
addProtectedField( "waitMaxMs", TypeS32, Offset(mWaitMaxMs, RandomWait), &_setWaitMax, &defaultProtectedGetFn,
|
||||
"The maximum time period in ms to wait before completion." );
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool RandomWait::_setWaitMin(void *object, const char *index, const char *data)
|
||||
{
|
||||
RandomWait *node = static_cast<RandomWait *>( object );
|
||||
node->mWaitMinMs = getMin(node->mWaitMaxMs, dAtoi( data ));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RandomWait::_setWaitMax(void *object, const char *index, const char *data)
|
||||
{
|
||||
RandomWait *node = static_cast<RandomWait *>( object );
|
||||
node->mWaitMaxMs = getMax(node->mWaitMinMs, dAtoi( data ));
|
||||
return false;
|
||||
}
|
||||
|
||||
Task *RandomWait::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new RandomWaitTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RandomWait task
|
||||
//------------------------------------------------------------------------------
|
||||
RandomWaitTask::RandomWaitTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
RandomWaitTask::~RandomWaitTask()
|
||||
{
|
||||
cancelEvent();
|
||||
}
|
||||
|
||||
void RandomWaitTask::cancelEvent()
|
||||
{
|
||||
if(Sim::isEventPending(mEventId))
|
||||
{
|
||||
Sim::cancelEvent(mEventId);
|
||||
mEventId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RandomWaitTask::onInitialize()
|
||||
{
|
||||
Parent::onInitialize();
|
||||
cancelEvent();
|
||||
}
|
||||
|
||||
void RandomWaitTask::onTerminate()
|
||||
{
|
||||
Parent::onTerminate();
|
||||
cancelEvent();
|
||||
}
|
||||
|
||||
Task* RandomWaitTask::update()
|
||||
{
|
||||
if(mStatus == RESUME)
|
||||
{
|
||||
mStatus = SUCCESS;
|
||||
mIsComplete = true;
|
||||
}
|
||||
else if(mStatus == INVALID)
|
||||
{
|
||||
RandomWait *node = static_cast<RandomWait*>(mNodeRep);
|
||||
mEventId = Sim::postEvent(mRunner, new TaskReactivateEvent(*this), Sim::getCurrentTime() + mRandI(node->getWaitMinMs(), node->getWaitMaxMs()));
|
||||
mStatus = SUSPENDED;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
83
Engine/source/BadBehavior/leaf/RandomWait.h
Normal file
83
Engine/source/BadBehavior/leaf/RandomWait.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_RANDOMWAIT_H_
|
||||
#define _BB_RANDOMWAIT_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Core.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// RandomWait leaf
|
||||
// Pauses for a random period of time between delayMin and delayMax ms before completing.
|
||||
//---------------------------------------------------------------------------
|
||||
class RandomWait : public LeafNode
|
||||
{
|
||||
typedef LeafNode Parent;
|
||||
|
||||
protected:
|
||||
static bool _setWaitMin(void *object, const char *index, const char *data);
|
||||
static bool _setWaitMax(void *object, const char *index, const char *data);
|
||||
|
||||
S32 mWaitMinMs;
|
||||
S32 mWaitMaxMs;
|
||||
|
||||
public:
|
||||
RandomWait();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
S32 getWaitMinMs() const { return mWaitMinMs; }
|
||||
S32 getWaitMaxMs() const { return mWaitMaxMs; }
|
||||
|
||||
DECLARE_CONOBJECT(RandomWait);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// RandomWait leaf task
|
||||
//---------------------------------------------------------------------------
|
||||
class RandomWaitTask : public Task
|
||||
{
|
||||
typedef Task Parent;
|
||||
|
||||
protected:
|
||||
U32 mEventId;
|
||||
|
||||
virtual void onInitialize();
|
||||
virtual void onTerminate();
|
||||
virtual Task* update();
|
||||
|
||||
void cancelEvent();
|
||||
|
||||
public:
|
||||
RandomWaitTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
virtual ~RandomWaitTask();
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
94
Engine/source/BadBehavior/leaf/ScriptEval.cpp
Normal file
94
Engine/source/BadBehavior/leaf/ScriptEval.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "ScriptEval.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ScriptEval node - warning, slow!
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(ScriptEval);
|
||||
|
||||
ScriptEval::ScriptEval()
|
||||
: mDefaultReturnStatus(SUCCESS)
|
||||
{
|
||||
}
|
||||
|
||||
void ScriptEval::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addField( "behaviorScript", TypeCommand, Offset(mBehaviorScript, ScriptEval),
|
||||
"@brief The command to execute when the leaf is ticked. Max 255 characters." );
|
||||
|
||||
addField( "defaultReturnStatus", TYPEID< BadBehavior::Status >(), Offset(mDefaultReturnStatus, ScriptEval),
|
||||
"@brief The default value for this node to return.");
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
Task *ScriptEval::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new ScriptEvalTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
Status ScriptEval::evaluateScript( SimObject *owner )
|
||||
{
|
||||
PROFILE_SCOPE(ScriptEval_evaluateScript);
|
||||
|
||||
if(mBehaviorScript.isEmpty())
|
||||
return mDefaultReturnStatus;
|
||||
|
||||
// get the result
|
||||
const char *result = Con::evaluatef("%%obj=%s; %s return %s;",
|
||||
owner->getIdString(),
|
||||
mBehaviorScript.c_str(),
|
||||
EngineMarshallData< BehaviorReturnType >(mDefaultReturnStatus));
|
||||
|
||||
if(result[0] == '1' || result[0] == '0')
|
||||
// map true or false to SUCCEED or FAILURE
|
||||
return static_cast<Status>(dAtoi(result));
|
||||
|
||||
// convert the returned value to our internal enum type
|
||||
return EngineUnmarshallData< BehaviorReturnType >()( result );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RunScript task
|
||||
//------------------------------------------------------------------------------
|
||||
ScriptEvalTask::ScriptEvalTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
Task* ScriptEvalTask::update()
|
||||
{
|
||||
mStatus = static_cast<ScriptEval*>(mNodeRep)->evaluateScript( mOwner );
|
||||
|
||||
return NULL; // leaves don't have children
|
||||
}
|
||||
75
Engine/source/BadBehavior/leaf/ScriptEval.h
Normal file
75
Engine/source/BadBehavior/leaf/ScriptEval.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_SCRIPTEVAL_H_
|
||||
#define _BB_SCRIPTEVAL_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Core.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// ScriptEval - evaluates a set of Torque Script commands when run
|
||||
// Warning - slow, handle with care!
|
||||
//---------------------------------------------------------------------------
|
||||
class ScriptEval : public LeafNode
|
||||
{
|
||||
typedef LeafNode Parent;
|
||||
|
||||
private:
|
||||
// status to return if the command does not return a value
|
||||
Status mDefaultReturnStatus;
|
||||
|
||||
// the torque script to evaluate
|
||||
String mBehaviorScript;
|
||||
|
||||
public:
|
||||
ScriptEval();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
// execute the script
|
||||
Status evaluateScript(SimObject *owner);
|
||||
|
||||
DECLARE_CONOBJECT(ScriptEval);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// ScriptEval task
|
||||
//---------------------------------------------------------------------------
|
||||
class ScriptEvalTask : public Task
|
||||
{
|
||||
typedef Task Parent;
|
||||
|
||||
protected:
|
||||
virtual Task* update();
|
||||
|
||||
public:
|
||||
ScriptEvalTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
#endif
|
||||
121
Engine/source/BadBehavior/leaf/ScriptFunc.cpp
Normal file
121
Engine/source/BadBehavior/leaf/ScriptFunc.cpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "ScriptFunc.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ScriptFunc node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(ScriptFunc);
|
||||
|
||||
ScriptFunc::ScriptFunc()
|
||||
: mDefaultReturnStatus(SUCCESS),
|
||||
mScriptFunction(StringTable->insert(""))
|
||||
{
|
||||
for(U8 i = 0; i < MAX_COMMAND_ARGS; ++i)
|
||||
mScriptArgs[i] = StringTable->insert("");
|
||||
}
|
||||
|
||||
|
||||
void ScriptFunc::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addField( "func", TypeCaseString, Offset(mScriptFunction, ScriptFunc),
|
||||
"@brief The function to execute when the leaf is ticked." );
|
||||
|
||||
addField( "args", TypeCaseString, Offset(mScriptArgs, ScriptFunc), MAX_COMMAND_ARGS,
|
||||
"@brief The arguments to be passed to the function to be executed." );
|
||||
|
||||
addField( "defaultReturnStatus", TYPEID< BadBehavior::Status >(), Offset(mDefaultReturnStatus, ScriptFunc),
|
||||
"@brief The default value for this node to return.");
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
Task *ScriptFunc::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new ScriptFuncTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
Status ScriptFunc::evaluate( SimObject *owner )
|
||||
{
|
||||
PROFILE_SCOPE(ScriptFunc_evaluate);
|
||||
|
||||
if(!owner)
|
||||
return INVALID;
|
||||
|
||||
if(!mScriptFunction || !mScriptFunction[0])
|
||||
return mDefaultReturnStatus;
|
||||
|
||||
S32 argc = 0;
|
||||
|
||||
const char *args[MAX_COMMAND_ARGS + 2];
|
||||
args[0] = mScriptFunction;
|
||||
|
||||
while(argc < MAX_COMMAND_ARGS && (mScriptArgs[argc] && mScriptArgs[argc][0]))
|
||||
{
|
||||
args[argc + 2] = mScriptArgs[argc];
|
||||
++argc;
|
||||
}
|
||||
|
||||
argc += 2;
|
||||
|
||||
// get the result
|
||||
const char *result = Con::execute(owner, argc, args);
|
||||
|
||||
// if function didn't return a result, return our default status
|
||||
if(!result || !result[0])
|
||||
return mDefaultReturnStatus;
|
||||
|
||||
// map true or false to SUCCEED or FAILURE
|
||||
if(result[0] == '1' || result[0] == '0')
|
||||
return static_cast<Status>(dAtoi(result));
|
||||
|
||||
// convert the returned value to our internal enum type
|
||||
return EngineUnmarshallData< BehaviorReturnType >()( result );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ScriptFunc task
|
||||
//------------------------------------------------------------------------------
|
||||
ScriptFuncTask::ScriptFuncTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner)
|
||||
{
|
||||
}
|
||||
|
||||
Task* ScriptFuncTask::update()
|
||||
{
|
||||
mStatus = static_cast<ScriptFunc*>(mNodeRep)->evaluate( mOwner );
|
||||
|
||||
if(mStatus != RUNNING && mStatus != SUSPENDED)
|
||||
mIsComplete = true;
|
||||
|
||||
return NULL; // leaves don't have children
|
||||
}
|
||||
79
Engine/source/BadBehavior/leaf/ScriptFunc.h
Normal file
79
Engine/source/BadBehavior/leaf/ScriptFunc.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_SCRIPTFUNC_H_
|
||||
#define _BB_SCRIPTFUNC_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Core.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
static const U8 MAX_COMMAND_ARGS = 4;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// ScriptFunc - executes a function on the owner object
|
||||
//---------------------------------------------------------------------------
|
||||
class ScriptFunc : public LeafNode
|
||||
{
|
||||
typedef LeafNode Parent;
|
||||
|
||||
protected:
|
||||
// the function to call
|
||||
StringTableEntry mScriptFunction;
|
||||
|
||||
// the arguments for the function
|
||||
StringTableEntry mScriptArgs[MAX_COMMAND_ARGS];
|
||||
|
||||
// status to return if the command does not return a value
|
||||
Status mDefaultReturnStatus;
|
||||
|
||||
public:
|
||||
ScriptFunc();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
// execute the command
|
||||
Status evaluate(SimObject *owner);
|
||||
|
||||
DECLARE_CONOBJECT(ScriptFunc);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// ScriptFunc task
|
||||
//---------------------------------------------------------------------------
|
||||
class ScriptFuncTask : public Task
|
||||
{
|
||||
typedef Task Parent;
|
||||
|
||||
protected:
|
||||
virtual Task* update();
|
||||
|
||||
public:
|
||||
ScriptFuncTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
#endif
|
||||
83
Engine/source/BadBehavior/leaf/ScriptedBehavior.cpp
Normal file
83
Engine/source/BadBehavior/leaf/ScriptedBehavior.cpp
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "ScriptedBehavior.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ScriptedBehavior node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(ScriptedBehavior);
|
||||
|
||||
IMPLEMENT_CALLBACK( ScriptedBehavior, onEnter, void, ( SimObject* owner ), ( owner ),
|
||||
"Called when the behavior is first run.\n"
|
||||
"@param owner The object that this behavior tree belongs to." );
|
||||
|
||||
IMPLEMENT_CALLBACK( ScriptedBehavior, onExit, void, ( SimObject* owner ), ( owner ),
|
||||
"Called when the behavior is complete.\n"
|
||||
"@param owner The object that this behavior tree belongs to." );
|
||||
|
||||
IMPLEMENT_CALLBACK( ScriptedBehavior, precondition, bool, ( SimObject* owner ), ( owner ),
|
||||
"Called prior to evaluating the behavior.\n"
|
||||
"@param owner The object that this behavior tree belongs to.\n"
|
||||
"A return value of false indicates that evaluation of the behavior should stop.\n"
|
||||
"A return value of true indicates that evaluation of the behavior should continue.");
|
||||
|
||||
IMPLEMENT_CALLBACK( ScriptedBehavior, behavior, Status, ( SimObject* owner ), ( owner ),
|
||||
"Evaluate the main behavior of this node.\n"
|
||||
"@param owner The object that this behavior tree belongs to.\n");
|
||||
|
||||
ScriptedBehavior::ScriptedBehavior()
|
||||
{
|
||||
}
|
||||
|
||||
bool ScriptedBehavior::precondition( SimObject *owner )
|
||||
{
|
||||
PROFILE_SCOPE( ScriptedBehavior_precondition);
|
||||
|
||||
if(isMethod("precondition"))
|
||||
return precondition_callback(owner);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptedBehavior::onEnter( SimObject *owner )
|
||||
{
|
||||
PROFILE_SCOPE( ScriptedBehavior_onEnter );
|
||||
onEnter_callback(owner);
|
||||
}
|
||||
|
||||
void ScriptedBehavior::onExit( SimObject *owner )
|
||||
{
|
||||
PROFILE_SCOPE( ScriptedBehavior_onExit );
|
||||
onExit_callback(owner);
|
||||
}
|
||||
|
||||
Status ScriptedBehavior::behavior( SimObject *owner )
|
||||
{
|
||||
PROFILE_SCOPE( ScriptedBehavior_behavior );
|
||||
return behavior_callback( owner );
|
||||
}
|
||||
56
Engine/source/BadBehavior/leaf/ScriptedBehavior.h
Normal file
56
Engine/source/BadBehavior/leaf/ScriptedBehavior.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_SCRIPTEDBEHAVIOR_H_
|
||||
#define _BB_SCRIPTEDBEHAVIOR_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/behavior.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// ScriptedBehavior - A structured behavior leaf node which defines a series
|
||||
// Of scripted callbacks
|
||||
//---------------------------------------------------------------------------
|
||||
class ScriptedBehavior : public Behavior
|
||||
{
|
||||
typedef Behavior Parent;
|
||||
|
||||
public:
|
||||
ScriptedBehavior();
|
||||
|
||||
virtual bool precondition( SimObject *owner );
|
||||
virtual void onEnter( SimObject *owner );
|
||||
virtual void onExit( SimObject *owner );
|
||||
virtual Status behavior( SimObject *owner );
|
||||
|
||||
DECLARE_CONOBJECT(ScriptedBehavior);
|
||||
DECLARE_CALLBACK(void, onEnter, (SimObject *owner));
|
||||
DECLARE_CALLBACK(void, onExit, (SimObject *owner));
|
||||
DECLARE_CALLBACK(bool, precondition, (SimObject *owner));
|
||||
DECLARE_CALLBACK(Status, behavior, (SimObject *owner));
|
||||
};
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
76
Engine/source/BadBehavior/leaf/SubTree.cpp
Normal file
76
Engine/source/BadBehavior/leaf/SubTree.cpp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "SubTree.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// SubTree node - links to another behavior tree
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(SubTree);
|
||||
|
||||
SubTree::SubTree()
|
||||
: mSubTreeName(0)
|
||||
{
|
||||
}
|
||||
|
||||
void SubTree::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addField( "subTreeName", TypeString, Offset(mSubTreeName, SubTree),
|
||||
"@brief The name of the behavior tree that this node links to. Max 255 characters." );
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
Task *SubTree::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
if(!mSubTreeName || mSubTreeName[0] == 0)
|
||||
{
|
||||
Con::errorf("SubTree::onInitialize: no sub tree specified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SimObject *subTreeNode;
|
||||
|
||||
if(!Sim::findObject(mSubTreeName, subTreeNode))
|
||||
{
|
||||
Con::errorf("SubTree:onInitialize: the specified sub tree does not exist");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Node *node = dynamic_cast<Node*>(subTreeNode);
|
||||
if(!node)
|
||||
{
|
||||
Con::errorf("SubTree::onInitialize: the specified sub tree is not a behavior tree node");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return node->createTask(owner, runner);
|
||||
}
|
||||
56
Engine/source/BadBehavior/leaf/SubTree.h
Normal file
56
Engine/source/BadBehavior/leaf/SubTree.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_SUBTREE_H_
|
||||
#define _BB_SUBTREE_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Core.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// SubTree decorator
|
||||
// Turns a named Behavior into a subtree of this node.
|
||||
// Does not actually have a child, so is a subclass of leaf
|
||||
//---------------------------------------------------------------------------
|
||||
class SubTree : public LeafNode
|
||||
{
|
||||
typedef LeafNode Parent;
|
||||
|
||||
protected:
|
||||
const char* mSubTreeName;
|
||||
|
||||
public:
|
||||
SubTree();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(SubTree);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
115
Engine/source/BadBehavior/leaf/Wait.cpp
Normal file
115
Engine/source/BadBehavior/leaf/Wait.cpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "Wait.h"
|
||||
#include "BadBehavior/core/Runner.h"
|
||||
|
||||
#include "math/mMathFn.h"
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Wait leaf node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(Wait);
|
||||
|
||||
Wait::Wait()
|
||||
: mWaitMs(1000)
|
||||
{
|
||||
}
|
||||
|
||||
void Wait::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addProtectedField( "waitMs", TypeS32, Offset(mWaitMs, Wait), &_setWait, &defaultProtectedGetFn,
|
||||
"The time in ms that the node should wait before completion." );
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool Wait::_setWait(void *object, const char *index, const char *data)
|
||||
{
|
||||
Wait *node = static_cast<Wait *>( object );
|
||||
node->mWaitMs = getMax(0, dAtoi( data ));
|
||||
return false;
|
||||
}
|
||||
|
||||
Task *Wait::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new WaitTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Wait task
|
||||
//------------------------------------------------------------------------------
|
||||
WaitTask::WaitTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner),
|
||||
mEventId(0)
|
||||
{
|
||||
}
|
||||
|
||||
WaitTask::~WaitTask()
|
||||
{
|
||||
cancelEvent();
|
||||
}
|
||||
|
||||
void WaitTask::cancelEvent()
|
||||
{
|
||||
if(Sim::isEventPending(mEventId))
|
||||
{
|
||||
Sim::cancelEvent(mEventId);
|
||||
mEventId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void WaitTask::onInitialize()
|
||||
{
|
||||
Parent::onInitialize();
|
||||
cancelEvent();
|
||||
}
|
||||
|
||||
void WaitTask::onTerminate()
|
||||
{
|
||||
Parent::onTerminate();
|
||||
cancelEvent();
|
||||
}
|
||||
|
||||
Task* WaitTask::update()
|
||||
{
|
||||
if(mStatus == RESUME)
|
||||
{
|
||||
mStatus = SUCCESS;
|
||||
mIsComplete = true;
|
||||
}
|
||||
else if(mStatus == INVALID)
|
||||
{
|
||||
mEventId = Sim::postEvent(mRunner, new TaskReactivateEvent(*this), Sim::getCurrentTime() + static_cast<Wait*>(mNodeRep)->getWaitMs());
|
||||
mStatus = SUSPENDED;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
80
Engine/source/BadBehavior/leaf/Wait.h
Normal file
80
Engine/source/BadBehavior/leaf/Wait.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_WAIT_H_
|
||||
#define _BB_WAIT_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Core.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// Wait leaf
|
||||
// Pauses for a set time period.
|
||||
//---------------------------------------------------------------------------
|
||||
class Wait : public LeafNode
|
||||
{
|
||||
typedef LeafNode Parent;
|
||||
|
||||
protected:
|
||||
static bool _setWait(void *object, const char *index, const char *data);
|
||||
|
||||
S32 mWaitMs;
|
||||
|
||||
public:
|
||||
Wait();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
S32 getWaitMs() const { return mWaitMs; }
|
||||
|
||||
DECLARE_CONOBJECT(Wait);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Wait leaf task
|
||||
//---------------------------------------------------------------------------
|
||||
class WaitTask : public Task
|
||||
{
|
||||
typedef Task Parent;
|
||||
|
||||
protected:
|
||||
U32 mEventId;
|
||||
|
||||
virtual void onInitialize();
|
||||
virtual void onTerminate();
|
||||
virtual Task* update();
|
||||
|
||||
void cancelEvent();
|
||||
|
||||
public:
|
||||
WaitTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
virtual ~WaitTask();
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
145
Engine/source/BadBehavior/leaf/WaitForSignal.cpp
Normal file
145
Engine/source/BadBehavior/leaf/WaitForSignal.cpp
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "WaitForSignal.h"
|
||||
#include "BadBehavior/core/Runner.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WaitForSignal leaf node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(WaitForSignal);
|
||||
|
||||
WaitForSignal::WaitForSignal()
|
||||
: mTimeoutMs(0)
|
||||
{
|
||||
}
|
||||
|
||||
void WaitForSignal::initPersistFields()
|
||||
{
|
||||
addGroup( "Behavior" );
|
||||
|
||||
addField( "signalName", TypeRealString, Offset(mSignalName, WaitForSignal),
|
||||
"The time in ms that the node should wait before completion." );
|
||||
|
||||
addProtectedField( "timeoutMs", TypeS32, Offset(mTimeoutMs, WaitForSignal), &_setTimeout, &defaultProtectedGetFn,
|
||||
"The maximum time in ms that the node should wait for the signal.\n"
|
||||
"A value of 0 indicates no limit");
|
||||
|
||||
endGroup( "Behavior" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
Task *WaitForSignal::createTask(SimObject &owner, BehaviorTreeRunner &runner)
|
||||
{
|
||||
return new WaitForSignalTask(*this, owner, runner);
|
||||
}
|
||||
|
||||
bool WaitForSignal::_setTimeout(void *object, const char *index, const char *data)
|
||||
{
|
||||
WaitForSignal *node = static_cast<WaitForSignal *>( object );
|
||||
node->mTimeoutMs = getMax(0, dAtoi( data ));
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Wait task
|
||||
//------------------------------------------------------------------------------
|
||||
WaitForSignalTask::WaitForSignalTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner)
|
||||
: Parent(node, owner, runner),
|
||||
mEventId(0)
|
||||
{
|
||||
}
|
||||
|
||||
WaitForSignalTask::~WaitForSignalTask()
|
||||
{
|
||||
unsubscribe();
|
||||
cancelEvent();
|
||||
}
|
||||
|
||||
void WaitForSignalTask::subscribe()
|
||||
{
|
||||
mRunner->subscribeToSignal(static_cast<WaitForSignal *>(mNodeRep)->getSignalName().c_str(), this);
|
||||
}
|
||||
|
||||
void WaitForSignalTask::unsubscribe()
|
||||
{
|
||||
mRunner->unsubscribeFromSignal(static_cast<WaitForSignal *>(mNodeRep)->getSignalName().c_str(), this);
|
||||
}
|
||||
|
||||
void WaitForSignalTask::onSignal()
|
||||
{
|
||||
onResume();
|
||||
}
|
||||
|
||||
void WaitForSignalTask::onTimeout()
|
||||
{
|
||||
mStatus = FAILURE;
|
||||
}
|
||||
|
||||
void WaitForSignalTask::cancelEvent()
|
||||
{
|
||||
if(mEventId != 0 && Sim::isEventPending(mEventId))
|
||||
{
|
||||
Sim::cancelEvent(mEventId);
|
||||
mEventId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void WaitForSignalTask::onInitialize()
|
||||
{
|
||||
Parent::onInitialize();
|
||||
subscribe();
|
||||
cancelEvent();
|
||||
}
|
||||
|
||||
void WaitForSignalTask::onTerminate()
|
||||
{
|
||||
Parent::onTerminate();
|
||||
unsubscribe();
|
||||
cancelEvent();
|
||||
}
|
||||
|
||||
Task* WaitForSignalTask::update()
|
||||
{
|
||||
if(mStatus == RESUME)
|
||||
{
|
||||
mStatus = SUCCESS;
|
||||
}
|
||||
else if (mStatus == INVALID)
|
||||
{
|
||||
mStatus = SUSPENDED;
|
||||
|
||||
S32 timeout = static_cast<WaitForSignal *>(mNodeRep)->getTimeoutMs();
|
||||
if(timeout > 0)
|
||||
mEventId = Sim::postEvent(mRunner, new WaitForSignalTimeoutEvent(*this), Sim::getCurrentTime() + timeout);
|
||||
}
|
||||
|
||||
if(mStatus == SUCCESS || mStatus == FAILURE)
|
||||
mIsComplete = true;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
114
Engine/source/BadBehavior/leaf/WaitForSignal.h
Normal file
114
Engine/source/BadBehavior/leaf/WaitForSignal.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_WAITFORSIGNAL_H_
|
||||
#define _BB_WAITFORSIGNAL_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/Core.h"
|
||||
#endif
|
||||
#ifndef _BB_SIGNAL_H_
|
||||
#include "BadBehavior/core/Signal.h"
|
||||
#endif
|
||||
#ifndef _SIMEVENTS_H_
|
||||
#include "console/simEvents.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// WaitForSignal leaf
|
||||
// Waits until it receives the requested signal.
|
||||
//---------------------------------------------------------------------------
|
||||
class WaitForSignal : public LeafNode
|
||||
{
|
||||
typedef LeafNode Parent;
|
||||
|
||||
protected:
|
||||
String mSignalName;
|
||||
S32 mTimeoutMs;
|
||||
|
||||
static bool _setTimeout(void *object, const char *index, const char *data);
|
||||
|
||||
public:
|
||||
WaitForSignal();
|
||||
|
||||
virtual Task *createTask(SimObject &owner, BehaviorTreeRunner &runner);
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
const String &getSignalName() const { return mSignalName; }
|
||||
S32 getTimeoutMs() const { return mTimeoutMs; }
|
||||
|
||||
DECLARE_CONOBJECT(WaitForSignal);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// WaitForSignal leaf task
|
||||
//---------------------------------------------------------------------------
|
||||
class WaitForSignalTask : public Task, public virtual SignalSubscriber
|
||||
{
|
||||
typedef Task Parent;
|
||||
|
||||
protected:
|
||||
U32 mEventId;
|
||||
|
||||
virtual void onInitialize();
|
||||
virtual void onTerminate();
|
||||
virtual Task* update();
|
||||
|
||||
void cancelEvent();
|
||||
|
||||
// SignalSubscriber
|
||||
virtual void subscribe();
|
||||
virtual void unsubscribe();
|
||||
|
||||
public:
|
||||
WaitForSignalTask(Node &node, SimObject &owner, BehaviorTreeRunner &runner);
|
||||
virtual ~WaitForSignalTask();
|
||||
|
||||
// SignalSubscriber
|
||||
virtual void onSignal();
|
||||
|
||||
// timeout
|
||||
void onTimeout();
|
||||
};
|
||||
|
||||
|
||||
class WaitForSignalTimeoutEvent : public SimEvent
|
||||
{
|
||||
WaitForSignalTask *mTask;
|
||||
public:
|
||||
WaitForSignalTimeoutEvent(WaitForSignalTask &task)
|
||||
{
|
||||
mTask = &task;
|
||||
}
|
||||
|
||||
void process( SimObject *object )
|
||||
{
|
||||
mTask->onTimeout();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
109
Engine/source/BadBehavior/leaf/compiled/followBehaviorAction.cpp
Normal file
109
Engine/source/BadBehavior/leaf/compiled/followBehaviorAction.cpp
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "followBehaviorAction.h"
|
||||
|
||||
#include "T3D/aiPlayer.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// FollowBehavior node
|
||||
//------------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT(FollowBehaviorAction);
|
||||
|
||||
FollowBehaviorAction::FollowBehaviorAction()
|
||||
{
|
||||
}
|
||||
|
||||
bool FollowBehaviorAction::precondition( SimObject *owner )
|
||||
{
|
||||
PROFILE_SCOPE( FollowBehaviorAction_precondition);
|
||||
|
||||
// check that our owner is an AIPlayer
|
||||
AIPlayer *aiPlayer = dynamic_cast<AIPlayer *>(owner);
|
||||
if(!aiPlayer)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FollowBehaviorAction::onEnter( SimObject *owner )
|
||||
{
|
||||
//PROFILE_SCOPE( FollowBehaviorAction_onEnter );
|
||||
}
|
||||
|
||||
void FollowBehaviorAction::onExit( SimObject *owner )
|
||||
{
|
||||
//PROFILE_SCOPE( FollowBehaviorAction_onExit );
|
||||
}
|
||||
|
||||
Status FollowBehaviorAction::behavior( SimObject *owner )
|
||||
{
|
||||
PROFILE_SCOPE( FollowBehaviorAction_behavior );
|
||||
|
||||
// get the owning AIPlayer object
|
||||
AIPlayer *aiPlayer = dynamic_cast<AIPlayer *>(owner);
|
||||
if(!aiPlayer)
|
||||
return FAILURE;
|
||||
|
||||
// get the script-specified followObject
|
||||
const char *followFieldName = StringTable->insert("followObject");
|
||||
const char *followFieldValue = owner->getDataField(followFieldName, NULL);
|
||||
if(!followFieldValue || !followFieldValue[0])
|
||||
return FAILURE;
|
||||
|
||||
SimObject *followSimObj = Sim::findObject(dAtoi(followFieldValue));
|
||||
if(!followSimObj)
|
||||
return FAILURE;
|
||||
|
||||
// check that the follow object is a SceneObject
|
||||
SceneObject *followObject = dynamic_cast<SceneObject *>(followSimObj);
|
||||
if(!followObject)
|
||||
return FAILURE;
|
||||
|
||||
// get the script-specified followDistance field
|
||||
const char *distanceFieldName = StringTable->insert("followDistance");
|
||||
const char *distanceFieldValue = owner->getDataField(distanceFieldName, NULL);
|
||||
float followDistance = 1.f;
|
||||
if(distanceFieldValue && distanceFieldValue[0])
|
||||
followDistance = dAtof(distanceFieldValue);
|
||||
|
||||
// try and stay at followDistance from the followObject
|
||||
Point3F targetPos = followObject->getPosition();
|
||||
Point3F followVec = aiPlayer->getPosition() - targetPos;
|
||||
|
||||
// get current distance (ignore z component)
|
||||
F32 curDist = Point3F(followVec.x, followVec.y, 0.f).len();
|
||||
|
||||
if(mFabs(curDist - followDistance) > aiPlayer->getMoveTolerance())
|
||||
{
|
||||
followVec.normalize();
|
||||
followVec *= followDistance;
|
||||
Point3F destination = targetPos + followVec;
|
||||
|
||||
aiPlayer->setMoveDestination(destination, true);
|
||||
return RUNNING;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BB_FOLLOWBEHAVIORACTION_H_
|
||||
#define _BB_FOLLOWBEHAVIORACTION_H_
|
||||
|
||||
#ifndef _BB_CORE_H_
|
||||
#include "BadBehavior/core/behavior.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
//---------------------------------------------------------------------------
|
||||
// FollowBehaviorAction - Make an AIPlayer follow another object
|
||||
// Demonstrates how to create a compiled behavior by subclassing Behavior
|
||||
//---------------------------------------------------------------------------
|
||||
class FollowBehaviorAction : public Behavior
|
||||
{
|
||||
typedef Behavior Parent;
|
||||
|
||||
public:
|
||||
FollowBehaviorAction();
|
||||
|
||||
virtual bool precondition( SimObject *owner );
|
||||
virtual void onEnter( SimObject *owner );
|
||||
virtual void onExit( SimObject *owner );
|
||||
virtual Status behavior( SimObject *owner );
|
||||
|
||||
DECLARE_CONOBJECT(FollowBehaviorAction);
|
||||
};
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
135
Engine/source/BadBehavior/tools/BTUndoActions.cpp
Normal file
135
Engine/source/BadBehavior/tools/BTUndoActions.cpp
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "BTUndoActions.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/simSet.h"
|
||||
|
||||
S32 getNextObjectInGroup(SimObject *object, SimGroup *group)
|
||||
{
|
||||
group->lock();
|
||||
S32 nextId = -1;
|
||||
|
||||
if(object != group->last() && group->find( group->begin(), group->end(), object ) != group->end())
|
||||
{
|
||||
for( SimSet::iterator i = group->begin(); i != group->end(); i++)
|
||||
{
|
||||
if( *i == object )
|
||||
{
|
||||
nextId = (*++i)->getId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
group->unlock();
|
||||
}
|
||||
|
||||
return nextId;
|
||||
}
|
||||
|
||||
IMPLEMENT_CONOBJECT( BTDeleteUndoAction );
|
||||
|
||||
ConsoleDocClass( BTDeleteUndoAction,
|
||||
"@brief Behavior Tree Editor delete undo instance\n\n"
|
||||
"Not intended for game development, for editors or internal use only.\n\n "
|
||||
"@internal");
|
||||
|
||||
BTDeleteUndoAction::BTDeleteUndoAction( const UTF8 *actionName )
|
||||
: UndoAction( actionName )
|
||||
{
|
||||
}
|
||||
|
||||
BTDeleteUndoAction::~BTDeleteUndoAction()
|
||||
{
|
||||
}
|
||||
|
||||
void BTDeleteUndoAction::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void BTDeleteUndoAction::deleteObject( SimObject *object )
|
||||
{
|
||||
AssertFatal( object, "BTDeleteUndoAction::deleteObject() - Got null object!" );
|
||||
AssertFatal( object->isProperlyAdded(),
|
||||
"BTDeleteUndoAction::deleteObject() - Object should be registered!" );
|
||||
|
||||
// Capture the object id.
|
||||
mObject.id = object->getId();
|
||||
|
||||
// Save the state.
|
||||
mObject.memento.save( object );
|
||||
|
||||
// Store the group.
|
||||
SimGroup *group = object->getGroup();
|
||||
if ( group )
|
||||
{
|
||||
mObject.groupId = group->getId();
|
||||
|
||||
// and the next object in the group
|
||||
mObject.nextId = getNextObjectInGroup(object, group);
|
||||
}
|
||||
|
||||
// Now delete the object.
|
||||
object->deleteObject();
|
||||
}
|
||||
|
||||
ConsoleMethod( BTDeleteUndoAction, deleteObject, void, 3, 3, "( SimObject obj )")
|
||||
{
|
||||
SimObject *obj = NULL;
|
||||
if ( Sim::findObject( argv[2], obj ) && obj )
|
||||
object->deleteObject( obj );
|
||||
}
|
||||
|
||||
void BTDeleteUndoAction::undo()
|
||||
{
|
||||
// Create the object.
|
||||
SimObject::setForcedId(mObject.id); // Restore the object's Id
|
||||
SimObject *object = mObject.memento.restore();
|
||||
if ( !object )
|
||||
return;
|
||||
|
||||
// Now restore its group.
|
||||
SimGroup *group;
|
||||
if ( Sim::findObject( mObject.groupId, group ) )
|
||||
{
|
||||
group->addObject( object );
|
||||
|
||||
// restore its position in the group
|
||||
SimObject *nextObj;
|
||||
if ( Sim::findObject( mObject.nextId, nextObj ) )
|
||||
{
|
||||
group->reOrder(object, nextObj);
|
||||
}
|
||||
}
|
||||
|
||||
Con::executef( this, "onUndone" );
|
||||
}
|
||||
|
||||
void BTDeleteUndoAction::redo()
|
||||
{
|
||||
SimObject *object = Sim::findObject( mObject.id );
|
||||
if ( object )
|
||||
object->deleteObject();
|
||||
|
||||
Con::executef( this, "onRedone" );
|
||||
}
|
||||
77
Engine/source/BadBehavior/tools/BTUndoActions.h
Normal file
77
Engine/source/BadBehavior/tools/BTUndoActions.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BT_UNDO_ACTIONS_H_
|
||||
#define _BT_UNDO_ACTIONS_H_
|
||||
|
||||
#ifndef _UNDO_H_
|
||||
#include "util/undo.h"
|
||||
#endif
|
||||
#ifndef _CONSOLE_SIMOBJECTMEMENTO_H_
|
||||
#include "console/simObjectMemento.h"
|
||||
#endif
|
||||
|
||||
S32 getNextObjectInSet(SimObject *obj, SimGroup &group);
|
||||
|
||||
class BTDeleteUndoAction : public UndoAction
|
||||
{
|
||||
typedef UndoAction Parent;
|
||||
|
||||
protected:
|
||||
|
||||
struct ObjectState
|
||||
{
|
||||
/// The object we deleted and will restore in undo.
|
||||
SimObjectId id;
|
||||
|
||||
/// The captured object state.
|
||||
SimObjectMemento memento;
|
||||
|
||||
/// Keep track of the parent group.
|
||||
SimObjectId groupId;
|
||||
|
||||
/// Keep track of the position within the parent group
|
||||
SimObjectId nextId;
|
||||
};
|
||||
|
||||
/// The object we're deleting.
|
||||
ObjectState mObject;
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_CONOBJECT( BTDeleteUndoAction );
|
||||
static void initPersistFields();
|
||||
|
||||
BTDeleteUndoAction( const UTF8* actionName = "Delete Object" );
|
||||
virtual ~BTDeleteUndoAction();
|
||||
|
||||
///
|
||||
void deleteObject( SimObject *object );
|
||||
|
||||
// UndoAction
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // _BT_UNDO_ACTIONS_H_
|
||||
301
Engine/source/BadBehavior/tools/guiBTViewCtrl.cpp
Normal file
301
Engine/source/BadBehavior/tools/guiBTViewCtrl.cpp
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "guiBTViewCtrl.h"
|
||||
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "gui/worldEditor/editorIconRegistry.h"
|
||||
#include "gui/controls/guiTextEditCtrl.h"
|
||||
|
||||
using namespace BadBehavior;
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiBehaviorTreeViewCtrl);
|
||||
|
||||
void GuiBehaviorTreeViewCtrl::onRenderCell(Point2I offset, Point2I cell, bool, bool )
|
||||
{
|
||||
if( !mVisibleItems.size() )
|
||||
return;
|
||||
|
||||
// Do some sanity checking and data retrieval.
|
||||
AssertFatal(cell.y < mVisibleItems.size(), "GuiTreeViewCtrl::onRenderCell: invalid cell");
|
||||
Item * item = mVisibleItems[cell.y];
|
||||
|
||||
// If there's no object, deal with it.
|
||||
if(item->isInspectorData())
|
||||
if(!item->getObject())
|
||||
return;
|
||||
|
||||
RectI drawRect( offset, mCellSize );
|
||||
GFXDrawUtil *drawer = GFX->getDrawUtil();
|
||||
drawer->clearBitmapModulation();
|
||||
|
||||
FrameAllocatorMarker txtBuff;
|
||||
|
||||
// Ok, we have the item. There are a few possibilities at this point:
|
||||
// - We need to draw inheritance lines and a treeview-chosen icon
|
||||
// OR
|
||||
// - We have to draw an item-dependent icon
|
||||
// - If we're mouseover, we have to highlight it.
|
||||
//
|
||||
// - We have to draw the text for the item
|
||||
// - Taking into account various mouseover states
|
||||
// - Taking into account the value (set or not)
|
||||
// - If it's an inspector data, we have to do some custom rendering
|
||||
// - ADDED: If it is being renamed, we also have custom rendering.
|
||||
|
||||
// Ok, first draw the tab and icon.
|
||||
|
||||
// Do we draw the tree lines?
|
||||
if( mFlags.test(ShowTreeLines) )
|
||||
{
|
||||
drawRect.point.x += ( mTabSize * item->mTabLevel );
|
||||
Item* parent = item->mParent;
|
||||
for ( S32 i = item->mTabLevel; ( parent && i > 0 ); i-- )
|
||||
{
|
||||
drawRect.point.x -= mTabSize;
|
||||
if ( parent->mNext )
|
||||
drawer->drawBitmapSR( mProfile->mTextureObject, drawRect.point, mProfile->mBitmapArrayRects[BmpLine] );
|
||||
|
||||
parent = parent->mParent;
|
||||
}
|
||||
}
|
||||
|
||||
// Now, the icon...
|
||||
drawRect.point.x = offset.x + mTabSize * item->mTabLevel;
|
||||
|
||||
// First, draw the rollover glow, if it's an inner node.
|
||||
if ( item->isParent() && item->mState.test( Item::MouseOverBmp ) )
|
||||
drawer->drawBitmapSR( mProfile->mTextureObject, drawRect.point, mProfile->mBitmapArrayRects[BmpGlow] );
|
||||
|
||||
// Now, do we draw a treeview-selected item or an item dependent one?
|
||||
S32 newOffset = 0; // This is stored so we can render glow, then update render pos.
|
||||
|
||||
S32 bitmap = 0;
|
||||
|
||||
// Ok, draw the treeview lines as appropriate.
|
||||
|
||||
bool drawBitmap = true;
|
||||
if ( !item->isParent() )
|
||||
{
|
||||
if( mFlags.test( ShowTreeLines ) )
|
||||
{
|
||||
if( ( item->mNext && item->mPrevious )
|
||||
|| ( item->mNext && item->mParent && ( !_isRootLevelItem( item ) || mShowRoot ) ) )
|
||||
bitmap = BmpChild;
|
||||
else if( item->mNext && ( !item->mParent || !mShowRoot ) )
|
||||
bitmap = BmpFirstChild;
|
||||
else if( item->mPrevious || ( item->mParent && !_isRootLevelItem( item ) ) )
|
||||
bitmap = BmpLastChild;
|
||||
else
|
||||
drawBitmap = false;
|
||||
}
|
||||
else
|
||||
drawBitmap = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap = item->isExpanded() ? BmpExp : BmpCon;
|
||||
|
||||
if( mFlags.test( ShowTreeLines ) )
|
||||
{
|
||||
// Shift indices to show versions with tree lines.
|
||||
|
||||
if ( item->mParent || item->mPrevious )
|
||||
bitmap += ( item->mNext ? 3 : 2 );
|
||||
else
|
||||
bitmap += ( item->mNext ? 1 : 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( ( bitmap >= 0 ) && ( bitmap < mProfile->mBitmapArrayRects.size() ) )
|
||||
{
|
||||
if( drawBitmap )
|
||||
drawer->drawBitmapSR( mProfile->mTextureObject, drawRect.point, mProfile->mBitmapArrayRects[bitmap] );
|
||||
newOffset = mProfile->mBitmapArrayRects[bitmap].extent.x;
|
||||
}
|
||||
|
||||
if(item->isInspectorData())
|
||||
{
|
||||
// draw lock icon if need be
|
||||
S32 icon = Lock1;
|
||||
S32 icon2 = Hidden;
|
||||
|
||||
if (item->getObject() && item->getObject()->isLocked())
|
||||
{
|
||||
if (mIconTable[icon])
|
||||
{
|
||||
//drawRect.point.x = offset.x + mTabSize * item->mTabLevel + mIconTable[icon].getWidth();
|
||||
drawRect.point.x += mIconTable[icon].getWidth();
|
||||
drawer->drawBitmap( mIconTable[icon], drawRect.point );
|
||||
}
|
||||
}
|
||||
|
||||
if (item->getObject() && item->getObject()->isHidden())
|
||||
{
|
||||
if (mIconTable[icon2])
|
||||
{
|
||||
//drawRect.point.x = offset.x + mTabSize * item->mTabLevel + mIconTable[icon].getWidth();
|
||||
drawRect.point.x += mIconTable[icon2].getWidth();
|
||||
drawer->drawBitmap( mIconTable[icon2], drawRect.point );
|
||||
}
|
||||
}
|
||||
|
||||
/*SimObject * pObject = item->getObject();
|
||||
SimGroup * pGroup = ( pObject == NULL ) ? NULL : dynamic_cast<SimGroup*>( pObject );
|
||||
|
||||
// If this item is a VirtualParent we can use the generic SimGroup123 icons.
|
||||
// However if there is already an icon in the EditorIconRegistry for this
|
||||
// exact class (not counting parent class icons) we want to use that instead.
|
||||
bool hasClassIcon = gEditorIcons.hasIconNoRecurse( pObject );
|
||||
|
||||
// draw the icon associated with the item
|
||||
if ( !hasClassIcon && item->mState.test(Item::VirtualParent))
|
||||
{
|
||||
if ( pGroup != NULL)
|
||||
{
|
||||
if (item->isExpanded())
|
||||
item->mIcon = SimGroup1;
|
||||
else
|
||||
item->mIcon = SimGroup2;
|
||||
}
|
||||
else
|
||||
item->mIcon = SimGroup2;
|
||||
}
|
||||
|
||||
if ( !hasClassIcon && item->mState.test(Item::Marked))
|
||||
{
|
||||
if (item->isInspectorData())
|
||||
{
|
||||
if ( pGroup != NULL )
|
||||
{
|
||||
if (item->isExpanded())
|
||||
item->mIcon = SimGroup3;
|
||||
else
|
||||
item->mIcon = SimGroup4;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
GFXTexHandle iconHandle;
|
||||
|
||||
if ( ( item->mIcon != -1 ) && mIconTable[item->mIcon] )
|
||||
iconHandle = mIconTable[item->mIcon];
|
||||
#ifdef TORQUE_TOOLS
|
||||
else
|
||||
iconHandle = gEditorIcons.findIcon( item->getObject() );
|
||||
#endif
|
||||
|
||||
if ( iconHandle.isValid() )
|
||||
{
|
||||
S32 iconHeight = (mItemHeight - iconHandle.getHeight()) / 2;
|
||||
S32 oldHeight = drawRect.point.y;
|
||||
if(iconHeight > 0)
|
||||
drawRect.point.y += iconHeight;
|
||||
drawRect.point.x += iconHandle.getWidth();
|
||||
drawer->drawBitmap( iconHandle, drawRect.point );
|
||||
drawRect.point.y = oldHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 icon = item->isExpanded() ? item->mScriptInfo.mExpandedImage : item->mScriptInfo.mNormalImage;
|
||||
if ( icon )
|
||||
{
|
||||
if (mIconTable[icon])
|
||||
{
|
||||
S32 iconHeight = (mItemHeight - mIconTable[icon].getHeight()) / 2;
|
||||
S32 oldHeight = drawRect.point.y;
|
||||
if(iconHeight > 0)
|
||||
drawRect.point.y += iconHeight;
|
||||
drawRect.point.x += mIconTable[icon].getWidth();
|
||||
drawer->drawBitmap( mIconTable[icon], drawRect.point );
|
||||
drawRect.point.y = oldHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, update offset so we can render some text!
|
||||
drawRect.point.x += newOffset;
|
||||
|
||||
// Ok, now we're off to rendering the actual data for the treeview item.
|
||||
|
||||
U32 bufLen = 1024; //item->mDataRenderWidth + 1;
|
||||
char *displayText = (char *)txtBuff.alloc(bufLen);
|
||||
displayText[bufLen-1] = 0;
|
||||
item->getDisplayText(bufLen, displayText);
|
||||
|
||||
// Draw the rollover/selected bitmap, if one was specified.
|
||||
drawRect.extent.x = mProfile->mFont->getStrWidth( displayText ) + ( 2 * mTextOffset );
|
||||
if ( item->mState.test( Item::Selected ) && mTexSelected )
|
||||
drawer->drawBitmapStretch( mTexSelected, drawRect );
|
||||
else if ( item->mState.test( Item::MouseOverText ) && mTexRollover )
|
||||
drawer->drawBitmapStretch( mTexRollover, drawRect );
|
||||
|
||||
// Offset a bit so as to space text properly.
|
||||
drawRect.point.x += mTextOffset;
|
||||
|
||||
// Determine what color the font should be.
|
||||
ColorI fontColor;
|
||||
|
||||
fontColor = item->mState.test( Item::Selected ) ? mProfile->mFontColorSEL :
|
||||
( item->mState.test( Item::MouseOverText ) ? mProfile->mFontColorHL : mProfile->mFontColor );
|
||||
|
||||
if (item->mState.test(Item::Selected))
|
||||
{
|
||||
drawer->drawRectFill(drawRect, mProfile->mFillColorSEL);
|
||||
}
|
||||
else if (item->mState.test(Item::MouseOverText))
|
||||
{
|
||||
drawer->drawRectFill(drawRect, mProfile->mFillColorHL);
|
||||
}
|
||||
|
||||
if( item->mState.test(Item::MouseOverText) )
|
||||
{
|
||||
fontColor = mProfile->mFontColorHL;
|
||||
}
|
||||
|
||||
drawer->setBitmapModulation( fontColor );
|
||||
|
||||
// Center the text horizontally.
|
||||
S32 height = (mItemHeight - mProfile->mFont->getHeight()) / 2;
|
||||
|
||||
if(height > 0)
|
||||
drawRect.point.y += height;
|
||||
|
||||
// JDD - offset by two pixels or so to keep the text from rendering RIGHT ONTOP of the outline
|
||||
drawRect.point.x += 2;
|
||||
|
||||
drawer->drawText( mProfile->mFont, drawRect.point, displayText, mProfile->mFontColors );
|
||||
|
||||
if ( mRenamingItem == item && mRenameCtrl )
|
||||
{
|
||||
Point2I ctrPos = globalToLocalCoord( drawRect.point );
|
||||
ctrPos.y -= height;
|
||||
ctrPos.x -= 2;
|
||||
|
||||
Point2I ctrExtent( getWidth() - ctrPos.x, drawRect.extent.y );
|
||||
|
||||
mRenameCtrl->setPosition( ctrPos );
|
||||
mRenameCtrl->setExtent( ctrExtent );
|
||||
mRenameCtrl->setVisible( true );
|
||||
}
|
||||
}
|
||||
45
Engine/source/BadBehavior/tools/guiBTViewCtrl.h
Normal file
45
Engine/source/BadBehavior/tools/guiBTViewCtrl.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUI_BTVIEWCTRL_H_
|
||||
#define _GUI_BTVIEWCTRL_H_
|
||||
|
||||
#ifndef _GUI_TREEVIEWCTRL_H
|
||||
#include "gui/controls/guiTreeViewCtrl.h"
|
||||
#endif
|
||||
|
||||
namespace BadBehavior
|
||||
{
|
||||
// subclassing GuiTreeViewCtrl so that we can tweak it for the behavior tree editor
|
||||
class GuiBehaviorTreeViewCtrl : public GuiTreeViewCtrl
|
||||
{
|
||||
typedef GuiTreeViewCtrl Parent;
|
||||
|
||||
public:
|
||||
void onRenderCell(Point2I offset, Point2I cell, bool, bool);
|
||||
|
||||
DECLARE_CONOBJECT(GuiBehaviorTreeViewCtrl);
|
||||
};
|
||||
|
||||
} // namespace BadBehavior
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue