Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / ai_service / event_reaction.cpp
blob54e62d789856bb4ea7032f92c6491b1b301829c6
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "stdpch.h"
20 #include "ai_mgr.h"
21 #include "ai.h"
22 #include "event_reaction.h"
23 #include "ai_grp.h"
24 #include "ais_actions.h" // for CWorkPtr::instance()
25 #include "continent.h"
27 using namespace AITYPES;
29 std::string CAIEventReaction::getIndexString() const
31 return getOwner()->getIndexString()+NLMISC::toString(":%u", getChildIndex());
35 void CAIEventReaction::setEvent(const std::string &eventName,CStateMachine *container)
37 if (!_eventMgr.isNULL())
38 _eventMgr->removeReaction(this);
40 nlassert(container);
41 _eventMgr= container->getEventManager(eventName);
42 #ifdef NL_DEBUG
43 _eventMgr.setData( this );
44 #endif
46 if (!_eventMgr.isNULL())
48 _eventMgr->addReaction(this);
50 else
52 nlwarning( "Failed to find event manager for events of type '%s' ", /*in Npc Mgr %u (%s)*/
53 eventName.c_str()); // , container->getAlias(), container->getAliasNode()->fullName().c_str());
57 void CAIEventReaction::setState(uint32 alias)
59 if (!_eventMgr.isNULL())
60 _eventMgr->removeReaction(this);
62 _states.clear();
63 _states.push_back(alias);
65 if (!_eventMgr.isNULL())
66 _eventMgr->addReaction(this);
69 uint32 CAIEventReaction::getState()
71 if (_states.empty())
72 return 0;
74 return _states[0];
77 void CAIEventReaction::setGroup(uint32 alias)
79 if (!_eventMgr.isNULL())
80 _eventMgr->removeReaction(this);
82 _groups.clear();
83 _groups.push_back(alias);
85 if (!_eventMgr.isNULL())
86 _eventMgr->addReaction(this);
89 IAILogicAction::TSmartPtr CAIEventReaction::buildAction(CAIEventActionNode *dsc, const CAIAliasDescriptionNode *eventNode, CStateMachine *container)
91 std::vector<IAILogicAction::TSmartPtr> subActions;
93 // build the sub actions into a vector
94 for (uint i=0;i<dsc->Children.size();++i)
96 subActions.push_back(buildAction(dsc->Children[i],eventNode,container));
99 IAILogicAction::TSmartPtr newAction=newAILogicAction(dsc->Action.c_str(),dsc->Args,subActions,eventNode,container);
101 CWorkPtr::addLogicAction(newAction, dsc->Alias);
103 for (uint i=0;i<dsc->_PropertyZones.size();++i)
105 newAction->addPropertyZone(dsc->_PropertyZones[i]);
106 // subActions.push_back(buildAction(dsc->Children[i],eventNode,container));
109 // call the factory to build the logic action object from the description record
110 return newAction;
113 void CAIEventReaction::processEventDescription(CAIEventDescription *dsc,CStateMachine *container)
115 // if we're updating remove event from manager before update to allow for sensible classification
116 // on re-insertion
117 if (!_eventMgr.isNULL())
118 _eventMgr->removeReaction(this);
120 nlassert(container);
121 // the event manager
122 _eventMgr= container->getEventManager(dsc->EventType);
123 #ifdef NL_DEBUG
124 _eventMgr.setData( this );
125 #endif
127 // if this isn't a fixed state event deal with state parameters
128 if (_type!=FixedState)
130 // the named state list
131 _states.clear();
132 uint32 i;
133 for (i=0;i<dsc->NamedStates.size();++i)
135 uint32 state=getAliasNode()->findAliasByNameAndType(dsc->NamedStates[i],AITypeNpcStateRoute);
137 if (state==0)
138 state=getAliasNode()->findAliasByNameAndType(dsc->NamedStates[i],AITypeNpcStateZone);
140 if (state==0)
142 // nlwarning("Warning: Dodgy event setup in '%s' because named state '%s' not found", container->getAliasNode()->fullName().c_str(), dsc->NamedStates[i].c_str());
143 nlwarning("Warning: Dodgy event setup because named state '%s' not found", dsc->NamedStates[i].c_str());
144 continue;
146 _states.push_back(state);
149 // state keyword filter
150 _stateFilter.clear();
151 for (i=0;i<dsc->StateKeywords.size();++i)
153 CKeywordFilter filter;
154 if (!CAIKeywords::stateFilter(dsc->StateKeywords[i], filter))
156 nlwarning("There are some keyword error in '%s'", getAliasNode()->fullName().c_str());
157 continue;
159 _stateFilter+=filter;
164 // if this isn't a fixed group event deal with group parameters
165 if (_type!=FixedGroup)
167 uint32 i;
168 // the named group list
169 _groups.clear();
170 for (i=0;i<dsc->NamedGroups.size();++i)
172 std::vector<CGroup*> grps;
173 // get all groups with the this name
174 CWorkPtr::aiInstance()->findGroup(grps, dsc->NamedGroups[i]);
175 const CAIAliasDescriptionNode *parent = getAliasNode();
176 // retrieve the manager.
177 while ( parent
178 && parent->getType() != AITypeManager)
180 parent = parent->getParent();
183 // remove any group that belong to another manager
184 if (parent)
186 uint nbToRemove = 0;
187 for (uint i=0; i<grps.size()-nbToRemove; ++i)
189 if (grps[i]->getManager().getAlias() != parent->getAlias())
191 std::swap(grps[i], grps.back());
194 grps.erase(grps.end()-nbToRemove, grps.end());
195 //grps.erase(std::remove_if(grps.begin(), grps.end(), CAliasTreeOwner::CAliasDiff(parent->getAlias())), grps.end());
197 else
199 nlwarning("In '%s': Can't find manager for this event!", getAliasFullName().c_str());
202 if (grps.empty())
204 nlwarning("In '%s': Dodgy event setup because named group '%s' not found",
205 getAliasFullName().c_str(),
206 dsc->NamedGroups[i].c_str());
207 continue;
210 for (uint j=0; j<grps.size(); ++j)
212 _groups.push_back(grps[j]->aliasTreeOwner()->getAlias());
216 // group keyword filter
217 _groupFilter.clear();
218 for (i=0;i<dsc->GroupKeywords.size();++i)
220 CKeywordFilter filter;
221 if (!CAIKeywords::groupFilter(dsc->GroupKeywords[i], filter))
223 nlwarning("There are some keyword error in '%s'", getAliasNode()->fullName().c_str());
224 continue;
226 _groupFilter+=filter;
230 // the action
231 _action=buildAction(dsc->Action,getAliasNode(),container);
233 if (_action.isNull())
235 nlwarning( "In '%s': failed to find action under the event",
236 getAliasFullName().c_str(),
237 dsc->EventType.c_str());
240 // if all went well link the event reaction to the reaction manager
241 if (!_eventMgr.isNULL())
243 _eventMgr->addReaction(this);
245 else
247 // nlwarning( "Failed to find event manager for events of type '%s' in Npc Mgr %u (%s)",
248 // dsc->EventType.c_str(), container->getAlias(), container->getAliasNode()->fullName().c_str());
249 nlwarning( "In '%s': failed to find event manager for events of type '%s'",
250 getAliasFullName().c_str(),
251 dsc->EventType.c_str());
256 std::string CStateInstance::buidStateInstanceDebugString () const
258 if ( !_state
259 && !_PunctualState)
260 return std::string("NO STATE");
262 CStateInstance *const statInstancePt=const_cast<CStateInstance*>(this);
264 std::string s=NLMISC::toString("STATE: %s (%s)[%s] PUNCTUAL: %s (%s)[%s]",
265 (!_state)? "NULL": _state->getName().c_str(),
266 statInstancePt->timerStateTimeout().toString().c_str(),
267 (!_NextState)? "NULL": _NextState->getName().c_str(),
268 (!_PunctualState)? "NULL": _PunctualState->getName().c_str(), statInstancePt->timerPunctTimeout().toString().c_str(),
269 _CancelPunctualState? "CANCEL": (!_NextPunctualState)? "NULL": _NextPunctualState->getName().c_str()
272 if (statInstancePt->timerUser(0).isEnabled())
273 s+= NLMISC::toString(" TO: %s",statInstancePt->timerUser(0).toString().c_str());
274 if (statInstancePt->timerUser(1).isEnabled())
275 s+= NLMISC::toString(" T1: %s",statInstancePt->timerUser(1).toString().c_str());
276 if (statInstancePt->timerUser(2).isEnabled())
277 s+= NLMISC::toString(" T2: %s",statInstancePt->timerUser(2).toString().c_str());
278 if (statInstancePt->timerUser(3).isEnabled())
279 s+= NLMISC::toString(" T3: %s",statInstancePt->timerUser(3).toString().c_str());
280 return s;