mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-24 09:28:21 +00:00
Merge remote-tracking branch 'upstream/master' into Warning_Cleanup
This commit is contained in:
@@ -1,5 +1,12 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 05/07/2014 ==
|
||||||
|
Kayen: AA/Item/Spells that allow pets to critical and flurry will now work on the owners swarm pets consistent with live.
|
||||||
|
|
||||||
|
== 05/05/2014 ==
|
||||||
|
Uleat: Oops! Wrong state check (conn_state != client_state)
|
||||||
|
Uleat: Test fix to eliminate seemingly random crashes when an AE spell is being used. (Possible access to uninstantiated pointers during client connection process when someone casts a beneficial AE spell within range of a connecting client.)
|
||||||
|
|
||||||
== 04/29/2014 ==
|
== 04/29/2014 ==
|
||||||
KLS: Implemented new map code based on some of Derision's earlier work. Old maps still work with this system and don't need to be regenerated. We're still working on a new azone solution for better/more efficient maps.
|
KLS: Implemented new map code based on some of Derision's earlier work. Old maps still work with this system and don't need to be regenerated. We're still working on a new azone solution for better/more efficient maps.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2011,7 +2011,7 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) {
|
|||||||
current_id = id;
|
current_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current_entry > 1260) {
|
if(current_entry >= 1260) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ IF(UNIX)
|
|||||||
TARGET_LINK_LIBRARIES(tests "${CMAKE_DL_LIBS}")
|
TARGET_LINK_LIBRARIES(tests "${CMAKE_DL_LIBS}")
|
||||||
TARGET_LINK_LIBRARIES(tests "z")
|
TARGET_LINK_LIBRARIES(tests "z")
|
||||||
TARGET_LINK_LIBRARIES(tests "m")
|
TARGET_LINK_LIBRARIES(tests "m")
|
||||||
IF(NOT DARWIN)
|
IF(NOT DARWIN)
|
||||||
TARGET_LINK_LIBRARIES(loginserver "rt")
|
TARGET_LINK_LIBRARIES(tests "rt")
|
||||||
ENDIF(NOT DARWIN)
|
ENDIF(NOT DARWIN)
|
||||||
TARGET_LINK_LIBRARIES(tests "pthread")
|
TARGET_LINK_LIBRARIES(tests "pthread")
|
||||||
ADD_DEFINITIONS(-fPIC)
|
ADD_DEFINITIONS(-fPIC)
|
||||||
ENDIF(UNIX)
|
ENDIF(UNIX)
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
UPDATE npc_types SET slow_mitigation = slow_mitigation * 100;
|
UPDATE npc_types SET slow_mitigation = slow_mitigation * 100;
|
||||||
|
|
||||||
-- Change variable type from FLOAT TO INT
|
-- Change variable type from FLOAT TO INT
|
||||||
ALTER TABLE npc_types MODIFY slow_mitigation smallint(4);
|
ALTER TABLE npc_types MODIFY slow_mitigation smallint(4) NOT NULL DEFAULT '0';
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
ALTER TABLE npc_types MODIFY slow_mitigation smallint(4) NOT NULL DEFAULT '0';
|
||||||
|
|
||||||
|
|
||||||
+1
-1
@@ -1358,7 +1358,7 @@ void Client::SendAA(uint32 id, int seq) {
|
|||||||
|
|
||||||
if (aa_stack){
|
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->current_level = saa->sof_current_level+1;
|
||||||
|
|
||||||
saa->max_level = saa->sof_max_level;
|
saa->max_level = saa->sof_max_level;
|
||||||
|
|||||||
+9
-2
@@ -1213,11 +1213,18 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPet()) {
|
if (IsPet() || (IsNPC() && CastToNPC()->GetSwarmOwner())) {
|
||||||
Mob *owner = GetOwner();
|
Mob *owner = nullptr;
|
||||||
|
|
||||||
|
if (IsPet())
|
||||||
|
owner = GetOwner();
|
||||||
|
else
|
||||||
|
owner = entity_list.GetMobID(CastToNPC()->GetSwarmOwner());
|
||||||
|
|
||||||
if (owner) {
|
if (owner) {
|
||||||
int16 flurry_chance = owner->aabonuses.PetFlurry +
|
int16 flurry_chance = owner->aabonuses.PetFlurry +
|
||||||
owner->spellbonuses.PetFlurry + owner->itembonuses.PetFlurry;
|
owner->spellbonuses.PetFlurry + owner->itembonuses.PetFlurry;
|
||||||
|
|
||||||
if (flurry_chance && (MakeRandomInt(0, 99) < flurry_chance))
|
if (flurry_chance && (MakeRandomInt(0, 99) < flurry_chance))
|
||||||
Flurry(nullptr);
|
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.
|
if (damage < 1) //We can't critical hit if we don't hit.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!IsPet())
|
if (IsPet())
|
||||||
|
owner = GetOwner();
|
||||||
|
else if ((IsNPC() && CastToNPC()->GetSwarmOwner()))
|
||||||
|
owner = entity_list.GetMobID(CastToNPC()->GetSwarmOwner());
|
||||||
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
owner = GetOwner();
|
|
||||||
|
|
||||||
if (!owner)
|
if (!owner)
|
||||||
return;
|
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
|
// 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
|
// 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);
|
TryPetCriticalHit(defender,skill,damage);
|
||||||
return;
|
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).
|
//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]
|
//Coded narrowly: Limit to one per client. Limit AA only. [1 = Skill Attack Chance, 2 = Skill]
|
||||||
|
|
||||||
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[1];
|
DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[1];
|
||||||
|
|
||||||
if(DoubleRipChance && (DoubleRipChance >= MakeRandomInt(0, 100))) {
|
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.y = aa_los_them_mob->GetY();
|
||||||
aa_los_them.z = aa_los_them_mob->GetZ();
|
aa_los_them.z = aa_los_them_mob->GetZ();
|
||||||
los_status = CheckLosFN(aa_los_them_mob);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -361,13 +361,13 @@ bool Client::Process() {
|
|||||||
aa_los_them.z = aa_los_them_mob->GetZ();
|
aa_los_them.z = aa_los_them_mob->GetZ();
|
||||||
los_status = CheckLosFN(auto_attack_target);
|
los_status = CheckLosFN(auto_attack_target);
|
||||||
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);
|
||||||
}
|
}
|
||||||
// If only our heading changes, we can skip the CheckLosFN call
|
// If only our heading changes, we can skip the CheckLosFN call
|
||||||
// but above we still need to update los_status_facing
|
// but above we still need to update los_status_facing
|
||||||
if (aa_los_me_heading != GetHeading()) {
|
if (aa_los_me_heading != GetHeading()) {
|
||||||
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
|
else
|
||||||
@@ -381,7 +381,7 @@ bool Client::Process() {
|
|||||||
aa_los_them.y = aa_los_them_mob->GetY();
|
aa_los_them.y = aa_los_them_mob->GetY();
|
||||||
aa_los_them.z = aa_los_them_mob->GetZ();
|
aa_los_them.z = aa_los_them_mob->GetZ();
|
||||||
los_status = CheckLosFN(auto_attack_target);
|
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))
|
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) {
|
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
|
||||||
curmob = it->second;
|
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
|
if (curmob == center) //do not affect center
|
||||||
continue;
|
continue;
|
||||||
if (curmob == caster && !affect_caster) //watch for caster too
|
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
|
// 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
|
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; }
|
{ 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 RangedAttack(Mob* other) { }
|
||||||
virtual void ThrowingAttack(Mob* other) { }
|
virtual void ThrowingAttack(Mob* other) { }
|
||||||
uint16 GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg);
|
uint16 GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg);
|
||||||
|
|||||||
Reference in New Issue
Block a user