Expand gruntwork to instances

Add NPC instance gruntwork data

Add instance-related commands
- /instance (instance ID)
- /npci [instance ID]
This commit is contained in:
Gent 2020-10-11 21:53:01 -04:00
parent bd34bb294c
commit c1fd51b721
3 changed files with 88 additions and 21 deletions

View File

@ -322,6 +322,59 @@ void refreshCommand(std::string full, std::vector<std::string>& args, CNSocket*
PlayerManager::sendPlayerTo(sock, plr->x, plr->y, plr->z); PlayerManager::sendPlayerTo(sock, plr->x, plr->y, plr->z);
} }
void instanceCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
Player* plr = PlayerManager::getPlayer(sock);
// no additional arguments: report current instance ID
if (args.size() < 2) {
ChatManager::sendServerMessage(sock, "[INST] Current instance ID: " + std::to_string(plr->instanceID));
return;
}
// move player to specified instance
// validate instance ID
char* instanceS;
int instance = std::strtol(args[1].c_str(), &instanceS, 10);
if (*instanceS) {
ChatManager::sendServerMessage(sock, "[INST] Invalid instance ID: " + args[1]);
return;
}
PlayerManager::sendPlayerTo(sock, plr->x, plr->y, plr->z, instance);
ChatManager::sendServerMessage(sock, "[INST] Switched to instance with ID " + std::to_string(instance));
}
void npcInstanceCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
PlayerView& plrv = PlayerManager::players[sock];
Player* plr = plrv.plr;
if (args.size() < 2) {
ChatManager::sendServerMessage(sock, "[NPCI] Instance ID must be specified");
ChatManager::sendServerMessage(sock, "[NPCI] Usage: /npci <instance ID>");
return;
}
BaseNPC* npc = NPCManager::getNearestNPC(plrv.currentChunks, plr->x, plr->y, plr->z);
if (npc == nullptr) {
ChatManager::sendServerMessage(sock, "[NPCI] No NPCs found nearby");
return;
}
// validate instance ID
char* instanceS;
int instance = std::strtol(args[1].c_str(), &instanceS, 10);
if (*instanceS) {
ChatManager::sendServerMessage(sock, "[NPCI] Invalid instance ID: " + args[1]);
return;
}
ChatManager::sendServerMessage(sock, "[NPCI] Moving NPC with ID " + std::to_string(npc->appearanceData.iNPC_ID) + " to instance " + std::to_string(instance));
TableData::RunningNPCMapNumbers[npc->appearanceData.iNPC_ID] = instance;
NPCManager::updateNPCInstance(npc->appearanceData.iNPC_ID, instance);
}
void flushCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) { void flushCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
TableData::flush(); TableData::flush();
ChatManager::sendServerMessage(sock, "Wrote gruntwork to " + settings::GRUNTWORKJSON); ChatManager::sendServerMessage(sock, "Wrote gruntwork to " + settings::GRUNTWORKJSON);
@ -335,8 +388,10 @@ void ChatManager::init() {
registerCommand("help", 100, helpCommand, "lists all unlocked commands"); registerCommand("help", 100, helpCommand, "lists all unlocked commands");
registerCommand("test", 1, testCommand); registerCommand("test", 1, testCommand);
registerCommand("access", 100, accessCommand); registerCommand("access", 100, accessCommand);
registerCommand("instance", 30, instanceCommand);
registerCommand("mss", 30, mssCommand); registerCommand("mss", 30, mssCommand);
registerCommand("npcr", 30, npcRotateCommand); registerCommand("npcr", 30, npcRotateCommand);
registerCommand("npci", 30, npcInstanceCommand);
registerCommand("summonW", 30, summonWCommand); registerCommand("summonW", 30, summonWCommand);
registerCommand("unsummonW", 30, unsummonWCommand); registerCommand("unsummonW", 30, unsummonWCommand);
registerCommand("toggleai", 30, toggleAiCommand); registerCommand("toggleai", 30, toggleAiCommand);

View File

@ -14,6 +14,7 @@
std::map<int32_t, std::vector<WarpLocation>> TableData::RunningSkywayRoutes; std::map<int32_t, std::vector<WarpLocation>> TableData::RunningSkywayRoutes;
std::map<int32_t, int> TableData::RunningNPCRotations; std::map<int32_t, int> TableData::RunningNPCRotations;
std::map<int32_t, int> TableData::RunningNPCMapNumbers;
std::map<int32_t, BaseNPC*> TableData::RunningMobs; std::map<int32_t, BaseNPC*> TableData::RunningMobs;
void TableData::init() { void TableData::init() {
@ -23,21 +24,13 @@ void TableData::init() {
try { try {
std::ifstream inFile(settings::NPCJSON); std::ifstream inFile(settings::NPCJSON);
nlohmann::json npcData; nlohmann::json npcData;
nlohmann::json nullExample;
// read file into json // read file into json
inFile >> npcData; inFile >> npcData;
int null = 0;
for (nlohmann::json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) { for (nlohmann::json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) {
if (npcData[_npc.key()]["mapNum"] == nullExample)
{
npcData[_npc.key()]["mapNum"] = 0;
_npc.value()["mapNum"] = 0;
null = 1;
//return;
}
auto npc = _npc.value(); auto npc = _npc.value();
BaseNPC *tmp = new BaseNPC(npc["x"], npc["y"], npc["z"], npc["angle"], INSTANCE_OVERWORLD, npc["id"], nextId); int instanceID = npc.find("mapNum") == npc.end() ? INSTANCE_OVERWORLD : (int)npc["mapNum"];
BaseNPC *tmp = new BaseNPC(npc["x"], npc["y"], npc["z"], npc["angle"], instanceID, npc["id"], nextId);
NPCManager::NPCs[nextId] = tmp; NPCManager::NPCs[nextId] = tmp;
NPCManager::updateNPCPosition(nextId, npc["x"], npc["y"], npc["z"]); NPCManager::updateNPCPosition(nextId, npc["x"], npc["y"], npc["z"]);
@ -46,13 +39,6 @@ void TableData::init() {
if (npc["id"] == 641 || npc["id"] == 642) if (npc["id"] == 641 || npc["id"] == 642)
NPCManager::RespawnPoints.push_back({ npc["x"], npc["y"], ((int)npc["z"]) + RESURRECT_HEIGHT }); NPCManager::RespawnPoints.push_back({ npc["x"], npc["y"], ((int)npc["z"]) + RESURRECT_HEIGHT });
} }
if (null == 1)
{
std::cout << "Updated Json to include Map Num" << std::endl;
std::ofstream outFile(settings::NPCJSON);
outFile << npcData << std::endl;
outFile.close();
}
} }
catch (const std::exception& err) { catch (const std::exception& err) {
std::cerr << "[WARN] Malformed NPCs.json file! Reason:" << err.what() << std::endl; std::cerr << "[WARN] Malformed NPCs.json file! Reason:" << err.what() << std::endl;
@ -75,7 +61,7 @@ void TableData::init() {
for (nlohmann::json::iterator _warp = warpData.begin(); _warp != warpData.end(); _warp++) { for (nlohmann::json::iterator _warp = warpData.begin(); _warp != warpData.end(); _warp++) {
auto warp = _warp.value(); auto warp = _warp.value();
WarpLocation warpLoc = { warp["m_iToX"], warp["m_iToY"], warp["m_iToZ"],warp["m_iToMapNum"],warp["m_iIsInstance"],warp["m_iLimit_TaskID"],warp["m_iNpcNumber"] }; WarpLocation warpLoc = { warp["m_iToX"], warp["m_iToY"], warp["m_iToZ"], warp["m_iToMapNum"], warp["m_iIsInstance"], warp["m_iLimit_TaskID"], warp["m_iNpcNumber"] };
int warpID = warp["m_iWarpNumber"]; int warpID = warp["m_iWarpNumber"];
NPCManager::Warps[warpID] = warpLoc; NPCManager::Warps[warpID] = warpLoc;
} }
@ -195,7 +181,8 @@ void TableData::init() {
for (nlohmann::json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) { for (nlohmann::json::iterator _npc = npcData.begin(); _npc != npcData.end(); _npc++) {
auto npc = _npc.value(); auto npc = _npc.value();
auto td = NPCManager::NPCData[(int)npc["iNPCType"]]; auto td = NPCManager::NPCData[(int)npc["iNPCType"]];
Mob *tmp = new Mob(npc["iX"], npc["iY"], npc["iZ"], npc["iAngle"], INSTANCE_OVERWORLD, npc["iNPCType"], npc["iHP"], td, nextId); int instanceID = npc.find("iMapNum") == npc.end() ? INSTANCE_OVERWORLD : (int)npc["iMapNum"];
Mob *tmp = new Mob(npc["iX"], npc["iY"], npc["iZ"], npc["iAngle"], instanceID, npc["iNPCType"], npc["iHP"], td, nextId);
NPCManager::NPCs[nextId] = tmp; NPCManager::NPCs[nextId] = tmp;
MobManager::Mobs[nextId] = (Mob*)NPCManager::NPCs[nextId]; MobManager::Mobs[nextId] = (Mob*)NPCManager::NPCs[nextId];
@ -418,12 +405,26 @@ void TableData::loadGruntwork(int32_t *nextId) {
RunningNPCRotations[npcID] = angle; RunningNPCRotations[npcID] = angle;
} }
// npc map numbers
auto npcMap = gruntwork["instances"];
for (auto _map = npcMap.begin(); _map != npcMap.end(); _map++) {
int32_t npcID = _map.value()["iNPCID"];
int instanceID = _map.value()["iMapNum"];
if (NPCManager::NPCs.find(npcID) == NPCManager::NPCs.end())
continue; // NPC not found
BaseNPC* npc = NPCManager::NPCs[npcID];
NPCManager::updateNPCInstance(npc->appearanceData.iNPC_ID, instanceID);
RunningNPCMapNumbers[npcID] = instanceID;
}
// mobs // mobs
auto mobs = gruntwork["mobs"]; auto mobs = gruntwork["mobs"];
for (auto _mob = mobs.begin(); _mob != mobs.end(); _mob++) { for (auto _mob = mobs.begin(); _mob != mobs.end(); _mob++) {
auto mob = _mob.value(); auto mob = _mob.value();
Mob *npc = new Mob(mob["iX"], mob["iY"], mob["iZ"], INSTANCE_OVERWORLD, mob["iNPCType"], int instanceID = mob.find("iMapNum") == mob.end() ? INSTANCE_OVERWORLD : (int)mob["iMapNum"];
Mob *npc = new Mob(mob["iX"], mob["iY"], mob["iZ"], instanceID, mob["iNPCType"],
NPCManager::NPCData[(int)mob["iNPCType"]], (*nextId)++); NPCManager::NPCData[(int)mob["iNPCType"]], (*nextId)++);
NPCManager::NPCs[npc->appearanceData.iNPC_ID] = npc; NPCManager::NPCs[npc->appearanceData.iNPC_ID] = npc;
@ -451,7 +452,7 @@ void TableData::flush() {
nlohmann::json route; nlohmann::json route;
route["iRouteID"] = (int)pair.first; route["iRouteID"] = (int)pair.first;
route["iMonkeySpeed"] = 1500; // TODO route["iMonkeySpeed"] = 1500;
std::cout << "serializing mss route " << (int)pair.first << std::endl; std::cout << "serializing mss route " << (int)pair.first << std::endl;
for (WarpLocation& point : pair.second) { for (WarpLocation& point : pair.second) {
@ -476,6 +477,15 @@ void TableData::flush() {
gruntwork["rotations"].push_back(rotation); gruntwork["rotations"].push_back(rotation);
} }
for (auto& pair : RunningNPCMapNumbers) {
nlohmann::json mapNumber;
mapNumber["iNPCID"] = (int)pair.first;
mapNumber["iMapNum"] = pair.second;
gruntwork["instances"].push_back(mapNumber);
}
for (auto& pair : RunningMobs) { for (auto& pair : RunningMobs) {
nlohmann::json mob; nlohmann::json mob;
Mob *m = (Mob*)pair.second; // we need spawnX, etc Mob *m = (Mob*)pair.second; // we need spawnX, etc
@ -489,6 +499,7 @@ void TableData::flush() {
mob["iX"] = m->spawnX; mob["iX"] = m->spawnX;
mob["iY"] = m->spawnY; mob["iY"] = m->spawnY;
mob["iZ"] = m->spawnZ; mob["iZ"] = m->spawnZ;
mob["iMapNum"] = m->instanceID;
// this is a bit imperfect, since this is a live angle, not a spawn angle so it'll change often, but eh // this is a bit imperfect, since this is a live angle, not a spawn angle so it'll change often, but eh
mob["iAngle"] = m->appearanceData.iAngle; mob["iAngle"] = m->appearanceData.iAngle;

View File

@ -7,6 +7,7 @@
namespace TableData { namespace TableData {
extern std::map<int32_t, std::vector<WarpLocation>> RunningSkywayRoutes; extern std::map<int32_t, std::vector<WarpLocation>> RunningSkywayRoutes;
extern std::map<int32_t, int> RunningNPCRotations; extern std::map<int32_t, int> RunningNPCRotations;
extern std::map<int32_t, int> RunningNPCMapNumbers;
extern std::map<int32_t, BaseNPC*> RunningMobs; extern std::map<int32_t, BaseNPC*> RunningMobs;
void init(); void init();