| @@ -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 |
| @@ -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; | ||
| } |
| @@ -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 |
| @@ -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; | ||
| } | ||
|
|
| @@ -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 |
| @@ -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; | ||
| } |
| @@ -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 |
| @@ -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; | ||
| } |
| @@ -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 |
| @@ -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 | ||
| } |
| @@ -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 |
| @@ -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 | ||
| } |
| @@ -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 |
| @@ -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 ); | ||
| } |
| @@ -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 |
| @@ -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); | ||
| } |
| @@ -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 |
| @@ -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; | ||
| } |
| @@ -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 |
| @@ -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; | ||
| } |
| @@ -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 |
| @@ -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 |
| @@ -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" ); | ||
| } |
| @@ -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_ |
| @@ -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 ); | ||
| } | ||
| } |
| @@ -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 |
| @@ -9,4 +9,5 @@ | ||
| // In this case all the code in the "custom" folder in your project's source directory would be added | ||
| // addSrcDir('../source/custom'); | ||
|
|
||
| includeModule("BadBehavior"); | ||
| ?> | ||
| @@ -9,4 +9,5 @@ | ||
| // In this case all the code in the "custom" folder in your project's source directory would be added | ||
| // addSrcDir('../source/custom'); | ||
|
|
||
| includeModule("BadBehavior"); | ||
| ?> | ||