1818#include < assert.h>
1919#include < stdio.h>
2020
21- // TODO: register for lvz packets and update objects
22-
2321namespace null {
2422
2523#define MAKE_MAGIC (c1, c2, c3, c4 ) (c1 | c2 << 8 | c3 << 16 | c4 << 24 )
@@ -209,11 +207,24 @@ LvzController::LvzController(MemoryArena& perm_arena, MemoryArena& temp_arena, F
209207 dispatcher.Register (ProtocolS2C::ModifyLVZ, OnLvzModifyPkt, this );
210208}
211209
210+ LvzObject* LvzController::FindObjectById (u16 id) {
211+ for (size_t i = 0 ; i < object_count; ++i) {
212+ LvzObject* check = objects + i;
213+ if (check->object_id == id) {
214+ return check;
215+ }
216+ }
217+ return nullptr ;
218+ }
219+
212220void LvzController::Update (float dt) {
213221 for (size_t i = 0 ; i < animation_count; ++i) {
214222 Animation* anim = animations + i;
215223
216224 anim->t += dt;
225+ if (anim->t >= anim->GetDuration ()) {
226+ anim->t -= anim->GetDuration ();
227+ }
217228 }
218229
219230 u32 tick = GetCurrentTick ();
@@ -250,7 +261,7 @@ void LvzController::Render(Camera& ui_camera, Camera& game_camera, Player* self,
250261 Vector2f base_y = GetScreenReferencePoint (*self, specview, ui_camera, reference_y);
251262
252263 Vector2f position (base_x.x + (float )obj->x_screen , base_y.y + (float )obj->y_screen );
253- Animation* anim = animations + obj->animation_index ;
264+ Animation* anim = animations + obj->animation_base + obj-> image_index ;
254265
255266 if (anim->sprite ->frames == nullptr ) continue ;
256267
@@ -263,7 +274,7 @@ void LvzController::Render(Camera& ui_camera, Camera& game_camera, Player* self,
263274 LvzObject* obj = active_map_objects[i];
264275
265276 Vector2f position (obj->x_map / 16 .0f , obj->y_map / 16 .0f );
266- Animation* anim = animations + obj->animation_index ;
277+ Animation* anim = animations + obj->animation_base + obj-> image_index ;
267278
268279 if (anim->sprite ->frames == nullptr ) continue ;
269280
@@ -292,7 +303,7 @@ void LvzController::OnLvzToggle(u8* pkt, size_t size) {
292303 // Disable any previous ones with this id before adding it in again
293304 DisableObject (toggle->id );
294305
295- animations[obj->animation_index ].t = 0 .0f ;
306+ animations[obj->animation_base + obj-> image_index ].t = 0 .0f ;
296307 obj->enabled_tick = GetCurrentTick ();
297308
298309 if (obj->map_object ) {
@@ -334,14 +345,87 @@ void LvzController::OnLvzModify(u8* pkt, size_t size) {
334345 u8 mode : 1 ;
335346 u8 reserved : 3 ;
336347 };
348+
349+ struct ModifyData {
350+ u16 map_object : 1 ;
351+ u16 id : 15 ;
352+
353+ union {
354+ struct {
355+ s16 map_x;
356+ s16 map_y;
357+ };
358+
359+ struct {
360+ u16 reference_point_x : 4 ; // ReferencePoint
361+ s16 screen_x : 12 ;
362+ u16 reference_point_y : 4 ; // ReferencePoint
363+ s16 screen_y : 12 ;
364+ };
365+ };
366+
367+ u8 image_id;
368+ u8 layer;
369+ u16 time : 12 ;
370+ u16 mode : 4 ;
371+ };
337372#pragma pack(pop)
338373
339- ModifyBitfield* mod = (ModifyBitfield*)(pkt + 1 );
374+ ModifyBitfield* mod_changed = (ModifyBitfield*)(pkt + 1 );
375+ ModifyData* mod = (ModifyData*)(pkt + 2 );
376+
377+ LvzObject* obj = FindObjectById (mod->id );
378+ if (!obj) {
379+ Log (LogLevel::Warning, " Got lvz modify for object id %d, but wasn't found." , (s32)mod->id );
380+ return ;
381+ }
382+
383+ // Check if this switched between screen/map.
384+ // I don't know if this is even possible, but handle it anyway.
385+ if (obj->map_object != mod->map_object ) {
386+ obj->map_object = mod->map_object ;
387+
388+ // Remove it from both map and screen object lists, then add it back to the appropriate one.
389+ DisableObject (obj->object_id );
390+
391+ if (obj->map_object ) {
392+ if (active_map_object_count < NULLSPACE_ARRAY_SIZE (active_map_objects)) {
393+ active_map_objects[active_map_object_count++] = obj;
394+ }
395+ } else {
396+ if (active_screen_object_count < NULLSPACE_ARRAY_SIZE (active_screen_objects)) {
397+ active_screen_objects[active_screen_object_count++] = obj;
398+ }
399+ }
400+ }
401+
402+ if (mod_changed->mode ) {
403+ obj->display_mode = mod->mode ;
404+ }
340405
341- #if 0
342- printf("Lvz modify (%zd): %d %d %d %d %d %d\n", size, mod->xy, mod->image, mod->layer, mod->time, mod->mode,
343- mod->reserved);
344- #endif
406+ if (mod_changed->xy ) {
407+ if (obj->map_object ) {
408+ obj->x_map = mod->map_x ;
409+ obj->y_map = mod->map_y ;
410+ } else {
411+ obj->x_screen = mod->screen_x ;
412+ obj->y_screen = mod->screen_y ;
413+ obj->x_type = mod->reference_point_x ;
414+ obj->y_type = mod->reference_point_y ;
415+ }
416+ }
417+
418+ if (mod_changed->image ) {
419+ obj->image_index = mod->image_id ;
420+ }
421+
422+ if (mod_changed->layer ) {
423+ obj->layer = (Layer)mod->layer ;
424+ }
425+
426+ if (mod_changed->time ) {
427+ obj->display_time = mod->time ;
428+ }
345429}
346430
347431void LvzController::OnMapInformation (u8 * pkt, size_t size) {
@@ -507,7 +591,7 @@ void LvzController::ProcessObjects(struct ObjectImageList* object_images, u8* da
507591 // Skip over object definitions first to simplify image creation
508592 ptr += sizeof (ObjectDefinition) * header->object_count ;
509593
510- size_t animation_base = animation_count;
594+ size_t animation_base = this -> animation_count ;
511595
512596 for (u32 i = 0 ; i < header->image_count ; ++i) {
513597 ImageDefinition* image = (ImageDefinition*)ptr;
@@ -583,7 +667,8 @@ void LvzController::ProcessObjects(struct ObjectImageList* object_images, u8* da
583667 obj->object_id = def->object_id ;
584668 obj->x_map = def->x_map ;
585669 obj->y_map = def->y_map ;
586- obj->animation_index = animation_base + def->image_number ;
670+ obj->animation_base = animation_base;
671+ obj->image_index = def->image_number ;
587672 obj->layer = GetLayer (def->layer );
588673 obj->display_time = def->display_time ;
589674 obj->display_mode = def->display_mode ;
0 commit comments