From d25e7ca4fc63b5345ab4f7364423b835ce5d9ed3 Mon Sep 17 00:00:00 2001 From: dongresource Date: Tue, 15 Dec 2020 23:16:18 +0100 Subject: [PATCH] Implement rudimentary NPC scripting framework and Lord Fuse boss fight --- src/MobManager.cpp | 5 +++++ src/NPCManager.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++ src/NPCManager.hpp | 17 +++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/src/MobManager.cpp b/src/MobManager.cpp index 9c2b627..6a1ca23 100644 --- a/src/MobManager.cpp +++ b/src/MobManager.cpp @@ -404,6 +404,11 @@ void MobManager::killMob(CNSocket *sock, Mob *mob) { // delay the despawn animation mob->despawned = false; + // fire any triggered events + for (NPCEvent& event : NPCManager::NPCEvents) + if (event.trigger == ON_KILLED && event.npcType == mob->appearanceData.iNPCType) + event.handler(sock, mob); + auto it = TransportManager::NPCQueues.find(mob->appearanceData.iNPC_ID); if (it == TransportManager::NPCQueues.end() || it->second.empty()) return; diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index f7961b6..e3594c6 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -816,3 +816,57 @@ void NPCManager::eggPickup(CNSocket* sock, CNPacketData* data) { egg->appearanceData.iHP = 0; } } + +#pragma region NPCEvents + +// summon right arm and stage 2 body +static void lordFuseStageTwo(CNSocket *sock, BaseNPC *npc) { + Mob *oldbody = (Mob*)npc; // adaptium, stun + Player *plr = PlayerManager::getPlayer(sock); + + std::cout << "Lord Fuse stage two" << std::endl; + + // Fuse doesn't move; spawnX, etc. is shorter to write than *appearanceData* + // Blastons, Heal + Mob *newbody = (Mob*)NPCManager::summonNPC(oldbody->spawnX, oldbody->spawnY, oldbody->spawnZ, plr->instanceID, 2467); + + newbody->appearanceData.iAngle = oldbody->appearanceData.iAngle; + NPCManager::updateNPCPosition(newbody->appearanceData.iNPC_ID, newbody->spawnX, newbody->spawnY, newbody->spawnZ, + plr->instanceID, oldbody->appearanceData.iAngle); + + // right arm, Adaptium, Stun + Mob *arm = (Mob*)NPCManager::summonNPC(oldbody->spawnX - 600, oldbody->spawnY, oldbody->spawnZ, plr->instanceID, 2469); + + arm->appearanceData.iAngle = oldbody->appearanceData.iAngle; + NPCManager::updateNPCPosition(arm->appearanceData.iNPC_ID, arm->spawnX, arm->spawnY, arm->spawnZ, + plr->instanceID, oldbody->appearanceData.iAngle); +} + +// summon left arm and stage 3 body +static void lordFuseStageThree(CNSocket *sock, BaseNPC *npc) { + Mob *oldbody = (Mob*)npc; + Player *plr = PlayerManager::getPlayer(sock); + + std::cout << "Lord Fuse stage three" << std::endl; + + // Cosmic, Damage Point + Mob *newbody = (Mob*)NPCManager::summonNPC(oldbody->spawnX, oldbody->spawnY, oldbody->spawnZ, plr->instanceID, 2468); + + newbody->appearanceData.iAngle = oldbody->appearanceData.iAngle; + NPCManager::updateNPCPosition(newbody->appearanceData.iNPC_ID, newbody->spawnX, newbody->spawnY, newbody->spawnZ, + plr->instanceID, oldbody->appearanceData.iAngle); + + // Blastons, Heal + Mob *arm = (Mob*)NPCManager::summonNPC(oldbody->spawnX + 600, oldbody->spawnY, oldbody->spawnZ, plr->instanceID, 2470); + + arm->appearanceData.iAngle = oldbody->appearanceData.iAngle; + NPCManager::updateNPCPosition(arm->appearanceData.iNPC_ID, arm->spawnX, arm->spawnY, arm->spawnZ, + plr->instanceID, oldbody->appearanceData.iAngle); +} + +std::vector NPCManager::NPCEvents = { + NPCEvent(2466, ON_KILLED, lordFuseStageTwo), + NPCEvent(2467, ON_KILLED, lordFuseStageThree), +}; + +#pragma endregion NPCEvents diff --git a/src/NPCManager.hpp b/src/NPCManager.hpp index 95ed318..7250f6e 100644 --- a/src/NPCManager.hpp +++ b/src/NPCManager.hpp @@ -12,6 +12,22 @@ #define RESURRECT_HEIGHT 400 +// placeholder; there's only one trigger type right now +enum Trigger { + ON_KILLED +}; + +typedef void (*NPCEventHandler)(CNSocket*, BaseNPC*); + +struct NPCEvent { + int32_t npcType; + int trigger; + NPCEventHandler handler; + + NPCEvent(int32_t t, int tr, NPCEventHandler hndlr) + : npcType(t), trigger(tr), handler(hndlr) {} +}; + // this should really be called vec3 or something... struct WarpLocation { int x, y, z, instanceID, isInstance, limitTaskID, npcID; @@ -40,6 +56,7 @@ namespace NPCManager { extern std::map NPCs; extern std::map Warps; extern std::vector RespawnPoints; + extern std::vector NPCEvents; extern std::unordered_map Eggs; extern std::map, time_t> EggBuffs; extern std::unordered_map EggTypes;