2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
6 // $Header: r:/t2repos/thief2/src/actreact/ssrclife.cpp,v 1.5 1998/10/05 17:28:14 mahk Exp $
13 // Must be last header
17 ////////////////////////////////////////////////////////////
18 // PERIODIC LIFE CYCLE IMPL
21 //------------------------------------------------------------
25 static const char* periodic_flags
[] =
28 "Destroy Object on Completion"
31 #define NUM_PERIODIC_FLAGS (sizeof(periodic_flags)/sizeof(periodic_flags[0]))
34 static sFieldDesc periodic_fields
[] =
36 { "Flags", kFieldTypeBits
, FieldLocation(sPeriodicLifeCycle
,flags
), kFieldFlagNone
, 0, NUM_PERIODIC_FLAGS
, NUM_PERIODIC_FLAGS
, periodic_flags
},
37 { "Period", kFieldTypeInt
, FieldLocation(sPeriodicLifeCycle
,period
), kFieldFlagUnsigned
},
38 { "Max Firings", kFieldTypeInt
, FieldLocation(sPeriodicLifeCycle
,max_firings
) },
39 { "Intensity Slope", kFieldTypeFloat
, FieldLocation(sPeriodicLifeCycle
,slope
) },
42 static sStructDesc periodic_sdesc
= StructDescBuild(sPeriodicLifeCycle
,kStructFlagNone
,periodic_fields
);
44 const sStructDesc
* sPeriodicLifeCycle::gpDesc
= &periodic_sdesc
;
46 //------------------------------------------------------------
50 struct sPeriodicLifeCycleFire
53 sPeriodicLifeCycle
& life
;
55 typedef tStimTimeStamp tTime
;
63 // iteration variables
69 sPeriodicLifeCycleFire(sPeriodicLifeCycle
* plife
, BOOL initial
, tStimLevel lv
, tTime s
, tTime l
, tTime n
)
70 : start(s
),last(l
),now(n
), i (0),life(*plife
),level(lv
)
73 // handle zero period case somewhat gracefully...
76 Warning(("Stim source has zero-length period\n"));
80 // convert period to freq so we don't have to divide twice
81 // @NOTE: possible precision issue.
82 float freq
= 1.0/life
.period
;
84 if (last
< start
) last
= start
;
92 // how many times we've already fired.
93 int fired
= (last
- start
) * freq
;
94 to_fire
= (now
- start
) * freq
;
96 // special case: send an event at the first firing
101 if (!(life
.flags
& sPeriodicLifeCycle::kNoMaxFirings
))
103 if (fired
>= life
.max_firings
)
104 to_fire
= 0; // we're expired
105 else if (to_fire
>= life
.max_firings
)
106 to_fire
= life
.max_firings
;
110 t
= start
+ life
.period
* fired
;
112 level
+= i
* life
.slope
;
116 BOOL
Next(tStimLevel
* plev
, tTime
* pt
, ulong
* flags
)
130 ulong destroy_mask
= sPeriodicLifeCycle::kNoMaxFirings
|sPeriodicLifeCycle::kDestroy
;
132 // destroy set but not no max firings
133 if ((life
.flags
& destroy_mask
) == sPeriodicLifeCycle::kDestroy
134 && i
== life
.max_firings
)
135 *flags
|= kStimDestroySrcObj
;
141 sPeriodicLifeCycle::sFire
* sPeriodicLifeCycle::BeginFiring(BOOL initial
,
143 tStimTimeStamp start
,
147 return new sFire(this,initial
,level
,start
,last
,now
);
150 BOOL
sPeriodicLifeCycle::FireNext(sFire
* fire
, tStimLevel
* nextlevel
, tStimTimeStamp
* nexttime
, ulong
* flags
)
153 return fire
->Next(nextlevel
,nexttime
,flags
);
156 BOOL
sPeriodicLifeCycle::EndFiring(sFire
* fire
)
158 BOOL retval
= (flags
& kNoMaxFirings
) || fire
->i
< max_firings
;