mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-12-23 11:50:04 +00:00
Minor tweaks.
* The server now refuses to start if any JSONs fail to load * Mobs now take height into account when losing aggro on a player * Mobs now aggro on the closest player in range, rather then on the earliest one to connect to the server of the ones in range * /summonW now works in IZs and Lairs as well * Lowered the extra height that mobs spawn at with /summonW to prevent glitching problems
This commit is contained in:
parent
3ce8cf2129
commit
bbd695cad1
@ -203,7 +203,7 @@ void mssCommand(std::string full, std::vector<std::string>& args, CNSocket* sock
|
||||
|
||||
void summonWCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||
if (args.size() < 2) {
|
||||
ChatManager::sendServerMessage(sock, "/level: no mob type specified");
|
||||
ChatManager::sendServerMessage(sock, "/summonW: no mob type specified");
|
||||
return;
|
||||
}
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
@ -225,7 +225,7 @@ void summonWCommand(std::string full, std::vector<std::string>& args, CNSocket*
|
||||
|
||||
BaseNPC *npc = nullptr;
|
||||
if (team == 2) {
|
||||
npc = new Mob(plr->x, plr->y, plr->z + 1000, plr->instanceID, type, NPCManager::NPCData[type], NPCManager::nextId++);
|
||||
npc = new Mob(plr->x, plr->y, plr->z + 200, plr->instanceID, type, NPCManager::NPCData[type], NPCManager::nextId++);
|
||||
npc->appearanceData.iAngle = (plr->angle + 180) % 360;
|
||||
|
||||
NPCManager::NPCs[npc->appearanceData.iNPC_ID] = npc;
|
||||
@ -240,9 +240,22 @@ void summonWCommand(std::string full, std::vector<std::string>& args, CNSocket*
|
||||
|
||||
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, plr->x, plr->y, plr->z);
|
||||
|
||||
// if we're in a lair, we need to spawn the mob in both the private instance and the template
|
||||
if ((plr->instanceID >> 32) != 0) {
|
||||
npc = new Mob(plr->x, plr->y, plr->z + 200, plr->instanceID & 0xffffffff, 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;
|
||||
|
||||
((Mob*)npc)->summoned = false;
|
||||
|
||||
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;
|
||||
TableData::RunningMobs[npc->appearanceData.iNPC_ID] = npc; // only record the one in the template
|
||||
}
|
||||
|
||||
void unsummonWCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "TransportManager.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
|
||||
std::map<int32_t, Mob*> MobManager::Mobs;
|
||||
@ -501,7 +502,8 @@ void MobManager::combatStep(Mob *mob, time_t currTime) {
|
||||
}
|
||||
|
||||
// retreat if the player leaves combat range
|
||||
distance = hypot(plr->x - mob->roamX, plr->y - mob->roamY);
|
||||
int xyDistance = hypot(plr->x - mob->roamX, plr->y - mob->roamY);
|
||||
distance = hypot(xyDistance, plr->z - mob->roamZ);
|
||||
if (distance >= mob->data["m_iCombatRange"]) {
|
||||
mob->target = nullptr;
|
||||
mob->state = MobState::RETREAT;
|
||||
@ -1034,6 +1036,9 @@ void MobManager::resendMobHP(Mob *mob) {
|
||||
* as the mob, since it might be near a chunk boundary.
|
||||
*/
|
||||
bool MobManager::aggroCheck(Mob *mob, time_t currTime) {
|
||||
CNSocket *closest = nullptr;
|
||||
int closestDistance = INT_MAX;
|
||||
|
||||
for (Chunk *chunk : mob->currentChunks) {
|
||||
for (CNSocket *s : chunk->players) {
|
||||
Player *plr = s->plr;
|
||||
@ -1053,22 +1058,28 @@ bool MobManager::aggroCheck(Mob *mob, time_t currTime) {
|
||||
int xyDistance = hypot(mob->appearanceData.iX - plr->x, mob->appearanceData.iY - plr->y);
|
||||
int distance = hypot(xyDistance, mob->appearanceData.iZ - plr->z);
|
||||
|
||||
if (distance > mobRange)
|
||||
if (distance > mobRange || distance > closestDistance)
|
||||
continue;
|
||||
|
||||
// found player. engage.
|
||||
mob->target = s;
|
||||
mob->state = MobState::COMBAT;
|
||||
mob->nextMovement = currTime;
|
||||
mob->nextAttack = 0;
|
||||
|
||||
mob->roamX = mob->appearanceData.iX;
|
||||
mob->roamY = mob->appearanceData.iY;
|
||||
mob->roamZ = mob->appearanceData.iZ;
|
||||
|
||||
return true;
|
||||
// found a player
|
||||
closest = s;
|
||||
closestDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (closest != nullptr) {
|
||||
// found closest player. engage.
|
||||
mob->target = closest;
|
||||
mob->state = MobState::COMBAT;
|
||||
mob->nextMovement = currTime;
|
||||
mob->nextAttack = 0;
|
||||
|
||||
mob->roamX = mob->appearanceData.iX;
|
||||
mob->roamY = mob->appearanceData.iY;
|
||||
mob->roamZ = mob->appearanceData.iZ;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -50,7 +50,8 @@ void TableData::init() {
|
||||
}
|
||||
}
|
||||
catch (const std::exception& err) {
|
||||
std::cerr << "[WARN] Malformed NPCs.json file! Reason:" << err.what() << std::endl;
|
||||
std::cerr << "[FATAL] Malformed NPCs.json file! Reason:" << err.what() << std::endl;
|
||||
terminate(0);
|
||||
}
|
||||
|
||||
// load everything else from xdttable
|
||||
@ -176,7 +177,8 @@ void TableData::init() {
|
||||
std::cout << "[INFO] Loaded " << NanoManager::NanoTable.size() << " nanos" << std::endl;
|
||||
}
|
||||
catch (const std::exception& err) {
|
||||
std::cerr << "[WARN] Malformed xdt.json file! Reason:" << err.what() << std::endl;
|
||||
std::cerr << "[FATAL] Malformed xdt.json file! Reason:" << err.what() << std::endl;
|
||||
terminate(0);
|
||||
}
|
||||
|
||||
// load temporary mob dump
|
||||
@ -203,7 +205,8 @@ void TableData::init() {
|
||||
std::cout << "[INFO] Populated " << NPCManager::NPCs.size() << " NPCs" << std::endl;
|
||||
}
|
||||
catch (const std::exception& err) {
|
||||
std::cerr << "[WARN] Malformed mobs.json file! Reason:" << err.what() << std::endl;
|
||||
std::cerr << "[FATAL] Malformed mobs.json file! Reason:" << err.what() << std::endl;
|
||||
terminate(0);
|
||||
}
|
||||
|
||||
loadDrops();
|
||||
@ -300,7 +303,8 @@ void TableData::loadPaths(int* nextId) {
|
||||
std::cout << "[INFO] Loaded " << TransportManager::NPCQueues.size() << " NPC paths" << std::endl;
|
||||
}
|
||||
catch (const std::exception& err) {
|
||||
std::cerr << "[WARN] Malformed paths.json file! Reason:" << err.what() << std::endl;
|
||||
std::cerr << "[FATAL] Malformed paths.json file! Reason:" << err.what() << std::endl;
|
||||
terminate(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,7 +417,8 @@ void TableData::loadDrops() {
|
||||
|
||||
}
|
||||
catch (const std::exception& err) {
|
||||
std::cerr << "[WARN] Malformed drops.json file! Reason:" << err.what() << std::endl;
|
||||
std::cerr << "[FATAL] Malformed drops.json file! Reason:" << err.what() << std::endl;
|
||||
terminate(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -563,7 +568,8 @@ void TableData::loadGruntwork(int32_t *nextId) {
|
||||
std::cout << "[INFO] Loaded gruntwork.json" << std::endl;
|
||||
}
|
||||
catch (const std::exception& err) {
|
||||
std::cerr << "[WARN] Malformed gruntwork.json file! Reason:" << err.what() << std::endl;
|
||||
std::cerr << "[FATAL] Malformed gruntwork.json file! Reason:" << err.what() << std::endl;
|
||||
terminate(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -623,7 +629,7 @@ void TableData::flush() {
|
||||
mob["iX"] = m->spawnX;
|
||||
mob["iY"] = m->spawnY;
|
||||
mob["iZ"] = m->spawnZ;
|
||||
mob["iMapNum"] = m->instanceID;
|
||||
mob["iMapNum"] = m->instanceID & 0xffffffff;
|
||||
// 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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user