mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 13:30:06 +00:00
Added /summonW and /unsummonW gruntwork commands.
Also: * Filled in the battery fileds in the REWARD_ITEM packets in MissionManager. * Removed redundant NPC_ENTER in npcSummonHandler()
This commit is contained in:
parent
6e3d0868cb
commit
606384445c
@ -4,11 +4,13 @@
|
|||||||
#include "PlayerManager.hpp"
|
#include "PlayerManager.hpp"
|
||||||
#include "TransportManager.hpp"
|
#include "TransportManager.hpp"
|
||||||
#include "TableData.hpp"
|
#include "TableData.hpp"
|
||||||
#include "limits.h"
|
#include "NPCManager.hpp"
|
||||||
|
#include "MobManager.hpp"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
std::map<std::string, ChatCommand> ChatManager::commands;
|
std::map<std::string, ChatCommand> ChatManager::commands;
|
||||||
|
|
||||||
@ -184,11 +186,87 @@ void mssCommand(std::string full, std::vector<std::string>& args, CNSocket* sock
|
|||||||
|
|
||||||
// mss ????
|
// mss ????
|
||||||
ChatManager::sendServerMessage(sock, "[MSS] Unknown command '" + args[2] + "'");
|
ChatManager::sendServerMessage(sock, "[MSS] Unknown command '" + args[2] + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
void summonWCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
|
char *rest;
|
||||||
|
int type = std::strtol(args[1].c_str(), &rest, 10);
|
||||||
|
if (*rest) {
|
||||||
|
ChatManager::sendServerMessage(sock, "Invalid NPC number: " + args[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// permission & sanity check
|
||||||
|
if (plr == nullptr || type >= 3314)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int team = NPCManager::NPCData[type]["m_iTeam"];
|
||||||
|
|
||||||
|
assert(NPCManager::nextId < INT32_MAX);
|
||||||
|
|
||||||
|
BaseNPC *npc = nullptr;
|
||||||
|
if (team == 2) {
|
||||||
|
npc = new Mob(plr->x, plr->y, plr->z, plr->instanceID, type, NPCManager::NPCData[type], NPCManager::nextId++);
|
||||||
|
npc->appearanceData.iAngle = (plr->angle + 180) % 360;
|
||||||
|
|
||||||
|
NPCManager::NPCs[npc->appearanceData.iNPC_ID] = npc;
|
||||||
|
MobManager::Mobs[npc->appearanceData.iNPC_ID] = (Mob*)npc;
|
||||||
|
|
||||||
|
// re-enable respawning
|
||||||
|
((Mob*)npc)->summoned = false;
|
||||||
|
} else {
|
||||||
|
ChatManager::sendServerMessage(sock, "Error: /summonW only supports Mobs at this time.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, plr->x, plr->y, plr->z);
|
||||||
|
|
||||||
|
ChatManager::sendServerMessage(sock, "/summonW: placed mob with type: " + std::to_string(type) +
|
||||||
|
", id: " + std::to_string(npc->appearanceData.iNPC_ID));
|
||||||
|
TableData::RunningMobs[npc->appearanceData.iNPC_ID] = npc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unsummonWCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
|
PlayerView& plrv = PlayerManager::players[sock];
|
||||||
|
Player* plr = plrv.plr;
|
||||||
|
|
||||||
|
// shamelessly stolen from npcRotateCommand()
|
||||||
|
BaseNPC* npc = nullptr;
|
||||||
|
int lastDist = INT_MAX;
|
||||||
|
for (auto c = plrv.currentChunks.begin(); c != plrv.currentChunks.end(); c++) {
|
||||||
|
Chunk* chunk = *c;
|
||||||
|
for (auto _npc = chunk->NPCs.begin(); _npc != chunk->NPCs.end(); _npc++) {
|
||||||
|
BaseNPC* npcTemp = NPCManager::NPCs[*_npc];
|
||||||
|
int distXY = std::hypot(plr->x - npcTemp->appearanceData.iX, plr->y - npcTemp->appearanceData.iY);
|
||||||
|
int dist = std::hypot(distXY, plr->z - npcTemp->appearanceData.iZ);
|
||||||
|
if (dist < lastDist) {
|
||||||
|
npc = npcTemp;
|
||||||
|
lastDist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (npc == nullptr) {
|
||||||
|
ChatManager::sendServerMessage(sock, "/unsummonW: No NPCs found nearby");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TableData::RunningMobs.find(npc->appearanceData.iNPC_ID) == TableData::RunningMobs.end()) {
|
||||||
|
ChatManager::sendServerMessage(sock, "/unsummonW: Closest NPC is not a gruntwork mob.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatManager::sendServerMessage(sock, "/unsummonW: removed mob with type: " + std::to_string(npc->appearanceData.iNPCType) +
|
||||||
|
", id: " + std::to_string(npc->appearanceData.iNPC_ID));
|
||||||
|
|
||||||
|
TableData::RunningMobs.erase(npc->appearanceData.iNPC_ID);
|
||||||
|
|
||||||
|
NPCManager::destroyNPC(npc->appearanceData.iNPC_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void npcRotateCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
void npcRotateCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
|
|
||||||
PlayerView& plrv = PlayerManager::players[sock];
|
PlayerView& plrv = PlayerManager::players[sock];
|
||||||
Player* plr = plrv.plr;
|
Player* plr = plrv.plr;
|
||||||
|
|
||||||
@ -230,8 +308,8 @@ void refreshCommand(std::string full, std::vector<std::string>& args, CNSocket*
|
|||||||
}
|
}
|
||||||
|
|
||||||
void flushCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
void flushCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
ChatManager::sendServerMessage(sock, "Wrote gruntwork to " + settings::GRUNTWORKJSON);
|
|
||||||
TableData::flush();
|
TableData::flush();
|
||||||
|
ChatManager::sendServerMessage(sock, "Wrote gruntwork to " + settings::GRUNTWORKJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatManager::init() {
|
void ChatManager::init() {
|
||||||
@ -244,6 +322,8 @@ void ChatManager::init() {
|
|||||||
// TODO: add help command
|
// TODO: add help command
|
||||||
registerCommand("mss", 30, mssCommand);
|
registerCommand("mss", 30, mssCommand);
|
||||||
registerCommand("npcr", 30, npcRotateCommand);
|
registerCommand("npcr", 30, npcRotateCommand);
|
||||||
|
registerCommand("summonW", 30, summonWCommand);
|
||||||
|
registerCommand("unsummonW", 30, unsummonWCommand);
|
||||||
registerCommand("flush", 30, flushCommand);
|
registerCommand("flush", 30, flushCommand);
|
||||||
registerCommand("level", 50, levelCommand);
|
registerCommand("level", 50, levelCommand);
|
||||||
registerCommand("population", 100, populationCommand);
|
registerCommand("population", 100, populationCommand);
|
||||||
|
@ -306,6 +306,8 @@ void MissionManager::dropQuestItem(CNSocket *sock, int task, int count, int id,
|
|||||||
reward->m_iFusionMatter = plr->fusionmatter;
|
reward->m_iFusionMatter = plr->fusionmatter;
|
||||||
reward->iFatigue = 100; // prevents warning message
|
reward->iFatigue = 100; // prevents warning message
|
||||||
reward->iFatigue_Level = 1;
|
reward->iFatigue_Level = 1;
|
||||||
|
reward->m_iBatteryN = plr->batteryN;
|
||||||
|
reward->m_iBatteryW = plr->batteryW;
|
||||||
|
|
||||||
reward->iItemCnt = 1; // remember to update resplen if you change this
|
reward->iItemCnt = 1; // remember to update resplen if you change this
|
||||||
reward->iTaskID = task;
|
reward->iTaskID = task;
|
||||||
@ -365,6 +367,8 @@ int MissionManager::giveMissionReward(CNSocket *sock, int task) {
|
|||||||
resp->iFatigue = 100; // prevents warning message
|
resp->iFatigue = 100; // prevents warning message
|
||||||
resp->iFatigue_Level = 1;
|
resp->iFatigue_Level = 1;
|
||||||
resp->iItemCnt = nrewards;
|
resp->iItemCnt = nrewards;
|
||||||
|
resp->m_iBatteryN = plr->batteryN;
|
||||||
|
resp->m_iBatteryW = plr->batteryW;
|
||||||
|
|
||||||
for (int i = 0; i < nrewards; i++) {
|
for (int i = 0; i < nrewards; i++) {
|
||||||
item[i].sItem.iType = reward->itemTypes[i];
|
item[i].sItem.iType = reward->itemTypes[i];
|
||||||
|
@ -531,7 +531,6 @@ void NPCManager::npcSummonHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
return; // malformed packet
|
return; // malformed packet
|
||||||
|
|
||||||
sP_CL2FE_REQ_NPC_SUMMON* req = (sP_CL2FE_REQ_NPC_SUMMON*)data->buf;
|
sP_CL2FE_REQ_NPC_SUMMON* req = (sP_CL2FE_REQ_NPC_SUMMON*)data->buf;
|
||||||
INITSTRUCT(sP_FE2CL_NPC_ENTER, resp);
|
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
// permission & sanity check
|
// permission & sanity check
|
||||||
@ -541,20 +540,15 @@ void NPCManager::npcSummonHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
int team = NPCData[req->iNPCType]["m_iTeam"];
|
int team = NPCData[req->iNPCType]["m_iTeam"];
|
||||||
|
|
||||||
assert(nextId < INT32_MAX);
|
assert(nextId < INT32_MAX);
|
||||||
resp.NPCAppearanceData.iNPC_ID = nextId++;
|
int id = nextId++;
|
||||||
resp.NPCAppearanceData.iNPCType = req->iNPCType;
|
|
||||||
resp.NPCAppearanceData.iHP = 1000;
|
|
||||||
resp.NPCAppearanceData.iX = plr->x;
|
|
||||||
resp.NPCAppearanceData.iY = plr->y;
|
|
||||||
resp.NPCAppearanceData.iZ = plr->z;
|
|
||||||
|
|
||||||
if (team == 2) {
|
if (team == 2) {
|
||||||
NPCs[resp.NPCAppearanceData.iNPC_ID] = new Mob(plr->x, plr->y, plr->z, plr->instanceID, req->iNPCType, NPCData[req->iNPCType], resp.NPCAppearanceData.iNPC_ID);
|
NPCs[id] = new Mob(plr->x, plr->y, plr->z, plr->instanceID, req->iNPCType, NPCData[req->iNPCType], id);
|
||||||
MobManager::Mobs[resp.NPCAppearanceData.iNPC_ID] = (Mob*)NPCs[resp.NPCAppearanceData.iNPC_ID];
|
MobManager::Mobs[id] = (Mob*)NPCs[id];
|
||||||
} else
|
} else
|
||||||
NPCs[resp.NPCAppearanceData.iNPC_ID] = new BaseNPC(plr->x, plr->y, plr->z, plr->instanceID, req->iNPCType, resp.NPCAppearanceData.iNPC_ID);
|
NPCs[id] = new BaseNPC(plr->x, plr->y, plr->z, plr->instanceID, req->iNPCType, id);
|
||||||
|
|
||||||
updateNPCPosition(resp.NPCAppearanceData.iNPC_ID, plr->x, plr->y, plr->z);
|
updateNPCPosition(id, plr->x, plr->y, plr->z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPCManager::npcWarpHandler(CNSocket* sock, CNPacketData* data) {
|
void NPCManager::npcWarpHandler(CNSocket* sock, CNPacketData* data) {
|
||||||
|
@ -222,7 +222,6 @@ void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z, int I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z) {
|
void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z) {
|
||||||
|
|
||||||
PlayerManager::updatePlayerPosition(sock, X, Y, Z);
|
PlayerManager::updatePlayerPosition(sock, X, Y, Z);
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_GOTO_SUCC, pkt);
|
INITSTRUCT(sP_FE2CL_REP_PC_GOTO_SUCC, pkt);
|
||||||
pkt.iX = X;
|
pkt.iX = X;
|
||||||
|
@ -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, BaseNPC*> TableData::RunningMobs;
|
||||||
|
|
||||||
void TableData::init() {
|
void TableData::init() {
|
||||||
int32_t nextId = 0;
|
int32_t nextId = 0;
|
||||||
@ -197,7 +198,7 @@ void TableData::init() {
|
|||||||
std::cerr << "[WARN] Malformed mobs.json file! Reason:" << err.what() << std::endl;
|
std::cerr << "[WARN] Malformed mobs.json file! Reason:" << err.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadGruntwork();
|
loadGruntwork(&nextId);
|
||||||
|
|
||||||
NPCManager::nextId = nextId;
|
NPCManager::nextId = nextId;
|
||||||
}
|
}
|
||||||
@ -340,7 +341,7 @@ void TableData::constructPathNPC(nlohmann::json::iterator _pathData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load gruntwork output; if it exists
|
// load gruntwork output; if it exists
|
||||||
void TableData::loadGruntwork() {
|
void TableData::loadGruntwork(int32_t *nextId) {
|
||||||
try {
|
try {
|
||||||
std::ifstream inFile(settings::GRUNTWORKJSON);
|
std::ifstream inFile(settings::GRUNTWORKJSON);
|
||||||
nlohmann::json gruntwork;
|
nlohmann::json gruntwork;
|
||||||
@ -376,6 +377,23 @@ void TableData::loadGruntwork() {
|
|||||||
npc->appearanceData.iAngle = angle;
|
npc->appearanceData.iAngle = angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mobs
|
||||||
|
auto mobs = gruntwork["mobs"];
|
||||||
|
for (auto _mob = mobs.begin(); _mob != mobs.end(); _mob++) {
|
||||||
|
auto mob = _mob.value();
|
||||||
|
|
||||||
|
Mob *npc = new Mob(mob["iX"], mob["iY"], mob["iZ"], INSTANCE_OVERWORLD, mob["iNPCType"],
|
||||||
|
NPCManager::NPCData[(int)mob["iNPCType"]], (*nextId)++);
|
||||||
|
|
||||||
|
NPCManager::NPCs[npc->appearanceData.iNPC_ID] = npc;
|
||||||
|
MobManager::Mobs[npc->appearanceData.iNPC_ID] = npc;
|
||||||
|
TableData::RunningMobs[npc->appearanceData.iNPC_ID] = npc;
|
||||||
|
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, mob["iX"], mob["iY"], mob["iZ"]);
|
||||||
|
|
||||||
|
// re-enable respawning
|
||||||
|
npc->summoned = false;
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "[INFO] Loaded gruntwork.json" << std::endl;
|
std::cout << "[INFO] Loaded gruntwork.json" << std::endl;
|
||||||
}
|
}
|
||||||
catch (const std::exception& err) {
|
catch (const std::exception& err) {
|
||||||
@ -417,5 +435,24 @@ void TableData::flush() {
|
|||||||
gruntwork["rotations"].push_back(rotation);
|
gruntwork["rotations"].push_back(rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& pair : RunningMobs) {
|
||||||
|
nlohmann::json mob;
|
||||||
|
Mob *m = (Mob*)pair.second; // we need spawnX, etc
|
||||||
|
|
||||||
|
if (NPCManager::NPCs.find(pair.first) == NPCManager::NPCs.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// NOTE: this format deviates slightly from the one in mobs.json
|
||||||
|
mob["iNPCType"] = (int)m->appearanceData.iNPCType;
|
||||||
|
mob["iHP"] = (int)m->maxHealth;
|
||||||
|
mob["iX"] = m->spawnX;
|
||||||
|
mob["iY"] = m->spawnY;
|
||||||
|
mob["iZ"] = m->spawnZ;
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
gruntwork["mobs"].push_back(mob);
|
||||||
|
}
|
||||||
|
|
||||||
file << gruntwork << std::endl;
|
file << gruntwork << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,11 @@
|
|||||||
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, BaseNPC*> RunningMobs;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void loadGruntwork();
|
void loadGruntwork(int32_t*);
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
int getItemType(int);
|
int getItemType(int);
|
||||||
|
@ -3,4 +3,6 @@ leak:ChunkManager::addPlayer
|
|||||||
leak:ChunkManager::addNPC
|
leak:ChunkManager::addNPC
|
||||||
leak:NPCManager::updateNPCPosition
|
leak:NPCManager::updateNPCPosition
|
||||||
leak:NPCManager::npcSummonHandler
|
leak:NPCManager::npcSummonHandler
|
||||||
|
leak:summonWCommand
|
||||||
|
leak:TableData::loadGruntwork
|
||||||
leak:nlohmann::basic_json
|
leak:nlohmann::basic_json
|
||||||
|
Loading…
Reference in New Issue
Block a user