Angel 3.2
A 2D Game Prototyping Engine
Brain.cpp
1 
2 // Copyright (C) 2008-2013, Shane Liesegang
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of the copyright holder nor the names of any
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "stdafx.h"
31 #include "../AI/Brain.h"
32 
33 #include "../AI/Sentient.h"
34 #include "../Infrastructure/TextRendering.h"
35 #include "../Util/MathUtil.h"
36 
37 AIBrain::AIBrain()
38 {
39  _current = _brainStateTable.end();
40  _drawMe = false;
41 }
42 
43 AIBrain::~AIBrain()
44 {
45  GotoNullState();
46  //clean up states
47  BrainStateTable::iterator itr = _brainStateTable.begin();
48  for( ; itr != _brainStateTable.end(); itr++ )
49  {
50  AIBrainState* pState = (*itr).second;
51  delete pState;
52  }
53 }
54 
55 void AIBrain::AddState( const String& id, AIBrainState* state )
56 {
57  //remove existing state in this ID
58  String useId = ToUpper(id);
59  BrainStateTable::iterator itr = _brainStateTable.find( useId );
60  if( itr != _brainStateTable.end() )
61  {
62  //delete second
63  delete (*itr).second;
64  }
65 
66  state->Initialize(this);
67 
68  _brainStateTable[useId] = state;
69 }
70 
71 void AIBrain::Update(float dt)
72 {
73  if( _brainStateTable.size() == 0 )
74  {
75  GetActor()->InitializeBrain();
76  GetActor()->StartBrain();
77  }
78  if( _current == _brainStateTable.end() )
79  return;
80 
81  (*_current).second->Update(dt);
82 
83 }
84 
85 void AIBrain::GotoState( const String& id )
86 {
87  String useId = ToUpper(id);
88  BrainStateTable::iterator itr = _brainStateTable.find( useId );
89  if( itr != _brainStateTable.end() )
90  {
91  AIBrainState* pNextState = (*itr).second;
92  AIBrainState* pLastState = NULL;
93  if( _current != _brainStateTable.end() )
94  {
95  (*_current).second->EndState( pNextState );
96 
97  pLastState = (*_current).second;
98  }
99 
100  _current = itr;
101  (*_current).second->BeginState( pLastState );
102  }
103 }
104 
105 void AIBrain::Render()
106 {
107  if( !_drawMe )
108  return;
109 
110  if( _current != _brainStateTable.end() )
111  {
112  Vector2 screenCenter = MathUtil::WorldToScreen( GetActor()->GetPosition().X, GetActor()->GetPosition().Y );
113  //Print some vals
114  glColor3f(0,0.f,1.f);
115  DrawGameText( (*_current).first, "ConsoleSmall", (int)screenCenter.X, (int)screenCenter.Y );
116  }
117 
118 }
119 
120 void AIBrain::GotoNullState()
121 {
122  if( _current != _brainStateTable.end() )
123  (*_current).second->EndState( NULL );
124 
125  _current = _brainStateTable.end();
126 }
127 
128 void AIBrain::EnableDrawing(bool enable)
129 {
130  _drawMe = enable;
131 }
132 
133 
134 void AIBrainState::Update(float dt)
135 {
136  CustomUpdate(dt);
137  for( unsigned int i = 0; i < _eventList.size(); i++ )
138  {
139  _eventList[i]->Update(dt);
140  }
141 }
142 
143 
144 void AIBrainState::EndState( AIBrainState* nextState )
145 {
146  CustomEndState( nextState );
147  ClearEvents();
148 }
149 
150 void AIBrainState::GotoState( const String& id )
151 {
152  _brain->GotoState( id );
153 }
154 
155 AIEvent* AIBrainState::RegisterEvent( AIEvent* newEvent )
156 {
157  _eventList.push_back( newEvent );
158  newEvent->SetBrain( _brain );
159  return newEvent;
160 }
161 
162 void AIBrainState::UnregisterEvent( AIEvent* oldEvent )
163 {
164  for( EventList::iterator itr = _eventList.begin(); itr != _eventList.end(); itr++ )
165  {
166  if( (*itr) == oldEvent )
167  {
168  _eventList.erase( itr );
169  StopEvent( oldEvent );
170  return;
171  }
172  }
173 }
174 
175 void AIBrainState::ClearEvents()
176 {
177  //stop and delete events
178  for( unsigned int i = 0; i < _eventList.size(); i++ )
179  {
180  StopEvent( _eventList[i]);
181  }
182  _eventList.clear();
183 }
184 
185 
186 void AIBrainState::StopEvent( AIEvent* pEvent )
187 {
188  pEvent->Stop();
189  delete pEvent;
190 }