mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 13:41:31 +00:00
Merge branch 'master' of github.com:EQEmu/Server
This commit is contained in:
commit
bfae4273c2
@ -1,5 +1,12 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 7/1/2017 ==
|
||||||
|
Akkadius: Resolve issues with NPC's hopping to the ceiling in small corridors
|
||||||
|
Akkadius: Improved grounding issues with NPC's during combat
|
||||||
|
Akkadius: Improved scenarios where NPC's need to be dragged out of the ground - they should correct themselves far more consistently
|
||||||
|
- Scenarios where an NPC is coming up from the bottom floor, or from the top floor, they will correct much better
|
||||||
|
- A video of these tests can be found here: https://www.youtube.com/watch?v=HtC7bVNM7ZQ&feature=youtu.be
|
||||||
|
|
||||||
== 6/28/2017 ==
|
== 6/28/2017 ==
|
||||||
Akkadius: Fixed issues with Z correctness when NPCs are pathing on normal grids
|
Akkadius: Fixed issues with Z correctness when NPCs are pathing on normal grids
|
||||||
Akkadius: Fixed issues with Z correctness when NPCs are engaged with players following
|
Akkadius: Fixed issues with Z correctness when NPCs are engaged with players following
|
||||||
|
|||||||
@ -275,6 +275,7 @@ RULE_BOOL(Map, FixPathingZAtWaypoints, false) //alternative to `WhenLoading`, ac
|
|||||||
RULE_BOOL(Map, FixPathingZWhenMoving, false) //very CPU intensive, but helps hopping with widely spaced waypoints.
|
RULE_BOOL(Map, FixPathingZWhenMoving, false) //very CPU intensive, but helps hopping with widely spaced waypoints.
|
||||||
RULE_BOOL(Map, FixPathingZOnSendTo, false) //try to repair Z coords in the SendTo routine as well.
|
RULE_BOOL(Map, FixPathingZOnSendTo, false) //try to repair Z coords in the SendTo routine as well.
|
||||||
RULE_BOOL(Map, FixZWhenMoving, true) // Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)
|
RULE_BOOL(Map, FixZWhenMoving, true) // Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)
|
||||||
|
RULE_BOOL(Map, MobZVisualDebug, false) // Displays spell effects determining whether or not NPC is hitting Best Z calcs (blue for hit, red for miss)
|
||||||
RULE_REAL(Map, FixPathingZMaxDeltaMoving, 20) //at runtime while pathing: max change in Z to allow the BestZ code to apply.
|
RULE_REAL(Map, FixPathingZMaxDeltaMoving, 20) //at runtime while pathing: max change in Z to allow the BestZ code to apply.
|
||||||
RULE_REAL(Map, FixPathingZMaxDeltaWaypoint, 20) //at runtime at each waypoint: max change in Z to allow the BestZ code to apply.
|
RULE_REAL(Map, FixPathingZMaxDeltaWaypoint, 20) //at runtime at each waypoint: max change in Z to allow the BestZ code to apply.
|
||||||
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20) //at runtime in SendTo: max change in Z to allow the BestZ code to apply.
|
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20) //at runtime in SendTo: max change in Z to allow the BestZ code to apply.
|
||||||
@ -349,6 +350,7 @@ RULE_INT(Spells, MaxTotalSlotsNPC, 60) // default to Tit's limit
|
|||||||
RULE_INT(Spells, MaxTotalSlotsPET, 30) // default to Tit's limit
|
RULE_INT(Spells, MaxTotalSlotsPET, 30) // default to Tit's limit
|
||||||
RULE_BOOL (Spells, EnableBlockedBuffs, true)
|
RULE_BOOL (Spells, EnableBlockedBuffs, true)
|
||||||
RULE_INT(Spells, ReflectType, 3) //0 = disabled, 1 = single target player spells only, 2 = all player spells, 3 = all single target spells, 4 = all spells
|
RULE_INT(Spells, ReflectType, 3) //0 = disabled, 1 = single target player spells only, 2 = all player spells, 3 = all single target spells, 4 = all spells
|
||||||
|
RULE_BOOL(Spells, ReflectMessagesClose, true) // Live functionality is for Reflect messages to show to players within close proximity, false shows just player reflecting
|
||||||
RULE_INT(Spells, VirusSpreadDistance, 30) // The distance a viral spell will jump to its next victim
|
RULE_INT(Spells, VirusSpreadDistance, 30) // The distance a viral spell will jump to its next victim
|
||||||
RULE_BOOL(Spells, LiveLikeFocusEffects, true) // Determines whether specific healing, dmg and mana reduction focuses are randomized
|
RULE_BOOL(Spells, LiveLikeFocusEffects, true) // Determines whether specific healing, dmg and mana reduction focuses are randomized
|
||||||
RULE_INT(Spells, BaseImmunityLevel, 55) // The level that targets start to be immune to stun, fear and mez spells with a max level of 0.
|
RULE_INT(Spells, BaseImmunityLevel, 55) // The level that targets start to be immune to stun, fear and mez spells with a max level of 0.
|
||||||
|
|||||||
@ -2388,12 +2388,6 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
|
|||||||
entity_list.UnMarkNPC(GetID());
|
entity_list.UnMarkNPC(GetID());
|
||||||
entity_list.RemoveNPC(GetID());
|
entity_list.RemoveNPC(GetID());
|
||||||
|
|
||||||
/* Fix Z on Corpse Creation */
|
|
||||||
glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);
|
|
||||||
float new_z = zone->zonemap->FindBestZ(dest, nullptr);
|
|
||||||
corpse->SetFlyMode(1);
|
|
||||||
corpse->GMMove(m_Position.x, m_Position.y, new_z + 5, m_Position.w);
|
|
||||||
|
|
||||||
this->SetID(0);
|
this->SetID(0);
|
||||||
|
|
||||||
if (killer != 0 && emoteid != 0)
|
if (killer != 0 && emoteid != 0)
|
||||||
|
|||||||
@ -96,7 +96,9 @@ bool Beacon::Process()
|
|||||||
Mob *caster = entity_list.GetMob(caster_id);
|
Mob *caster = entity_list.GetMob(caster_id);
|
||||||
if(caster && spell_iterations-- && max_targets)
|
if(caster && spell_iterations-- && max_targets)
|
||||||
{
|
{
|
||||||
bool affect_caster = (!caster->IsNPC() && !caster->IsAIControlled()); //NPC AE spells do not affect the NPC caster
|
// NPCs should never be affected by an AE they cast. PB AEs shouldn't affect caster either
|
||||||
|
// I don't think any other cases that get here matter
|
||||||
|
bool affect_caster = (!caster->IsNPC() && !caster->IsAIControlled()) && spells[spell_id].targettype != ST_AECaster;
|
||||||
entity_list.AESpell(caster, this, spell_id, affect_caster, resist_adjust, &max_targets);
|
entity_list.AESpell(caster, this, spell_id, affect_caster, resist_adjust, &max_targets);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -48,6 +48,14 @@ void Mob::CalcBonuses()
|
|||||||
SetAttackTimer();
|
SetAttackTimer();
|
||||||
CalcAC();
|
CalcAC();
|
||||||
|
|
||||||
|
/* Fast walking NPC's are prone to disappear into walls/hills
|
||||||
|
We set this here because NPC's can cast spells to change walkspeed/runspeed
|
||||||
|
*/
|
||||||
|
float get_walk_speed = static_cast<float>(0.025f * this->GetWalkspeed());
|
||||||
|
if (get_walk_speed >= 0.9 && this->fix_z_timer.GetDuration() != 100) {
|
||||||
|
this->fix_z_timer.SetTimer(100);
|
||||||
|
}
|
||||||
|
|
||||||
rooted = FindType(SE_Root);
|
rooted = FindType(SE_Root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4242,7 +4242,7 @@ bool Client::GroupFollow(Client* inviter) {
|
|||||||
RemoveAutoXTargets();
|
RemoveAutoXTargets();
|
||||||
}
|
}
|
||||||
|
|
||||||
SetXTargetAutoMgr(GetXTargetAutoMgr());
|
SetXTargetAutoMgr(raid->GetXTargetAutoMgr());
|
||||||
if (!GetXTargetAutoMgr()->empty())
|
if (!GetXTargetAutoMgr()->empty())
|
||||||
SetDirtyAutoHaters();
|
SetDirtyAutoHaters();
|
||||||
|
|
||||||
|
|||||||
@ -173,6 +173,7 @@ int command_init(void)
|
|||||||
command_add("checklos", "- Check for line of sight to your target", 50, command_checklos) ||
|
command_add("checklos", "- Check for line of sight to your target", 50, command_checklos) ||
|
||||||
command_add("clearinvsnapshots", "[use rule] - Clear inventory snapshot history (true - elapsed entries, false - all entries)", 200, command_clearinvsnapshots) ||
|
command_add("clearinvsnapshots", "[use rule] - Clear inventory snapshot history (true - elapsed entries, false - all entries)", 200, command_clearinvsnapshots) ||
|
||||||
command_add("corpse", "- Manipulate corpses, use with no arguments for help", 50, command_corpse) ||
|
command_add("corpse", "- Manipulate corpses, use with no arguments for help", 50, command_corpse) ||
|
||||||
|
command_add("corpsefix", "Attempts to bring corpses from underneath the ground within close proximity of the player", 0, command_corpsefix) ||
|
||||||
command_add("crashtest", "- Crash the zoneserver", 255, command_crashtest) ||
|
command_add("crashtest", "- Crash the zoneserver", 255, command_crashtest) ||
|
||||||
command_add("cvs", "- Summary of client versions currently online.", 200, command_cvs) ||
|
command_add("cvs", "- Summary of client versions currently online.", 200, command_cvs) ||
|
||||||
command_add("damage", "[amount] - Damage your target", 100, command_damage) ||
|
command_add("damage", "[amount] - Damage your target", 100, command_damage) ||
|
||||||
@ -2977,6 +2978,11 @@ void command_reloadqst(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void command_corpsefix(Client *c, const Seperator *sep)
|
||||||
|
{
|
||||||
|
entity_list.CorpseFix(c);
|
||||||
|
}
|
||||||
|
|
||||||
void command_reloadworld(Client *c, const Seperator *sep)
|
void command_reloadworld(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
c->Message(0, "Reloading quest cache and repopping zones worldwide.");
|
c->Message(0, "Reloading quest cache and repopping zones worldwide.");
|
||||||
|
|||||||
@ -72,6 +72,7 @@ void command_checklos(Client *c, const Seperator *sep);
|
|||||||
void command_clearinvsnapshots(Client *c, const Seperator *sep);
|
void command_clearinvsnapshots(Client *c, const Seperator *sep);
|
||||||
void command_connectworldserver(Client *c, const Seperator *sep);
|
void command_connectworldserver(Client *c, const Seperator *sep);
|
||||||
void command_corpse(Client *c, const Seperator *sep);
|
void command_corpse(Client *c, const Seperator *sep);
|
||||||
|
void command_corpsefix(Client *c, const Seperator *sep);
|
||||||
void command_crashtest(Client *c, const Seperator *sep);
|
void command_crashtest(Client *c, const Seperator *sep);
|
||||||
void command_cvs(Client *c, const Seperator *sep);
|
void command_cvs(Client *c, const Seperator *sep);
|
||||||
void command_d1(Client *c, const Seperator *sep);
|
void command_d1(Client *c, const Seperator *sep);
|
||||||
|
|||||||
@ -730,8 +730,6 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
|||||||
// test to fix possible cause of random zone crashes..external methods accessing client properties before they're initialized
|
// test to fix possible cause of random zone crashes..external methods accessing client properties before they're initialized
|
||||||
if (curmob->IsClient() && !curmob->CastToClient()->ClientFinishedLoading())
|
if (curmob->IsClient() && !curmob->CastToClient()->ClientFinishedLoading())
|
||||||
continue;
|
continue;
|
||||||
if (curmob == center) //do not affect center
|
|
||||||
continue;
|
|
||||||
if (curmob == caster && !affect_caster) //watch for caster too
|
if (curmob == caster && !affect_caster) //watch for caster too
|
||||||
continue;
|
continue;
|
||||||
if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && curmob->IsPetOwnerClient())
|
if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && curmob->IsPetOwnerClient())
|
||||||
|
|||||||
@ -2845,6 +2845,22 @@ int32 EntityList::DeleteNPCCorpses()
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityList::CorpseFix(Client* c)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto it = corpse_list.begin();
|
||||||
|
while (it != corpse_list.end()) {
|
||||||
|
Corpse* corpse = it->second;
|
||||||
|
if (corpse->IsNPCCorpse()) {
|
||||||
|
if (DistanceNoZ(c->GetPosition(), corpse->GetPosition()) < 100) {
|
||||||
|
c->Message(15, "Attempting to fix %s", it->second->GetCleanName());
|
||||||
|
corpse->GMMove(corpse->GetX(), corpse->GetY(), c->GetZ() + 2, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// returns the number of corpses deleted. A negative number indicates an error code.
|
// returns the number of corpses deleted. A negative number indicates an error code.
|
||||||
int32 EntityList::DeletePlayerCorpses()
|
int32 EntityList::DeletePlayerCorpses()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -386,6 +386,7 @@ public:
|
|||||||
void FindPathsToAllNPCs();
|
void FindPathsToAllNPCs();
|
||||||
int32 DeleteNPCCorpses();
|
int32 DeleteNPCCorpses();
|
||||||
int32 DeletePlayerCorpses();
|
int32 DeletePlayerCorpses();
|
||||||
|
void CorpseFix(Client* c);
|
||||||
void WriteEntityIDs();
|
void WriteEntityIDs();
|
||||||
void HalveAggro(Mob* who);
|
void HalveAggro(Mob* who);
|
||||||
void DoubleAggro(Mob* who);
|
void DoubleAggro(Mob* who);
|
||||||
|
|||||||
@ -113,7 +113,7 @@ Mob::Mob(const char* in_name,
|
|||||||
tmHidden(-1),
|
tmHidden(-1),
|
||||||
mitigation_ac(0),
|
mitigation_ac(0),
|
||||||
m_specialattacks(eSpecialAttacks::None),
|
m_specialattacks(eSpecialAttacks::None),
|
||||||
fix_z_timer(1000),
|
fix_z_timer(300),
|
||||||
fix_z_timer_engaged(100)
|
fix_z_timer_engaged(100)
|
||||||
{
|
{
|
||||||
targeted = 0;
|
targeted = 0;
|
||||||
@ -121,6 +121,8 @@ Mob::Mob(const char* in_name,
|
|||||||
tar_vector=0;
|
tar_vector=0;
|
||||||
currently_fleeing = false;
|
currently_fleeing = false;
|
||||||
|
|
||||||
|
last_z = 0;
|
||||||
|
|
||||||
AI_Init();
|
AI_Init();
|
||||||
SetMoving(false);
|
SetMoving(false);
|
||||||
moved=false;
|
moved=false;
|
||||||
|
|||||||
@ -492,6 +492,7 @@ public:
|
|||||||
inline const float GetTarVZ() const { return m_TargetV.z; }
|
inline const float GetTarVZ() const { return m_TargetV.z; }
|
||||||
inline const float GetTarVector() const { return tar_vector; }
|
inline const float GetTarVector() const { return tar_vector; }
|
||||||
inline const uint8 GetTarNDX() const { return tar_ndx; }
|
inline const uint8 GetTarNDX() const { return tar_ndx; }
|
||||||
|
inline const int8 GetFlyMode() const { return flymode; }
|
||||||
bool IsBoat() const;
|
bool IsBoat() const;
|
||||||
|
|
||||||
//Group
|
//Group
|
||||||
@ -1067,6 +1068,8 @@ public:
|
|||||||
int GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item);
|
int GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item);
|
||||||
int GetWeaponDamage(Mob *against, const EQEmu::ItemInstance *weapon_item, uint32 *hate = nullptr);
|
int GetWeaponDamage(Mob *against, const EQEmu::ItemInstance *weapon_item, uint32 *hate = nullptr);
|
||||||
|
|
||||||
|
float last_z;
|
||||||
|
|
||||||
// Bots HealRotation methods
|
// Bots HealRotation methods
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
bool IsHealRotationTarget() { return (m_target_of_heal_rotation.use_count() && m_target_of_heal_rotation.get()); }
|
bool IsHealRotationTarget() { return (m_target_of_heal_rotation.use_count() && m_target_of_heal_rotation.get()); }
|
||||||
|
|||||||
@ -998,9 +998,16 @@ void Mob::AI_Process() {
|
|||||||
|
|
||||||
/* Fix Z when following during pull, not when engaged and stationary */
|
/* Fix Z when following during pull, not when engaged and stationary */
|
||||||
if (moving && fix_z_timer_engaged.Check())
|
if (moving && fix_z_timer_engaged.Check())
|
||||||
if(this->GetTarget())
|
if (this->GetTarget()) {
|
||||||
if(DistanceNoZ(this->GetPosition(), this->GetTarget()->GetPosition()) > 50)
|
/* If we are engaged, moving and following client, let's look for best Z more often */
|
||||||
|
if (DistanceNoZ(this->GetPosition(), this->GetTarget()->GetPosition()) > 50) {
|
||||||
this->FixZ();
|
this->FixZ();
|
||||||
|
}
|
||||||
|
/* If we are close to client and our Z differences aren't big, match the client */
|
||||||
|
else if (std::abs(this->GetZ() - this->GetTarget()->GetZ()) <= 5 && this->GetTarget()->IsClient()) {
|
||||||
|
this->m_Position.z = this->GetTarget()->GetZ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(m_PlayerState & static_cast<uint32>(PlayerState::Aggressive)))
|
if (!(m_PlayerState & static_cast<uint32>(PlayerState::Aggressive)))
|
||||||
SendAddPlayerState(PlayerState::Aggressive);
|
SendAddPlayerState(PlayerState::Aggressive);
|
||||||
|
|||||||
@ -2241,7 +2241,9 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
|
|||||||
if(ae_center && ae_center == this && IsBeneficialSpell(spell_id))
|
if(ae_center && ae_center == this && IsBeneficialSpell(spell_id))
|
||||||
SpellOnTarget(spell_id, this);
|
SpellOnTarget(spell_id, this);
|
||||||
|
|
||||||
bool affect_caster = !IsNPC(); //NPC AE spells do not affect the NPC caster
|
// NPCs should never be affected by an AE they cast. PB AEs shouldn't affect caster either
|
||||||
|
// I don't think any other cases that get here matter
|
||||||
|
bool affect_caster = !IsNPC() && spells[spell_id].targettype != ST_AECaster;
|
||||||
|
|
||||||
if (spells[spell_id].targettype == ST_AETargetHateList)
|
if (spells[spell_id].targettype == ST_AETargetHateList)
|
||||||
hate_list.SpellCast(this, spell_id, spells[spell_id].aoerange, ae_center);
|
hate_list.SpellCast(this, spell_id, spells[spell_id].aoerange, ae_center);
|
||||||
@ -3804,8 +3806,22 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (reflect_chance) {
|
if (reflect_chance) {
|
||||||
entity_list.MessageClose_StringID(this, false, RuleI(Range, SpellMessages), MT_Spells,
|
|
||||||
SPELL_REFLECT, GetCleanName(), spelltar->GetCleanName());
|
if (RuleB(Spells, ReflectMessagesClose)) {
|
||||||
|
entity_list.MessageClose_StringID(
|
||||||
|
this, /* Sender */
|
||||||
|
false, /* Skip Sender */
|
||||||
|
RuleI(Range, SpellMessages), /* Range */
|
||||||
|
MT_Spells, /* Type */
|
||||||
|
SPELL_REFLECT, /* String ID */
|
||||||
|
GetCleanName(), /* Message 1 */
|
||||||
|
spelltar->GetCleanName() /* Message 2 */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Message_StringID(MT_Spells, SPELL_REFLECT, GetCleanName(), spelltar->GetCleanName());
|
||||||
|
}
|
||||||
|
|
||||||
CheckNumHitsRemaining(NumHit::ReflectSpell);
|
CheckNumHitsRemaining(NumHit::ReflectSpell);
|
||||||
// caster actually appears to change
|
// caster actually appears to change
|
||||||
// ex. During OMM fight you click your reflect mask and you get the recourse from the reflected
|
// ex. During OMM fight you click your reflect mask and you get the recourse from the reflected
|
||||||
|
|||||||
@ -212,22 +212,6 @@ void NPC::UpdateWaypoint(int wp_index)
|
|||||||
cur_wp_pause = cur->pause;
|
cur_wp_pause = cur->pause;
|
||||||
Log(Logs::Detail, Logs::AI, "Next waypoint %d: (%.3f, %.3f, %.3f, %.3f)", wp_index, m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, m_CurrentWayPoint.w);
|
Log(Logs::Detail, Logs::AI, "Next waypoint %d: (%.3f, %.3f, %.3f, %.3f)", wp_index, m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, m_CurrentWayPoint.w);
|
||||||
|
|
||||||
//fix up pathing Z
|
|
||||||
if (zone->HasMap() && RuleB(Map, FixPathingZAtWaypoints) && !IsBoat())
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!RuleB(Watermap, CheckForWaterAtWaypoints) || !zone->HasWaterMap() ||
|
|
||||||
(zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_CurrentWayPoint))))
|
|
||||||
{
|
|
||||||
glm::vec3 dest(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z);
|
|
||||||
|
|
||||||
float newz = zone->zonemap->FindBestZ(dest, nullptr);
|
|
||||||
|
|
||||||
if ((newz > -2000) && std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaWaypoint))
|
|
||||||
m_CurrentWayPoint.z = newz + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::CalculateNewWaypoint()
|
void NPC::CalculateNewWaypoint()
|
||||||
@ -780,20 +764,6 @@ void NPC::AssignWaypoints(int32 grid)
|
|||||||
newwp.y = atof(row[1]);
|
newwp.y = atof(row[1]);
|
||||||
newwp.z = atof(row[2]);
|
newwp.z = atof(row[2]);
|
||||||
|
|
||||||
if (zone->HasMap() && RuleB(Map, FixPathingZWhenLoading))
|
|
||||||
{
|
|
||||||
auto positon = glm::vec3(newwp.x, newwp.y, newwp.z);
|
|
||||||
if (!RuleB(Watermap, CheckWaypointsInWaterWhenLoading) || !zone->HasWaterMap() ||
|
|
||||||
(zone->HasWaterMap() && !zone->watermap->InWater(positon)))
|
|
||||||
{
|
|
||||||
glm::vec3 dest(newwp.x, newwp.y, newwp.z);
|
|
||||||
float newz = zone->zonemap->FindBestZ(dest, nullptr);
|
|
||||||
|
|
||||||
if ((newz > -2000) && std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaLoading))
|
|
||||||
newwp.z = newz + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newwp.pause = atoi(row[3]);
|
newwp.pause = atoi(row[3]);
|
||||||
newwp.heading = atof(row[4]);
|
newwp.heading = atof(row[4]);
|
||||||
Waypoints.push_back(newwp);
|
Waypoints.push_back(newwp);
|
||||||
@ -870,6 +840,7 @@ void Mob::SendToFixZ(float new_x, float new_y, float new_z) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mob::FixZ() {
|
void Mob::FixZ() {
|
||||||
|
|
||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
timer.reset();
|
timer.reset();
|
||||||
|
|
||||||
@ -878,9 +849,8 @@ void Mob::FixZ() {
|
|||||||
if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
|
if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
|
||||||
(zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position))))
|
(zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position))))
|
||||||
{
|
{
|
||||||
glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);
|
/* Any more than 5 in the offset makes NPC's hop/snap to ceiling in small corridors */
|
||||||
|
float new_z = this->FindGroundZ(m_Position.x, m_Position.y, 5);
|
||||||
float new_z = zone->zonemap->FindBestZ(dest, nullptr);
|
|
||||||
|
|
||||||
auto duration = timer.elapsed();
|
auto duration = timer.elapsed();
|
||||||
|
|
||||||
@ -896,8 +866,20 @@ void Mob::FixZ() {
|
|||||||
duration
|
duration
|
||||||
);
|
);
|
||||||
|
|
||||||
if ((new_z > -2000) && std::abs(new_z - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving))
|
if ((new_z > -2000) && std::abs(m_Position.z - new_z) < 35) {
|
||||||
m_Position.z = new_z + 1;
|
if (RuleB(Map, MobZVisualDebug))
|
||||||
|
this->SendAppearanceEffect(78, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
m_Position.z = new_z;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (RuleB(Map, MobZVisualDebug))
|
||||||
|
this->SendAppearanceEffect(103, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
Log(Logs::General, Logs::Debug, "%s is failing to find Z %f", this->GetCleanName(), std::abs(m_Position.z - new_z));
|
||||||
|
}
|
||||||
|
|
||||||
|
last_z = m_Position.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user