Merge pull request #309 from KayenEQ/Development

Max Range attack calculation fix.
This commit is contained in:
KayenEQ 2014-12-04 02:58:28 -05:00
commit 65dcfd55a7
4 changed files with 56 additions and 10 deletions

View File

@ -1,5 +1,9 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 12/04/2014 ==
Kayen: Ranged attacks will now more accurately check MAX firing range, fixing the issue where you would
hit ranged attack and nothing would happpen due to incorrect server side range checks.
== 12/01/2014 ==
Trevius: Mercenaries now spawn as the same Gender and Size of the Merchant they are purchased from.
Trevius: Mercenaries now spawn with randomized facial features when purchased.

View File

@ -737,6 +737,7 @@ public:
void ProjectileAttack();
inline bool HasProjectileAttack() const { return ActiveProjectileATK; }
inline void SetProjectileAttack(bool value) { ActiveProjectileATK = value; }
float GetRangeDistTargetSizeMod(Mob* other);
bool CanDoSpecialAttack(Mob *other);
bool Flurry(ExtraAttackOptions *opts);
bool Rampage(ExtraAttackOptions *opts);

View File

@ -765,15 +765,16 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
}
}
float range = RangeItem->Range + AmmoItem->Range + 5.0f; //Fudge it a little, client will let you hit something at 0 0 0 when you are at 205 0 0
float range = RangeItem->Range + AmmoItem->Range + GetRangeDistTargetSizeMod(GetTarget());
mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", range);
range *= range;
if(DistNoRootNoZ(*GetTarget()) > range) {
if(DistNoRoot(*GetTarget()) > range) {
mlog(COMBAT__RANGED, "Ranged attack out of range... client should catch this. (%f > %f).\n", DistNoRootNoZ(*GetTarget()), range);
//target is out of range, client does a message
Message_StringID(13,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase.
return;
}
else if(DistNoRootNoZ(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
else if(DistNoRoot(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
Message_StringID(15,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase.
return;
}
@ -1128,6 +1129,45 @@ void Mob::ProjectileAttack()
SetProjectileAttack(false);
}
float Mob::GetRangeDistTargetSizeMod(Mob* other)
{
/*
Range is enforced client side, therefore these numbers do not need to be 100% accurate just close enough to
prevent any exploitation. The range mod changes in some situations depending on if size is from spawn or from SendIllusionPacket changes.
At present time only calculate from spawn (it is no consistent what happens to the calc when changing it after spawn).
*/
if (!other)
return 0.0f;
float tsize = other->GetSize();
if (GetSize() > tsize)
tsize = GetSize();
float mod = 0.0f;
/*These are correct numbers if mob size is changed via #size (Don't know why it matters but it does)
if (tsize < 7)
mod = 16.0f;
else if (tsize >=7 && tsize <= 20)
mod = 16.0f + (0.6f * (tsize - 6.0f));
else if (tsize >=20 && tsize <= 60)
mod = 25.0f + (1.25f * (tsize - 20.0f));
else
mod = 75.0f;
*/
if (tsize < 10)
mod = 18.0f;
else if (tsize >=10 && tsize < 15)
mod = 20.0f + (4.0f * (tsize - 10.0f));
else if (tsize >=15 && tsize <= 20)
mod = 42.0f + (5.8f * (tsize - 15.0f));
else
mod = 75.0f;
return (mod + 2.0f); //Add 2.0f as buffer to prevent any chance of failures, client enforce range check regardless.
}
void NPC::RangedAttack(Mob* other)
{
@ -1333,16 +1373,16 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
}
}
int range = item->Range +50/*Fudge it a little, client will let you hit something at 0 0 0 when you are at 205 0 0*/;
float range = item->Range + GetRangeDistTargetSizeMod(GetTarget());
mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", range);
range *= range;
if(DistNoRootNoZ(*GetTarget()) > range) {
if(DistNoRoot(*GetTarget()) > range) {
mlog(COMBAT__RANGED, "Throwing attack out of range... client should catch this. (%f > %f).\n", DistNoRootNoZ(*GetTarget()), range);
//target is out of range, client does a message
Message_StringID(13,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase.
return;
}
else if(DistNoRootNoZ(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
return;
else if(DistNoRoot(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
Message_StringID(15,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase.
}
if(!IsAttackAllowed(GetTarget()) ||

View File

@ -396,7 +396,8 @@
#define SONG_ENDS_OTHER 12688 //%1's song ends.
#define SONG_ENDS_ABRUPTLY_OTHER 12689 //%1's song ends abruptly.
#define DIVINE_AURA_NO_ATK 12695 //You can't attack while invulnerable!
#define TRY_ATTACKING_SOMEONE 12696 //Try attacking someone other than yourself, it's more productive.
#define TRY_ATTACKING_SOMEONE 12696 //Try attacking someone other than yourself, it's more productive
#define RANGED_TOO_CLOSE 12698 //Your target is too close to use a ranged weapon!
#define BACKSTAB_WEAPON 12874 //You need a piercing weapon as your primary weapon in order to backstab
#define MORE_SKILLED_THAN_I 12931 //%1 tells you, 'You are more skilled than I! What could I possibly teach you?'
#define SURNAME_EXISTS 12939 //You already have a surname. Operation failed.