66#include " zBase.h"
77#include " zNPCTypeCommon.h"
88#include " zEntDestructObj.h"
9+ #include " containers.h"
910
1011#include < types.h>
1112
@@ -47,6 +48,29 @@ void xLaserBoltEmitter::set_texture(RwRaster* raster)
4748
4849void xLaserBoltEmitter::reset ()
4950{
51+ static_queue<bolt>::iterator it = this ->bolts .begin ();
52+ while (it != this ->bolts .end ())
53+ {
54+ bolt& b = *it;
55+
56+ effect_data* itfx = this ->fx [6 ];
57+ effect_data* endfx = itfx + this ->fxsize [6 ];
58+ while (itfx != endfx)
59+ {
60+ emit_fx (*itfx, b, b.hit_dist , b.hit_dist , (1 .0f / 60 .0f ));
61+ itfx++;
62+ }
63+
64+ ++it;
65+ }
66+
67+ this ->bolts .clear ();
68+ start_collide = 0 ;
69+
70+ for (S32 i = FX_WHEN_LAUNCH; i < MAX_FX_WHEN; i++)
71+ {
72+ reset_fx ((fx_when_enum)i);
73+ }
5074}
5175
5276void xLaserBoltEmitter::refresh_config ()
@@ -63,6 +87,99 @@ void xLaserBoltEmitter::refresh_config()
6387 this ->ialpha = alpha;
6488}
6589
90+ void xLaserBoltEmitter::emit (const xVec3& loc, const xVec3& dir)
91+ {
92+ if (this ->bolts .full ())
93+ {
94+ this ->bolts .pop_back ();
95+ }
96+
97+ bolt& b = this ->bolts .push_front ();
98+ b.origin = b.loc = loc;
99+ b.dir = dir;
100+ b.dist = b.prev_dist = b.prev_check_dist = 0 .0f ;
101+ b.hit_dist = cfg.kill_dist ;
102+ b.hit_ent = NULL ;
103+ b.emitted = 0 .0f ;
104+ b.context = NULL ;
105+
106+ if (cfg.rand_ang > 0 .0f )
107+ {
108+ perturb_dir (b.dir , cfg.rand_ang );
109+ }
110+
111+ if (cfg.hit_interval > 0 )
112+ {
113+ pre_collide (b);
114+ }
115+
116+ start_collide++;
117+
118+ effect_data* fx = this ->fx [0 ];
119+ effect_data* fx_end = fx + this ->fxsize [0 ];
120+ while (fx != fx_end)
121+ {
122+ emit_fx (*fx, b, 0 .0f , 0 .0f , (1 .0f / 60 .0f ));
123+ fx++;
124+ }
125+ }
126+
127+ void xLaserBoltEmitter::update (F32 dt)
128+ {
129+ debug_update (dt);
130+
131+ if (start_collide)
132+ {
133+
134+ }
135+ else
136+ {
137+
138+ }
139+
140+ static_queue<bolt>::iterator it;
141+ while (it != this ->bolts .end ())
142+ {
143+ bolt& b = *it;
144+
145+ update (b, dt);
146+
147+ U8 collided;
148+ F32 prev_dist;
149+ effect_data* itfx;
150+ effect_data* endfx;
151+ // effect_data* itfx;
152+ // effect_data* endfx;
153+ }
154+ }
155+
156+ void xLaserBoltEmitter::render ()
157+ {
158+ debug_render ();
159+
160+ RxObjSpace3DVertex* vert;
161+ RxObjSpace3DVertex* v = get_vert_buffer (*(S32*)&vert);
162+
163+ RwRenderStateSet (rwRENDERSTATETEXTURERASTER, bolt_raster);
164+
165+ static_queue<bolt>::iterator it = bolts.begin ();
166+ while (it != bolts.end ())
167+ {
168+ if ((S32)(v - (v - vert)) < 6 )
169+ {
170+ flush_verts (v, (S32)(v - (v - vert)));
171+ }
172+
173+ render (*it, v);
174+ ++it;
175+ }
176+
177+ if (v != vert)
178+ {
179+ flush_verts (v, vert - v);
180+ }
181+ }
182+
66183void xLaserBoltEmitter::attach_effects (fx_when_enum when, effect_data* fx, size_t fxsize)
67184{
68185 this ->fx [when] = fx;
@@ -71,6 +188,56 @@ void xLaserBoltEmitter::attach_effects(fx_when_enum when, effect_data* fx, size_
71188 debug_refresh_effects (when);
72189}
73190
191+ void xLaserBoltEmitter::pre_collide (bolt& b)
192+ {
193+ xVec3 origin;
194+ xVec3 dir;
195+ xCollis coll;
196+
197+ origin = b.origin ;
198+ dir = b.dir ;
199+ xRayHitsSceneFlags (globals.sceneCur , (xRay3*)&origin, &coll, XENT_COLLTYPE_PLYR, 0x22 );
200+
201+ if (coll.flags & 0x1 )
202+ {
203+ b.hit_dist = coll.dist ;
204+ b.hit_norm = coll.norm ;
205+ }
206+
207+ log_collide_statics (coll.flags & 0x1 );
208+ }
209+
210+ RxObjSpace3DVertex* xLaserBoltEmitter::render (bolt& b, RxObjSpace3DVertex *vert)
211+ {
212+ F32 dist0 = b.prev_dist - this ->cfg .length ;
213+ if (dist0 < 0 .0f )
214+ {
215+ dist0 = 0 .0f ;
216+ }
217+
218+ F32 dist1 = b.dist ;
219+ if (dist1 <= b.hit_dist )
220+ {
221+ dist1 = dist0;
222+ }
223+
224+ if (dist0 < dist1)
225+ {
226+ return vert;
227+ }
228+
229+ xVec3 loc0 = b.origin + b.dir * dist0;
230+ xVec3 loc1 = b.dir * dist0;
231+ // xMat4x3 &cam_mat;
232+ xVec3 dir;
233+ xVec3 right;
234+ xVec3 half_right;
235+
236+
237+ set_bolt_verts (vert, loc0, loc1, 0xFF , half_right);
238+ return vert;
239+ }
240+
74241RxObjSpace3DVertex* xLaserBoltEmitter::get_vert_buffer (S32& dat)
75242{
76243 dat = (U32)0x1e0 ;
@@ -94,14 +261,167 @@ void xLaserBoltEmitter::apply_damage(xLaserBoltEmitter::bolt& b)
94261 }
95262}
96263
97- // WIP.
98264void xLaserBoltEmitter::reset_fx (fx_when_enum when)
99265{
100- for (U32 i = 0 ; i < sizeof (fx); i++)
101- {
102- U32* sizePtr = &this ->fxsize [when];
103- effect_data** effect = &this ->fx [when];
266+ effect_data* cur_fx = this ->fx [when];
267+ effect_data* fx_end = cur_fx + this ->fxsize [when];
268+ while (cur_fx != fx_end)
269+ {
270+ cur_fx->irate = cur_fx->rate > 0 .0f ? 1 .0f / cur_fx->rate : 0 .0f ;
271+ cur_fx++;
272+ }
273+ }
104274
275+ void xLaserBoltEmitter::update_fx (bolt& b, F32 prev_dist, F32 dt)
276+ {
277+ F32 tail_dist = b.dist - this ->cfg .length ;
278+ if (b.dist < this ->cfg .length )
279+ {
280+ effect_data* itfx = this ->fx [2 ];
281+ effect_data* endfx = itfx + this ->fxsize [2 ];
282+ while (itfx != endfx)
283+ {
284+ emit_fx (*itfx, b, 0 .0f , 0 .0f , dt);
285+ itfx++;
286+ }
287+ }
288+ else if (tail_dist < b.hit_dist )
289+ {
290+ F32 from_dist = prev_dist - this ->cfg .length ;
105291
292+ effect_data* itfx = this ->fx [5 ];
293+ effect_data* endfx = itfx + this ->fxsize [5 ];
294+ if (from_dist < 0 .0f )
295+ {
296+ from_dist = 0 .0f ;
297+ }
298+
299+ while (itfx != endfx)
300+ {
301+ emit_fx (*itfx, b, from_dist, tail_dist, dt);
302+ itfx++;
303+ }
304+ }
305+
306+ if (b.dist < b.hit_dist )
307+ {
308+ effect_data* itfx = this ->fx [4 ];
309+ effect_data* endfx = itfx + this ->fxsize [4 ];
310+ while (itfx != endfx)
311+ {
312+ emit_fx (*itfx, b, prev_dist, b.dist , dt);
313+ itfx++;
314+ }
315+ }
316+ else if (tail_dist < b.hit_dist )
317+ {
318+ effect_data* itfx = this ->fx [3 ];
319+ effect_data* endfx = itfx + this ->fxsize [3 ];
320+ while (itfx != endfx)
321+ {
322+ emit_fx (*itfx, b, b.hit_dist , b.hit_dist , dt);
323+ itfx++;
324+ }
325+ }
326+ }
327+
328+ void xLaserBoltEmitter::emit_particle (effect_data& effect, bolt& b, F32 from_dist, F32 to_dist, F32 dt)
329+ {
330+ xParEmitter& pe = *effect.par ;
331+ xParEmitterAsset& pea = *pe.tasset ;
332+ F32 velmag = pea.vel .y ;
333+
334+ switch (effect.orient )
335+ {
336+ case FX_ORIENT_PATH:
337+ pea.vel = b.dir * velmag;
338+ break ;
339+ case FX_ORIENT_IPATH:
340+ pea.vel = b.dir * -velmag;
341+ break ;
342+ case FX_ORIENT_HIT_NORM:
343+ pea.vel = b.hit_norm * velmag;
344+ break ;
345+ case FX_ORIENT_HIT_REFLECT:
346+ break ;
347+ }
348+
349+ if (pea.emit_type == eParEmitterLine)
350+ {
351+ pea.e_line .pos1 = b.origin + b.dir * from_dist;
352+ pea.e_line .pos2 = b.origin + b.dir * to_dist;
353+ xParEmitterEmit (&pe, dt);
354+ }
355+ else
356+ {
357+ xVec3 oldloc = pea.pos ;
358+ pea.pos += b.origin + b.dir * to_dist;
359+
360+ xParEmitterEmit (&pe, dt);
361+ pea.pos = oldloc;
362+ }
363+ }
364+
365+ void xLaserBoltEmitter::emit_decal (effect_data& effect, bolt& b, F32 from_dist, F32 to_dist, F32 dt)
366+ {
367+ xMat4x3 mat;
368+
369+ switch (effect.orient )
370+ {
371+ case FX_ORIENT_DEFAULT:
372+ case FX_ORIENT_PATH:
373+ case FX_ORIENT_IPATH:
374+ xMat3x3LookVec3 (mat, b.dir );
375+ break ;
376+ case FX_ORIENT_HIT_NORM:
377+ xMat3x3LookVec3 (mat, b.hit_norm );
378+ break ;
379+ case FX_ORIENT_HIT_REFLECT:
380+ break ;
381+ }
382+
383+ mat.pos = b.origin + b.dir * to_dist;
384+ effect.decal ->emit (mat, -1 );
385+ }
386+
387+ void xLaserBoltEmitter::emit_decal_dist (effect_data& effect, bolt& b, F32 from_dist, F32 to_dist, F32 dt)
388+ {
389+ F32 start_dist = to_dist - from_dist;
390+ b.emitted = effect.rate * start_dist + b.emitted ;
391+
392+ S32 total = effect.rate * start_dist + b.emitted ;
393+ b.emitted -= total;
394+
395+ if (total <= 0 )
396+ {
397+ return ;
398+ }
399+
400+ xMat4x3 mat;
401+ switch (effect.orient )
402+ {
403+ case FX_ORIENT_DEFAULT:
404+ case FX_ORIENT_PATH:
405+ case FX_ORIENT_IPATH:
406+ xMat3x3LookVec3 (mat, b.dir );
407+ break ;
408+ case FX_ORIENT_HIT_NORM:
409+ xMat3x3LookVec3 (mat, b.hit_norm );
410+ break ;
411+ case FX_ORIENT_HIT_REFLECT:
412+ break ;
413+ }
414+
415+ xVec3 dloc = b.dir * effect.irate ;
416+ mat.pos = b.origin + b.dir * start_dist;
417+ for (S32 i = 0 ; i < total; i++)
418+ {
419+ if (((xDecalEmitter*)effect.par )->full ())
420+ {
421+ break ;
422+ }
423+
424+ ((xDecalEmitter*)effect.par )->emit (mat, -1 );
425+ mat.pos += dloc;
106426 }
107427}
0 commit comments