Added ai command setEquipment
[ryzomcore.git] / ryzom / server / src / ai_service / service_main.cpp
blob38f2756fac13fbaa13dbc454765c7ed138f59fa0
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2014-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "stdpch.h"
24 #include "nel/ligo/primitive.h"
25 #include "nel/ligo/ligo_config.h"
26 #include "game_share/tick_event_handler.h"
27 #include "game_share/ryzom_version.h"
29 #include "world_container.h"
30 #include "ai.h"
31 #include "ai_mgr.h"
32 #include "ai_keywords.h"
33 #include "mirrors.h"
34 #include "messages.h"
35 #include "ais_actions.h"
36 #include "egs_interface.h"
37 #include "aids_interface.h"
38 #include "game_share/fame.h"
39 #include "visual_properties_interface.h"
41 #include "ais_user_models.h"
43 #ifdef NL_OS_WINDOWS
44 # ifndef NL_COMP_MINGW
45 # define NOMINMAX
46 # endif
47 # include <windows.h>
48 #endif // NL_OS_WINDOWS
50 //#include "nel/misc/bitmap.h"
52 using namespace NLMISC;
53 using namespace NLNET;
54 using namespace std;
56 // force admin module to link in
57 extern void admin_modules_forceLink();
58 void foo()
60 admin_modules_forceLink();
63 bool EGSHasMirrorReady = false;
64 bool IOSHasMirrorReady = false;
66 // The ligo config
67 NLLIGO::CLigoConfig LigoConfig;
69 namespace AICOMP
71 bool compileExternalScript (const char *filename, const char *outputFilename);
74 /*-----------------------------------------------------------------*\
75 SERVICE CLASS
76 \*-----------------------------------------------------------------*/
78 class CAIService : public NLNET::IService
80 public:
81 void commandStart();
82 void init();
83 bool update();
84 void release();
85 void tickRelease();
88 // callback for the 'tick' update message
89 void cbTick();
91 // callback for the 'tick' release message
92 void cbTickRelease()
94 (static_cast<CAIService*>(CAIService::getInstance()))->tickRelease();
97 /*-----------------------------------------------------------------*\
98 SERVICE INIT & RELEASE
99 \*-----------------------------------------------------------------*/
102 static void cbServiceMirrorUp( const std::string& serviceName, NLNET::TServiceId serviceId, void * )
104 if (serviceName == "IOS")
106 IOSHasMirrorReady = true;
109 if (serviceName == "EGS")
111 EGSHasMirrorReady = true;
113 // force an AI update on EGS up
114 CAIS::instance().update();
116 //send custom data to EGS
117 CAIUserModelManager::getInstance()->sendUserModels();
118 CAIUserModelManager::getInstance()->sendCustomLootTables();
121 CAIS::instance().serviceEvent(CServiceEvent(serviceId, serviceName, CServiceEvent::SERVICE_UP));
124 static void cbServiceDown( const std::string& serviceName, NLNET::TServiceId serviceId, void * )
126 if ( serviceName == "IOS" )
128 IOSHasMirrorReady = false;
131 if ( serviceName == "EGS" )
133 EGSHasMirrorReady = false;
136 CAIS::instance().serviceEvent(CServiceEvent(serviceId, serviceName, CServiceEvent::SERVICE_DOWN));
140 void CAIService::commandStart()
142 // Compile an AI script ?
143 if (haveArg ('c'))
145 string scriptFilename = getArg ('c');
146 bool result = false;
147 if (!scriptFilename.empty ())
149 string outputFilename;
150 if (haveArg ('o'))
151 outputFilename = getArg ('o');
153 // Compile and exit
154 result = AICOMP::compileExternalScript (scriptFilename.c_str (), outputFilename.c_str ());
156 else
157 nlwarning ("No script filename");
159 ::exit (result?0:-1);
163 ///init
164 void CAIService::init (void)
166 // start any available system command.
167 CConfigFile::CVar *sysCmds = IService::getInstance()->ConfigFile.getVarPtr("SystemCmd");
168 if (sysCmds != NULL)
170 for (uint i=0; i<sysCmds->size(); ++i)
172 string cmd = sysCmds->asString(i);
174 nlinfo("Invoking system command '%s'...", cmd.c_str());
175 int ret = system(cmd.c_str());
176 nlinfo(" command returned %d", ret);
180 // read sheet_id.bin and don't prune out unknown files
181 CSheetId::init(false);
183 // Init singleton manager
184 CSingletonRegistry::getInstance()->init();
186 // init static fame manager
187 CStaticFames::getInstance();
189 setVersion (RYZOM_PRODUCT_VERSION);
191 // Init ligo
192 if (!LigoConfig.readPrimitiveClass ("world_editor_classes.xml", false))
194 // Should be in R:\leveldesign\world_editor_files
195 nlerror ("Can't load ligo primitive config file world_editor_classes.xml");
199 // have ligo library register its own class types for its class factory
200 NLLIGO::Register();
202 // setup the update systems
203 setUpdateTimeout(100);
207 // init sub systems
208 CAIKeywords::init();
209 CMirrors::init(cbTick, NULL, cbTickRelease);
210 CMessages::init();
211 AISHEETS::CSheets::getInstance()->init();
213 // initialise the AI_SHARE library
214 AI_SHARE::init(&LigoConfig);
216 // set the primitive context
217 NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig;
219 CAISActions::init();
221 CEGSInterface::init();
222 CTimeInterface::init();
223 CCombatInterface::init();
224 CVisualPropertiesInterface::init();
225 CAIDSInterface::init();
227 // register the service up and service down callbacks
228 CMirrors::Mirror.setServiceMirrorUpCallback("*", cbServiceMirrorUp, 0);
229 CMirrors::Mirror.setServiceDownCallback( "*", cbServiceDown, 0);
230 // CUnifiedNetwork::getInstance()->setServiceDownCallback( "*", cbServiceDown, 0);
232 CConfigFile::CVar *clientCreature=IService::getInstance()->ConfigFile.getVarPtr ("CreatureDebug");
233 if (clientCreature)
235 CAIS::instance().setClientCreatureDebug(clientCreature->asInt()!=0);
240 ///release
242 void CAIService::release()
247 void CAIService::tickRelease (void)
249 CWorldContainer::clear();
251 // release sub systems
252 CAIS::instance().release();
254 CAIDSInterface::release();
255 CVisualPropertiesInterface::release();
256 CCombatInterface::release();
257 CTimeInterface::release();
258 CEGSInterface::release();
260 CAISActions::release();
262 AISHEETS::CSheets::getInstance()->release();
263 CMessages::release();
265 CMirrors::release();
267 CFamilyProfileFactory::instance().release();
269 CSingletonRegistry::getInstance()->release();
272 void dispatchEvents()
274 H_AUTO(dispatchEvents);
275 while (!CCombatInterface::_events.empty())
277 CAIEntityPhysical *target=CAIS::instance().getEntityPhysical(CCombatInterface::_events.front()._targetRow);
278 if (target)
279 target->processEvent( CCombatInterface::_events.front() );
280 CCombatInterface::_events.pop_front();
284 /*-----------------------------------------------------------------*\
285 SERVICE UPDATES
286 \*-----------------------------------------------------------------*/
288 ///update called on each 'tick' message from tick service
290 void cbTick()
292 // cleanup stat variables
293 // StatCSpawnBotFauna = 0;
294 // StatCSpawnBotNpc = 0;
295 // StatCBotPet = 0;
296 // StatCAIContinent = 0;
297 // StatCSpawnGroupFauna = 0;
298 // StatCSpawnGroupNpc = 0;
299 // StatCSpawnGroupPet = 0;
300 // StatCAIInstance = 0;
301 // StatCMgrFauna = 0;
302 // StatCMgrNpc = 0;
303 // StatCMgrPet = 0;
304 // StatCBotPlayer = 0;
305 // StatCPlayerManager = 0;
306 // StatCcontinent = 0;
307 // StatCRegion = 0;
308 // StatCCellZone = 0;
310 if ( CMirrors::mirrorIsReady() )
312 CAIS::instance().update();
314 CEGSInterface::update();
315 CTimeInterface::update();
316 CVisualPropertiesInterface::update();
318 dispatchEvents();
320 CMirrors::update();
323 H_AUTO(CSingletonRegistry_tickUpdate)
324 CSingletonRegistry::getInstance()->tickUpdate();
330 //prototype for a global routine in commands.cpp
331 void UpdateWatches();
333 uint ForceTicks=0;
335 ///update called every coplete cycle of service loop
336 bool CAIService::update (void)
338 // NLMEMORY::CheckHeap(true);
340 UpdateWatches();
341 // NLMEMORY::CheckHeap(true);
343 if (ForceTicks)
345 // We update a false perception (as if we force ticks, it meens we don't receive true one because we're off-line).
347 // We make a false tick.
348 ForceTicks--;
349 cbTick();
352 CSingletonRegistry::getInstance()->serviceUpdate();
354 return true;
359 /*-----------------------------------------------------------------*\
360 NLNET_SERVICE_MAIN
361 \*-----------------------------------------------------------------*/
362 NLNET_SERVICE_MAIN (CAIService, "AIS", "ai_service", 0, EmptyCallbackArray, "", "")