|
@@ -1,127 +1,133 @@
|
|
|
-#include "Base.h"
|
|
|
|
|
-#include "AIStateMachine.h"
|
|
|
|
|
-#include "AIAgent.h"
|
|
|
|
|
-#include "AIMessage.h"
|
|
|
|
|
-#include "Game.h"
|
|
|
|
|
-
|
|
|
|
|
-namespace gameplay
|
|
|
|
|
-{
|
|
|
|
|
-
|
|
|
|
|
-AIStateMachine::AIStateMachine(AIAgent* agent)
|
|
|
|
|
- : _agent(agent), _currentState(&AIState::_empty)
|
|
|
|
|
-{
|
|
|
|
|
- GP_ASSERT(agent);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-AIStateMachine::~AIStateMachine()
|
|
|
|
|
-{
|
|
|
|
|
- // Release all states
|
|
|
|
|
- for (std::list<AIState*>::iterator itr = _states.begin(); itr != _states.end(); ++itr)
|
|
|
|
|
- {
|
|
|
|
|
- (*itr)->release();
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-AIAgent* AIStateMachine::getAgent() const
|
|
|
|
|
-{
|
|
|
|
|
- return _agent;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-AIState* AIStateMachine::addState(const char* id)
|
|
|
|
|
-{
|
|
|
|
|
- AIState* state = AIState::create(id);
|
|
|
|
|
- _states.push_back(state);
|
|
|
|
|
- return state;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void AIStateMachine::addState(AIState* state)
|
|
|
|
|
-{
|
|
|
|
|
- state->addRef();
|
|
|
|
|
- _states.push_back(state);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void AIStateMachine::removeState(AIState* state)
|
|
|
|
|
-{
|
|
|
|
|
- std::list<AIState*>::iterator itr = std::find(_states.begin(), _states.end(), state);
|
|
|
|
|
- if (itr != _states.end())
|
|
|
|
|
- {
|
|
|
|
|
- _states.erase(itr);
|
|
|
|
|
- state->release();
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-AIState* AIStateMachine::getState(const char* id) const
|
|
|
|
|
-{
|
|
|
|
|
- GP_ASSERT(id);
|
|
|
|
|
-
|
|
|
|
|
- AIState* state;
|
|
|
|
|
- for (std::list<AIState*>::const_iterator itr = _states.begin(); itr != _states.end(); ++itr)
|
|
|
|
|
- {
|
|
|
|
|
- state = (*itr);
|
|
|
|
|
-
|
|
|
|
|
- if (strcmp(id, state->getId()) == 0)
|
|
|
|
|
- return state;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return NULL;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-AIState* AIStateMachine::getActiveState() const
|
|
|
|
|
-{
|
|
|
|
|
- return _currentState;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-bool AIStateMachine::hasState(AIState* state) const
|
|
|
|
|
-{
|
|
|
|
|
- GP_ASSERT(state);
|
|
|
|
|
-
|
|
|
|
|
- return (std::find(_states.begin(), _states.end(), state) != _states.end());
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-AIState* AIStateMachine::setState(const char* id)
|
|
|
|
|
-{
|
|
|
|
|
- AIState* state = getState(id);
|
|
|
|
|
- if (state)
|
|
|
|
|
- sendChangeStateMessage(state);
|
|
|
|
|
- return state;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-bool AIStateMachine::setState(AIState* state)
|
|
|
|
|
-{
|
|
|
|
|
- if (hasState(state))
|
|
|
|
|
- {
|
|
|
|
|
- sendChangeStateMessage(state);
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return false;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void AIStateMachine::sendChangeStateMessage(AIState* newState)
|
|
|
|
|
-{
|
|
|
|
|
- AIMessage* message = AIMessage::create(0, _agent->getId(), _agent->getId(), 1);
|
|
|
|
|
- message->_messageType = AIMessage::MESSAGE_TYPE_STATE_CHANGE;
|
|
|
|
|
- message->setString(0, newState->getId());
|
|
|
|
|
- Game::getInstance()->getAIController()->sendMessage(message);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void AIStateMachine::setStateInternal(AIState* state)
|
|
|
|
|
-{
|
|
|
|
|
- GP_ASSERT(hasState(state));
|
|
|
|
|
-
|
|
|
|
|
- // Fire the exit event for the current state
|
|
|
|
|
- _currentState->exit(this);
|
|
|
|
|
-
|
|
|
|
|
- // Set the new state
|
|
|
|
|
- _currentState = state;
|
|
|
|
|
-
|
|
|
|
|
- // Fire the enter event for the new state
|
|
|
|
|
- _currentState->enter(this);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void AIStateMachine::update(float elapsedTime)
|
|
|
|
|
-{
|
|
|
|
|
- _currentState->update(this, elapsedTime);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-}
|
|
|
|
|
|
|
+#include "Base.h"
|
|
|
|
|
+#include "AIStateMachine.h"
|
|
|
|
|
+#include "AIAgent.h"
|
|
|
|
|
+#include "AIMessage.h"
|
|
|
|
|
+#include "Game.h"
|
|
|
|
|
+
|
|
|
|
|
+namespace gameplay
|
|
|
|
|
+{
|
|
|
|
|
+
|
|
|
|
|
+AIStateMachine::AIStateMachine(AIAgent* agent)
|
|
|
|
|
+ : _agent(agent)
|
|
|
|
|
+{
|
|
|
|
|
+ GP_ASSERT(agent);
|
|
|
|
|
+ if (AIState::_empty)
|
|
|
|
|
+ AIState::_empty->addRef();
|
|
|
|
|
+ else
|
|
|
|
|
+ AIState::_empty = new AIState("");
|
|
|
|
|
+ _currentState = AIState::_empty;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+AIStateMachine::~AIStateMachine()
|
|
|
|
|
+{
|
|
|
|
|
+ // Release all states
|
|
|
|
|
+ for (std::list<AIState*>::iterator itr = _states.begin(); itr != _states.end(); ++itr)
|
|
|
|
|
+ {
|
|
|
|
|
+ (*itr)->release();
|
|
|
|
|
+ }
|
|
|
|
|
+ SAFE_RELEASE(AIState::_empty);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+AIAgent* AIStateMachine::getAgent() const
|
|
|
|
|
+{
|
|
|
|
|
+ return _agent;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+AIState* AIStateMachine::addState(const char* id)
|
|
|
|
|
+{
|
|
|
|
|
+ AIState* state = AIState::create(id);
|
|
|
|
|
+ _states.push_back(state);
|
|
|
|
|
+ return state;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void AIStateMachine::addState(AIState* state)
|
|
|
|
|
+{
|
|
|
|
|
+ state->addRef();
|
|
|
|
|
+ _states.push_back(state);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void AIStateMachine::removeState(AIState* state)
|
|
|
|
|
+{
|
|
|
|
|
+ std::list<AIState*>::iterator itr = std::find(_states.begin(), _states.end(), state);
|
|
|
|
|
+ if (itr != _states.end())
|
|
|
|
|
+ {
|
|
|
|
|
+ _states.erase(itr);
|
|
|
|
|
+ state->release();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+AIState* AIStateMachine::getState(const char* id) const
|
|
|
|
|
+{
|
|
|
|
|
+ GP_ASSERT(id);
|
|
|
|
|
+
|
|
|
|
|
+ AIState* state;
|
|
|
|
|
+ for (std::list<AIState*>::const_iterator itr = _states.begin(); itr != _states.end(); ++itr)
|
|
|
|
|
+ {
|
|
|
|
|
+ state = (*itr);
|
|
|
|
|
+
|
|
|
|
|
+ if (strcmp(id, state->getId()) == 0)
|
|
|
|
|
+ return state;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+AIState* AIStateMachine::getActiveState() const
|
|
|
|
|
+{
|
|
|
|
|
+ return _currentState;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+bool AIStateMachine::hasState(AIState* state) const
|
|
|
|
|
+{
|
|
|
|
|
+ GP_ASSERT(state);
|
|
|
|
|
+
|
|
|
|
|
+ return (std::find(_states.begin(), _states.end(), state) != _states.end());
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+AIState* AIStateMachine::setState(const char* id)
|
|
|
|
|
+{
|
|
|
|
|
+ AIState* state = getState(id);
|
|
|
|
|
+ if (state)
|
|
|
|
|
+ sendChangeStateMessage(state);
|
|
|
|
|
+ return state;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+bool AIStateMachine::setState(AIState* state)
|
|
|
|
|
+{
|
|
|
|
|
+ if (hasState(state))
|
|
|
|
|
+ {
|
|
|
|
|
+ sendChangeStateMessage(state);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void AIStateMachine::sendChangeStateMessage(AIState* newState)
|
|
|
|
|
+{
|
|
|
|
|
+ AIMessage* message = AIMessage::create(0, _agent->getId(), _agent->getId(), 1);
|
|
|
|
|
+ message->_messageType = AIMessage::MESSAGE_TYPE_STATE_CHANGE;
|
|
|
|
|
+ message->setString(0, newState->getId());
|
|
|
|
|
+ Game::getInstance()->getAIController()->sendMessage(message);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void AIStateMachine::setStateInternal(AIState* state)
|
|
|
|
|
+{
|
|
|
|
|
+ GP_ASSERT(hasState(state));
|
|
|
|
|
+
|
|
|
|
|
+ // Fire the exit event for the current state
|
|
|
|
|
+ _currentState->exit(this);
|
|
|
|
|
+
|
|
|
|
|
+ // Set the new state
|
|
|
|
|
+ _currentState = state;
|
|
|
|
|
+
|
|
|
|
|
+ // Fire the enter event for the new state
|
|
|
|
|
+ _currentState->enter(this);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void AIStateMachine::update(float elapsedTime)
|
|
|
|
|
+{
|
|
|
|
|
+ _currentState->update(this, elapsedTime);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+}
|