1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3 #ifndef EVENT_HANDLER_H
4 #define EVENT_HANDLER_H
5
6 #include <string>
7 #include <vector>
8 #include <map>
9
10 #include "System/EventClient.h"
11 #include "Sim/Units/Unit.h"
12 #include "Sim/Features/Feature.h"
13 #include "Sim/Projectiles/Projectile.h"
14
15 class CWeapon;
16 struct Command;
17 struct BuildInfo;
18
19
20 class CEventHandler
21 {
22 public:
23 CEventHandler();
24 ~CEventHandler();
25
26 void AddClient(CEventClient* ec);
27 void RemoveClient(CEventClient* ec);
28
29 bool InsertEvent(CEventClient* ec, const std::string& ciName);
30 bool RemoveEvent(CEventClient* ec, const std::string& ciName);
31
32 void GetEventList(std::vector<std::string>& list) const;
33
34 bool IsKnown(const std::string& ciName) const;
35 bool IsManaged(const std::string& ciName) const;
36 bool IsUnsynced(const std::string& ciName) const;
37 bool IsController(const std::string& ciName) const;
38
39 public: // EventBatchHandler
40 void UpdateUnits();
41 void UpdateDrawUnits();
42 void DeleteSyncedUnits();
43 void UpdateFeatures();
44 void UpdateDrawFeatures();
45 void DeleteSyncedFeatures();
46 void UpdateProjectiles();
47 void UpdateDrawProjectiles();
48 void DeleteSyncedProjectiles();
49 void UpdateObjects();
50 void DeleteSyncedObjects();
51 public:
52 /**
53 * @name Synced_events
54 * @{
55 */
56 void Load(IArchive* archive);
57
58 void GamePreload();
59 void GameStart();
60 void GameOver(const std::vector<unsigned char>& winningAllyTeams);
61 void GamePaused(int playerID, bool paused);
62 void GameFrame(int gameFrame);
63 void GameID(const unsigned char* gameID, unsigned int numBytes);
64
65 void TeamDied(int teamID);
66 void TeamChanged(int teamID);
67 void PlayerChanged(int playerID);
68 void PlayerAdded(int playerID);
69 void PlayerRemoved(int playerID, int reason);
70
71 void UnitCreated(const CUnit* unit, const CUnit* builder);
72 void UnitFinished(const CUnit* unit);
73 void UnitFromFactory(const CUnit* unit, const CUnit* factory,
74 bool userOrders);
75 void UnitDestroyed(const CUnit* unit, const CUnit* attacker);
76 void UnitTaken(const CUnit* unit, int oldTeam, int newTeam);
77 void UnitGiven(const CUnit* unit, int oldTeam, int newTeam);
78
79 //FIXME no events
80 void RenderUnitCreated(const CUnit* unit, int cloaked);
81 void RenderUnitDestroyed(const CUnit* unit);
82 void RenderUnitCloakChanged(const CUnit* unit, int cloaked);
83 void RenderUnitLOSChanged(const CUnit* unit, int allyTeam, int newStatus);
84 void RenderUnitMoved(const CUnit* unit, const float3& newpos);
85 void RenderFeatureCreated(const CFeature* feature);
86 void RenderFeatureDestroyed(const CFeature* feature);
87 void RenderFeatureMoved(const CFeature* feature, const float3& oldpos, const float3& newpos);
88 void RenderProjectileCreated(const CProjectile* proj);
89 void RenderProjectileDestroyed(const CProjectile* proj);
90 void UnsyncedProjectileCreated(const CProjectile* proj);
91 void UnsyncedProjectileDestroyed(const CProjectile* proj);
92
93 void UnitIdle(const CUnit* unit);
94 void UnitCommand(const CUnit* unit, const Command& command);
95 void UnitCmdDone(const CUnit* unit, const Command& command);
96 void UnitDamaged(
97 const CUnit* unit,
98 const CUnit* attacker,
99 float damage,
100 int weaponDefID,
101 int projectileID,
102 bool paralyzer);
103 void UnitExperience(const CUnit* unit, float oldExperience);
104 void UnitHarvestStorageFull(const CUnit* unit);
105
106 void UnitSeismicPing(const CUnit* unit, int allyTeam,
107 const float3& pos, float strength);
108 void UnitEnteredRadar(const CUnit* unit, int allyTeam);
109 void UnitEnteredLos(const CUnit* unit, int allyTeam);
110 void UnitLeftRadar(const CUnit* unit, int allyTeam);
111 void UnitLeftLos(const CUnit* unit, int allyTeam);
112
113 void UnitEnteredWater(const CUnit* unit);
114 void UnitEnteredAir(const CUnit* unit);
115 void UnitLeftWater(const CUnit* unit);
116 void UnitLeftAir(const CUnit* unit);
117
118 void UnitLoaded(const CUnit* unit, const CUnit* transport);
119 void UnitUnloaded(const CUnit* unit, const CUnit* transport);
120
121 void UnitCloaked(const CUnit* unit);
122 void UnitDecloaked(const CUnit* unit);
123
124 void UnitUnitCollision(const CUnit* collider, const CUnit* collidee);
125 void UnitFeatureCollision(const CUnit* collider, const CFeature* collidee);
126 void UnitMoved(const CUnit* unit);
127 void UnitMoveFailed(const CUnit* unit);
128
129 void FeatureCreated(const CFeature* feature);
130 void FeatureDestroyed(const CFeature* feature);
131 void FeatureDamaged(
132 const CFeature* feature,
133 const CUnit* attacker,
134 float damage,
135 int weaponDefID,
136 int projectileID);
137 void FeatureMoved(const CFeature* feature, const float3& oldpos);
138
139 void ProjectileCreated(const CProjectile* proj, int allyTeam);
140 void ProjectileDestroyed(const CProjectile* proj, int allyTeam);
141
142 bool Explosion(int weaponDefID, int projectileID, const float3& pos, const CUnit* owner);
143
144 void StockpileChanged(const CUnit* unit,
145 const CWeapon* weapon, int oldCount);
146
147 bool CommandFallback(const CUnit* unit, const Command& cmd);
148 bool AllowCommand(const CUnit* unit, const Command& cmd, bool fromSynced);
149
150 bool AllowUnitCreation(const UnitDef* unitDef, const CUnit* builder, const BuildInfo* buildInfo);
151 bool AllowUnitTransfer(const CUnit* unit, int newTeam, bool capture);
152 bool AllowUnitBuildStep(const CUnit* builder, const CUnit* unit, float part);
153 bool AllowFeatureCreation(const FeatureDef* featureDef, int allyTeamID, const float3& pos);
154 bool AllowFeatureBuildStep(const CUnit* builder, const CFeature* feature, float part);
155 bool AllowResourceLevel(int teamID, const string& type, float level);
156 bool AllowResourceTransfer(int oldTeam, int newTeam, const string& type, float amount);
157 bool AllowDirectUnitControl(int playerID, const CUnit* unit);
158 bool AllowBuilderHoldFire(const CUnit* unit, int action);
159 bool AllowStartPosition(int playerID, unsigned char readyState, const float3& clampedPos, const float3& rawPickPos);
160
161 bool TerraformComplete(const CUnit* unit, const CUnit* build);
162 bool MoveCtrlNotify(const CUnit* unit, int data);
163
164 int AllowWeaponTargetCheck(unsigned int attackerID, unsigned int attackerWeaponNum, unsigned int attackerWeaponDefID);
165 bool AllowWeaponTarget(
166 unsigned int attackerID,
167 unsigned int targetID,
168 unsigned int attackerWeaponNum,
169 unsigned int attackerWeaponDefID,
170 float* targetPriority
171 );
172 bool AllowWeaponInterceptTarget(const CUnit* interceptorUnit, const CWeapon* interceptorWeapon, const CProjectile* interceptorTarget);
173
174 bool UnitPreDamaged(
175 const CUnit* unit,
176 const CUnit* attacker,
177 float damage,
178 int weaponDefID,
179 int projectileID,
180 bool paralyzer,
181 float* newDamage,
182 float* impulseMult);
183
184 bool FeaturePreDamaged(
185 const CFeature* feature,
186 const CUnit* attacker,
187 float damage,
188 int weaponDefID,
189 int projectileID,
190 float* newDamage,
191 float* impulseMult);
192
193 bool ShieldPreDamaged(const CProjectile*, const CWeapon*, const CUnit*, bool);
194
195 bool SyncedActionFallback(const string& line, int playerID);
196 /// @}
197
198 public:
199 /**
200 * @name Unsynced_events
201 * @{
202 */
203 void Save(zipFile archive);
204
205 void UnsyncedHeightMapUpdate(const SRectangle& rect);
206 void Update();
207
208 bool KeyPress(int key, bool isRepeat);
209 bool KeyRelease(int key);
210 bool TextInput(const std::string& utf8);
211 bool MouseMove(int x, int y, int dx, int dy, int button);
212 bool MousePress(int x, int y, int button);
213 void MouseRelease(int x, int y, int button);
214 bool MouseWheel(bool up, float value);
215 bool JoystickEvent(const std::string& event, int val1, int val2);
216 bool IsAbove(int x, int y);
217
218 std::string GetTooltip(int x, int y);
219
220 bool DefaultCommand(const CUnit* unit, const CFeature* feature, int& cmd);
221
222 bool CommandNotify(const Command& cmd);
223
224 bool AddConsoleLine(const std::string& msg, const std::string& section, int level);
225
226 void LastMessagePosition(const float3& pos);
227
228 bool GroupChanged(int groupID);
229
230 bool GameSetup(const std::string& state, bool& ready,
231 const map<int, std::string>& playerStates);
232
233 std::string WorldTooltip(const CUnit* unit,
234 const CFeature* feature,
235 const float3* groundPos);
236
237 bool MapDrawCmd(int playerID, int type,
238 const float3* pos0,
239 const float3* pos1,
240 const std::string* label);
241
242 void SunChanged(const float3& sunDir);
243
244 void ViewResize();
245
246 void DrawGenesis();
247 void DrawWorld();
248 void DrawWorldPreUnit();
249 void DrawWorldShadow();
250 void DrawWorldReflection();
251 void DrawWorldRefraction();
252 void DrawScreenEffects();
253 void DrawScreen();
254 void DrawInMiniMap();
255 void DrawInMiniMapBackground();
256
257 bool DrawUnit(const CUnit* unit);
258 bool DrawFeature(const CFeature* feature);
259 bool DrawShield(const CUnit* unit, const CWeapon* weapon);
260 bool DrawProjectile(const CProjectile* projectile);
261
262 /// @brief this UNSYNCED event is generated every GameServer::gameProgressFrameInterval
263 /// it skips network queuing and caching and can be used to calculate the current catchup
264 /// percentage when reconnecting to a running game
265 void GameProgress(int gameFrame);
266
267 void CollectGarbage();
268 void DbgTimingInfo(DbgTimingInfoType type, const spring_time start, const spring_time end);
269 /// @}
270
271 //FIXME no real event
272 void LoadedModelRequested();
273
274 private:
275 typedef vector<CEventClient*> EventClientList;
276
277 enum EventPropertyBits {
278 MANAGED_BIT = (1 << 0), // managed by eventHandler
279 UNSYNCED_BIT = (1 << 1), // delivers unsynced information
280 CONTROL_BIT = (1 << 2) // controls synced information
281 };
282
283 class EventInfo {
284 public:
EventInfo()285 EventInfo() : list(NULL), propBits(0) {}
EventInfo(const std::string & _name,EventClientList * _list,int _bits)286 EventInfo(const std::string& _name, EventClientList* _list, int _bits)
287 : name(_name), list(_list), propBits(_bits) {}
~EventInfo()288 ~EventInfo() {}
289
GetName()290 inline const std::string& GetName() const { return name; }
GetList()291 inline EventClientList* GetList() const { return list; }
GetPropBits()292 inline int GetPropBits() const { return propBits; }
HasPropBit(int bit)293 inline bool HasPropBit(int bit) const { return propBits & bit; }
294
295 private:
296 std::string name;
297 EventClientList* list;
298 int propBits;
299 };
300
301 typedef map<std::string, EventInfo> EventMap;
302
303 private:
304 void SetupEvent(const std::string& ciName,
305 EventClientList* list, int props);
306 void ListInsert(EventClientList& ciList, CEventClient* ec);
307 void ListRemove(EventClientList& ciList, CEventClient* ec);
308
309 private:
310 CEventClient* mouseOwner;
311
312 private:
313 EventMap eventMap;
314
315 EventClientList handles;
316
317 #define SETUP_EVENT(name, props) EventClientList list ## name;
318 #define SETUP_UNMANAGED_EVENT(name, props)
319 #include "Events.def"
320 #undef SETUP_EVENT
321 #undef SETUP_UNMANAGED_EVENT
322 };
323
324
325 extern CEventHandler eventHandler;
326
327
328 /******************************************************************************/
329 /******************************************************************************/
330 //
331 // Inlined call-in loops
332 //
333
334 #define ITERATE_EVENTCLIENTLIST(name, ...) \
335 for (int i = 0; i < list##name.size(); ) { \
336 CEventClient* ec = list##name[i]; \
337 ec->name(__VA_ARGS__); \
338 if (i < list##name.size() && ec == list##name[i]) \
339 ++i; /* the call-in may remove itself from the list */ \
340 }
341
342 #define ITERATE_ALLYTEAM_EVENTCLIENTLIST(name, allyTeam, ...) \
343 for (int i = 0; i < list##name.size(); ) { \
344 CEventClient* ec = list##name[i]; \
345 if (ec->CanReadAllyTeam(allyTeam)) { \
346 ec->name(__VA_ARGS__); \
347 } \
348 if (i < list##name.size() && ec == list##name[i]) \
349 ++i; /* the call-in may remove itself from the list */ \
350 }
351
352 #define ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(name, unit, ...) \
353 const auto unitAllyTeam = unit->allyteam; \
354 for (int i = 0; i < list##name.size(); ) { \
355 CEventClient* ec = list##name[i]; \
356 if (ec->CanReadAllyTeam(unitAllyTeam)) { \
357 ec->name(unit, __VA_ARGS__); \
358 } \
359 if (i < list##name.size() && ec == list##name[i]) \
360 ++i; /* the call-in may remove itself from the list */ \
361 }
362
UnitCreated(const CUnit * unit,const CUnit * builder)363 inline void CEventHandler::UnitCreated(const CUnit* unit, const CUnit* builder)
364 {
365 ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(UnitCreated, unit, builder)
366 }
367
368
UnitDestroyed(const CUnit * unit,const CUnit * attacker)369 inline void CEventHandler::UnitDestroyed(const CUnit* unit,
370 const CUnit* attacker)
371 {
372 ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(UnitDestroyed, unit, attacker)
373 }
374
375 #define UNIT_CALLIN_NO_PARAM(name) \
376 inline void CEventHandler:: name (const CUnit* unit) \
377 { \
378 const auto unitAllyTeam = unit->allyteam; \
379 for (int i = 0; i < list##name.size(); ) { \
380 CEventClient* ec = list##name[i]; \
381 if (ec->CanReadAllyTeam(unitAllyTeam)) { \
382 ec->name(unit); \
383 } \
384 if (i < list##name.size() && ec == list##name[i]) \
385 ++i; /* the call-in may remove itself from the list */ \
386 } \
387 }
388
389 UNIT_CALLIN_NO_PARAM(UnitFinished)
UNIT_CALLIN_NO_PARAM(UnitIdle)390 UNIT_CALLIN_NO_PARAM(UnitIdle)
391 UNIT_CALLIN_NO_PARAM(UnitMoveFailed)
392 UNIT_CALLIN_NO_PARAM(UnitEnteredWater)
393 UNIT_CALLIN_NO_PARAM(UnitEnteredAir)
394 UNIT_CALLIN_NO_PARAM(UnitLeftWater)
395 UNIT_CALLIN_NO_PARAM(UnitLeftAir)
396 UNIT_CALLIN_NO_PARAM(UnitMoved)
397
398 #define UNIT_CALLIN_INT_PARAMS(name) \
399 inline void CEventHandler:: Unit ## name (const CUnit* unit, int p1, int p2) \
400 { \
401 ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(Unit ## name, unit, p1, p2) \
402 }
403
404 UNIT_CALLIN_INT_PARAMS(Taken)
405 UNIT_CALLIN_INT_PARAMS(Given)
406
407
408 #define UNIT_CALLIN_LOS_PARAM(name) \
409 inline void CEventHandler:: Unit ## name (const CUnit* unit, int at) \
410 { \
411 ITERATE_ALLYTEAM_EVENTCLIENTLIST(Unit ## name, at, unit, at) \
412 }
413
414 UNIT_CALLIN_LOS_PARAM(EnteredRadar)
415 UNIT_CALLIN_LOS_PARAM(EnteredLos)
416 UNIT_CALLIN_LOS_PARAM(LeftRadar)
417 UNIT_CALLIN_LOS_PARAM(LeftLos)
418
419
420
421 inline void CEventHandler::UnitFromFactory(const CUnit* unit,
422 const CUnit* factory,
423 bool userOrders)
424 {
425 ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(UnitFromFactory, unit, factory, userOrders)
426 }
427
428
429 UNIT_CALLIN_NO_PARAM(UnitCloaked)
UNIT_CALLIN_NO_PARAM(UnitDecloaked)430 UNIT_CALLIN_NO_PARAM(UnitDecloaked)
431
432
433 inline void CEventHandler::UnitUnitCollision(const CUnit* collider, const CUnit* collidee)
434 {
435 ITERATE_EVENTCLIENTLIST(UnitUnitCollision, collider, collidee)
436 }
437
UnitFeatureCollision(const CUnit * collider,const CFeature * collidee)438 inline void CEventHandler::UnitFeatureCollision(const CUnit* collider, const CFeature* collidee)
439 {
440 ITERATE_EVENTCLIENTLIST(UnitFeatureCollision, collider, collidee)
441 }
442
443
444
UnitCommand(const CUnit * unit,const Command & command)445 inline void CEventHandler::UnitCommand(const CUnit* unit,
446 const Command& command)
447 {
448 ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(UnitCommand, unit, command)
449 }
450
451
452
UnitCmdDone(const CUnit * unit,const Command & command)453 inline void CEventHandler::UnitCmdDone(const CUnit* unit,
454 const Command& command)
455 {
456 ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(UnitCmdDone, unit, command)
457 }
458
459
UnitDamaged(const CUnit * unit,const CUnit * attacker,float damage,int weaponDefID,int projectileID,bool paralyzer)460 inline void CEventHandler::UnitDamaged(
461 const CUnit* unit,
462 const CUnit* attacker,
463 float damage,
464 int weaponDefID,
465 int projectileID,
466 bool paralyzer)
467 {
468 ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(UnitDamaged, unit, attacker, damage, weaponDefID, projectileID, paralyzer)
469 }
470
471
UnitExperience(const CUnit * unit,float oldExperience)472 inline void CEventHandler::UnitExperience(const CUnit* unit,
473 float oldExperience)
474 {
475 ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(UnitExperience, unit, oldExperience)
476 }
477
478
UnitSeismicPing(const CUnit * unit,int allyTeam,const float3 & pos,float strength)479 inline void CEventHandler::UnitSeismicPing(const CUnit* unit,
480 int allyTeam,
481 const float3& pos,
482 float strength)
483 {
484 ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(UnitSeismicPing, unit, allyTeam, pos, strength)
485 }
486
487
UnitLoaded(const CUnit * unit,const CUnit * transport)488 inline void CEventHandler::UnitLoaded(const CUnit* unit,
489 const CUnit* transport)
490 {
491 const int count = listUnitLoaded.size();
492 for (int i = 0; i < count; i++) {
493 CEventClient* ec = listUnitLoaded[i];
494 const int ecAllyTeam = ec->GetReadAllyTeam();
495 if (ec->GetFullRead() ||
496 (ecAllyTeam == unit->allyteam) ||
497 (ecAllyTeam == transport->allyteam)) {
498 ec->UnitLoaded(unit, transport);
499 }
500 }
501 }
502
503
UnitUnloaded(const CUnit * unit,const CUnit * transport)504 inline void CEventHandler::UnitUnloaded(const CUnit* unit,
505 const CUnit* transport)
506 {
507 const int count = listUnitUnloaded.size();
508 for (int i = 0; i < count; i++) {
509 CEventClient* ec = listUnitUnloaded[i];
510 const int ecAllyTeam = ec->GetReadAllyTeam();
511 if (ec->GetFullRead() ||
512 (ecAllyTeam == unit->allyteam) ||
513 (ecAllyTeam == transport->allyteam)) {
514 ec->UnitUnloaded(unit, transport);
515 }
516 }
517 }
518
FeatureCreated(const CFeature * feature)519 inline void CEventHandler::FeatureCreated(const CFeature* feature)
520 {
521 const int featureAllyTeam = feature->allyteam;
522 const int count = listFeatureCreated.size();
523 for (int i = 0; i < count; i++) {
524 CEventClient* ec = listFeatureCreated[i];
525 if ((featureAllyTeam < 0) || ec->CanReadAllyTeam(featureAllyTeam)) {
526 ec->FeatureCreated(feature);
527 }
528 }
529 }
530
FeatureDestroyed(const CFeature * feature)531 inline void CEventHandler::FeatureDestroyed(const CFeature* feature)
532 {
533 const int featureAllyTeam = feature->allyteam;
534 const int count = listFeatureDestroyed.size();
535 for (int i = 0; i < count; i++) {
536 CEventClient* ec = listFeatureDestroyed[i];
537 if ((featureAllyTeam < 0) || ec->CanReadAllyTeam(featureAllyTeam)) {
538 ec->FeatureDestroyed(feature);
539 }
540 }
541 }
542
FeatureDamaged(const CFeature * feature,const CUnit * attacker,float damage,int weaponDefID,int projectileID)543 inline void CEventHandler::FeatureDamaged(
544 const CFeature* feature,
545 const CUnit* attacker,
546 float damage,
547 int weaponDefID,
548 int projectileID)
549 {
550 const int featureAllyTeam = feature->allyteam;
551 const int count = listFeatureDamaged.size();
552
553 for (int i = 0; i < count; i++) {
554 CEventClient* ec = listFeatureDamaged[i];
555 if (featureAllyTeam < 0 || ec->CanReadAllyTeam(featureAllyTeam)) {
556 ec->FeatureDamaged(feature, attacker, damage, weaponDefID, projectileID);
557 }
558 }
559 }
560
FeatureMoved(const CFeature * feature,const float3 & oldpos)561 inline void CEventHandler::FeatureMoved(const CFeature* feature, const float3& oldpos)
562 {
563 const int featureAllyTeam = feature->allyteam;
564 const int count = listFeatureMoved.size();
565 for (int i = 0; i < count; i++) {
566 CEventClient* ec = listFeatureMoved[i];
567 if ((featureAllyTeam < 0) || ec->CanReadAllyTeam(featureAllyTeam)) {
568 ec->FeatureMoved(feature, oldpos);
569 }
570 }
571 }
572
573
ProjectileCreated(const CProjectile * proj,int allyTeam)574 inline void CEventHandler::ProjectileCreated(const CProjectile* proj, int allyTeam)
575 {
576 const int count = listProjectileCreated.size();
577 for (int i = 0; i < count; i++) {
578 CEventClient* ec = listProjectileCreated[i];
579 if ((allyTeam < 0) || // projectile had no owner at creation
580 ec->CanReadAllyTeam(allyTeam)) {
581 ec->ProjectileCreated(proj);
582 }
583 }
584 }
585
586
ProjectileDestroyed(const CProjectile * proj,int allyTeam)587 inline void CEventHandler::ProjectileDestroyed(const CProjectile* proj, int allyTeam)
588 {
589 const int count = listProjectileDestroyed.size();
590 for (int i = 0; i < count; i++) {
591 CEventClient* ec = listProjectileDestroyed[i];
592 if ((allyTeam < 0) || // projectile had no owner at creation
593 ec->CanReadAllyTeam(allyTeam)) {
594 ec->ProjectileDestroyed(proj);
595 }
596 }
597 }
598
599
UnsyncedHeightMapUpdate(const SRectangle & rect)600 inline void CEventHandler::UnsyncedHeightMapUpdate(const SRectangle& rect)
601 {
602 ITERATE_EVENTCLIENTLIST(UnsyncedHeightMapUpdate, rect)
603 }
604
605
606
607
Explosion(int weaponDefID,int projectileID,const float3 & pos,const CUnit * owner)608 inline bool CEventHandler::Explosion(int weaponDefID, int projectileID, const float3& pos, const CUnit* owner)
609 {
610 const int count = listExplosion.size();
611 bool noGfx = false;
612 for (int i = 0; i < count; i++) {
613 CEventClient* ec = listExplosion[i];
614 if (ec->GetFullRead()) {
615 noGfx = noGfx || ec->Explosion(weaponDefID, projectileID, pos, owner);
616 }
617 }
618 return noGfx;
619 }
620
621
StockpileChanged(const CUnit * unit,const CWeapon * weapon,int oldCount)622 inline void CEventHandler::StockpileChanged(const CUnit* unit,
623 const CWeapon* weapon,
624 int oldCount)
625 {
626 ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST(StockpileChanged, unit, weapon, oldCount)
627 }
628
629
DefaultCommand(const CUnit * unit,const CFeature * feature,int & cmd)630 inline bool CEventHandler::DefaultCommand(const CUnit* unit,
631 const CFeature* feature,
632 int& cmd)
633 {
634 // reverse order, user has the override
635 const int count = listDefaultCommand.size();
636 for (int i = (count - 1); i >= 0; i--) {
637 CEventClient* ec = listDefaultCommand[i];
638 if (ec->DefaultCommand(unit, feature, cmd)) {
639 return true;
640 }
641 }
642 return false;
643 }
644
645
646
RenderUnitCreated(const CUnit * unit,int cloaked)647 inline void CEventHandler::RenderUnitCreated(const CUnit* unit, int cloaked)
648 {
649 ITERATE_EVENTCLIENTLIST(RenderUnitCreated, unit, cloaked)
650 }
651
RenderUnitDestroyed(const CUnit * unit)652 inline void CEventHandler::RenderUnitDestroyed(const CUnit* unit)
653 {
654 ITERATE_EVENTCLIENTLIST(RenderUnitDestroyed, unit)
655 }
656
RenderUnitCloakChanged(const CUnit * unit,int cloaked)657 inline void CEventHandler::RenderUnitCloakChanged(const CUnit* unit, int cloaked)
658 {
659 ITERATE_EVENTCLIENTLIST(RenderUnitCloakChanged, unit, cloaked)
660 }
661
RenderUnitLOSChanged(const CUnit * unit,int allyTeam,int newStatus)662 inline void CEventHandler::RenderUnitLOSChanged(const CUnit* unit, int allyTeam, int newStatus)
663 {
664 ITERATE_EVENTCLIENTLIST(RenderUnitLOSChanged, unit, allyTeam, newStatus)
665 }
666
RenderUnitMoved(const CUnit * unit,const float3 & newpos)667 inline void CEventHandler::RenderUnitMoved(const CUnit* unit, const float3& newpos)
668 {
669 ITERATE_EVENTCLIENTLIST(RenderUnitMoved, unit, newpos)
670 }
671
RenderFeatureCreated(const CFeature * feature)672 inline void CEventHandler::RenderFeatureCreated(const CFeature* feature)
673 {
674 ITERATE_EVENTCLIENTLIST(RenderFeatureCreated, feature)
675 }
676
RenderFeatureDestroyed(const CFeature * feature)677 inline void CEventHandler::RenderFeatureDestroyed(const CFeature* feature)
678 {
679 ITERATE_EVENTCLIENTLIST(RenderFeatureDestroyed, feature)
680 }
681
RenderFeatureMoved(const CFeature * feature,const float3 & oldpos,const float3 & newpos)682 inline void CEventHandler::RenderFeatureMoved(const CFeature* feature, const float3& oldpos, const float3& newpos)
683 {
684 ITERATE_EVENTCLIENTLIST(RenderFeatureMoved, feature, oldpos, newpos)
685 }
686
RenderProjectileCreated(const CProjectile * proj)687 inline void CEventHandler::RenderProjectileCreated(const CProjectile* proj)
688 {
689 ITERATE_EVENTCLIENTLIST(RenderProjectileCreated, proj)
690 }
691
RenderProjectileDestroyed(const CProjectile * proj)692 inline void CEventHandler::RenderProjectileDestroyed(const CProjectile* proj)
693 {
694 ITERATE_EVENTCLIENTLIST(RenderProjectileDestroyed, proj)
695 }
696
697
698 #undef ITERATE_EVENTCLIENTLIST
699 #undef ITERATE_ALLYTEAM_EVENTCLIENTLIST
700 #undef ITERATE_UNIT_ALLYTEAM_EVENTCLIENTLIST
701 #undef UNIT_CALLIN_NO_PARAM
702 #undef UNIT_CALLIN_INT_PARAMS
703 #undef UNIT_CALLIN_LOS_PARAM
704
705 #endif /* EVENT_HANDLER_H */
706
707