diff --git a/config.ini b/config.ini index bd72bbc..1df6030 100644 --- a/config.ini +++ b/config.ini @@ -4,7 +4,7 @@ port=8001 # enables two randomly generated characters in the # character selection menu for convenience -randomcharacters=false +randomcharacters=true # Shard Server configuration [shard] @@ -12,7 +12,7 @@ port=8002 # you'll want to change this one ip=192.168.1.183 # distance at which other players and NPCs become visible -view=20000 +view=1000 # little message players see when they enter the game motd=Welcome to OpenFusion! diff --git a/src/CNShardServer.hpp b/src/CNShardServer.hpp index fd83cef..2f69e73 100644 --- a/src/CNShardServer.hpp +++ b/src/CNShardServer.hpp @@ -40,6 +40,8 @@ enum SHARDPACKETID { P_FE2CL_PC_ZIPLINE = 822083703, P_FE2CL_PC_MOVEPLATFORM = 822083704, P_FE2CL_PC_SLOPE = 822083705, + P_FE2CL_NPC_ENTER = 822083595, + P_FE2CL_NPC_EXIT = 822083596, P_FE2CL_REP_PC_GOTO_SUCC = 822083633, P_FE2CL_GM_REP_PC_SET_VALUE = 822083781, P_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC = 822083602, diff --git a/src/NPC.hpp b/src/NPC.hpp new file mode 100644 index 0000000..f467040 --- /dev/null +++ b/src/NPC.hpp @@ -0,0 +1,26 @@ +#ifndef _NPCCLASS_HPP +#define _NPCCLASS_HPP + +#include "CNStructs.hpp" + +class BaseNPC { +public: + sNPCAppearanceData appearanceData; + + BaseNPC() {}; + BaseNPC(int x, int y, int z, int type) { + appearanceData.iX = x; + appearanceData.iY = y; + appearanceData.iZ = z; + appearanceData.iNPCType = type; + appearanceData.iHP = 400; + appearanceData.iAngle = 0; + appearanceData.iConditionBitFlag = 0; + appearanceData.iBarkerType = 0; + + // hopefully no collisions happen :eyes: + appearanceData.iNPC_ID = (int32_t)getTime(); + }; +}; + +#endif \ No newline at end of file diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 1b08f75..b8d6c15 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -1,5 +1,64 @@ #include "NPCManager.hpp" +#include "settings.hpp" + +#include +#include +#include + +std::map NPCManager::NPCs; void NPCManager::init() { - + /* BaseNPC test(settings::SPAWN_X, settings::SPAWN_Y, settings::SPAWN_Z, 727); + NPCs[test.appearanceData.iNPC_ID] = test; */ +} + +void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) { + std::list yesView; + std::list noView; + + for (auto pair : NPCs) { + int diffX = abs(view.plr.x - pair.second.appearanceData.iX); + int diffY = abs(view.plr.y - pair.second.appearanceData.iY); + + if (diffX < settings::VIEWDISTANCE && diffY < settings::VIEWDISTANCE) { + yesView.push_back(pair.first); + } else { + noView.push_back(pair.first); + } + } + + std::list::iterator i = view.viewableNPCs.begin(); + while (i != view.viewableNPCs.end()) { + int32_t id = *i; + + if (std::find(noView.begin(), noView.end(), id) != noView.end()) { + // it shouldn't be visible, send NPC_EXIT + sP_FE2CL_NPC_EXIT* exitData = (sP_FE2CL_NPC_EXIT*)xmalloc(sizeof(sP_FE2CL_NPC_EXIT)); + + exitData->iNPC_ID = id; + + sock->sendPacket(new CNPacketData((void*)exitData, P_FE2CL_NPC_EXIT, sizeof(sP_FE2CL_NPC_EXIT), sock->getFEKey())); + + // remove from view + view.viewableNPCs.erase(i++); + } + + ++i; + } + + for (int32_t id : yesView) { + if (std::find(view.viewableNPCs.begin(), view.viewableNPCs.end(), id) == view.viewableNPCs.end()) { + + // needs to be added to viewableNPCs! send NPC_ENTER + sP_FE2CL_NPC_ENTER* enterData = (sP_FE2CL_NPC_ENTER*)xmalloc(sizeof(sP_FE2CL_NPC_ENTER)); + + enterData->NPCAppearanceData = NPCs[id].appearanceData; + + sock->sendPacket(new CNPacketData((void*)enterData, P_FE2CL_NPC_ENTER, sizeof(sP_FE2CL_NPC_ENTER), sock->getFEKey())); + + view.viewableNPCs.push_back(id); + } + } + + PlayerManager::players[sock].viewableNPCs = view.viewableNPCs; } \ No newline at end of file diff --git a/src/NPCManager.hpp b/src/NPCManager.hpp index 659a666..03b7dde 100644 --- a/src/NPCManager.hpp +++ b/src/NPCManager.hpp @@ -2,13 +2,16 @@ #define _NPCMANAGER_HPP #include "CNProtocol.hpp" +#include "PlayerManager.hpp" +#include "NPC.hpp" #include namespace NPCManager { + extern std::map NPCs; void init(); - + void updatePlayerNPCS(CNSocket* sock, PlayerView& plr); } #endif \ No newline at end of file diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 021cd57..44aa96f 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -1,5 +1,6 @@ #include "CNProtocol.hpp" #include "PlayerManager.hpp" +#include "NPCManager.hpp" #include "CNShardServer.hpp" #include "CNShared.hpp" @@ -145,6 +146,8 @@ void PlayerManager::updatePlayerPosition(CNSocket* sock, int X, int Y, int Z) { players[otherSock].viewable.push_back(sock); } } + + NPCManager::updatePlayerNPCS(sock, players[sock]); } void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { diff --git a/src/PlayerManager.hpp b/src/PlayerManager.hpp index 77e8a4a..bfee3f1 100644 --- a/src/PlayerManager.hpp +++ b/src/PlayerManager.hpp @@ -11,6 +11,7 @@ struct PlayerView { std::list viewable; + std::list viewableNPCs; Player plr; int long lastHeartbeat; }; diff --git a/src/main.cpp b/src/main.cpp index 0fc3af6..4cf48d5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ #include "PlayerManager.hpp" #include "ChatManager.hpp" #include "NanoManager.hpp" +#include "NPCManager.hpp" #include "settings.hpp" @@ -30,6 +31,7 @@ int main() { PlayerManager::init(); ChatManager::init(); NanoManager::init(); + NPCManager::init(); std::cout << "[INFO] Starting Server Threads..." << std::endl; CNLoginServer loginServer(settings::LOGINPORT);