Merge branch 'master' into eqstream

This commit is contained in:
KimLS 2017-07-06 18:15:11 -07:00
commit 58c15b0287
13 changed files with 66 additions and 58 deletions

View File

@ -1,5 +1,12 @@
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 ==
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

View File

@ -350,6 +350,7 @@ RULE_INT(Spells, MaxTotalSlotsNPC, 60) // default to Tit's limit
RULE_INT(Spells, MaxTotalSlotsPET, 30) // default to Tit's limit
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_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_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.

View File

@ -2388,18 +2388,6 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
entity_list.UnMarkNPC(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);
float size = GetSize();
if (size > 10)
size = 10;
new_z += size / 2;
corpse->GMMove(m_Position.x, m_Position.y, new_z, m_Position.w);
this->SetID(0);
if (killer != 0 && emoteid != 0)

View File

@ -96,7 +96,9 @@ bool Beacon::Process()
Mob *caster = entity_list.GetMob(caster_id);
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);
}
else

View File

@ -173,6 +173,7 @@ int command_init(void)
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("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("cvs", "- Summary of client versions currently online.", 200, command_cvs) ||
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)
{
c->Message(0, "Reloading quest cache and repopping zones worldwide.");

View File

@ -72,6 +72,7 @@ void command_checklos(Client *c, const Seperator *sep);
void command_clearinvsnapshots(Client *c, const Seperator *sep);
void command_connectworldserver(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_cvs(Client *c, const Seperator *sep);
void command_d1(Client *c, const Seperator *sep);

View File

@ -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
if (curmob->IsClient() && !curmob->CastToClient()->ClientFinishedLoading())
continue;
if (curmob == center) //do not affect center
continue;
if (curmob == caster && !affect_caster) //watch for caster too
continue;
if (spells[spell_id].targettype == ST_TargetAENoPlayersPets && curmob->IsPetOwnerClient())

View File

@ -2845,6 +2845,22 @@ int32 EntityList::DeleteNPCCorpses()
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.
int32 EntityList::DeletePlayerCorpses()
{

View File

@ -386,6 +386,7 @@ public:
void FindPathsToAllNPCs();
int32 DeleteNPCCorpses();
int32 DeletePlayerCorpses();
void CorpseFix(Client* c);
void WriteEntityIDs();
void HalveAggro(Mob* who);
void DoubleAggro(Mob* who);

View File

@ -492,6 +492,7 @@ public:
inline const float GetTarVZ() const { return m_TargetV.z; }
inline const float GetTarVector() const { return tar_vector; }
inline const uint8 GetTarNDX() const { return tar_ndx; }
inline const int8 GetFlyMode() const { return flymode; }
bool IsBoat() const;
//Group

View File

@ -998,9 +998,16 @@ void Mob::AI_Process() {
/* Fix Z when following during pull, not when engaged and stationary */
if (moving && fix_z_timer_engaged.Check())
if(this->GetTarget())
if(DistanceNoZ(this->GetPosition(), this->GetTarget()->GetPosition()) > 50)
if (this->GetTarget()) {
/* 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();
}
/* 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)))
SendAddPlayerState(PlayerState::Aggressive);

View File

@ -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))
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)
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;
}
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);
// caster actually appears to change
// ex. During OMM fight you click your reflect mask and you get the recourse from the reflected

View File

@ -212,22 +212,6 @@ void NPC::UpdateWaypoint(int wp_index)
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);
//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()
@ -780,20 +764,6 @@ void NPC::AssignWaypoints(int32 grid)
newwp.y = atof(row[1]);
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.heading = atof(row[4]);
Waypoints.push_back(newwp);
@ -879,8 +849,8 @@ void Mob::FixZ() {
if (!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
(zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position))))
{
float new_z = this->FindGroundZ(m_Position.x, m_Position.y, 10);
/* 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);
auto duration = timer.elapsed();
@ -896,12 +866,6 @@ void Mob::FixZ() {
duration
);
float size = GetSize();
if (size > 10)
size = 10;
new_z += size / 2;
if ((new_z > -2000) && std::abs(m_Position.z - new_z) < 35) {
if (RuleB(Map, MobZVisualDebug))
this->SendAppearanceEffect(78, 0, 0, 0, 0);