mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 21:40:05 +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) {
|
void summonWCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
if (args.size() < 2) {
|
if (args.size() < 2) {
|
||||||
ChatManager::sendServerMessage(sock, "/level: no mob type specified");
|
ChatManager::sendServerMessage(sock, "/summonW: no mob type specified");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
@ -225,7 +225,7 @@ void summonWCommand(std::string full, std::vector<std::string>& args, CNSocket*
|
|||||||
|
|
||||||
BaseNPC *npc = nullptr;
|
BaseNPC *npc = nullptr;
|
||||||
if (team == 2) {
|
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;
|
npc->appearanceData.iAngle = (plr->angle + 180) % 360;
|
||||||
|
|
||||||
NPCManager::NPCs[npc->appearanceData.iNPC_ID] = npc;
|
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);
|
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) +
|
ChatManager::sendServerMessage(sock, "/summonW: placed mob with type: " + std::to_string(type) +
|
||||||
", id: " + std::to_string(npc->appearanceData.iNPC_ID));
|
", 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) {
|
void unsummonWCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "TransportManager.hpp"
|
#include "TransportManager.hpp"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <limits.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
std::map<int32_t, Mob*> MobManager::Mobs;
|
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
|
// 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"]) {
|
if (distance >= mob->data["m_iCombatRange"]) {
|
||||||
mob->target = nullptr;
|
mob->target = nullptr;
|
||||||
mob->state = MobState::RETREAT;
|
mob->state = MobState::RETREAT;
|
||||||
@ -1034,6 +1036,9 @@ void MobManager::resendMobHP(Mob *mob) {
|
|||||||
* as the mob, since it might be near a chunk boundary.
|
* as the mob, since it might be near a chunk boundary.
|
||||||
*/
|
*/
|
||||||
bool MobManager::aggroCheck(Mob *mob, time_t currTime) {
|
bool MobManager::aggroCheck(Mob *mob, time_t currTime) {
|
||||||
|
CNSocket *closest = nullptr;
|
||||||
|
int closestDistance = INT_MAX;
|
||||||
|
|
||||||
for (Chunk *chunk : mob->currentChunks) {
|
for (Chunk *chunk : mob->currentChunks) {
|
||||||
for (CNSocket *s : chunk->players) {
|
for (CNSocket *s : chunk->players) {
|
||||||
Player *plr = s->plr;
|
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 xyDistance = hypot(mob->appearanceData.iX - plr->x, mob->appearanceData.iY - plr->y);
|
||||||
int distance = hypot(xyDistance, mob->appearanceData.iZ - plr->z);
|
int distance = hypot(xyDistance, mob->appearanceData.iZ - plr->z);
|
||||||
|
|
||||||
if (distance > mobRange)
|
if (distance > mobRange || distance > closestDistance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// found player. engage.
|
// found a player
|
||||||
mob->target = s;
|
closest = s;
|
||||||
mob->state = MobState::COMBAT;
|
closestDistance = distance;
|
||||||
mob->nextMovement = currTime;
|
|
||||||
mob->nextAttack = 0;
|
|
||||||
|
|
||||||
mob->roamX = mob->appearanceData.iX;
|
|
||||||
mob->roamY = mob->appearanceData.iY;
|
|
||||||
mob->roamZ = mob->appearanceData.iZ;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,8 @@ void TableData::init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& err) {
|
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
|
// load everything else from xdttable
|
||||||
@ -176,7 +177,8 @@ void TableData::init() {
|
|||||||
std::cout << "[INFO] Loaded " << NanoManager::NanoTable.size() << " nanos" << std::endl;
|
std::cout << "[INFO] Loaded " << NanoManager::NanoTable.size() << " nanos" << std::endl;
|
||||||
}
|
}
|
||||||
catch (const std::exception& err) {
|
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
|
// load temporary mob dump
|
||||||
@ -203,7 +205,8 @@ void TableData::init() {
|
|||||||
std::cout << "[INFO] Populated " << NPCManager::NPCs.size() << " NPCs" << std::endl;
|
std::cout << "[INFO] Populated " << NPCManager::NPCs.size() << " NPCs" << std::endl;
|
||||||
}
|
}
|
||||||
catch (const std::exception& err) {
|
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();
|
loadDrops();
|
||||||
@ -300,7 +303,8 @@ void TableData::loadPaths(int* nextId) {
|
|||||||
std::cout << "[INFO] Loaded " << TransportManager::NPCQueues.size() << " NPC paths" << std::endl;
|
std::cout << "[INFO] Loaded " << TransportManager::NPCQueues.size() << " NPC paths" << std::endl;
|
||||||
}
|
}
|
||||||
catch (const std::exception& err) {
|
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) {
|
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;
|
std::cout << "[INFO] Loaded gruntwork.json" << std::endl;
|
||||||
}
|
}
|
||||||
catch (const std::exception& err) {
|
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["iX"] = m->spawnX;
|
||||||
mob["iY"] = m->spawnY;
|
mob["iY"] = m->spawnY;
|
||||||
mob["iZ"] = m->spawnZ;
|
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
|
// 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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user