From 85bf45573199c69dd93d9c02e5bb85f0a5be3fee Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Sat, 4 Jul 2026 18:43:09 -0500 Subject: [PATCH] entity pos sets chunk now --- .../cutscene/item/entity/cutsceneentityadd.c | 8 +------ src/dusk/rpg/entity/entity.c | 22 +++++++++++++++++++ src/dusk/rpg/entity/entity.h | 19 +++++++++++++++- src/dusk/rpg/overworld/map.c | 13 +++++------ src/dusk/rpg/rpg.c | 8 +------ 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/src/dusk/rpg/cutscene/item/entity/cutsceneentityadd.c b/src/dusk/rpg/cutscene/item/entity/cutsceneentityadd.c index 481aab77..0ab8c36e 100644 --- a/src/dusk/rpg/cutscene/item/entity/cutsceneentityadd.c +++ b/src/dusk/rpg/cutscene/item/entity/cutsceneentityadd.c @@ -8,7 +8,6 @@ #include "rpg/cutscene/item/cutsceneitem.h" #include "rpg/cutscene/cutscenesystem.h" #include "rpg/entity/entity.h" -#include "rpg/overworld/map.h" #include "assert/assert.h" void cutsceneEntityAddStart( @@ -20,12 +19,7 @@ void cutsceneEntityAddStart( entity_t *entity = &ENTITIES[entIndex]; entityInit(entity, item->entityAdd.entityType); - entityPositionSet(entity, item->entityAdd.position); - - chunkpos_t cp; - worldPosToChunkPos(&entity->position, &cp); - chunkindex_t ci = mapGetChunkIndexAt(cp); - if(ci != -1) entitySetChunk(entity, (uint8_t)ci); + entityPositionSet(entity, item->entityAdd.position);// Also assigns chunk. CUTSCENE_SYSTEM.entityLastCreated = entity; CUTSCENE_SYSTEM.entityLastRef = entity; diff --git a/src/dusk/rpg/entity/entity.c b/src/dusk/rpg/entity/entity.c index 2106ac99..84a55c61 100644 --- a/src/dusk/rpg/entity/entity.c +++ b/src/dusk/rpg/entity/entity.c @@ -223,6 +223,7 @@ void entityWalk(entity_t *entity, const entitydir_t direction) { entity->position = newPos; entity->animation = ENTITY_ANIM_WALK; entity->animTime = ENTITY_ANIM_WALK_DURATION;// TODO: Running vs walking + entityUpdateChunk(entity); } void entityRun(entity_t *entity, const entitydir_t direction) { @@ -245,6 +246,17 @@ entity_t * entityGetAt(const worldpos_t position) { return NULL; } +entity_t * entityGetByGlobalId(const entityglobalid_t globalId) { + entity_t *ent = ENTITIES; + do { + if(ent->type == ENTITY_TYPE_NULL) continue; + if(ent->globalId != globalId) continue; + return ent; + } while(++ent, ent < &ENTITIES[ENTITY_COUNT]); + + return NULL; +} + uint8_t entityGetAvailable() { entity_t *ent = ENTITIES; do { @@ -261,6 +273,7 @@ void entityPositionSet(entity_t *entity, const worldpos_t pos) { entity->animation = ENTITY_ANIM_IDLE; entity->animTime = 0; entity->walkEndCooldown = 0; + entityUpdateChunk(entity); } void entitySetChunk(entity_t *entity, const uint8_t chunkIndex) { @@ -289,4 +302,13 @@ void entitySetChunk(entity_t *entity, const uint8_t chunkIndex) { } } } +} + +void entityUpdateChunk(entity_t *entity) { + assertNotNull(entity, "Entity pointer cannot be NULL"); + + chunkpos_t cp; + worldPosToChunkPos(&entity->position, &cp); + chunkindex_t ci = mapGetChunkIndexAt(cp); + if(ci != -1) entitySetChunk(entity, (uint8_t)ci); } \ No newline at end of file diff --git a/src/dusk/rpg/entity/entity.h b/src/dusk/rpg/entity/entity.h index 8cbfee13..e184b3b3 100644 --- a/src/dusk/rpg/entity/entity.h +++ b/src/dusk/rpg/entity/entity.h @@ -118,13 +118,21 @@ void entityRun(entity_t *entity, const entitydir_t direction); /** * Gets the entity at a specific world position. - * + * * @param map Pointer to the map to check. * @param pos The world position to check. * @return Pointer to the entity at the position, or NULL if none. */ entity_t *entityGetAt(const worldpos_t pos); +/** + * Gets the entity with the given global ID, if one is currently loaded. + * + * @param globalId The global ID to search for. + * @return Pointer to the matching entity, or NULL if none is loaded. + */ +entity_t *entityGetByGlobalId(const entityglobalid_t globalId); + /** * Gets an available entity index. * @@ -141,6 +149,15 @@ uint8_t entityGetAvailable(); */ void entitySetChunk(entity_t *entity, const uint8_t chunkIndex); +/** + * Resolves the chunk that an entity's current position falls into and + * assigns the entity to it via entitySetChunk. Leaves the entity's chunk + * unchanged if its position doesn't fall within any loaded chunk. + * + * @param entity Pointer to the entity to update. + */ +void entityUpdateChunk(entity_t *entity); + /** * Instantly moves an entity to a world position, resetting movement state. * diff --git a/src/dusk/rpg/overworld/map.c b/src/dusk/rpg/overworld/map.c index ba302deb..5d54cebf 100644 --- a/src/dusk/rpg/overworld/map.c +++ b/src/dusk/rpg/overworld/map.c @@ -281,6 +281,11 @@ entity_t * mapSpawnEntity( "Global ID is out of range for entity global init callbacks" ); + // Already spawned? Reuse the existing entity instead of making a + // duplicate - two entities must never share a global ID. + entity_t *existing = entityGetByGlobalId(globalId); + if(existing != NULL) return existing; + // See if there is a callback for this entity first. const entityglobaldef_t *def = &ENTITY_GLOBAL_LIST[globalId]; assertNotNull(def, "No global entity definition for this ID"); @@ -294,13 +299,7 @@ entity_t * mapSpawnEntity( entity_t *entity = &ENTITIES[index]; entityInit(entity, def->type); entity->globalId = globalId; - entityPositionSet(entity, position); - - // Assign to the local chunk. - chunkpos_t cp; - worldPosToChunkPos(&entity->position, &cp); - chunkindex_t ci = mapGetChunkIndexAt(cp); - if(ci != -1) entitySetChunk(entity, (uint8_t)ci); + entityPositionSet(entity, position);// Also assigns the entity's chunk. // Invoke the callback to initialize the entity. entityglobalcreate_t create = { diff --git a/src/dusk/rpg/rpg.c b/src/dusk/rpg/rpg.c index 279215c3..abf0e976 100644 --- a/src/dusk/rpg/rpg.c +++ b/src/dusk/rpg/rpg.c @@ -35,15 +35,9 @@ errorret_t rpgInit(void) { assertTrue(entIndex != 0xFF, "No available entity slots!."); entity_t *ent = &ENTITIES[entIndex]; entityInit(ent, ENTITY_TYPE_PLAYER); - entityPositionSet(ent, (worldpos_t){ 10, 2, 0 }); + entityPositionSet(ent, (worldpos_t){ 10, 2, 0 });// Also assigns the chunk. RPG_CAMERA.mode = RPG_CAMERA_MODE_FOLLOW_ENTITY; RPG_CAMERA.followEntity.followEntityId = ent->id; - { - chunkpos_t cp; - worldPosToChunkPos(&ent->position, &cp); - chunkindex_t ci = mapGetChunkIndexAt(cp); - if(ci != -1) entitySetChunk(ent, (uint8_t)ci); - } mapSpawnEntity(3, (worldpos_t){ 8, 8, 1 });