/
TSESpaceObjectsImpl.h
1762 lines (1539 loc) · 90.3 KB
/
TSESpaceObjectsImpl.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// TSESpaceObjectsImpl.h
//
// Transcendence CSpaceObject classes
// Copyright (c) 2015 by Kronosaur Productions, LLC. All Rights Reserved.
#pragma once
template <DWORD CLASSID>
class TSpaceObjectImpl : public CSpaceObject
{
public:
TSpaceObjectImpl (CUniverse &Universe) : CSpaceObject(Universe)
{ }
static constexpr DWORD ClassID (void) { return CLASSID; }
protected:
virtual DWORD GetClassID (void) const override { return CLASSID; }
};
class CAreaDamage : public TSpaceObjectImpl<OBJID_CAREADAMAGE>
{
public:
CAreaDamage (CUniverse &Universe);
~CAreaDamage (void);
static ALERROR Create (CSystem &System, SShotCreateCtx &Ctx, CAreaDamage **retpObj);
// CSpaceObject virtuals
virtual CString GetDamageCauseNounPhrase (DWORD dwFlags) override { return m_Source.GetDamageCauseNounPhrase(dwFlags); }
virtual const CDamageSource &GetDamageSource (void) const override { return m_Source; }
virtual Metric GetMaxSpeed (void) const override { return m_pDesc->GetAveExpansionSpeed(); }
virtual CString GetNamePattern (DWORD dwNounPhraseFlags = 0, DWORD *retdwFlags = NULL) const override;
virtual CString GetObjClassName (void) override { return CONSTLIT("CAreaDamage"); }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return CSystem::layerEffects; }
virtual CSpaceObject *GetSecondarySource (void) override { return m_Source.GetSecondaryObj(); }
virtual CSovereign *GetSovereign (void) const override { return m_pSovereign; }
virtual CDesignType *GetType (void) const override { return m_pDesc->GetWeaponType(); }
virtual CWeaponFireDesc *GetWeaponFireDesc (void) override { return m_pDesc; }
virtual void OnMove (const CVector &vOldPos, Metric rSeconds) override;
virtual void OnSystemLoaded (void) override;
virtual void PaintLRSForeground (CG32bitImage &Dest, int x, int y, const ViewportTransform &Trans) override;
virtual bool PointInObject (const CVector &vObjPos, const CVector &vPointPos) const override;
protected:
// Virtuals to be overridden
virtual bool CanHit (CSpaceObject *pObj) override { return MissileCanHitObj(pObj, m_Source, m_pDesc); }
virtual void ObjectDestroyedHook (const SDestroyCtx &Ctx) override;
virtual EDamageResults OnDamage (SDamageCtx &Ctx) override { return damagePassthrough; }
virtual void OnDestroyed (SDestroyCtx &Ctx) override;
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
private:
CWeaponFireDesc *m_pDesc; // Weapon descriptor
TSharedPtr<CItemEnhancementStack> m_pEnhancements; // Stack of enhancements
IEffectPainter *m_pPainter; // Effect painter
int m_iInitialDelay; // Delay before start
int m_iTick; // Counter
int m_iLifeLeft; // Ticks left
CDamageSource m_Source; // Object that fired the beam
CSovereign *m_pSovereign; // Sovereign
};
class CBeam : public TSpaceObjectImpl<OBJID_CBEAM>
{
public:
CBeam (CUniverse &Universe);
// CSpaceObject virtuals
virtual void CreateReflection (const CVector &vPos, int iDirection, CMissile **retpReflection = NULL) override;
virtual Categories GetCategory (void) const override { return catBeam; }
virtual CString GetDamageCauseNounPhrase (DWORD dwFlags) override { return m_Source.GetDamageCauseNounPhrase(dwFlags); }
virtual const CDamageSource &GetDamageSource (void) const override { return m_Source; }
virtual int GetInteraction (void) const override { return 0; }
virtual Metric GetMaxSpeed (void) const override { return m_pDesc->GetRatedSpeed(); }
virtual CString GetNamePattern (DWORD dwNounPhraseFlags = 0, DWORD *retdwFlags = NULL) const override;
virtual CString GetObjClassName (void) override { return CONSTLIT("CBeam"); }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return CSystem::layerStations; }
virtual CSpaceObject *GetSecondarySource (void) override { return m_Source.GetSecondaryObj(); }
virtual CSovereign *GetSovereign (void) const override { return m_pSovereign; }
virtual CWeaponFireDesc *GetWeaponFireDesc (void) override { return m_pDesc; }
virtual void OnMove (const CVector &vOldPos, Metric rSeconds) override;
protected:
// Virtuals to be overridden
virtual bool CanHit (CSpaceObject *pObj) override { return MissileCanHitObj(pObj, m_Source, m_pDesc); }
virtual void ObjectDestroyedHook (const SDestroyCtx &Ctx) override;
virtual EDamageResults OnDamage (SDamageCtx &Ctx) override { return damagePassthrough; }
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
private:
void ComputeOffsets (void);
CWeaponFireDesc *m_pDesc; // Weapon descriptor
int m_iBonus; // Bonus damage
int m_iRotation; // Direction
CVector m_vPaintTo; // Paint from old position to this location
int m_iTick; // Ticks that we have been alive
int m_iLifeLeft; // Ticks left
CDamageSource m_Source; // Object that fired the beam
CSovereign *m_pSovereign; // Sovereign
CSpaceObject *m_pHit; // Object that was hit
int m_iHitDir; // Direction from which object was hit
int m_xFromOffset; // Offsets for painting (volatile)
int m_yFromOffset;
int m_xToOffset;
int m_yToOffset;
DWORD m_fReflection:1; // TRUE if this is a reflection
DWORD m_dwSpareFlags:31; // Flags
};
class CBoundaryMarker : public TSpaceObjectImpl<OBJID_CBOUNDARYMARKER>
{
public:
CBoundaryMarker (CUniverse &Universe);
static ALERROR Create (CSystem &System,
const CVector &vStartPos,
CBoundaryMarker **retpMarker);
void AddSegment (const CVector &vEndpoint);
void CloseBoundary (void);
bool FindIntersectSegment (const CVector &vStart, const CVector &vEnd, CVector *retvSegInt, CVector *retvSegEnd, int *retiSeg);
void GetSegment (int iSeg, CVector *retvStart, CVector *retvEnd);
// CSpaceObject virtuals
virtual CBoundaryMarker *AsBoundaryMarker (void) override { return this; }
virtual bool IsAnchored (void) const override { return true; }
protected:
// CSpaceObject virtuals
virtual bool CanHit (CSpaceObject *pObj) override { return false; }
virtual CString GetObjClassName (void) override { return CONSTLIT("CBoundaryMarker"); }
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
virtual void PaintLRSForeground (CG32bitImage &Dest, int x, int y, const ViewportTransform &Trans) override { }
private:
TArray<CVector> m_Path;
};
class CContinuousBeam : public TSpaceObjectImpl<OBJID_CCONTINUOUSBEAM>
{
public:
CContinuousBeam (CUniverse &Universe);
~CContinuousBeam (void);
static ALERROR Create (CSystem &System, SShotCreateCtx &Ctx, CContinuousBeam **retpObj);
// CSpaceObject virtuals
virtual void AddContinuousBeam (const CVector &vPos, const CVector &vVel, int iDirection) override;
virtual CString DebugCrashInfo (void) override;
virtual CString GetDamageCauseNounPhrase (DWORD dwFlags) override { return m_Source.GetDamageCauseNounPhrase(dwFlags); }
virtual const CDamageSource &GetDamageSource (void) const override { return m_Source; }
virtual int GetInteraction (void) const override { return m_pDesc->GetInteraction(); }
virtual Metric GetMaxSpeed (void) const override { return m_pDesc->GetRatedSpeed(); }
virtual CString GetNamePattern (DWORD dwNounPhraseFlags = 0, DWORD *retdwFlags = NULL) const override;
virtual CString GetObjClassName (void) override { return CONSTLIT("CContinuousBeam"); }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return CSystem::layerEffects; }
virtual int GetRotation (void) const override { return m_iLastDirection; }
virtual CSpaceObject *GetSecondarySource (void) override { return m_Source.GetSecondaryObj(); }
virtual CSovereign *GetSovereign (void) const override { return m_pSovereign; }
virtual CDesignType *GetType (void) const override { return m_pDesc->GetWeaponType(); }
virtual CWeaponFireDesc *GetWeaponFireDesc (void) override { return m_pDesc; }
virtual void OnMove (const CVector &vOldPos, Metric rSeconds) override;
virtual bool PointInObject (const CVector &vObjPos, const CVector &vPointPos) const override;
protected:
// Virtuals to be overridden
virtual bool CanHit (CSpaceObject *pObj) override { return MissileCanHitObj(pObj, m_Source, m_pDesc); }
virtual void ObjectDestroyedHook (const SDestroyCtx &Ctx) override;
virtual EDamageResults OnDamage (SDamageCtx &Ctx) override { return damagePassthrough; }
virtual void OnDestroyed (SDestroyCtx &Ctx) override;
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
private:
struct SSegment
{
SSegment (void) :
fAlive(true),
fHit(false),
fPassthrough(false)
{
}
CVector vPos; // Position of head of segment
CVector vDeltaPos; // Change in position per tick
DWORD dwGeneration; // Created on this tick
int iDamage; // Damage in points
TArray<DWORD> Hits; // Object ID of what we hit last tick
DWORD fAlive:1; // Segment is still alive
DWORD fHit:1; // We hit something last frame
DWORD fPassthrough:1; // We passed through.
DWORD dwSpare:29;
};
void AddSegment (const CVector &vPos, const CVector &vVel, int iDamage);
EDamageResults DoDamage (CSpaceObject *pHit, const CVector &vHitPos, int iHitDir);
bool HitTestSegment (SSegment &Segment, CVector *retvHitPos);
void PaintSegment (CG32bitImage &Dest, const CVector &vFrom, const CVector &vTo, SViewportPaintCtx &Ctx) const;
void UpdateBeamMotion (Metric rSeconds, CVector *retvNewPos, Metric *retrMaxBoundsX, Metric *retrMaxBoundsY);
// This is the origin of the particle array in object coordinates. We
// always use a fixed anchor because the motion of the particles
// determines the position of the particle damage object (and not vice
// versa, as in SFXParticleSystem).
//
// We use 0,0 as a fixed point, which works as long as we can still
// convert kilometers to pixels and still be in range. We're good for
// at least 1,000 light-minutes. [But if we ever need to scale beyond
// that, then we should set the origin to the original shot position.]
const CVector &GetOrigin (void) const { return NullVector; }
CWeaponFireDesc *m_pDesc; // Weapon descriptor
TSharedPtr<CItemEnhancementStack> m_pEnhancements; // Stack of enhancements
CSpaceObject *m_pTarget; // Target
int m_iTick; // Counter
int m_iLifetime; // Lifetime of any one segment
int m_iLastDirection; // Most recent direction
CDamageSource m_Source; // Object that fired the beam
CSovereign *m_pSovereign; // Sovereign
TArray<SSegment> m_Segments; // All beam segments
TArray<CHitCtx> m_Hits; // Objects hit by this segment last tick
IEffectPainter *m_pPainter; // Effect for beam
DWORD m_fSpare1:1;
DWORD m_fSpare2:1;
DWORD m_fSpare3:1;
DWORD m_fSpare4:1;
DWORD m_fSpare5:1;
DWORD m_fSpare6:1;
DWORD m_fSpare7:1;
DWORD m_fSpare8:1;
DWORD m_dwSpare:24;
};
class CDisintegrationEffect : public TSpaceObjectImpl<OBJID_CDISINTEGRATIONEFFECT>
{
public:
CDisintegrationEffect (CUniverse &Universe);
virtual ~CDisintegrationEffect (void);
static ALERROR Create (CSystem &System,
const CVector &vPos,
const CVector &vVel,
const CObjectImageArray &MaskImage,
int iMaskTick,
int iMaskRotation,
CDisintegrationEffect **retpEffect);
// CSpaceObject virtuals
virtual CString GetObjClassName (void) override { return CONSTLIT("CDisintegrationEffect"); }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return CSystem::layerEffects; }
protected:
// CSpaceObject virtuals
virtual void ObjectDestroyedHook (const SDestroyCtx &Ctx) override;
virtual EDamageResults OnDamage (SDamageCtx &Ctx) override { return damagePassthrough; }
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) override;
virtual void OnUpdateExtended (const CTimeSpan &ExtraTime) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
virtual void OnMove (const CVector &vOldPos, Metric rSeconds) override;
private:
struct SParticle
{
int x; // Position in 256th of a pixel
int y;
int xV; // Velocity in 256th of a pixel
int yV; // per tick
int iTicksLeft;
CG32bitPixel rgbColor;
WORD wSpare;
};
void InitParticle (SParticle *pParticle);
int m_iTick;
CObjectImageArray m_MaskImage;
int m_iMaskTick;
int m_iMaskRotation;
// particles
int m_iParticleCount;
SParticle *m_pParticles;
};
class CEffect : public TSpaceObjectImpl<OBJID_CEFFECT>
{
public:
struct SCreateOptions
{
CSpaceObject *pAnchor = NULL;
int iRotation = 0;
bool bLoop = false;
};
CEffect (CUniverse &Universe);
virtual ~CEffect (void);
static ALERROR Create (CSystem &System,
IEffectPainter *pPainter,
const CVector &vPos,
const CVector &vVel,
const SCreateOptions &Options = SCreateOptions(),
CEffect **retpEffect = NULL);
int GetLifetime (void) const { return m_iLifetime; }
void SetLifetime (int iLifetime) { m_iLifetime = iLifetime; }
// CSpaceObject virtuals
virtual bool CanMove (void) const { return true; }
virtual bool IsAnchored (void) const override { return (m_pAnchor != NULL); }
virtual CString GetObjClassName (void) override { return CONSTLIT("CEffect"); }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return CSystem::layerEffects; }
virtual int GetRotation (void) const override { return m_iRotation; }
virtual bool SetProperty (const CString &sProperty, ICCItem *pValue, CString *retsError) override;
protected:
// CSpaceObject virtuals
virtual void ObjectDestroyedHook (const SDestroyCtx &Ctx) override;
virtual EDamageResults OnDamage (SDamageCtx &Ctx) override { return damagePassthrough; }
virtual ICCItemPtr OnFindProperty (CCodeChainCtx &CCX, const CString &sProperty) const override;
virtual void OnMove (const CVector &vOldPos, Metric rSeconds) override;
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) override;
virtual void OnUpdateExtended (const CTimeSpan &ExtraTime) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
private:
CEffectCreator *GetEffectCreator (void);
IEffectPainter *m_pPainter;
CSpaceObject *m_pAnchor;
int m_iLifetime;
int m_iRotation;
int m_iTick;
static TPropertyHandler<CEffect> m_PropertyTable;
};
class CFractureEffect : public TSpaceObjectImpl<OBJID_CFRACTUREEFFECT>
{
public:
enum Style
{
styleExplosion,
styleLinearSweep,
};
CFractureEffect (CUniverse &Universe);
virtual ~CFractureEffect (void);
static ALERROR CreateExplosion (CSystem &System,
const CVector &vPos,
const CVector &vVel,
const CObjectImageArray &Image,
int iImageTick,
int iImageRotation,
CFractureEffect **retpEffect);
static ALERROR CreateLinearSweep(CSystem &System,
const CVector &vPos,
const CVector &vVel,
const CObjectImageArray &Image,
int iImageTick,
int iImageRotation,
Metric rSweepDirection,
CFractureEffect **retpEffect);
// CSpaceObject virtuals
virtual Categories GetCategory (void) const override { return catFractureEffect; }
virtual CString GetObjClassName (void) override { return CONSTLIT("CFractureEffect"); }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return CSystem::layerEffects; }
virtual void MarkImages (void) override { m_Image.MarkImage(); }
virtual void SetAttractor (CSpaceObject *pObj) override;
protected:
// CSpaceObject virtuals
virtual void ObjectDestroyedHook (const SDestroyCtx &Ctx) override;
virtual EDamageResults OnDamage (SDamageCtx &Ctx) override { return damagePassthrough; }
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) override;
virtual void OnUpdateExtended (const CTimeSpan &ExtraTime) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
virtual void OnMove (const CVector &vOldPos, Metric rSeconds) override;
private:
struct SParticle
{
int x; // Position in 256th of a pixel
int y;
int xV; // Velocity in 256th of a pixel
int yV; // per tick
int iSleepTicks; // Stay still for this many ticks before moving
int xSrc; // Position in source
int ySrc;
int iShape; // Index of shape (-1 = destroyed)
};
void InitParticleArray (void);
int m_iTick;
int m_iLifeTime;
CObjectImageArray m_Image;
int m_iImageTick;
int m_iImageRotation;
int m_iStyle;
int m_iCellSize;
int m_iParticleCount;
SParticle *m_pParticles;
CSpaceObject *m_pAttractor;
double m_rSweepDirection;
};
class CMarker : public TSpaceObjectImpl<OBJID_CMARKER>
{
public:
CMarker (CUniverse &Universe);
~CMarker (void);
static ALERROR Create (CSystem &System,
CSovereign *pSovereign,
const CVector &vPos,
const CVector &vVel,
const CString &sName,
CMarker **retpMarker);
void SetOrbit (const COrbit &Orbit);
// CSpaceObject virtuals
virtual Categories GetCategory (void) const override { return catMarker; }
virtual const COrbit *GetMapOrbit (void) const override { return m_pMapOrbit; }
virtual CString GetNamePattern (DWORD dwNounPhraseFlags = 0, DWORD *retdwFlags = NULL) const override { if (retdwFlags) *retdwFlags = 0; return m_sName; }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return CSystem::layerEffects; }
virtual ICCItem *GetPropertyCompatible (CCodeChainCtx &Ctx, const CString &sName) const override;
virtual bool IsAnchored (void) const override { return true; }
virtual bool IsMarker (void) const override { return true; }
virtual void OnObjLeaveGate (CSpaceObject *pObj) override;
virtual bool SetProperty (const CString &sName, ICCItem *pValue, CString *retsError) override;
virtual bool ShowMapOrbit (void) const override { return (m_pMapOrbit != NULL); }
protected:
virtual bool CanHit (CSpaceObject *pObj) override { return false; }
virtual CSovereign *GetSovereign (void) const override;
virtual CString GetObjClassName (void) override { return CONSTLIT("CMarker"); }
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnPaintMap (CMapViewportCtx &Ctx, CG32bitImage &Dest, int x, int y) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
virtual void PaintLRSForeground (CG32bitImage &Dest, int x, int y, const ViewportTransform &Trans) override { }
private:
enum EStyles
{
styleNone = 0, // Invisible
styleSmallCross = 1, // Paint small cross
};
CString m_sName; // Name
CSovereign *m_pSovereign; // Sovereign
EStyles m_iStyle; // Paint style
COrbit *m_pMapOrbit; // Orbit to draw on map (may be NULL)
};
class CMissile : public TSpaceObjectImpl<OBJID_CMISSILE>
{
public:
CMissile (CUniverse &Universe);
~CMissile (void);
static ALERROR Create (CSystem &System, SShotCreateCtx &Ctx, CMissile **retpMissile);
// CSpaceObject virtuals
virtual CMissile *AsMissile (void) override { return this; }
virtual bool CanAttack (void) const override { return m_fTargetable; }
virtual bool CanBeAttacked (void) const override { return m_fTargetable; }
virtual bool CanThrust (void) const override { return (m_pDesc->GetManeuverRate() > 0); }
virtual void CreateReflection (const CVector &vPos, int iDirection, CMissile **retpReflection = NULL) override;
virtual CString DebugCrashInfo (void) override;
virtual void DetonateNow (CSpaceObject *pHit) override;
virtual CSpaceObject *GetBase (void) const override { return m_Source.GetObj(); }
virtual Categories GetCategory (void) const override;
virtual CString GetDamageCauseNounPhrase (DWORD dwFlags) override { return m_Source.GetDamageCauseNounPhrase(dwFlags); }
virtual const CDamageSource &GetDamageSource (void) const override { return m_Source; }
virtual int GetInteraction (void) const override { return m_pDesc->GetInteraction(); }
virtual int GetLastFireTime (void) const override;
virtual int GetLevel (void) const override { return m_pDesc->GetLevel(); }
virtual Metric GetMaxSpeed (void) const override { return m_pDesc->GetRatedSpeed(); }
virtual CString GetNamePattern (DWORD dwNounPhraseFlags = 0, DWORD *retdwFlags = NULL) const override;
virtual CString GetObjClassName (void) override { return CONSTLIT("CMissile"); }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return (m_pDesc->GetPassthrough() > 0 ? CSystem::layerEffects : CSystem::layerStations); }
virtual int GetRotation (void) const override { return m_iRotation; }
virtual CSpaceObject *GetSecondarySource (void) override { return m_Source.GetSecondaryObj(); }
virtual CSovereign *GetSovereign (void) const override { return m_pSovereign; }
virtual int GetStealth (void) const override;
virtual CSpaceObject *GetTarget (DWORD dwFlags = 0) const override { return m_pTarget; }
virtual CDesignType *GetType (void) const override { return m_pDesc->GetWeaponType(); }
virtual CWeaponFireDesc *GetWeaponFireDesc (void) override { return m_pDesc; }
virtual bool HasAttribute (const CString &sAttribute) const override;
virtual bool IsAngryAt (const CSpaceObject *pObj) const override;
virtual bool IsInactive (void) const override { return (m_fDestroyOnAnimationDone ? true : false); }
virtual bool IsIntangible (void) const override { return (IsInactive() || IsDestroyed()); }
virtual bool IsTargetableProjectile (void) const override { return m_fTargetable; }
virtual bool IsUnreal (void) const override { return (IsInactive() || IsSuspended() || IsDestroyed()); }
virtual void OnMove (const CVector &vOldPos, Metric rSeconds) override;
virtual void PaintLRSForeground (CG32bitImage &Dest, int x, int y, const ViewportTransform &Trans) override;
virtual bool PointInObject (const CVector &vObjPos, const CVector &vPointPos) const override;
virtual bool SetProperty (const CString &sName, ICCItem *pValue, CString *retsError) override;
protected:
// Virtuals to be overridden
virtual bool CanHit (CSpaceObject *pObj) override { return MissileCanHitObj(pObj, m_Source, m_pDesc); }
virtual void ObjectDestroyedHook (const SDestroyCtx &Ctx) override;
virtual EDamageResults OnDamage (SDamageCtx &Ctx) override;
virtual void OnDestroyed (SDestroyCtx &Ctx) override;
virtual ICCItemPtr OnFindProperty (CCodeChainCtx &CCX, const CString &sProperty) const override;
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
private:
struct SExhaustParticle
{
CVector vPos; // Position of particle
CVector vVel; // Velocity of particle
};
int ComputeVaporTrail (void);
void CreateFragments (const CVector &vPos);
int GetManeuverRate (void) const;
bool IsTracking (void) const;
bool IsTrackingTime (int iTick) const;
bool SetMissileFade (void);
CWeaponFireDesc *m_pDesc; // Weapon descriptor
TSharedPtr<CItemEnhancementStack> m_pEnhancements; // Stack of enhancements
int m_iLifeLeft; // Ticks left
int m_iHitPoints; // HP left
IEffectPainter *m_pPainter; // Effect painter
CDamageSource m_Source; // Object that fired missile
CSovereign *m_pSovereign; // Sovereign
CSpaceObject *m_pHit; // Object hit
CVector m_vHitPos; // Position hit
int m_iHitDir; // Direction hit
int m_iNextDetonation; // Detonate on this tick (-1 = none)
int m_iRotation; // Current rotation (degrees)
CSpaceObject *m_pTarget; // Target
int m_iTick; // Number of ticks of life so far
TQueue<SExhaustParticle> *m_pExhaust; // Array of exhaust particles
CG16bitBinaryRegion *m_pVaporTrailRegions; // Array of vapor trail regions
int m_iSavedRotationsCount; // Number of saved rotations
int *m_pSavedRotations; // Array of saved rotation angles
DWORD m_fDestroyOnAnimationDone:1; // TRUE if destroyed (only around to paint effect)
DWORD m_fReflection:1; // TRUE if this is a reflection
DWORD m_fDetonate:1; // TRUE if we should detonate on next update
DWORD m_fPassthrough:1; // TRUE if shot passed through
DWORD m_fPainterFade:1; // TRUE if we need to paint a fading painter
DWORD m_fFragment:1; // TRUE if we're a fragment
DWORD m_fTargetable:1; // TRUE if we can be targetted
DWORD m_dwSpareFlags:25; // Flags
// Property table
static TPropertyHandler<CMissile> m_PropertyTable;
};
class CParticleDamage : public TSpaceObjectImpl<OBJID_CPARTICLEDAMAGE>
{
public:
CParticleDamage (CUniverse &Universe);
~CParticleDamage (void);
static ALERROR Create (CSystem &System, SShotCreateCtx &Ctx, CParticleDamage **retpObj);
// CSpaceObject virtuals
virtual bool CanThrust (void) const override { return (m_pDesc->GetManeuverRate() > 0); }
virtual Categories GetCategory (void) const override;
virtual CString GetDamageCauseNounPhrase (DWORD dwFlags) override { return m_Source.GetDamageCauseNounPhrase(dwFlags); }
virtual const CDamageSource &GetDamageSource (void) const override { return m_Source; }
virtual Metric GetMaxSpeed (void) const override { return m_pDesc->GetRatedSpeed(); }
virtual CString GetNamePattern (DWORD dwNounPhraseFlags = 0, DWORD *retdwFlags = NULL) const override;
virtual CString GetObjClassName (void) override { return CONSTLIT("CParticleDamage"); }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return CSystem::layerEffects; }
virtual CSpaceObject *GetSecondarySource (void) override { return m_Source.GetSecondaryObj(); }
virtual CSovereign *GetSovereign (void) const override { return m_pSovereign; }
virtual CDesignType *GetType (void) const override { return m_pDesc->GetWeaponType(); }
virtual CWeaponFireDesc *GetWeaponFireDesc (void) override { return m_pDesc; }
virtual bool IsInactive (void) const override { return (m_fPainterFade ? true : false); }
virtual bool IsIntangible (void) const override { return ((m_fPainterFade || IsDestroyed()) ? true : false); }
virtual bool IsUnreal (void) const override { return (IsInactive() || IsSuspended() || IsDestroyed()); }
virtual void OnMove (const CVector &vOldPos, Metric rSeconds) override;
virtual bool PointInObject (const CVector &vObjPos, const CVector &vPointPos) const override;
protected:
// Virtuals to be overridden
virtual bool CanHit (CSpaceObject *pObj) override { return MissileCanHitObj(pObj, m_Source, m_pDesc); }
virtual void ObjectDestroyedHook (const SDestroyCtx &Ctx) override;
virtual EDamageResults OnDamage (SDamageCtx &Ctx) override { return damagePassthrough; }
virtual void OnDestroyed (SDestroyCtx &Ctx) override;
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
private:
// This is the origin of the particle array in object coordinates. We
// always use a fixed anchor because the motion of the particles
// determines the position of the particle damage object (and not vice
// versa, as in SFXParticleSystem).
//
// We use 0,0 as a fixed point, which works as long as we can still
// convert kilometers to pixels and still be in range. We're good for
// at least 1,000 light-minutes. [But if we ever need to scale beyond
// that, then we should set the origin to the original shot position.]
const CVector &GetOrigin (void) const { return NullVector; }
bool IsTracking (void) const;
bool SetMissileFade (void);
CWeaponFireDesc *m_pDesc; // Weapon descriptor
TSharedPtr<CItemEnhancementStack> m_pEnhancements; // Stack of enhancements
CSpaceObject *m_pTarget; // Target
int m_iTick; // Counter
int m_iLifeLeft; // Ticks left
int m_iRotation; // Initial rotation
int m_iEmitTime; // Ticks to emit new particles
CDamageSource m_Source; // Object that fired the beam
CSovereign *m_pSovereign; // Sovereign
int m_iDamage; // Damage in points
int m_iParticleCount; // Number of particles generated
CVector m_vEmitSourcePos; // Emit source position
CVector m_vEmitSourceVel; // Emit source velocity
int m_iEmitDirection; // Emit direction
IEffectPainter *m_pEffectPainter; // Additional effect
IEffectPainter *m_pParticlePainter; // Painter to use for each particle
CParticleArray m_Particles;
DWORD m_fPainterFade:1;
DWORD m_fSpare2:1;
DWORD m_fSpare3:1;
DWORD m_fSpare4:1;
DWORD m_fSpare5:1;
DWORD m_fSpare6:1;
DWORD m_fSpare7:1;
DWORD m_fSpare8:1;
DWORD m_dwSpare:24;
friend struct SParticle;
};
class CParticleEffect : public TSpaceObjectImpl<OBJID_CPARTICLEEFFECT>
{
public:
enum ParticlePainting
{
paintDot,
paintImage,
paintSmoke,
paintFlame,
};
struct SParticleType
{
SParticleType (void) :
iPaintStyle(paintDot),
rgbColor(CG32bitPixel(0xff, 0xff, 0xff)),
iRegenerationTimer(0),
iLifespan(0),
rAveSpeed(0.0),
iDirection(-1),
iDirRange(0),
rRadius(0.0),
rHoleRadius(0.0),
rDampening(1.0f),
pDamageDesc(NULL),
m_fMaxRadius(false),
m_fLifespan(false),
m_fWake(false),
m_fRegenerate(false),
m_fDrag(false),
m_fFreeDesc(false)
{ }
~SParticleType (void)
{
if (m_fFreeDesc && pDamageDesc)
delete pDamageDesc;
}
int iPaintStyle; // Painting style
CObjectImageArray Image; // Image for each particle
CG32bitPixel rgbColor; // Color of particle
int iRegenerationTimer; // Max lifespan of entire group
int iLifespan; // Max lifespan (in ticks)
Metric rAveSpeed; // Average speed of particles
int iDirection; // Direction (-1 == all directions)
int iDirRange; // Span to either side (in degrees)
Metric rRadius; // Radius of particle field
Metric rHoleRadius; // Keep particles out of the center
Metric rDampening; // Velocity dampening constant
CWeaponFireDesc *pDamageDesc; // Damage caused to objects in field
DWORD m_fMaxRadius:1; // TRUE if we should keep particles in radius
DWORD m_fLifespan:1; // TRUE if particles have a lifespan
DWORD m_fWake:1; // TRUE if particles are affected by passing objects
DWORD m_fRegenerate:1; // TRUE if particles regenerate when they die
DWORD m_fDrag:1; // TRUE if particles are subject to drag
DWORD m_fFreeDesc:1; // TRUE if we own the pDesc structure
};
CParticleEffect (CUniverse &Universe);
~CParticleEffect (void);
static ALERROR Create (CSystem &System,
CXMLElement *pDesc,
const CVector &vPos,
const CVector &vVel,
CParticleEffect **retpEffect);
static ALERROR CreateEmpty (CSystem &System,
CSpaceObject *pAnchor,
const CVector &vPos,
const CVector &vVel,
CParticleEffect **retpEffect);
static ALERROR CreateExplosion (CSystem &System,
CSpaceObject *pAnchor,
const CVector &vPos,
const CVector &vVel,
int iCount,
Metric rAveSpeed,
int iTotalLifespan,
int iParticleLifespan,
const CObjectImageArray &Image,
CParticleEffect **retpEffect);
static ALERROR CreateGeyser (CSystem &System,
CSpaceObject *pAnchor,
const CVector &vPos,
const CVector &vVel,
int iTotalLifespan,
int iParticleCount,
ParticlePainting iParticleStyle,
int iParticleLifespan,
Metric rAveSpeed,
int iDirection,
int iAngleWidth,
CParticleEffect **retpEffect);
void AddGroup (SParticleType *pType, int iCount);
// CSpaceObject virtuals
virtual bool CanBeHitBy (const DamageDesc &Damage) override;
virtual bool CanMove (void) const { return true; }
virtual CString GetNamePattern (DWORD dwNounPhraseFlags = 0, DWORD *retdwFlags = NULL) const override { if (retdwFlags) *retdwFlags = 0; return m_sName; }
virtual CString GetObjClassName (void) override { return CONSTLIT("CParticleEffect"); }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return CSystem::layerSpace; }
virtual bool IsAnchored (void) const override { return (m_pAnchor != NULL); }
virtual void PaintLRSForeground (CG32bitImage &Dest, int x, int y, const ViewportTransform &Trans) override;
protected:
// Virtuals to be overridden
virtual bool CanHit (CSpaceObject *pObj) override { return false; }
virtual void ObjectDestroyedHook (const SDestroyCtx &Ctx) override;
virtual EDamageResults OnDamage (SDamageCtx &Ctx) override;
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
virtual void OnMove (const CVector &vOldPos, Metric rSeconds) override;
virtual bool PointInObject (const CVector &vObjPos, const CVector &vPointPos) const override;
private:
enum Constants
{
ctMaxParticleGroups = 8,
ctMaxObjsInField = 16,
};
struct SParticle
{
bool IsValid (void) { return iLifeLeft != -1; }
int iDestiny;
int iLifeLeft;
CVector vPos;
CVector vVel;
};
struct SParticleArray
{
~SParticleArray (void)
{
if (pType)
delete pType;
if (pParticles)
delete [] pParticles;
}
SParticleType *pType;
int iAlive;
int iCount;
SParticle *pParticles;
SParticleArray *pNext;
};
void CreateGroup (SParticleType *pType, int iCount, SParticleArray **retpGroup);
void PaintFlameParticles (SParticleArray *pGroup, CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx);
void PaintSmokeParticles (SParticleArray *pGroup, CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx);
void SetParticleSpeed (SParticleType *pType, SParticle *pParticle);
CString m_sName;
SParticleArray *m_pFirstGroup;
CSpaceObject *m_pAnchor;
};
class CPOVMarker : public TSpaceObjectImpl<OBJID_CPOVMARKER>
{
public:
CPOVMarker (CUniverse &Universe);
static ALERROR Create (CSystem &System,
const CVector &vPos,
const CVector &vVel,
CPOVMarker **retpMarker);
virtual bool IsAnchored (void) const override { return true; }
protected:
virtual bool CanHit (CSpaceObject *pObj) override { return false; }
virtual CSovereign *GetSovereign (void) const override;
virtual void OnLosePOV (void) override;
virtual CString GetObjClassName (void) override { return CONSTLIT("CPOVMarker"); }
virtual void PaintLRSForeground (CG32bitImage &Dest, int x, int y, const ViewportTransform &Trans) override { }
private:
};
class CRadiusDamage : public TSpaceObjectImpl<OBJID_CRADIUSDAMAGE>
{
public:
CRadiusDamage (CUniverse &Universe);
~CRadiusDamage (void);
static ALERROR Create (CSystem &System, SShotCreateCtx &Ctx, CRadiusDamage **retpObj);
// CSpaceObject virtuals
virtual CString DebugCrashInfo (void) override;
virtual CString GetDamageCauseNounPhrase (DWORD dwFlags) override { return m_Source.GetDamageCauseNounPhrase(dwFlags); }
virtual const CDamageSource &GetDamageSource (void) const override { return m_Source; }
virtual CString GetNamePattern (DWORD dwNounPhraseFlags = 0, DWORD *retdwFlags = NULL) const override;
virtual CString GetObjClassName (void) override { return CONSTLIT("CRadiusDamage"); }
virtual CSystem::LayerEnum GetPaintLayer (void) const override { return CSystem::layerEffects; }
virtual CSpaceObject *GetSecondarySource (void) override { return m_Source.GetSecondaryObj(); }
virtual CSovereign *GetSovereign (void) const override { return m_pSovereign; }
virtual CDesignType *GetType (void) const override { return m_pDesc->GetWeaponType(); }
virtual CWeaponFireDesc *GetWeaponFireDesc (void) override { return m_pDesc; }
virtual void OnMove (const CVector &vOldPos, Metric rSeconds) override;
virtual void OnSystemLoaded (void) override;
virtual bool PointInObject (const CVector &vObjPos, const CVector &vPointPos) const override;
protected:
// Virtuals to be overridden
virtual bool CanHit (CSpaceObject *pObj) override { return MissileCanHitObj(pObj, m_Source, m_pDesc); }
virtual void ObjectDestroyedHook (const SDestroyCtx &Ctx) override;
virtual EDamageResults OnDamage (SDamageCtx &Ctx) override { return damagePassthrough; }
virtual void OnDestroyed (SDestroyCtx &Ctx) override;
virtual void OnPaint (CG32bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx) override;
virtual void OnReadFromStream (SLoadCtx &Ctx) override;
virtual void OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) override;
virtual void OnWriteToStream (IWriteStream *pStream) override;
private:
void DamageAll (SUpdateCtx &Ctx);
CWeaponFireDesc *m_pDesc; // Weapon descriptor
TSharedPtr<CItemEnhancementStack> m_pEnhancements; // Stack of enhancements
IEffectPainter *m_pPainter; // Effect painter
int m_iTick; // Counter
int m_iLifeLeft; // Ticks left
CDamageSource m_Source; // Object that fired the shot
CSpaceObject *m_pTarget; // Target
CSovereign *m_pSovereign; // Sovereign
};
class CShip : public TSpaceObjectImpl<OBJID_CSHIP>
{
public:
enum RemoveDeviceStatus
{
remOK = 0, // Can remove this device
remTooMuchCargo = 1, // Can't remove cargo expansion (because too much cargo)
remNotInstalled = 2, // Device is not installed
remReplaceOnly = 3, // Device can be replaced but not removed
remCannotRemove = 4, // Custom reason
};
struct SAttachedSectionInfo
{
CShip *pObj;
int iHP; // Total hit points (all armor segments)
int iMaxHP; // Max hit points
CVector vPos; // Origin is center of image, scaled to unit vector
};
CShip (CUniverse &Universe);
virtual ~CShip (void);
static ALERROR CreateFromClass (CSystem &System,
CShipClass *pClass,
IShipController *pController,
CDesignType *pOverride,
CSovereign *pSovereign,
const CVector &vPos,
const CVector &vVel,
int iRotation,
SShipGeneratorCtx *pCtx,
CShip **retpShip);
// Orders
void CancelCurrentOrder (void) { m_pController->CancelCurrentOrder(); }
IShipController::OrderTypes GetCurrentOrder (CSpaceObject **retpTarget = NULL, IShipController::SData *retData = NULL) const { return m_pController->GetCurrentOrderEx(retpTarget, retData); }
DWORD GetCurrentOrderData (void) { return m_pController->GetCurrentOrderData(); }
// Armor methods
CInstalledArmor *GetArmorSection (int iSect) { return &m_Armor.GetSegment(iSect); }
int GetArmorSectionCount (void) const { return m_Armor.GetSegmentCount(); }
int DamageArmor (int iSect, DamageDesc &Damage);
void InstallItemAsArmor (CItemListManipulator &ItemList, int iSect);
bool IsArmorDamaged (int iSect);
void RepairArmor (int iSect, int iHitPoints, int *retiHPRepaired = NULL);
bool SetCursorAtArmor (CItemListManipulator &ItemList, int iSect) const;
void UninstallArmor (CItemListManipulator &ItemList);
// Compartments
virtual bool IsMultiHull (void) const override { return m_pClass->GetInteriorDesc().IsMultiHull(); }
void GetAttachedSectionInfo (TArray<SAttachedSectionInfo> &Result) const;
bool HasAttachedSections (void) const { return m_fHasShipCompartments; }
bool IsShipSection (void) const { return m_fShipCompartment; }
bool RepairInterior (int iRepairHP) { return m_Interior.RepairHitPoints(this, m_pClass->GetInteriorDesc(), iRepairHP); }
void SetAsShipSection (CShip *pMain);
// Device methods