diff --git a/data/dynos_coop.c.h b/data/dynos_coop.c.h index 98d4e11a5..ddeb6ba4a 100644 --- a/data/dynos_coop.c.h +++ b/data/dynos_coop.c.h @@ -13,6 +13,7 @@ const char* dynos_packs_get(s32 index); bool dynos_packs_get_enabled(s32 index); void dynos_packs_set_enabled(s32 index, bool value); +void dynos_add_actor_custom(const char *modPath, const char* geoName); const void* dynos_geolayout_get(const char *name); #endif diff --git a/data/dynos_coop_c.cpp b/data/dynos_coop_c.cpp index 5f431df8e..c3a0e6fee 100644 --- a/data/dynos_coop_c.cpp +++ b/data/dynos_coop_c.cpp @@ -53,6 +53,10 @@ void dynos_packs_set_enabled(s32 index, bool value) { DynOS_Gfx_GetPacksEnabled()[index] = value; } +void dynos_add_actor_custom(const char *modPath, const char* geoName) { + DynOS_Geo_AddActorCustom(modPath, geoName); +} + const void* dynos_geolayout_get(const char *name) { return DynOS_Geo_GetActorLayoutFromName(name); } diff --git a/data/dynos_gfx_load.cpp b/data/dynos_gfx_load.cpp index ba0c61d54..97d90bd10 100644 --- a/data/dynos_gfx_load.cpp +++ b/data/dynos_gfx_load.cpp @@ -272,7 +272,11 @@ GfxData *DynOS_Gfx_LoadFromBinary(const SysPath &aPackFolder, const char *aActor // Look for actor in pack if (_Pack) { for (s32 i = 0; i != _Pack->mGfxData.Count(); ++i) { +#ifdef COOP + if (!strcmp(_Pack->mGfxData[i].first, aActorName)) { +#else if (_Pack->mGfxData[i].first == aActorName) { // Perfectly valid, aActorName comes from static RO data, so its address never changes during execution +#endif return _Pack->mGfxData[i].second; } } diff --git a/data/dynos_gfx_read.cpp b/data/dynos_gfx_read.cpp index d8060bbd2..a85e26429 100644 --- a/data/dynos_gfx_read.cpp +++ b/data/dynos_gfx_read.cpp @@ -1826,9 +1826,6 @@ void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) { // If there is an existing binary file for this layout, skip and go to the next actor SysPath _BinFilename = fstring("%s/%s.bin", aPackFolder.c_str(), _GeoRootName.begin()); if (fs_sys_file_exists(_BinFilename.c_str())) { -#ifdef COOP - DynOS_Geo_AddActorCustom(aPackFolder, _GeoRootName.begin()); -#endif continue; } @@ -1884,10 +1881,6 @@ void DynOS_Gfx_GeneratePack(const SysPath &aPackFolder) { } else { Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount); } -#ifdef COOP - // Add to custom actors - DynOS_Geo_AddActorCustom(aPackFolder, _GeoRootName.begin()); -#endif // Clear data pointers ClearGfxDataNodes(_GfxData->mLights); ClearGfxDataNodes(_GfxData->mTextures); diff --git a/src/pc/mods/mod.c b/src/pc/mods/mod.c index 688dbc2ce..295bbf120 100644 --- a/src/pc/mods/mod.c +++ b/src/pc/mods/mod.c @@ -1,9 +1,47 @@ #include "mod.h" #include "mods.h" #include "mods_utils.h" +#include "data/dynos_coop.c.h" #include "pc/utils/misc.h" #include "pc/debuglog.h" +void mod_activate(struct Mod* mod) { + // activate dynos models + for (int i = 0; i < mod->fileCount; i++) { + struct ModFile* file = &mod->files[i]; + if (!str_ends_with(file->relativePath, ".bin")) { + continue; + } + + char dynosPath[SYS_MAX_PATH] = { 0 }; + if (snprintf(dynosPath, SYS_MAX_PATH - 1, "%s/actors", mod->basePath) < 0) { + LOG_ERROR("Failed to concat dynos path"); + continue; + } + + // copy geo name + char geoName[64] = { 0 }; + if (snprintf(geoName, 63, "%s", path_basename(file->relativePath)) < 0) { + LOG_ERROR("Truncated geo name"); + continue; + } + + // remove '.bin' + char* g = geoName; + while (*g != '\0') { + if (*g == '.') { + *g = '\0'; + break; + } + g++; + } + + // Add to custom actors + dynos_add_actor_custom(dynosPath, geoName); + LOG_INFO("Activating DynOS: '%s', '%s'", dynosPath, geoName); + } +} + void mod_clear(struct Mod* mod) { for (int j = 0; j < mod->fileCount; j++) { struct ModFile* file = &mod->files[j]; diff --git a/src/pc/mods/mod.h b/src/pc/mods/mod.h index 142c67fa4..3123b5350 100644 --- a/src/pc/mods/mod.h +++ b/src/pc/mods/mod.h @@ -30,6 +30,7 @@ struct Mod { size_t size; }; +void mod_activate(struct Mod* mod); void mod_clear(struct Mod* mod); bool mod_load(struct Mods* mods, char* basePath, char* modName); diff --git a/src/pc/mods/mods.c b/src/pc/mods/mods.c index 47e5df31e..03bb2b4f3 100644 --- a/src/pc/mods/mods.c +++ b/src/pc/mods/mods.c @@ -62,6 +62,7 @@ void mods_activate(struct Mods* mods) { struct Mod* mod = mods->entries[i]; if (mod->enabled) { gActiveMods.entries[gActiveMods.entryCount++] = mod; + mod_activate(mod); } } diff --git a/src/pc/network/network.h b/src/pc/network/network.h index af9fba0ff..0ee3ee743 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -80,7 +80,7 @@ struct SyncObject { void* extraFields[MAX_SYNC_OBJECT_FIELDS]; bool rememberLastReliablePacket; bool lastReliablePacketIsStale; - u8 extendedModelId; + u16 extendedModelId; }; enum PlayerInteractions { diff --git a/src/pc/network/packets/packet_object.c b/src/pc/network/packets/packet_object.c index f1a02d0e0..d2261008a 100644 --- a/src/pc/network/packets/packet_object.c +++ b/src/pc/network/packets/packet_object.c @@ -150,7 +150,7 @@ struct SyncObject* network_init_object(struct Object *o, float maxSyncDistance) so->on_forget = NULL; so->syncDeathEvent = true; if (!hadSyncId) { - so->extendedModelId = 0xFF; + so->extendedModelId = 0xFFFF; } so->randomSeed = (u16)(o->oSyncID * 7951); memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS); diff --git a/src/pc/network/packets/packet_spawn_objects.c b/src/pc/network/packets/packet_spawn_objects.c index c9d536956..b10ac77bb 100644 --- a/src/pc/network/packets/packet_spawn_objects.c +++ b/src/pc/network/packets/packet_spawn_objects.c @@ -21,7 +21,7 @@ struct SpawnObjectData { s16 activeFlags; s32 rawData[80]; u8 globalPlayerIndex; - u8 extendedModelId; + u16 extendedModelId; }; #pragma pack() @@ -74,9 +74,9 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[] u32 model = models[i]; u8 parentId = generate_parent_id(objects, i, true); u32 behaviorId = get_id_from_behavior(o->behavior); - u8 extendedModelId = (o->oSyncID != 0 && gSyncObjects[o->oSyncID].o == o) - ? gSyncObjects[o->oSyncID].extendedModelId - : 0xFF; + u16 extendedModelId = (o->oSyncID != 0 && gSyncObjects[o->oSyncID].o == o) + ? gSyncObjects[o->oSyncID].extendedModelId + : 0xFFFF; packet_write(&p, &parentId, sizeof(u8)); packet_write(&p, &model, sizeof(u32)); packet_write(&p, &behaviorId, sizeof(u32)); @@ -86,7 +86,7 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[] packet_write(&p, &o->header.gfx.scale[1], sizeof(f32)); packet_write(&p, &o->header.gfx.scale[2], sizeof(f32)); packet_write(&p, &o->globalPlayerIndex, sizeof(u8)); - packet_write(&p, &extendedModelId, sizeof(u8)); + packet_write(&p, &extendedModelId, sizeof(u16)); } if (sendToLocalIndex == PACKET_DESTINATION_BROADCAST) { @@ -122,7 +122,7 @@ void network_receive_spawn_objects(struct Packet* p) { packet_read(p, &scale[1], sizeof(f32)); packet_read(p, &scale[2], sizeof(f32)); packet_read(p, &data.globalPlayerIndex, sizeof(u8)); - packet_read(p, &data.extendedModelId, sizeof(u8)); + packet_read(p, &data.extendedModelId, sizeof(u16)); struct Object* parentObj = NULL; if (data.parentId == (u8)-1) { @@ -155,7 +155,7 @@ void network_receive_spawn_objects(struct Packet* p) { } // load extended model - if (data.extendedModelId != 0xFF) { + if (data.extendedModelId != 0xFFFF) { u8 loadedModelId = smlua_model_util_load(data.extendedModelId); if (loadedModelId != 0xFF) { data.model = loadedModelId;