Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. 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 General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_MESSAGETYPES
19 : #define INCLUDED_MESSAGETYPES
20 :
21 : #include "simulation2/system/Components.h"
22 : #include "simulation2/system/Entity.h"
23 : #include "simulation2/system/Message.h"
24 :
25 : #include "simulation2/helpers/Player.h"
26 : #include "simulation2/helpers/Position.h"
27 :
28 : #include "simulation2/components/ICmpPathfinder.h"
29 :
30 : #include "maths/Vector3D.h"
31 :
32 : #include "ps/CStr.h"
33 :
34 : #define DEFAULT_MESSAGE_IMPL(name) \
35 : virtual int GetType() const { return MT_##name; } \
36 : virtual const char* GetScriptHandlerName() const { return "On" #name; } \
37 : virtual const char* GetScriptGlobalHandlerName() const { return "OnGlobal" #name; } \
38 : virtual JS::Value ToJSVal(const ScriptInterface& scriptInterface) const; \
39 : static CMessage* FromJSVal(const ScriptInterface&, JS::HandleValue val);
40 :
41 : class SceneCollector;
42 : class CFrustum;
43 :
44 4 : class CMessageTurnStart final : public CMessage
45 : {
46 : public:
47 29 : DEFAULT_MESSAGE_IMPL(TurnStart)
48 :
49 4 : CMessageTurnStart()
50 4 : {
51 4 : }
52 : };
53 :
54 : // The update process is split into a number of phases, in an attempt
55 : // to cope with dependencies between components. Each phase is implemented
56 : // as a separate message. Simulation2.cpp sends them in sequence.
57 :
58 : /**
59 : * Generic per-turn update message, for things that don't care much about ordering.
60 : */
61 108 : class CMessageUpdate final : public CMessage
62 : {
63 : public:
64 140 : DEFAULT_MESSAGE_IMPL(Update)
65 :
66 105 : CMessageUpdate(fixed turnLength) :
67 105 : turnLength(turnLength)
68 : {
69 105 : }
70 :
71 : fixed turnLength;
72 : };
73 :
74 : /**
75 : * Update phase for formation controller movement (must happen before individual
76 : * units move to follow their formation).
77 : */
78 0 : class CMessageUpdate_MotionFormation final : public CMessage
79 : {
80 : public:
81 0 : DEFAULT_MESSAGE_IMPL(Update_MotionFormation)
82 :
83 0 : CMessageUpdate_MotionFormation(fixed turnLength) :
84 0 : turnLength(turnLength)
85 : {
86 0 : }
87 :
88 : fixed turnLength;
89 : };
90 :
91 : /**
92 : * Update phase for non-formation-controller unit movement.
93 : */
94 0 : class CMessageUpdate_MotionUnit final : public CMessage
95 : {
96 : public:
97 0 : DEFAULT_MESSAGE_IMPL(Update_MotionUnit)
98 :
99 0 : CMessageUpdate_MotionUnit(fixed turnLength) :
100 0 : turnLength(turnLength)
101 : {
102 0 : }
103 :
104 : fixed turnLength;
105 : };
106 :
107 : /**
108 : * Final update phase, after all other updates.
109 : */
110 0 : class CMessageUpdate_Final final : public CMessage
111 : {
112 : public:
113 0 : DEFAULT_MESSAGE_IMPL(Update_Final)
114 :
115 0 : CMessageUpdate_Final(fixed turnLength) :
116 0 : turnLength(turnLength)
117 : {
118 0 : }
119 :
120 : fixed turnLength;
121 : };
122 :
123 : /**
124 : * Prepare for rendering a new frame (set up model positions etc).
125 : */
126 1 : class CMessageInterpolate final : public CMessage
127 : {
128 : public:
129 14 : DEFAULT_MESSAGE_IMPL(Interpolate)
130 :
131 1 : CMessageInterpolate(float deltaSimTime, float offset, float deltaRealTime) :
132 1 : deltaSimTime(deltaSimTime), offset(offset), deltaRealTime(deltaRealTime)
133 : {
134 1 : }
135 :
136 : /// Elapsed simulation time since previous interpolate, in seconds. This is similar to the elapsed real time, except
137 : /// it is scaled by the current simulation rate (and might indeed be zero).
138 : float deltaSimTime;
139 : /// Range [0, 1] (inclusive); fractional time of current frame between previous/next simulation turns.
140 : float offset;
141 : /// Elapsed real time since previous interpolate, in seconds.
142 : float deltaRealTime;
143 : };
144 :
145 : /**
146 : * Add renderable objects to the scene collector.
147 : * Called after CMessageInterpolate.
148 : */
149 0 : class CMessageRenderSubmit final : public CMessage
150 : {
151 : public:
152 0 : DEFAULT_MESSAGE_IMPL(RenderSubmit)
153 :
154 0 : CMessageRenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling) :
155 0 : collector(collector), frustum(frustum), culling(culling)
156 : {
157 0 : }
158 :
159 : SceneCollector& collector;
160 : const CFrustum& frustum;
161 : bool culling;
162 : };
163 :
164 : /**
165 : * Handle progressive loading of resources.
166 : * A component that listens to this message must do the following:
167 : * - Increase *msg.total by the non-zero number of loading tasks this component can perform.
168 : * - If *msg.progressed == true, return and do nothing.
169 : * - If you've loaded everything, increase *msg.progress by the value you added to .total
170 : * - Otherwise do some loading, set *msg.progressed = true, and increase *msg.progress by a
171 : * value indicating how much progress you've made in total (0 <= p <= what you added to .total)
172 : * In some situations these messages will never be sent - components must ensure they
173 : * load all their data themselves before using it in that case.
174 : */
175 0 : class CMessageProgressiveLoad final : public CMessage
176 : {
177 : public:
178 0 : DEFAULT_MESSAGE_IMPL(ProgressiveLoad)
179 :
180 0 : CMessageProgressiveLoad(bool* progressed, int* total, int* progress) :
181 0 : progressed(progressed), total(total), progress(progress)
182 : {
183 0 : }
184 :
185 : bool* progressed;
186 : int* total;
187 : int* progress;
188 : };
189 :
190 : /**
191 : * Broadcast after the entire simulation state has been deserialized.
192 : * Components should do all their self-contained work in their Deserialize
193 : * function when possible. But any reinitialisation that depends on other
194 : * components or other entities, that might not be constructed until later
195 : * in the deserialization process, may be done in response to this message
196 : * instead.
197 : */
198 3 : class CMessageDeserialized final : public CMessage
199 : {
200 : public:
201 12 : DEFAULT_MESSAGE_IMPL(Deserialized)
202 :
203 3 : CMessageDeserialized()
204 3 : {
205 3 : }
206 : };
207 :
208 :
209 : /**
210 : * This is sent immediately after a new entity's components have all been created
211 : * and initialised.
212 : */
213 11 : class CMessageCreate final : public CMessage
214 : {
215 : public:
216 49 : DEFAULT_MESSAGE_IMPL(Create)
217 :
218 11 : CMessageCreate(entity_id_t entity) :
219 11 : entity(entity)
220 : {
221 11 : }
222 :
223 : entity_id_t entity;
224 : };
225 :
226 : /**
227 : * This is sent immediately before a destroyed entity is flushed and really destroyed.
228 : * (That is, after CComponentManager::DestroyComponentsSoon and inside FlushDestroyedComponents).
229 : * The entity will still exist at the time this message is sent.
230 : * It's possible for this message to be sent multiple times for one entity, but all its components
231 : * will have been deleted after the first time.
232 : */
233 4 : class CMessageDestroy final : public CMessage
234 : {
235 : public:
236 27 : DEFAULT_MESSAGE_IMPL(Destroy)
237 :
238 4 : CMessageDestroy(entity_id_t entity) :
239 4 : entity(entity)
240 : {
241 4 : }
242 :
243 : entity_id_t entity;
244 : };
245 :
246 11 : class CMessageOwnershipChanged final : public CMessage
247 : {
248 : public:
249 11 : DEFAULT_MESSAGE_IMPL(OwnershipChanged)
250 :
251 11 : CMessageOwnershipChanged(entity_id_t entity, player_id_t from, player_id_t to) :
252 11 : entity(entity), from(from), to(to)
253 : {
254 11 : }
255 :
256 : entity_id_t entity;
257 : player_id_t from;
258 : player_id_t to;
259 : };
260 :
261 : /**
262 : * Sent by CCmpPosition whenever anything has changed that will affect the
263 : * return value of GetPosition2D() or GetRotation().Y
264 : *
265 : * If @c inWorld is false, then the other fields are invalid and meaningless.
266 : * Otherwise they represent the current position.
267 : */
268 1051 : class CMessagePositionChanged final : public CMessage
269 : {
270 : public:
271 1103 : DEFAULT_MESSAGE_IMPL(PositionChanged)
272 :
273 1051 : CMessagePositionChanged(entity_id_t entity, bool inWorld, entity_pos_t x, entity_pos_t z, entity_angle_t a) :
274 1051 : entity(entity), inWorld(inWorld), x(x), z(z), a(a)
275 : {
276 1051 : }
277 :
278 : entity_id_t entity;
279 : bool inWorld;
280 : entity_pos_t x, z;
281 : entity_angle_t a;
282 : };
283 :
284 : /**
285 : * Sent by CCmpPosition whenever anything has changed that will affect the
286 : * return value of GetInterpolatedTransform()
287 : */
288 22 : class CMessageInterpolatedPositionChanged final : public CMessage
289 : {
290 : public:
291 110 : DEFAULT_MESSAGE_IMPL(InterpolatedPositionChanged)
292 :
293 22 : CMessageInterpolatedPositionChanged(entity_id_t entity, bool inWorld, const CVector3D& pos0, const CVector3D& pos1) :
294 22 : entity(entity), inWorld(inWorld), pos0(pos0), pos1(pos1)
295 : {
296 22 : }
297 :
298 : entity_id_t entity;
299 : bool inWorld;
300 : CVector3D pos0;
301 : CVector3D pos1;
302 : };
303 :
304 : /*Sent whenever the territory type (neutral,own,enemy) differs from the former type*/
305 0 : class CMessageTerritoryPositionChanged final : public CMessage
306 : {
307 : public:
308 0 : DEFAULT_MESSAGE_IMPL(TerritoryPositionChanged)
309 :
310 0 : CMessageTerritoryPositionChanged(entity_id_t entity, player_id_t newTerritory) :
311 0 : entity(entity), newTerritory(newTerritory)
312 : {
313 0 : }
314 :
315 : entity_id_t entity;
316 : player_id_t newTerritory;
317 : };
318 :
319 : /**
320 : * Sent by CCmpUnitMotion during Update if an event happened that might interest other components.
321 : */
322 0 : class CMessageMotionUpdate final : public CMessage
323 : {
324 : public:
325 0 : DEFAULT_MESSAGE_IMPL(MotionUpdate)
326 :
327 : enum UpdateType {
328 : LIKELY_SUCCESS, // UnitMotion considers it is arrived at destination.
329 : LIKELY_FAILURE, // UnitMotion says it cannot reach the destination.
330 : OBSTRUCTED, // UnitMotion was obstructed. This does not mean stuck, but can be a hint to run range checks.
331 : VERY_OBSTRUCTED, // Sent when obstructed several time in a row.
332 : LENGTH
333 : };
334 :
335 : static const std::array<const char*, UpdateType::LENGTH> UpdateTypeStr;
336 :
337 0 : CMessageMotionUpdate(UpdateType ut) : updateType(ut)
338 : {
339 0 : }
340 :
341 : UpdateType updateType;
342 : };
343 :
344 : /**
345 : * Sent when water height has been changed.
346 : */
347 0 : class CMessageWaterChanged final : public CMessage
348 : {
349 : public:
350 0 : DEFAULT_MESSAGE_IMPL(WaterChanged)
351 :
352 0 : CMessageWaterChanged()
353 0 : {
354 0 : }
355 : };
356 :
357 : /**
358 : * Sent when terrain (texture or elevation) has been changed.
359 : */
360 0 : class CMessageTerrainChanged final : public CMessage
361 : {
362 : public:
363 0 : DEFAULT_MESSAGE_IMPL(TerrainChanged)
364 :
365 0 : CMessageTerrainChanged(int32_t i0, int32_t j0, int32_t i1, int32_t j1) :
366 0 : i0(i0), j0(j0), i1(i1), j1(j1)
367 : {
368 0 : }
369 :
370 : int32_t i0, j0, i1, j1; // inclusive lower bound, exclusive upper bound, in tiles
371 : };
372 :
373 : /**
374 : * Sent, at most once per turn, when the visibility of an entity changed
375 : */
376 0 : class CMessageVisibilityChanged final : public CMessage
377 : {
378 : public:
379 0 : DEFAULT_MESSAGE_IMPL(VisibilityChanged)
380 :
381 0 : CMessageVisibilityChanged(player_id_t player, entity_id_t ent, int oldVisibility, int newVisibility) :
382 0 : player(player), ent(ent), oldVisibility(oldVisibility), newVisibility(newVisibility)
383 : {
384 0 : }
385 :
386 : player_id_t player;
387 : entity_id_t ent;
388 : int oldVisibility;
389 : int newVisibility;
390 : };
391 :
392 : /**
393 : * Sent when then obstruction of an entity has changed in a manner
394 : * that changes 'block movement' properties.
395 : */
396 0 : class CMessageMovementObstructionChanged final : public CMessage
397 : {
398 : public:
399 0 : DEFAULT_MESSAGE_IMPL(MovementObstructionChanged)
400 :
401 0 : CMessageMovementObstructionChanged()
402 0 : {
403 0 : }
404 : };
405 :
406 : /**
407 : * Sent when ObstructionManager's view of the shape of the world has changed
408 : * (changing the TILE_OUTOFBOUNDS tiles returned by Rasterise).
409 : */
410 0 : class CMessageObstructionMapShapeChanged final : public CMessage
411 : {
412 : public:
413 0 : DEFAULT_MESSAGE_IMPL(ObstructionMapShapeChanged)
414 :
415 0 : CMessageObstructionMapShapeChanged()
416 0 : {
417 0 : }
418 : };
419 :
420 : /**
421 : * Sent when territory assignments have changed.
422 : */
423 0 : class CMessageTerritoriesChanged final : public CMessage
424 : {
425 : public:
426 0 : DEFAULT_MESSAGE_IMPL(TerritoriesChanged)
427 :
428 0 : CMessageTerritoriesChanged()
429 0 : {
430 0 : }
431 : };
432 :
433 : /**
434 : * Sent by CCmpRangeManager at most once per turn, when an active range query
435 : * has had matching units enter/leave the range since the last RangeUpdate.
436 : */
437 0 : class CMessageRangeUpdate final : public CMessage
438 : {
439 : public:
440 0 : DEFAULT_MESSAGE_IMPL(RangeUpdate)
441 :
442 :
443 :
444 : u32 tag;
445 : std::vector<entity_id_t> added;
446 : std::vector<entity_id_t> removed;
447 :
448 : // CCmpRangeManager wants to store a vector of messages and wants to
449 : // swap vectors instead of copying (to save on memory allocations),
450 : // so add some constructors for it:
451 :
452 : // don't init tag in empty ctor
453 0 : CMessageRangeUpdate()
454 0 : {
455 0 : }
456 : CMessageRangeUpdate(u32 tag) : tag(tag)
457 : {
458 : }
459 : CMessageRangeUpdate(u32 tag, const std::vector<entity_id_t>& added, const std::vector<entity_id_t>& removed)
460 : : tag(tag), added(added), removed(removed)
461 : {
462 : }
463 0 : CMessageRangeUpdate(const CMessageRangeUpdate& other)
464 0 : : CMessage(), tag(other.tag), added(other.added), removed(other.removed)
465 : {
466 0 : }
467 : CMessageRangeUpdate& operator=(const CMessageRangeUpdate& other)
468 : {
469 : tag = other.tag;
470 : added = other.added;
471 : removed = other.removed;
472 : return *this;
473 : }
474 : };
475 :
476 : /**
477 : * Sent by CCmpPathfinder after async path requests.
478 : */
479 0 : class CMessagePathResult final : public CMessage
480 : {
481 : public:
482 0 : DEFAULT_MESSAGE_IMPL(PathResult)
483 :
484 0 : CMessagePathResult(u32 ticket, const WaypointPath& path) :
485 0 : ticket(ticket), path(path)
486 : {
487 0 : }
488 :
489 : u32 ticket;
490 : WaypointPath path;
491 : };
492 :
493 : /**
494 : * Sent by aura manager when a value of a certain entity's component is changed
495 : */
496 0 : class CMessageValueModification final : public CMessage
497 : {
498 : public:
499 0 : DEFAULT_MESSAGE_IMPL(ValueModification)
500 :
501 0 : CMessageValueModification(const std::vector<entity_id_t>& entities, std::wstring component, const std::vector<std::wstring>& valueNames) :
502 : entities(entities),
503 : component(component),
504 0 : valueNames(valueNames)
505 : {
506 0 : }
507 :
508 : std::vector<entity_id_t> entities;
509 : std::wstring component;
510 : std::vector<std::wstring> valueNames;
511 : };
512 :
513 : /**
514 : * Sent by atlas if the playercolor has been changed.
515 : */
516 0 : class CMessagePlayerColorChanged final : public CMessage
517 : {
518 : public:
519 0 : DEFAULT_MESSAGE_IMPL(PlayerColorChanged)
520 :
521 0 : CMessagePlayerColorChanged(player_id_t player) :
522 0 : player(player)
523 : {
524 0 : }
525 :
526 : player_id_t player;
527 : };
528 :
529 : /**
530 : * Sent by aura and tech managers when a value of a certain template's component is changed
531 : */
532 0 : class CMessageTemplateModification final : public CMessage
533 : {
534 : public:
535 0 : DEFAULT_MESSAGE_IMPL(TemplateModification)
536 :
537 0 : CMessageTemplateModification(player_id_t player, std::wstring component, const std::vector<std::wstring>& valueNames) :
538 : player(player),
539 : component(component),
540 0 : valueNames(valueNames)
541 : {
542 0 : }
543 :
544 : player_id_t player;
545 : std::wstring component;
546 : std::vector<std::wstring> valueNames;
547 : };
548 :
549 : /**
550 : * Sent by CCmpVision when an entity's vision range changes.
551 : */
552 0 : class CMessageVisionRangeChanged final : public CMessage
553 : {
554 : public:
555 0 : DEFAULT_MESSAGE_IMPL(VisionRangeChanged)
556 :
557 0 : CMessageVisionRangeChanged(entity_id_t entity, entity_pos_t oldRange, entity_pos_t newRange) :
558 0 : entity(entity), oldRange(oldRange), newRange(newRange)
559 : {
560 0 : }
561 :
562 : entity_id_t entity;
563 : entity_pos_t oldRange;
564 : entity_pos_t newRange;
565 : };
566 :
567 : /**
568 : * Sent by CCmpVision when an entity's vision sharing changes.
569 : */
570 0 : class CMessageVisionSharingChanged final : public CMessage
571 : {
572 : public:
573 0 : DEFAULT_MESSAGE_IMPL(VisionSharingChanged)
574 :
575 0 : CMessageVisionSharingChanged(entity_id_t entity, player_id_t player, bool add) :
576 0 : entity(entity), player(player), add(add)
577 : {
578 0 : }
579 :
580 : entity_id_t entity;
581 : player_id_t player;
582 : bool add;
583 : };
584 :
585 : /**
586 : * Sent when an entity pings the minimap
587 : */
588 0 : class CMessageMinimapPing final : public CMessage
589 : {
590 : public:
591 0 : DEFAULT_MESSAGE_IMPL(MinimapPing)
592 :
593 0 : CMessageMinimapPing()
594 0 : {
595 0 : }
596 : };
597 :
598 : /**
599 : * Cinematics events
600 : */
601 :
602 1 : class CMessageCinemaPathEnded final : public CMessage
603 : {
604 : public:
605 5 : DEFAULT_MESSAGE_IMPL(CinemaPathEnded)
606 :
607 1 : CMessageCinemaPathEnded(CStrW name) :
608 1 : name(name)
609 : {
610 1 : }
611 :
612 : CStrW name;
613 : };
614 :
615 2 : class CMessageCinemaQueueEnded final : public CMessage
616 : {
617 : public:
618 5 : DEFAULT_MESSAGE_IMPL(CinemaQueueEnded)
619 : };
620 :
621 : #endif // INCLUDED_MESSAGETYPES
|