// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdpch.h" #include "ai_mgr.h" #include "ai.h" #include "event_reaction.h" #include "ai_grp.h" #include "ais_actions.h" // for CWorkPtr::instance() #include "continent.h" using namespace AITYPES; std::string CAIEventReaction::getIndexString() const { return getOwner()->getIndexString()+NLMISC::toString(":%u", getChildIndex()); } void CAIEventReaction::setEvent(const std::string &eventName,CStateMachine *container) { if (!_eventMgr.isNULL()) _eventMgr->removeReaction(this); nlassert(container); _eventMgr= container->getEventManager(eventName); #ifdef NL_DEBUG _eventMgr.setData( this ); #endif if (!_eventMgr.isNULL()) { _eventMgr->addReaction(this); } else { nlwarning( "Failed to find event manager for events of type '%s' ", /*in Npc Mgr %u (%s)*/ eventName.c_str()); // , container->getAlias(), container->getAliasNode()->fullName().c_str()); } } void CAIEventReaction::setState(uint32 alias) { if (!_eventMgr.isNULL()) _eventMgr->removeReaction(this); _states.clear(); _states.push_back(alias); if (!_eventMgr.isNULL()) _eventMgr->addReaction(this); } void CAIEventReaction::setGroup(uint32 alias) { if (!_eventMgr.isNULL()) _eventMgr->removeReaction(this); _groups.clear(); _groups.push_back(alias); if (!_eventMgr.isNULL()) _eventMgr->addReaction(this); } IAILogicAction::TSmartPtr CAIEventReaction::buildAction(CAIEventActionNode *dsc, const CAIAliasDescriptionNode *eventNode, CStateMachine *container) { std::vector subActions; // build the sub actions into a vector for (uint i=0;iChildren.size();++i) { subActions.push_back(buildAction(dsc->Children[i],eventNode,container)); } IAILogicAction::TSmartPtr newAction=newAILogicAction(dsc->Action.c_str(),dsc->Args,subActions,eventNode,container); CWorkPtr::addLogicAction(newAction, dsc->Alias); for (uint i=0;i_PropertyZones.size();++i) { newAction->addPropertyZone(dsc->_PropertyZones[i]); // subActions.push_back(buildAction(dsc->Children[i],eventNode,container)); } // call the factory to build the logic action object from the description record return newAction; } void CAIEventReaction::processEventDescription(CAIEventDescription *dsc,CStateMachine *container) { // if we're updating remove event from manager before update to allow for sensible classification // on re-insertion if (!_eventMgr.isNULL()) _eventMgr->removeReaction(this); nlassert(container); // the event manager _eventMgr= container->getEventManager(dsc->EventType); #ifdef NL_DEBUG _eventMgr.setData( this ); #endif // if this isn't a fixed state event deal with state parameters if (_type!=FixedState) { // the named state list _states.clear(); uint32 i; for (i=0;iNamedStates.size();++i) { uint32 state=getAliasNode()->findAliasByNameAndType(dsc->NamedStates[i],AITypeNpcStateRoute); if (state==0) state=getAliasNode()->findAliasByNameAndType(dsc->NamedStates[i],AITypeNpcStateZone); if (state==0) { // nlwarning("Warning: Dodgy event setup in '%s' because named state '%s' not found", container->getAliasNode()->fullName().c_str(), dsc->NamedStates[i].c_str()); nlwarning("Warning: Dodgy event setup because named state '%s' not found", dsc->NamedStates[i].c_str()); continue; } _states.push_back(state); } // state keyword filter _stateFilter.clear(); for (i=0;iStateKeywords.size();++i) { CKeywordFilter filter; if (!CAIKeywords::stateFilter(dsc->StateKeywords[i], filter)) { nlwarning("There are some keyword error in '%s'", getAliasNode()->fullName().c_str()); continue; } _stateFilter+=filter; } } // if this isn't a fixed group event deal with group parameters if (_type!=FixedGroup) { uint32 i; // the named group list _groups.clear(); for (i=0;iNamedGroups.size();++i) { std::vector grps; // get all groups with the this name CWorkPtr::aiInstance()->findGroup(grps, dsc->NamedGroups[i]); const CAIAliasDescriptionNode *parent = getAliasNode(); // retrieve the manager. while ( parent && parent->getType() != AITypeManager) { parent = parent->getParent(); } // remove any group that belong to another manager if (parent) { uint nbToRemove = 0; for (uint i=0; igetManager().getAlias() != parent->getAlias()) { std::swap(grps[i], grps.back()); } } grps.erase(grps.end()-nbToRemove, grps.end()); //grps.erase(std::remove_if(grps.begin(), grps.end(), CAliasTreeOwner::CAliasDiff(parent->getAlias())), grps.end()); } else { nlwarning("In '%s': Can't find manager for this event!", getAliasFullName().c_str()); } if (grps.empty()) { nlwarning("In '%s': Dodgy event setup because named group '%s' not found", getAliasFullName().c_str(), dsc->NamedGroups[i].c_str()); continue; } for (uint j=0; jaliasTreeOwner()->getAlias()); } } // group keyword filter _groupFilter.clear(); for (i=0;iGroupKeywords.size();++i) { CKeywordFilter filter; if (!CAIKeywords::groupFilter(dsc->GroupKeywords[i], filter)) { nlwarning("There are some keyword error in '%s'", getAliasNode()->fullName().c_str()); continue; } _groupFilter+=filter; } } // the action _action=buildAction(dsc->Action,getAliasNode(),container); if (_action.isNull()) { nlwarning( "In '%s': failed to find action under the event", getAliasFullName().c_str(), dsc->EventType.c_str()); } // if all went well link the event reaction to the reaction manager if (!_eventMgr.isNULL()) { _eventMgr->addReaction(this); } else { // nlwarning( "Failed to find event manager for events of type '%s' in Npc Mgr %u (%s)", // dsc->EventType.c_str(), container->getAlias(), container->getAliasNode()->fullName().c_str()); nlwarning( "In '%s': failed to find event manager for events of type '%s'", getAliasFullName().c_str(), dsc->EventType.c_str()); } } std::string CStateInstance::buidStateInstanceDebugString () const { if ( !_state && !_PunctualState) return std::string("NO STATE"); CStateInstance *const statInstancePt=const_cast(this); std::string s=NLMISC::toString("STATE: %s (%s)[%s] PUNCTUAL: %s (%s)[%s]", (!_state)? "NULL": _state->getName().c_str(), statInstancePt->timerStateTimeout().toString().c_str(), (!_NextState)? "NULL": _NextState->getName().c_str(), (!_PunctualState)? "NULL": _PunctualState->getName().c_str(), statInstancePt->timerPunctTimeout().toString().c_str(), _CancelPunctualState? "CANCEL": (!_NextPunctualState)? "NULL": _NextPunctualState->getName().c_str() ); if (statInstancePt->timerUser(0).isEnabled()) s+= NLMISC::toString(" TO: %s",statInstancePt->timerUser(0).toString().c_str()); if (statInstancePt->timerUser(1).isEnabled()) s+= NLMISC::toString(" T1: %s",statInstancePt->timerUser(1).toString().c_str()); if (statInstancePt->timerUser(2).isEnabled()) s+= NLMISC::toString(" T2: %s",statInstancePt->timerUser(2).toString().c_str()); if (statInstancePt->timerUser(3).isEnabled()) s+= NLMISC::toString(" T3: %s",statInstancePt->timerUser(3).toString().c_str()); return s; }