mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 13:30:06 +00:00
[refactor] BaseNPC now uses Entity XYZ fields for handling positions
- fixed many references to Entity.appearanceData.i[XYZ] to use the base Entity XYZ values - BaseNPC::enterIntoViewOf grabs the position from the base Entity XYZ values - NPCManager::updateNPCPosition updates the base Entity XYZ values - MobAI.c/deadStep() also sends it's packet based on the Entity XYZ values
This commit is contained in:
parent
48fb510b53
commit
9b84d9dc4d
@ -273,7 +273,7 @@ void Chunking::createInstance(uint64_t instanceID) {
|
|||||||
if (((Mob*)baseNPC)->groupLeader != 0 && ((Mob*)baseNPC)->groupLeader != npcID)
|
if (((Mob*)baseNPC)->groupLeader != 0 && ((Mob*)baseNPC)->groupLeader != npcID)
|
||||||
continue; // follower; don't copy individually
|
continue; // follower; don't copy individually
|
||||||
|
|
||||||
Mob* newMob = new Mob(baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ, baseNPC->appearanceData.iAngle,
|
Mob* newMob = new Mob(baseNPC->x, baseNPC->y, baseNPC->z, baseNPC->appearanceData.iAngle,
|
||||||
instanceID, baseNPC->appearanceData.iNPCType, NPCManager::NPCData[baseNPC->appearanceData.iNPCType], NPCManager::nextId++);
|
instanceID, baseNPC->appearanceData.iNPCType, NPCManager::NPCData[baseNPC->appearanceData.iNPCType], NPCManager::nextId++);
|
||||||
NPCManager::NPCs[newMob->appearanceData.iNPC_ID] = newMob;
|
NPCManager::NPCs[newMob->appearanceData.iNPC_ID] = newMob;
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ void Chunking::createInstance(uint64_t instanceID) {
|
|||||||
int followerID = NPCManager::nextId++; // id for follower
|
int followerID = NPCManager::nextId++; // id for follower
|
||||||
BaseNPC* baseFollower = NPCManager::NPCs[mobData->groupMember[i]]; // follower from template
|
BaseNPC* baseFollower = NPCManager::NPCs[mobData->groupMember[i]]; // follower from template
|
||||||
// new follower instance
|
// new follower instance
|
||||||
Mob* newMobFollower = new Mob(baseFollower->appearanceData.iX, baseFollower->appearanceData.iY, baseFollower->appearanceData.iZ, baseFollower->appearanceData.iAngle,
|
Mob* newMobFollower = new Mob(baseFollower->x, baseFollower->y, baseFollower->z, baseFollower->appearanceData.iAngle,
|
||||||
instanceID, baseFollower->appearanceData.iNPCType, NPCManager::NPCData[baseFollower->appearanceData.iNPCType], followerID);
|
instanceID, baseFollower->appearanceData.iNPCType, NPCManager::NPCData[baseFollower->appearanceData.iNPCType], followerID);
|
||||||
// add follower to NPC maps
|
// add follower to NPC maps
|
||||||
NPCManager::NPCs[followerID] = newMobFollower;
|
NPCManager::NPCs[followerID] = newMobFollower;
|
||||||
@ -296,18 +296,18 @@ void Chunking::createInstance(uint64_t instanceID) {
|
|||||||
newMobFollower->offsetY = ((Mob*)baseFollower)->offsetY;
|
newMobFollower->offsetY = ((Mob*)baseFollower)->offsetY;
|
||||||
// add follower copy to leader copy
|
// add follower copy to leader copy
|
||||||
newMob->groupMember[i] = followerID;
|
newMob->groupMember[i] = followerID;
|
||||||
NPCManager::updateNPCPosition(followerID, baseFollower->appearanceData.iX, baseFollower->appearanceData.iY, baseFollower->appearanceData.iZ,
|
NPCManager::updateNPCPosition(followerID, baseFollower->x, baseFollower->y, baseFollower->z,
|
||||||
instanceID, baseFollower->appearanceData.iAngle);
|
instanceID, baseFollower->appearanceData.iAngle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NPCManager::updateNPCPosition(newMob->appearanceData.iNPC_ID, baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ,
|
NPCManager::updateNPCPosition(newMob->appearanceData.iNPC_ID, baseNPC->x, baseNPC->y, baseNPC->z,
|
||||||
instanceID, baseNPC->appearanceData.iAngle);
|
instanceID, baseNPC->appearanceData.iAngle);
|
||||||
} else {
|
} else {
|
||||||
BaseNPC* newNPC = new BaseNPC(baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ, baseNPC->appearanceData.iAngle,
|
BaseNPC* newNPC = new BaseNPC(baseNPC->x, baseNPC->y, baseNPC->z, baseNPC->appearanceData.iAngle,
|
||||||
instanceID, baseNPC->appearanceData.iNPCType, NPCManager::nextId++);
|
instanceID, baseNPC->appearanceData.iNPCType, NPCManager::nextId++);
|
||||||
NPCManager::NPCs[newNPC->appearanceData.iNPC_ID] = newNPC;
|
NPCManager::NPCs[newNPC->appearanceData.iNPC_ID] = newNPC;
|
||||||
NPCManager::updateNPCPosition(newNPC->appearanceData.iNPC_ID, baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ,
|
NPCManager::updateNPCPosition(newNPC->appearanceData.iNPC_ID, baseNPC->x, baseNPC->y, baseNPC->z,
|
||||||
instanceID, baseNPC->appearanceData.iAngle);
|
instanceID, baseNPC->appearanceData.iAngle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,9 +321,9 @@ static void toggleAiCommand(std::string full, std::vector<std::string>& args, CN
|
|||||||
|
|
||||||
// mobs with static paths can chill where they are
|
// mobs with static paths can chill where they are
|
||||||
if (mob->staticPath) {
|
if (mob->staticPath) {
|
||||||
mob->roamX = mob->appearanceData.iX;
|
mob->roamX = mob->x;
|
||||||
mob->roamY = mob->appearanceData.iY;
|
mob->roamY = mob->y;
|
||||||
mob->roamZ = mob->appearanceData.iZ;
|
mob->roamZ = mob->z;
|
||||||
} else {
|
} else {
|
||||||
mob->roamX = mob->spawnX;
|
mob->roamX = mob->spawnX;
|
||||||
mob->roamY = mob->spawnY;
|
mob->roamY = mob->spawnY;
|
||||||
@ -343,11 +343,11 @@ static void npcRotateCommand(std::string full, std::vector<std::string>& args, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
int angle = (plr->angle + 180) % 360;
|
int angle = (plr->angle + 180) % 360;
|
||||||
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, npc->appearanceData.iX, npc->appearanceData.iY, npc->appearanceData.iZ, npc->instanceID, angle);
|
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, npc->x, npc->y, npc->z, npc->instanceID, angle);
|
||||||
|
|
||||||
// if it's a gruntwork NPC, rotate in-place
|
// if it's a gruntwork NPC, rotate in-place
|
||||||
if (TableData::RunningMobs.find(npc->appearanceData.iNPC_ID) != TableData::RunningMobs.end()) {
|
if (TableData::RunningMobs.find(npc->appearanceData.iNPC_ID) != TableData::RunningMobs.end()) {
|
||||||
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, npc->appearanceData.iX, npc->appearanceData.iY, npc->appearanceData.iZ, npc->instanceID, angle);
|
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, npc->x, npc->y, npc->z, npc->instanceID, angle);
|
||||||
|
|
||||||
Chat::sendServerMessage(sock, "[NPCR] Successfully set angle to " + std::to_string(angle) + " for gruntwork NPC "
|
Chat::sendServerMessage(sock, "[NPCR] Successfully set angle to " + std::to_string(angle) + " for gruntwork NPC "
|
||||||
+ std::to_string(npc->appearanceData.iNPC_ID));
|
+ std::to_string(npc->appearanceData.iNPC_ID));
|
||||||
@ -435,7 +435,7 @@ static void npcInstanceCommand(std::string full, std::vector<std::string>& args,
|
|||||||
|
|
||||||
Chat::sendServerMessage(sock, "[NPCI] Moving NPC with ID " + std::to_string(npc->appearanceData.iNPC_ID) + " to instance " + std::to_string(instance));
|
Chat::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;
|
TableData::RunningNPCMapNumbers[npc->appearanceData.iNPC_ID] = instance;
|
||||||
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, npc->appearanceData.iX, npc->appearanceData.iY, npc->appearanceData.iZ, instance, npc->appearanceData.iAngle);
|
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, npc->x, npc->y, npc->z, instance, npc->appearanceData.iAngle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void minfoCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
static void minfoCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
@ -666,9 +666,9 @@ static void whoisCommand(std::string full, std::vector<std::string>& args, CNSoc
|
|||||||
Chat::sendServerMessage(sock, "[WHOIS] HP: " + std::to_string(npc->appearanceData.iHP));
|
Chat::sendServerMessage(sock, "[WHOIS] HP: " + std::to_string(npc->appearanceData.iHP));
|
||||||
Chat::sendServerMessage(sock, "[WHOIS] CBF: " + std::to_string(npc->appearanceData.iConditionBitFlag));
|
Chat::sendServerMessage(sock, "[WHOIS] CBF: " + std::to_string(npc->appearanceData.iConditionBitFlag));
|
||||||
Chat::sendServerMessage(sock, "[WHOIS] EntityType: " + std::to_string((int)npc->type));
|
Chat::sendServerMessage(sock, "[WHOIS] EntityType: " + std::to_string((int)npc->type));
|
||||||
Chat::sendServerMessage(sock, "[WHOIS] X: " + std::to_string(npc->appearanceData.iX));
|
Chat::sendServerMessage(sock, "[WHOIS] X: " + std::to_string(npc->x));
|
||||||
Chat::sendServerMessage(sock, "[WHOIS] Y: " + std::to_string(npc->appearanceData.iY));
|
Chat::sendServerMessage(sock, "[WHOIS] Y: " + std::to_string(npc->y));
|
||||||
Chat::sendServerMessage(sock, "[WHOIS] Z: " + std::to_string(npc->appearanceData.iZ));
|
Chat::sendServerMessage(sock, "[WHOIS] Z: " + std::to_string(npc->z));
|
||||||
Chat::sendServerMessage(sock, "[WHOIS] Angle: " + std::to_string(npc->appearanceData.iAngle));
|
Chat::sendServerMessage(sock, "[WHOIS] Angle: " + std::to_string(npc->appearanceData.iAngle));
|
||||||
std::string chunkPosition = std::to_string(std::get<0>(npc->chunkPos)) + ", " + std::to_string(std::get<1>(npc->chunkPos)) + ", " + std::to_string(std::get<2>(npc->chunkPos));
|
std::string chunkPosition = std::to_string(std::get<0>(npc->chunkPos)) + ", " + std::to_string(std::get<1>(npc->chunkPos)) + ", " + std::to_string(std::get<2>(npc->chunkPos));
|
||||||
Chat::sendServerMessage(sock, "[WHOIS] Chunk: {" + chunkPosition + "}");
|
Chat::sendServerMessage(sock, "[WHOIS] Chunk: {" + chunkPosition + "}");
|
||||||
|
@ -174,7 +174,7 @@ static void eggPickup(CNSocket* sock, CNPacketData* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* this has some issues with position desync, leaving it out for now
|
/* this has some issues with position desync, leaving it out for now
|
||||||
if (abs(egg->appearanceData.iX - plr->x)>500 || abs(egg->appearanceData.iY - plr->y) > 500) {
|
if (abs(egg->x - plr->x)>500 || abs(egg->y - plr->y) > 500) {
|
||||||
std::cout << "[WARN] Player tried to open an egg isn't nearby?!" << std::endl;
|
std::cout << "[WARN] Player tried to open an egg isn't nearby?!" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,9 @@ Entity *EntityRef::getEntity() const {
|
|||||||
void BaseNPC::enterIntoViewOf(CNSocket *sock) {
|
void BaseNPC::enterIntoViewOf(CNSocket *sock) {
|
||||||
INITSTRUCT(sP_FE2CL_NPC_ENTER, pkt);
|
INITSTRUCT(sP_FE2CL_NPC_ENTER, pkt);
|
||||||
pkt.NPCAppearanceData = appearanceData;
|
pkt.NPCAppearanceData = appearanceData;
|
||||||
|
pkt.NPCAppearanceData.iX = x;
|
||||||
|
pkt.NPCAppearanceData.iY = y;
|
||||||
|
pkt.NPCAppearanceData.iZ = z;
|
||||||
sock->sendPacket(pkt, P_FE2CL_NPC_ENTER);
|
sock->sendPacket(pkt, P_FE2CL_NPC_ENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +57,7 @@ void Bus::enterIntoViewOf(CNSocket *sock) {
|
|||||||
// TODO: Potentially decouple this from BaseNPC?
|
// TODO: Potentially decouple this from BaseNPC?
|
||||||
pkt.AppearanceData = {
|
pkt.AppearanceData = {
|
||||||
3, appearanceData.iNPC_ID, appearanceData.iNPCType,
|
3, appearanceData.iNPC_ID, appearanceData.iNPCType,
|
||||||
appearanceData.iX, appearanceData.iY, appearanceData.iZ
|
x, y, z
|
||||||
};
|
};
|
||||||
|
|
||||||
sock->sendPacket(pkt, P_FE2CL_TRANSPORTATION_ENTER);
|
sock->sendPacket(pkt, P_FE2CL_TRANSPORTATION_ENTER);
|
||||||
|
@ -77,10 +77,10 @@ class BaseNPC : public Entity {
|
|||||||
public:
|
public:
|
||||||
sNPCAppearanceData appearanceData = {};
|
sNPCAppearanceData appearanceData = {};
|
||||||
|
|
||||||
BaseNPC(int x, int y, int z, int angle, uint64_t iID, int t, int id) { // XXX
|
BaseNPC(int _X, int _Y, int _Z, int angle, uint64_t iID, int t, int id) { // XXX
|
||||||
appearanceData.iX = x;
|
x = _X;
|
||||||
appearanceData.iY = y;
|
y = _Y;
|
||||||
appearanceData.iZ = z;
|
z = _Z;
|
||||||
appearanceData.iNPCType = t;
|
appearanceData.iNPCType = t;
|
||||||
appearanceData.iHP = 400;
|
appearanceData.iHP = 400;
|
||||||
appearanceData.iAngle = angle;
|
appearanceData.iAngle = angle;
|
||||||
|
@ -147,8 +147,8 @@ bool MobAI::aggroCheck(Mob *mob, time_t currTime) {
|
|||||||
mobRange = -1;
|
mobRange = -1;
|
||||||
|
|
||||||
// height is relevant for aggro distance because of platforming
|
// height is relevant for aggro distance because of platforming
|
||||||
int xyDistance = hypot(mob->appearanceData.iX - plr->x, mob->appearanceData.iY - plr->y);
|
int xyDistance = hypot(mob->x - plr->x, mob->y - plr->y);
|
||||||
int distance = hypot(xyDistance, (mob->appearanceData.iZ - plr->z) * 2); // difference in Z counts twice
|
int distance = hypot(xyDistance, (mob->z - plr->z) * 2); // difference in Z counts twice
|
||||||
|
|
||||||
if (distance > mobRange || distance > closestDistance)
|
if (distance > mobRange || distance > closestDistance)
|
||||||
continue;
|
continue;
|
||||||
@ -394,9 +394,9 @@ void MobAI::enterCombat(CNSocket *sock, Mob *mob) {
|
|||||||
mob->nextMovement = getTime();
|
mob->nextMovement = getTime();
|
||||||
mob->nextAttack = 0;
|
mob->nextAttack = 0;
|
||||||
|
|
||||||
mob->roamX = mob->appearanceData.iX;
|
mob->roamX = mob->x;
|
||||||
mob->roamY = mob->appearanceData.iY;
|
mob->roamY = mob->y;
|
||||||
mob->roamZ = mob->appearanceData.iZ;
|
mob->roamZ = mob->z;
|
||||||
|
|
||||||
int skillID = (int)mob->data["m_iPassiveBuff"]; // cast passive
|
int skillID = (int)mob->data["m_iPassiveBuff"]; // cast passive
|
||||||
std::vector<int> targetData = {1, mob->appearanceData.iNPC_ID, 0, 0, 0};
|
std::vector<int> targetData = {1, mob->appearanceData.iNPC_ID, 0, 0, 0};
|
||||||
@ -453,9 +453,9 @@ static void deadStep(Mob *mob, time_t currTime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pre-set spawn coordinates if not marked for removal
|
// pre-set spawn coordinates if not marked for removal
|
||||||
mob->appearanceData.iX = mob->spawnX;
|
mob->x = mob->spawnX;
|
||||||
mob->appearanceData.iY = mob->spawnY;
|
mob->y = mob->spawnY;
|
||||||
mob->appearanceData.iZ = mob->spawnZ;
|
mob->z = mob->spawnZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// to guide their groupmates, group leaders still need to move despite being dead
|
// to guide their groupmates, group leaders still need to move despite being dead
|
||||||
@ -474,9 +474,9 @@ static void deadStep(Mob *mob, time_t currTime) {
|
|||||||
if (mob->groupLeader != 0) {
|
if (mob->groupLeader != 0) {
|
||||||
if (NPCManager::NPCs.find(mob->groupLeader) != NPCManager::NPCs.end() && NPCManager::NPCs[mob->groupLeader]->type == EntityType::MOB) {
|
if (NPCManager::NPCs.find(mob->groupLeader) != NPCManager::NPCs.end() && NPCManager::NPCs[mob->groupLeader]->type == EntityType::MOB) {
|
||||||
Mob* leaderMob = (Mob*)NPCManager::NPCs[mob->groupLeader];
|
Mob* leaderMob = (Mob*)NPCManager::NPCs[mob->groupLeader];
|
||||||
mob->appearanceData.iX = leaderMob->appearanceData.iX + mob->offsetX;
|
mob->x = leaderMob->x + mob->offsetX;
|
||||||
mob->appearanceData.iY = leaderMob->appearanceData.iY + mob->offsetY;
|
mob->y = leaderMob->y + mob->offsetY;
|
||||||
mob->appearanceData.iZ = leaderMob->appearanceData.iZ;
|
mob->z = leaderMob->z;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "[WARN] deadStep: mob cannot find it's leader!" << std::endl;
|
std::cout << "[WARN] deadStep: mob cannot find it's leader!" << std::endl;
|
||||||
}
|
}
|
||||||
@ -485,6 +485,9 @@ static void deadStep(Mob *mob, time_t currTime) {
|
|||||||
INITSTRUCT(sP_FE2CL_NPC_NEW, pkt);
|
INITSTRUCT(sP_FE2CL_NPC_NEW, pkt);
|
||||||
|
|
||||||
pkt.NPCAppearanceData = mob->appearanceData;
|
pkt.NPCAppearanceData = mob->appearanceData;
|
||||||
|
pkt.NPCAppearanceData.iX = mob->x;
|
||||||
|
pkt.NPCAppearanceData.iY = mob->y;
|
||||||
|
pkt.NPCAppearanceData.iZ = mob->z;
|
||||||
|
|
||||||
// notify all nearby players
|
// notify all nearby players
|
||||||
NPCManager::sendToViewable(mob, &pkt, P_FE2CL_NPC_NEW, sizeof(sP_FE2CL_NPC_NEW));
|
NPCManager::sendToViewable(mob, &pkt, P_FE2CL_NPC_NEW, sizeof(sP_FE2CL_NPC_NEW));
|
||||||
@ -556,7 +559,7 @@ static void combatStep(Mob *mob, time_t currTime) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int distance = hypot(plr->x - mob->appearanceData.iX, plr->y - mob->appearanceData.iY);
|
int distance = hypot(plr->x - mob->x, plr->y - mob->y);
|
||||||
int mobRange = (int)mob->data["m_iAtkRange"] + (int)mob->data["m_iRadius"];
|
int mobRange = (int)mob->data["m_iAtkRange"] + (int)mob->data["m_iRadius"];
|
||||||
|
|
||||||
if (currTime >= mob->nextAttack) {
|
if (currTime >= mob->nextAttack) {
|
||||||
@ -588,18 +591,18 @@ static void combatStep(Mob *mob, time_t currTime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
distanceToTravel = std::min(distance-mobRange+1, speed*2/5);
|
distanceToTravel = std::min(distance-mobRange+1, speed*2/5);
|
||||||
auto targ = lerp(mob->appearanceData.iX, mob->appearanceData.iY, targetX, targetY, distanceToTravel);
|
auto targ = lerp(mob->x, mob->y, targetX, targetY, distanceToTravel);
|
||||||
if (distanceToTravel < speed*2/5 && currTime >= mob->nextAttack)
|
if (distanceToTravel < speed*2/5 && currTime >= mob->nextAttack)
|
||||||
mob->nextAttack = 0;
|
mob->nextAttack = 0;
|
||||||
|
|
||||||
NPCManager::updateNPCPosition(mob->appearanceData.iNPC_ID, targ.first, targ.second, mob->appearanceData.iZ, mob->instanceID, mob->appearanceData.iAngle);
|
NPCManager::updateNPCPosition(mob->appearanceData.iNPC_ID, targ.first, targ.second, mob->z, mob->instanceID, mob->appearanceData.iAngle);
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_NPC_MOVE, pkt);
|
INITSTRUCT(sP_FE2CL_NPC_MOVE, pkt);
|
||||||
|
|
||||||
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
||||||
pkt.iSpeed = speed;
|
pkt.iSpeed = speed;
|
||||||
pkt.iToX = mob->appearanceData.iX = targ.first;
|
pkt.iToX = mob->x = targ.first;
|
||||||
pkt.iToY = mob->appearanceData.iY = targ.second;
|
pkt.iToY = mob->y = targ.second;
|
||||||
pkt.iToZ = plr->z;
|
pkt.iToZ = plr->z;
|
||||||
pkt.iMoveStyle = 1;
|
pkt.iMoveStyle = 1;
|
||||||
|
|
||||||
@ -681,13 +684,13 @@ static void roamingStep(Mob *mob, time_t currTime) {
|
|||||||
farX = xStart + rand() % mob->idleRange;
|
farX = xStart + rand() % mob->idleRange;
|
||||||
farY = yStart + rand() % mob->idleRange;
|
farY = yStart + rand() % mob->idleRange;
|
||||||
|
|
||||||
distance = std::abs(std::max(farX - mob->appearanceData.iX, farY - mob->appearanceData.iY));
|
distance = std::abs(std::max(farX - mob->x, farY - mob->y));
|
||||||
if (distance == 0)
|
if (distance == 0)
|
||||||
distance += 1; // hack to avoid FPE
|
distance += 1; // hack to avoid FPE
|
||||||
|
|
||||||
// if it's too short a walk, go further in that direction
|
// if it's too short a walk, go further in that direction
|
||||||
farX = mob->appearanceData.iX + (farX - mob->appearanceData.iX) * minDistance / distance;
|
farX = mob->x + (farX - mob->x) * minDistance / distance;
|
||||||
farY = mob->appearanceData.iY + (farY - mob->appearanceData.iY) * minDistance / distance;
|
farY = mob->y + (farY - mob->y) * minDistance / distance;
|
||||||
|
|
||||||
// but don't got out of bounds
|
// but don't got out of bounds
|
||||||
farX = std::clamp(farX, xStart, xStart + mob->idleRange);
|
farX = std::clamp(farX, xStart, xStart + mob->idleRange);
|
||||||
@ -698,8 +701,8 @@ static void roamingStep(Mob *mob, time_t currTime) {
|
|||||||
speed /= 2;
|
speed /= 2;
|
||||||
|
|
||||||
std::queue<WarpLocation> queue;
|
std::queue<WarpLocation> queue;
|
||||||
WarpLocation from = { mob->appearanceData.iX, mob->appearanceData.iY, mob->appearanceData.iZ };
|
WarpLocation from = { mob->x, mob->y, mob->z };
|
||||||
WarpLocation to = { farX, farY, mob->appearanceData.iZ };
|
WarpLocation to = { farX, farY, mob->z };
|
||||||
|
|
||||||
// add a route to the queue; to be processed in Transport::stepNPCPathing()
|
// add a route to the queue; to be processed in Transport::stepNPCPathing()
|
||||||
Transport::lerp(&queue, from, to, speed);
|
Transport::lerp(&queue, from, to, speed);
|
||||||
@ -718,8 +721,8 @@ static void roamingStep(Mob *mob, time_t currTime) {
|
|||||||
|
|
||||||
std::queue<WarpLocation> queue2;
|
std::queue<WarpLocation> queue2;
|
||||||
Mob* followerMob = (Mob*)NPCManager::NPCs[mob->groupMember[i]];
|
Mob* followerMob = (Mob*)NPCManager::NPCs[mob->groupMember[i]];
|
||||||
from = { followerMob->appearanceData.iX, followerMob->appearanceData.iY, followerMob->appearanceData.iZ };
|
from = { followerMob->x, followerMob->y, followerMob->z };
|
||||||
to = { farX + followerMob->offsetX, farY + followerMob->offsetY, followerMob->appearanceData.iZ };
|
to = { farX + followerMob->offsetX, farY + followerMob->offsetY, followerMob->z };
|
||||||
Transport::lerp(&queue2, from, to, speed);
|
Transport::lerp(&queue2, from, to, speed);
|
||||||
Transport::NPCQueues[followerMob->appearanceData.iNPC_ID] = queue2;
|
Transport::NPCQueues[followerMob->appearanceData.iNPC_ID] = queue2;
|
||||||
}
|
}
|
||||||
@ -733,19 +736,19 @@ static void retreatStep(Mob *mob, time_t currTime) {
|
|||||||
mob->nextMovement = currTime + 400;
|
mob->nextMovement = currTime + 400;
|
||||||
|
|
||||||
// distance between spawn point and current location
|
// distance between spawn point and current location
|
||||||
int distance = hypot(mob->appearanceData.iX - mob->roamX, mob->appearanceData.iY - mob->roamY);
|
int distance = hypot(mob->x - mob->roamX, mob->y - mob->roamY);
|
||||||
|
|
||||||
//if (distance > mob->data["m_iIdleRange"]) {
|
//if (distance > mob->data["m_iIdleRange"]) {
|
||||||
if (distance > 10) {
|
if (distance > 10) {
|
||||||
INITSTRUCT(sP_FE2CL_NPC_MOVE, pkt);
|
INITSTRUCT(sP_FE2CL_NPC_MOVE, pkt);
|
||||||
|
|
||||||
auto targ = lerp(mob->appearanceData.iX, mob->appearanceData.iY, mob->roamX, mob->roamY, (int)mob->data["m_iRunSpeed"]*4/5);
|
auto targ = lerp(mob->x, mob->y, mob->roamX, mob->roamY, (int)mob->data["m_iRunSpeed"]*4/5);
|
||||||
|
|
||||||
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
||||||
pkt.iSpeed = (int)mob->data["m_iRunSpeed"] * 2;
|
pkt.iSpeed = (int)mob->data["m_iRunSpeed"] * 2;
|
||||||
pkt.iToX = mob->appearanceData.iX = targ.first;
|
pkt.iToX = mob->x = targ.first;
|
||||||
pkt.iToY = mob->appearanceData.iY = targ.second;
|
pkt.iToY = mob->y = targ.second;
|
||||||
pkt.iToZ = mob->appearanceData.iZ = mob->spawnZ;
|
pkt.iToZ = mob->z = mob->spawnZ;
|
||||||
pkt.iMoveStyle = 1;
|
pkt.iMoveStyle = 1;
|
||||||
|
|
||||||
// notify all nearby players
|
// notify all nearby players
|
||||||
|
@ -68,9 +68,9 @@ struct Mob : public CombatNPC {
|
|||||||
dropType = data["m_iDropType"];
|
dropType = data["m_iDropType"];
|
||||||
level = data["m_iNpcLevel"];
|
level = data["m_iNpcLevel"];
|
||||||
|
|
||||||
roamX = spawnX = appearanceData.iX;
|
roamX = spawnX = x;
|
||||||
roamY = spawnY = appearanceData.iY;
|
roamY = spawnY = y;
|
||||||
roamZ = spawnZ = appearanceData.iZ;
|
roamZ = spawnZ = z;
|
||||||
|
|
||||||
offsetX = 0;
|
offsetX = 0;
|
||||||
offsetY = 0;
|
offsetY = 0;
|
||||||
|
@ -69,9 +69,9 @@ void NPCManager::updateNPCPosition(int32_t id, int X, int Y, int Z, uint64_t I,
|
|||||||
npc->appearanceData.iAngle = angle;
|
npc->appearanceData.iAngle = angle;
|
||||||
ChunkPos oldChunk = npc->chunkPos;
|
ChunkPos oldChunk = npc->chunkPos;
|
||||||
ChunkPos newChunk = Chunking::chunkPosAt(X, Y, I);
|
ChunkPos newChunk = Chunking::chunkPosAt(X, Y, I);
|
||||||
npc->appearanceData.iX = X;
|
npc->x = X;
|
||||||
npc->appearanceData.iY = Y;
|
npc->y = Y;
|
||||||
npc->appearanceData.iZ = Z;
|
npc->z = Z;
|
||||||
npc->instanceID = I;
|
npc->instanceID = I;
|
||||||
if (oldChunk == newChunk)
|
if (oldChunk == newChunk)
|
||||||
return; // didn't change chunks
|
return; // didn't change chunks
|
||||||
@ -280,8 +280,8 @@ BaseNPC* NPCManager::getNearestNPC(std::set<Chunk*>* chunks, int X, int Y, int Z
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
BaseNPC* npcTemp = (BaseNPC*)ent->getEntity();
|
BaseNPC* npcTemp = (BaseNPC*)ent->getEntity();
|
||||||
int distXY = std::hypot(X - npcTemp->appearanceData.iX, Y - npcTemp->appearanceData.iY);
|
int distXY = std::hypot(X - npcTemp->x, Y - npcTemp->y);
|
||||||
int dist = std::hypot(distXY, Z - npcTemp->appearanceData.iZ);
|
int dist = std::hypot(distXY, Z - npcTemp->z);
|
||||||
if (dist < lastDist) {
|
if (dist < lastDist) {
|
||||||
npc = npcTemp;
|
npc = npcTemp;
|
||||||
lastDist = dist;
|
lastDist = dist;
|
||||||
|
@ -333,9 +333,9 @@ static void nanoRecallRegisterHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_REGIST_RXCOM, response);
|
INITSTRUCT(sP_FE2CL_REP_REGIST_RXCOM, response);
|
||||||
response.iMapNum = plr->recallInstance = (int32_t)npc->instanceID; // Never going to recall into a Fusion Lair
|
response.iMapNum = plr->recallInstance = (int32_t)npc->instanceID; // Never going to recall into a Fusion Lair
|
||||||
response.iX = plr->recallX = npc->appearanceData.iX;
|
response.iX = plr->recallX = npc->x;
|
||||||
response.iY = plr->recallY = npc->appearanceData.iY;
|
response.iY = plr->recallY = npc->y;
|
||||||
response.iZ = plr->recallZ = npc->appearanceData.iZ;
|
response.iZ = plr->recallZ = npc->z;
|
||||||
sock->sendPacket(response, P_FE2CL_REP_REGIST_RXCOM);
|
sock->sendPacket(response, P_FE2CL_REP_REGIST_RXCOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ static void loadPaths(int* nextId) {
|
|||||||
// spawn a slider
|
// spawn a slider
|
||||||
Bus* slider = new Bus(point.x, point.y, point.z, 0, INSTANCE_OVERWORLD, 1, (*nextId)++);
|
Bus* slider = new Bus(point.x, point.y, point.z, 0, INSTANCE_OVERWORLD, 1, (*nextId)++);
|
||||||
NPCManager::NPCs[slider->appearanceData.iNPC_ID] = slider;
|
NPCManager::NPCs[slider->appearanceData.iNPC_ID] = slider;
|
||||||
NPCManager::updateNPCPosition(slider->appearanceData.iNPC_ID, slider->appearanceData.iX, slider->appearanceData.iY, slider->appearanceData.iZ, INSTANCE_OVERWORLD, 0);
|
NPCManager::updateNPCPosition(slider->appearanceData.iNPC_ID, slider->x, slider->y, slider->z, INSTANCE_OVERWORLD, 0);
|
||||||
Transport::NPCQueues[slider->appearanceData.iNPC_ID] = route;
|
Transport::NPCQueues[slider->appearanceData.iNPC_ID] = route;
|
||||||
}
|
}
|
||||||
// rotate
|
// rotate
|
||||||
@ -456,8 +456,8 @@ static void loadGruntwork(int32_t *nextId) {
|
|||||||
if (NPCManager::NPCs.find(npcID) == NPCManager::NPCs.end())
|
if (NPCManager::NPCs.find(npcID) == NPCManager::NPCs.end())
|
||||||
continue; // NPC not found
|
continue; // NPC not found
|
||||||
BaseNPC* npc = NPCManager::NPCs[npcID];
|
BaseNPC* npc = NPCManager::NPCs[npcID];
|
||||||
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, npc->appearanceData.iX, npc->appearanceData.iY,
|
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, npc->x, npc->y,
|
||||||
npc->appearanceData.iZ, instanceID, npc->appearanceData.iAngle);
|
npc->z, instanceID, npc->appearanceData.iAngle);
|
||||||
|
|
||||||
RunningNPCMapNumbers[npcID] = instanceID;
|
RunningNPCMapNumbers[npcID] = instanceID;
|
||||||
}
|
}
|
||||||
@ -967,9 +967,9 @@ void TableData::flush() {
|
|||||||
y = m->spawnY;
|
y = m->spawnY;
|
||||||
z = m->spawnZ;
|
z = m->spawnZ;
|
||||||
} else {
|
} else {
|
||||||
x = npc->appearanceData.iX;
|
x = npc->x;
|
||||||
y = npc->appearanceData.iY;
|
y = npc->y;
|
||||||
z = npc->appearanceData.iZ;
|
z = npc->z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: this format deviates slightly from the one in mobs.json
|
// NOTE: this format deviates slightly from the one in mobs.json
|
||||||
@ -1014,9 +1014,9 @@ void TableData::flush() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x = npc->appearanceData.iX;
|
x = npc->x;
|
||||||
y = npc->appearanceData.iY;
|
y = npc->y;
|
||||||
z = npc->appearanceData.iZ;
|
z = npc->z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: this format deviates slightly from the one in mobs.json
|
// NOTE: this format deviates slightly from the one in mobs.json
|
||||||
@ -1054,9 +1054,9 @@ void TableData::flush() {
|
|||||||
continue;
|
continue;
|
||||||
// we can trust that if it exists, it probably is indeed an egg
|
// we can trust that if it exists, it probably is indeed an egg
|
||||||
|
|
||||||
egg["iX"] = npc->appearanceData.iX;
|
egg["iX"] = npc->x;
|
||||||
egg["iY"] = npc->appearanceData.iY;
|
egg["iY"] = npc->y;
|
||||||
egg["iZ"] = npc->appearanceData.iZ;
|
egg["iZ"] = npc->z;
|
||||||
int mapnum = MAPNUM(npc->instanceID);
|
int mapnum = MAPNUM(npc->instanceID);
|
||||||
if (mapnum != 0)
|
if (mapnum != 0)
|
||||||
egg["iMapNum"] = mapnum;
|
egg["iMapNum"] = mapnum;
|
||||||
|
@ -271,8 +271,8 @@ static void stepNPCPathing() {
|
|||||||
queue->pop(); // remove point from front of queue
|
queue->pop(); // remove point from front of queue
|
||||||
|
|
||||||
// calculate displacement
|
// calculate displacement
|
||||||
int dXY = hypot(point.x - npc->appearanceData.iX, point.y - npc->appearanceData.iY); // XY plane distance
|
int dXY = hypot(point.x - npc->x, point.y - npc->y); // XY plane distance
|
||||||
int distanceBetween = hypot(dXY, point.z - npc->appearanceData.iZ); // total distance
|
int distanceBetween = hypot(dXY, point.z - npc->z); // total distance
|
||||||
|
|
||||||
// update NPC location to update viewables
|
// update NPC location to update viewables
|
||||||
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, point.x, point.y, point.z, npc->instanceID, npc->appearanceData.iAngle);
|
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, point.x, point.y, point.z, npc->instanceID, npc->appearanceData.iAngle);
|
||||||
|
Loading…
Reference in New Issue
Block a user