Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / ai_service / nf_helpers.cpp
blob6eb80797998ef9a25102152e2f61c4816f919937
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/>.
17 #include "stdpch.h"
19 #include "script_compiler.h"
21 #include "ai_grp_npc.h"
22 #include "group_profile.h"
23 #include "ai_generic_fight.h"
24 #include "server_share/msg_brick_service.h"
26 #include "continent_inline.h"
27 #include "dyn_grp_inline.h"
29 #include "ai_script_data_manager.h"
31 using std::string;
32 using std::vector;
33 using namespace NLMISC;
34 using namespace AIVM;
35 using namespace AICOMP;
36 using namespace AITYPES;
37 using namespace RYAI_MAP_CRUNCH;
39 AITYPES::CPropertySet readSet(std::string strings, std::string separator = "|")
41 AITYPES::CPropertySet properties;
42 CStringSeparator const sep(strings, separator);
43 while (sep.hasNext())
44 properties.addProperty(AITYPES::CPropertyId::create(sep.get()));
45 return properties;
48 // CStateInstance
49 IScriptContext* spawnNewGroup(CStateInstance* entity, CScriptStack& stack, CAIInstance* aiInstance, CAIVector const& spawnPosition, sint32 baseLevel, double dispersionRadius)
51 string stateMachineName = stack.top();
52 stack.pop();
53 string dynGroupName = stack.top();
54 stack.pop();
56 if (!entity)
58 nlwarning("spawnNewGroup failed because entity==NULL");
59 return NULL; // return a normal stack.
62 CGroupDesc<CGroupFamily> const* groupDesc = NULL;
64 // Find the group template.
65 // :TODO: Replace it with a faster map access.
66 FOREACH (itCont, CCont<CContinent>, aiInstance->continents())
68 FOREACH (itRegion, CCont<CRegion>, itCont->regions())
70 FOREACH (itFamily, CCont<CGroupFamily>, itRegion->groupFamilies())
72 FOREACH (itGroupDesc, CCont<CGroupDesc<CGroupFamily> >, itFamily->groupDescs())
74 if (itGroupDesc->getFullName()==dynGroupName || itGroupDesc->getName()==dynGroupName)
76 groupDesc = *itGroupDesc;
77 goto groupFound;
83 groupFound:
84 if (groupDesc==NULL)
86 nlwarning("spawnNewGroup failed: No Group Template Found: '%s'",dynGroupName.c_str());
87 return NULL;
90 // Find the state machine as a manager
91 CManager* manager=NULL;
92 FOREACH(itCont, CCont<CManager>, aiInstance->managers())
94 if (itCont->getFullName()==stateMachineName || itCont->getName()==stateMachineName)
96 manager = *itCont;
97 break;
100 if (!manager)
102 nlwarning("spawnNpcGroup failed : Unknown stateMachine: '%s'", stateMachineName.c_str());
103 return NULL;
105 // Find the state machine as a npc manager
106 CMgrNpc* npcManager = dynamic_cast<CMgrNpc*>(manager);
107 if (!npcManager)
109 nlwarning("spawnNpcGroup failed : Not a npc state machine !: '%s'", stateMachineName.c_str());
110 return NULL;
112 // Get the state machine
113 CStateMachine const* stateMachine = manager->getStateMachine();
114 if (stateMachine->cstStates().size()==0)
115 stateMachine = NULL;
116 // Save the creator state
117 bool const savePlayerAttackable = groupDesc->getGDPlayerAttackable();
118 bool const saveBotAttackable = groupDesc->getGDBotAttackable();
119 // Set it to a correct value (:TODO: see why)
120 groupDesc->setGDPlayerAttackable(true);
121 groupDesc->setGDBotAttackable(true);
122 // Create the group
123 CGroupNpc* const grp = groupDesc->createNpcGroup(npcManager, spawnPosition, dispersionRadius, baseLevel);
124 // Restore the creator state
125 groupDesc->setGDPlayerAttackable(savePlayerAttackable);
126 groupDesc->setGDBotAttackable(saveBotAttackable);
127 // Verify that the group was created
128 if (!grp)
130 nlwarning("spawnNpcGroup failed : group cannot spawn !: %s", stateMachineName.c_str());
131 return NULL;
133 // Set the new group parameters
134 grp->autoDestroy(true);
135 grp->getPersistentStateInstance()->setParentStateInstance(entity->getPersistentStateInstance());
136 grp->initDynGrp(groupDesc, NULL);
137 // Verify that we have a state in the state machine
138 #if !FINAL_VERSION
139 if (!stateMachine || stateMachine->cstStates().size()==0)
140 nlwarning("no state defined for StateMachine in Manager %s", manager->getFullName().c_str());
141 #endif
142 // Set the group in that state
143 if(stateMachine)
144 grp->setStartState(stateMachine->cstStates()[0]); // sets the first state (must exist!).
145 grp->updateStateInstance(); // directly call his first state (to retrieve associated params).
147 return grp;
150 void getZoneWithFlags_helper(CStateInstance* entity, CScriptStack& stack, CAIInstance* const aiInstance, CZoneScorer const& scorer)
152 // :FIXME: Copy n past from getZoneWithFlags2 begin
153 // Get all the cell-zones
154 vector<CCellZone*> cellZones;
155 FOREACH(itCont, CCont<CContinent>, aiInstance->continents())
157 FOREACH(itRegion, CCont<CRegion>, itCont->regions())
159 FOREACH(itCellZone, CCont<CCellZone>, itRegion->cellZones())
161 cellZones.push_back(*itCellZone);
165 // Shuffle 'em
166 std::random_shuffle(cellZones.begin(), cellZones.end());
167 // While no zone found
168 FOREACH(itCellZone, std::vector<CCellZone*>, cellZones)
170 // Get all cells
171 vector<CCell*> cells;
172 FOREACH(it, CCont<CCell>, (*itCellZone)->cells())
173 cells.push_back(*it);
174 // Shuffle 'em
175 std::random_shuffle(cells.begin(), cells.end());
176 // Get a zone with a good score
177 CNpcZone const* spawnZone = CCellZone::lookupNpcZoneScorer(cells, scorer);
178 if (spawnZone)
180 stack.push(spawnZone->getAliasTreeOwner().getAliasFullName());
181 return;
185 nlwarning("getZoneWithFlags/getNearestZoneWithFlags No Zone Found");
186 stack.push(string());
187 return;