mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 13:16:39 +00:00
Merge remote-tracking branch 'upstream/master' into Warning_Cleanup
This commit is contained in:
+1
-1
@@ -1358,7 +1358,7 @@ void Client::SendAA(uint32 id, int seq) {
|
||||
|
||||
if (aa_stack){
|
||||
|
||||
if (saa->sof_current_level > 1 && value == 0)
|
||||
if (saa->sof_current_level >= 1 && value == 0)
|
||||
saa->current_level = saa->sof_current_level+1;
|
||||
|
||||
saa->max_level = saa->sof_max_level;
|
||||
|
||||
+9
-2
@@ -1213,11 +1213,18 @@ void Mob::AI_Process() {
|
||||
}
|
||||
}
|
||||
|
||||
if (IsPet()) {
|
||||
Mob *owner = GetOwner();
|
||||
if (IsPet() || (IsNPC() && CastToNPC()->GetSwarmOwner())) {
|
||||
Mob *owner = nullptr;
|
||||
|
||||
if (IsPet())
|
||||
owner = GetOwner();
|
||||
else
|
||||
owner = entity_list.GetMobID(CastToNPC()->GetSwarmOwner());
|
||||
|
||||
if (owner) {
|
||||
int16 flurry_chance = owner->aabonuses.PetFlurry +
|
||||
owner->spellbonuses.PetFlurry + owner->itembonuses.PetFlurry;
|
||||
|
||||
if (flurry_chance && (MakeRandomInt(0, 99) < flurry_chance))
|
||||
Flurry(nullptr);
|
||||
}
|
||||
|
||||
+7
-4
@@ -4226,11 +4226,13 @@ void Mob::TryPetCriticalHit(Mob *defender, uint16 skill, int32 &damage)
|
||||
if (damage < 1) //We can't critical hit if we don't hit.
|
||||
return;
|
||||
|
||||
if (!IsPet())
|
||||
if (IsPet())
|
||||
owner = GetOwner();
|
||||
else if ((IsNPC() && CastToNPC()->GetSwarmOwner()))
|
||||
owner = entity_list.GetMobID(CastToNPC()->GetSwarmOwner());
|
||||
else
|
||||
return;
|
||||
|
||||
owner = GetOwner();
|
||||
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
@@ -4267,7 +4269,7 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack
|
||||
|
||||
// decided to branch this into it's own function since it's going to be duplicating a lot of the
|
||||
// code in here, but could lead to some confusion otherwise
|
||||
if (IsPet() && GetOwner()->IsClient()) {
|
||||
if (IsPet() && GetOwner()->IsClient() || (IsNPC() && CastToNPC()->GetSwarmOwner())) {
|
||||
TryPetCriticalHit(defender,skill,damage);
|
||||
return;
|
||||
}
|
||||
@@ -4456,6 +4458,7 @@ void Mob::DoRiposte(Mob* defender) {
|
||||
|
||||
//Double Riposte effect, allows for a chance to do RIPOSTE with a skill specfic special attack (ie Return Kick).
|
||||
//Coded narrowly: Limit to one per client. Limit AA only. [1 = Skill Attack Chance, 2 = Skill]
|
||||
|
||||
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[1];
|
||||
|
||||
if(DoubleRipChance && (DoubleRipChance >= MakeRandomInt(0, 100))) {
|
||||
|
||||
@@ -1328,7 +1328,7 @@ void Client::Handle_OP_AutoAttack(const EQApplicationPacket *app)
|
||||
aa_los_them.y = aa_los_them_mob->GetY();
|
||||
aa_los_them.z = aa_los_them_mob->GetZ();
|
||||
los_status = CheckLosFN(aa_los_them_mob);
|
||||
los_status_facing = aa_los_them_mob->InFrontMob(this, aa_los_them.x, aa_los_them.y);
|
||||
los_status_facing = IsFacingMob(aa_los_them_mob);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -361,13 +361,13 @@ bool Client::Process() {
|
||||
aa_los_them.z = aa_los_them_mob->GetZ();
|
||||
los_status = CheckLosFN(auto_attack_target);
|
||||
aa_los_me_heading = GetHeading();
|
||||
los_status_facing = aa_los_them_mob->InFrontMob(this, aa_los_them.x, aa_los_them.y);
|
||||
los_status_facing = IsFacingMob(aa_los_them_mob);
|
||||
}
|
||||
// If only our heading changes, we can skip the CheckLosFN call
|
||||
// but above we still need to update los_status_facing
|
||||
if (aa_los_me_heading != GetHeading()) {
|
||||
aa_los_me_heading = GetHeading();
|
||||
los_status_facing = aa_los_them_mob->InFrontMob(this, aa_los_them.x, aa_los_them.y);
|
||||
los_status_facing = IsFacingMob(aa_los_them_mob);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -381,7 +381,7 @@ bool Client::Process() {
|
||||
aa_los_them.y = aa_los_them_mob->GetY();
|
||||
aa_los_them.z = aa_los_them_mob->GetZ();
|
||||
los_status = CheckLosFN(auto_attack_target);
|
||||
los_status_facing = aa_los_them_mob->InFrontMob(this, aa_los_them.x, aa_los_them.y);
|
||||
los_status_facing = IsFacingMob(aa_los_them_mob);
|
||||
}
|
||||
|
||||
if (!CombatRange(auto_attack_target))
|
||||
|
||||
@@ -748,6 +748,9 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
|
||||
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
|
||||
curmob = it->second;
|
||||
// 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
|
||||
|
||||
@@ -5046,3 +5046,54 @@ void Mob::ProcessSpecialAbilities(const std::string str) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// derived from client to keep these functions more consistent
|
||||
// if anything seems weird, blame SoE
|
||||
bool Mob::IsFacingMob(Mob *other)
|
||||
{
|
||||
if (!other)
|
||||
return false;
|
||||
float angle = HeadingAngleToMob(other);
|
||||
// what the client uses appears to be 2x our internal heading
|
||||
float heading = GetHeading() * 2.0;
|
||||
|
||||
if (angle > 472.0 && heading < 40.0)
|
||||
angle = heading;
|
||||
if (angle < 40.0 && heading > 472.0)
|
||||
angle = heading;
|
||||
|
||||
if (fabs(angle - heading) <= 80.0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// All numbers derived from the client
|
||||
float Mob::HeadingAngleToMob(Mob *other)
|
||||
{
|
||||
float mob_x = other->GetX();
|
||||
float mob_y = other->GetY();
|
||||
float this_x = GetX();
|
||||
float this_y = GetY();
|
||||
|
||||
float y_diff = fabs(this_y - mob_y);
|
||||
float x_diff = fabs(this_x - mob_x);
|
||||
if (y_diff < 0.0000009999999974752427)
|
||||
y_diff = 0.0000009999999974752427;
|
||||
|
||||
float angle = atan2(x_diff, y_diff) * 180.0 * 0.3183099014828645; // angle, nice "pi"
|
||||
|
||||
// return the right thing based on relative quadrant
|
||||
// I'm sure this could be improved for readability, but whatever
|
||||
if (this_y >= mob_y) {
|
||||
if (mob_x >= this_x)
|
||||
return (90.0 - angle + 90.0) * 511.5 * 0.0027777778;
|
||||
if (mob_x <= this_x)
|
||||
return (angle + 180.0) * 511.5 * 0.0027777778;
|
||||
}
|
||||
if (this_y > mob_y || mob_x > this_x)
|
||||
return angle * 511.5 * 0.0027777778;
|
||||
else
|
||||
return (90.0 - angle + 270.0) * 511.5 * 0.0027777778;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,8 @@ public:
|
||||
// less than 56 is in front, greater than 56 is usually where the client generates the messages
|
||||
inline bool InFrontMob(Mob *other = 0, float ourx = 0.0f, float oury = 0.0f) const
|
||||
{ return (!other || other == this) ? true : MobAngle(other, ourx, oury) < 56.0f; }
|
||||
bool IsFacingMob(Mob *other); // kind of does the same as InFrontMob, but derived from client
|
||||
float HeadingAngleToMob(Mob *other); // to keep consistent with client generated messages
|
||||
virtual void RangedAttack(Mob* other) { }
|
||||
virtual void ThrowingAttack(Mob* other) { }
|
||||
uint16 GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg);
|
||||
|
||||
Reference in New Issue
Block a user