11#include " xBase.h"
22#include " xEnt.h"
33#include " xLinkAsset.h"
4+ #include " xEntMotion.h"
45#include " xString.h"
56#include " zParEmitter.h"
7+ #include " zGlobals.h"
68#include < types.h>
79
810#include " zEntHangable.h"
@@ -12,6 +14,9 @@ static zParEmitter* sCandleSmokeEmitter;
1214static U32 sChandelierHash ;
1315static zParEmitter* sMountEmitter ;
1416
17+ static void zEntHangable_Update (zEntHangable* ent, xScene*, F32 dt);
18+ S32 zEntHangableEventCB (xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase*);
19+
1520void zEntHangable_SetupFX ()
1621{
1722 sCandleEmitter = zParEmitterFind (" PAREMIT_CHAND_CANDLE" );
@@ -22,9 +27,41 @@ void zEntHangable_SetupFX()
2227
2328static void HangableSetup (zEntHangable* ent, xEntAsset* asset)
2429{
25- xEntHangableAsset* hangAsset;
30+ xEntHangableAsset* hangAsset = (xEntHangableAsset *)(&asset[ 1 ]) ;
2631 xVec3* center;
2732 xMat3x3 hackMat;
33+
34+ ent->pflags = 0 ;
35+ ent->chkby = 0 ;
36+ ent->penby = 0 ;
37+ ent->update = (xEntUpdateCallback)zEntHangable_Update;
38+ ent->move = NULL ;
39+ ent->eventFunc = zEntHangableEventCB;
40+ ent->hangInfo = hangAsset;
41+ center = &ent->asset ->pos ;
42+ ent->pivot .x = center[0 ].x ;
43+ ent->pivot .y = center[0 ].y + hangAsset->pivotOffset ;
44+ ent->pivot .z = center[0 ].z ;
45+ ent->endpos .x = center[0 ].x ;
46+ ent->endpos .y = ent->pivot .y - hangAsset->leverArm ;
47+ ent->endpos .z = center[0 ].z ;
48+ ent->vel .x = 0 .0f ;
49+ ent->vel .y = 0 .0f ;
50+ ent->vel .z = 0 .0f ;
51+ ent->grabTimer = 0 .0f ;
52+ ent->spin = 0 .0f ;
53+ ent->state = 0 ;
54+ ent->shaggy = NULL ;
55+ ent->follow = NULL ;
56+ ent->enabled = 1 ;
57+ ent->moving = 0 ;
58+ ent->candle_timer = 3 .0f ;
59+ ent->candle_state = 0 ;
60+ center = &ent->asset ->ang ;
61+ xMat3x3Euler (&hackMat, center[0 ].x , center[0 ].y , center[0 ].z );
62+ ent->swingplane .x = hackMat.right .x ;
63+ ent->swingplane .y = hackMat.right .y ;
64+ ent->swingplane .z = hackMat.right .z ;
2865}
2966
3067void zEntHangable_Init (void * a, void * b)
@@ -38,8 +75,8 @@ void zEntHangable_Init(zEntHangable* ent, xEntAsset* asset)
3875
3976 if (ent->linkCount )
4077 {
41- // TODO: Not quite correct
42- ent->link = (xLinkAsset*)(ent-> asset + 1 );
78+ xEnt* next = (xEnt*)&((xEntMotion*)(ent-> asset ))[ 1 ]; // Not in DWARF, but anything to make this less of an eyesore.
79+ ent->link = (xLinkAsset*)(&next-> link ); // Maybe...???
4380 }
4481 else
4582 {
@@ -51,33 +88,87 @@ void zEntHangable_Init(zEntHangable* ent, xEntAsset* asset)
5188
5289static void zEntHangable_UpdateFX (zEntHangable* ent)
5390{
54- xVec3 offset_rlii0006[8 ];
91+ // Points of a (wobbly) circle in 3D space.
92+ xVec3 offset_rlii0006[8 ] =
93+ {
94+ { 0.0 , 0.561 , 0.613 },
95+ { 0.43345639 , 0.432 , 0.43345639 },
96+ { 0.613 , 0.543 , 0.0 },
97+ { 0.43345639 , 0.526 , -0.43345639 },
98+ { 0.0 , 0.526 , -0.613 },
99+ { -0.43345639 , 0.505 , -0.43345639 },
100+ { -0.613 , 0.543 , 0.0 },
101+ { -0.43345639 , 0.48 , 0.4334563 }
102+ };
103+
55104 xVec3* local_offset;
56105 xParEmitterCustomSettings info;
57106 zParEmitter* emitter;
58- S32 i;
107+
108+ if ((ent->flags & 1 ) && (ent->asset ->modelInfoID == sChandelierHash ))
109+ {
110+ local_offset = &offset_rlii0006[0 ];
111+
112+ // Missing unreachable branches here.
113+ if (ent->candle_state == 2 )
114+ {
115+ return ;
116+ }
117+
118+ info.custom_flags = 0x100 ;
119+
120+ if (ent->candle_state == 0 )
121+ {
122+ emitter = sCandleEmitter ;
123+ }
124+ else
125+ {
126+ emitter = sCandleSmokeEmitter ;
127+ }
128+
129+ for (S32 i = 0 ; i < sizeof (offset_rlii0006) / sizeof (xVec3); i++)
130+ {
131+ xVec3 mul;
132+ xMat3x3RMulVec (&mul, xEntGetFrame (ent), &local_offset[i]);
133+ xVec3Add (&info.pos , &mul, xEntGetPos (ent));
134+ xParEmitterEmitCustom (emitter, (1 .0f / 30 .0f ), &info);
135+ }
136+ }
59137}
60138
61139void zEntHangable_Update (zEntHangable* ent, xScene*, F32 dt)
62140{
63141 xVec3 unitHang;
64142}
65143
66- static void zEntHangableMountFX (zEntHangable*)
144+ // Equivalent; scheduling.
145+ static void zEntHangableMountFX (zEntHangable* ent)
67146{
68- }
147+ xParEmitterCustomSettings info;
69148
70- S32 zEntHangableEventCB (xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase*)
71- {
72- zEntHangable* ent; // r20
73- zEnt* follow; // r2
74- // FloatAndVoid dist; // r29+0x20C
75- return 0 ;
149+ if (sMountEmitter != NULL )
150+ {
151+ info.custom_flags = 0x300 ;
152+ for (S32 i = 0 ; i < 10 ; i++)
153+ {
154+ info.pos = ent->pivot ;
155+ info.vel .x = 0 .0f ;
156+ info.vel .y = -(xurand () * 2 .0f - -2 .0f );
157+ info.vel .z = 0 .0f ;
158+ xParEmitterEmitCustom (sMountEmitter , (1 .0f / 30 .0f ), &info);
159+ }
160+ }
76161}
77162
78163static bool HangableIsMovingTooMuch (xVec3* a, xVec3* b, xVec3* c, xVec3* d)
79164{
80- return false ;
165+ F32 dist = ((d->x * d->x ) + (d->y * d->y ) + (d->z * d->z )) -
166+ ((c->x * c->x ) + (c->y * c->y ) + (c->z * c->z ));
167+ if ((dist > 20 .0f ) || (dist < -20 .0f ))
168+ {
169+ return 1 ;
170+ }
171+ return 0 ;
81172}
82173
83174void zEntHangable_SetMatrix (zEntHangable* ent, F32 f)
@@ -102,18 +193,85 @@ void zEntHangable_Reset(zEntHangable* ent)
102193 HangableSetup (ent, ent->asset );
103194}
104195
105- void zEntHangable_SetShaggy (zEntHangable* ent, zEnt* b )
196+ void zEntHangable_SetShaggy (zEntHangable* ent, zEnt* shaggy )
106197{
198+ if (shaggy != NULL )
199+ {
200+ if (ent->shaggy == NULL )
201+ {
202+ ent->shaggy = shaggy;
203+ shaggy->frame ->mode = 1 ;
204+ shaggy->frame ->vel .x = 0 .0f ;
205+ shaggy->frame ->vel .y = 0 .0f ;
206+ shaggy->frame ->vel .z = 0 .0f ;
207+ shaggy->frame ->mat .pos .x = ent->model ->Mat ->pos .x ;
208+ shaggy->frame ->mat .pos .z = ent->model ->Mat ->pos .z ;
209+ *shaggy->model ->Mat = *(RwMatrixTag *)(&shaggy->frame ->mat );
210+ }
211+ }
212+ else if (ent->shaggy != NULL )
213+ {
214+ ent->shaggy = NULL ;
215+ }
107216}
108217
109218void zEntHangable_FollowUpdate (zEntHangable* ent)
110219{
111220 xVec3* center;
221+ xVec3 delta;
222+ xVec3 pivot;
223+
224+ if (ent->follow == NULL )
225+ {
226+ return ;
227+ }
228+
229+ xEntHangableAsset* hang = (xEntHangableAsset *)(&ent->asset [1 ]);
230+
231+ center = (xVec3*)(&ent->follow ->model ->Mat ->pos );
232+ pivot.x = center->x ;
233+ pivot.y = center->y + hang->pivotOffset ;
234+ pivot.z = center->z ;
235+
236+ delta.x = pivot.x - ent->pivot .x ;
237+ delta.y = pivot.y - ent->pivot .y ;
238+ delta.z = pivot.z - ent->pivot .z ;
239+
240+ ent->pivot = pivot;
241+
242+ if (globals.player .HangEnt == ent)
243+ {
244+ globals.player .HangPivot = pivot;
245+ globals.player .ent .model ->Mat ->pos .x += delta.x ;
246+ globals.player .ent .model ->Mat ->pos .y += delta.y ;
247+ globals.player .ent .model ->Mat ->pos .z += delta.z ;
248+ }
249+
250+ ent->endpos .x += delta.x ;
251+ ent->endpos .y += delta.y ;
252+ ent->endpos .z += delta.z ;
253+
254+ center = (xVec3*)(&ent->model ->Mat ->pos );
255+ center->x += delta.x ;
256+ center = (xVec3*)(&ent->model ->Mat ->pos );
257+ center->y += delta.y ;
258+ center = (xVec3*)(&ent->model ->Mat ->pos );
259+ center->z += delta.z ;
260+
261+ if (ent->shaggy != NULL )
262+ {
263+ center = (xVec3*)(&ent->shaggy ->model ->Mat ->pos );
264+ center->x += delta.x ;
265+ center = (xVec3*)(&ent->shaggy ->model ->Mat ->pos );
266+ center->y += delta.y ;
267+ center = (xVec3*)(&ent->shaggy ->model ->Mat ->pos );
268+ center->z += delta.z ;
269+ }
112270}
113271
114272void zEntHangable_SetFollow (zEntHangable* ent, zEnt* b)
115273{
116- if (b)
274+ if (b != NULL )
117275 {
118276 ent->follow = b;
119277 zEntHangable_FollowUpdate (ent);
0 commit comments