Implemented projectile on impact for Throwing

This commit is contained in:
KayenEQ 2014-11-28 07:08:28 -05:00
parent 67863e364b
commit 3d83f647bf
2 changed files with 86 additions and 24 deletions

View File

@ -722,7 +722,7 @@ public:
int32 ReduceAllDamage(int32 damage);
virtual void DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance=false, bool CanAvoid=true);
virtual void DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const Item_Struct* item=nullptr, uint16 weapon_damage=0, int16 chance_mod=0,int16 focus=0, int ReuseTime=0, uint32 ammo_id=0, int AmmoSlot=0);
virtual void DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const Item_Struct* AmmoItem=nullptr, uint16 weapon_damage=0, int16 chance_mod=0,int16 focus=0, int ReuseTime=0, uint32 range_id=0, int AmmoSlot=0);
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod=0, int16 focus=0, bool CanRiposte=false, int ReuseTime=0);
virtual void DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const ItemInst* Ammo=nullptr, uint16 weapon_damage=0, int16 chance_mod=0, int16 focus=0, int ReuseTime=0, uint32 range_id=0, uint32 ammo_id=0, const Item_Struct *AmmoItem=nullptr, int AmmoSlot=0);
bool TryProjectileAttack(Mob* other, const Item_Struct *item, SkillUseTypes skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot);

View File

@ -852,16 +852,14 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
if (IsClient()){
_RangeWeapon = CastToClient()->m_inv[MainRange];
if (!_RangeWeapon || _RangeWeapon->GetItem()->ID != range_id)
RangeWeapon = nullptr;
else
RangeWeapon = _RangeWeapon;
if (_RangeWeapon && !_RangeWeapon->GetItem() && _RangeWeapon->GetItem()->ID == range_id)
RangeWeapon = _RangeWeapon;
_Ammo = CastToClient()->m_inv[AmmoSlot];
if (!_Ammo || _Ammo->GetItem()->ID != ammo_id)
ammo_lost = database.GetItem(ammo_id);
else
if (_Ammo && _Ammo->GetItem() && _Ammo->GetItem()->ID == ammo_id)
Ammo = _Ammo;
else
ammo_lost = database.GetItem(ammo_id);
}
}
}
@ -1035,14 +1033,19 @@ bool Mob::TryProjectileAttack(Mob* other, const Item_Struct *item, SkillUseTypes
float hit = 60.0f + (distance / 1.8f); //Calcuation: 60 = Animation Lag, 1.8 = Speed modifier for speed of (4)
ProjectileAtk[slot].increment = 1;
ProjectileAtk[slot].hit_increment = hit; //This projected hit time if target does NOT MOVE
ProjectileAtk[slot].hit_increment = static_cast<uint16>(hit); //This projected hit time if target does NOT MOVE
ProjectileAtk[slot].target_id = other->GetID();
ProjectileAtk[slot].wpn_dmg = weapon_dmg;
ProjectileAtk[slot].origin_x = GetX();
ProjectileAtk[slot].origin_y = GetY();
ProjectileAtk[slot].origin_z = GetZ();
ProjectileAtk[slot].ranged_id = RangeWeapon->GetItem()->ID;
ProjectileAtk[slot].ammo_id = Ammo->GetItem()->ID;
if (RangeWeapon && RangeWeapon->GetItem())
ProjectileAtk[slot].ranged_id = RangeWeapon->GetItem()->ID;
if (Ammo && Ammo->GetItem())
ProjectileAtk[slot].ammo_id = Ammo->GetItem()->ID;
ProjectileAtk[slot].ammo_slot = 0;
ProjectileAtk[slot].skill = skillInUse;
@ -1077,8 +1080,9 @@ void Mob::ProjectileAttack()
if (target && target->IsMoving()){ //Only recalculate hit increment if target moving
//Due to frequency that we need to check increment the targets position variables may not be updated even if moving. Do a simple check before calculating distance.
if (ProjectileAtk[i].sanitycheck != target->GetX() * target->GetY()){
ProjectileAtk[i].sanitycheck = target->GetX() * target->GetY();
float _sanitycheck = target->GetX() * target->GetY();
if (ProjectileAtk[i].sanitycheck != _sanitycheck){
ProjectileAtk[i].sanitycheck = _sanitycheck;
float distance = target->CalculateDistance(ProjectileAtk[i].origin_x, ProjectileAtk[i].origin_y, ProjectileAtk[i].origin_z);
float hit = 60.0f + (distance / 1.8f); //Calcuation: 60 = Animation Lag, 1.8 = Speed modifier for speed of (4)
ProjectileAtk[i].hit_increment = static_cast<uint16>(hit);
@ -1090,6 +1094,8 @@ void Mob::ProjectileAttack()
if (target){
if (ProjectileAtk[i].skill == SkillArchery)
DoArcheryAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0,ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_id, nullptr, ProjectileAtk[i].ammo_slot);
else if (ProjectileAtk[i].skill == SkillThrowing)
DoThrowingAttackDmg(target, nullptr, nullptr,ProjectileAtk[i].wpn_dmg,0,0,0, ProjectileAtk[i].ranged_id, ProjectileAtk[i].ammo_slot);
}
ProjectileAtk[i].increment = 0;
@ -1330,7 +1336,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
else if(DistNoRootNoZ(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
return;
}
Shout("SLOT = %i", ammo_slot);
if(!IsAttackAllowed(GetTarget()) ||
IsCasting() ||
IsSitting() ||
@ -1341,8 +1347,6 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
(GetAppearance() == eaDead)){
return;
}
//send item animation, also does the throw animation
SendItemAnimation(GetTarget(), item, SkillThrowing);
DoThrowingAttackDmg(GetTarget(), RangeWeapon, item);
@ -1352,14 +1356,62 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
CommonBreakInvisible();
}
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* item, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime, uint32 ammo_id, int AmmoSlot)
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* AmmoItem, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime, uint32 range_id, int AmmoSlot)
{
if (!CanDoSpecialAttack(other))
if ((other == nullptr ||
((IsClient() && CastToClient()->dead) ||
(other->IsClient() && other->CastToClient()->dead)) ||
HasDied() ||
(!IsAttackAllowed(other)) ||
(other->GetInvul() ||
other->GetSpecialAbility(IMMUNE_MELEE))))
{
return;
}
if (!other->CheckHitChance(this, SkillThrowing, MainPrimary, chance_mod)){
const ItemInst* _RangeWeapon = nullptr;
const Item_Struct* ammo_lost = nullptr;
/*
If LaunchProjectile is false this function will do archery damage on target,
otherwise it will shoot the projectile at the target, once the projectile hits target
this function is then run again to do the damage portion
*/
bool LaunchProjectile = false;
bool ProjectileMiss = false;
if (RuleB(Combat, ProjectileDmgOnImpact)){
if (AmmoItem)
LaunchProjectile = true;
else{
if (!RangeWeapon && range_id){
if (weapon_damage == 0)
ProjectileMiss = true; //This indicates that MISS was originally calculated.
if (IsClient()){
_RangeWeapon = CastToClient()->m_inv[AmmoSlot];
if (_RangeWeapon && _RangeWeapon->GetItem() && _RangeWeapon->GetItem()->ID != range_id)
RangeWeapon = _RangeWeapon;
else
ammo_lost = database.GetItem(range_id);
}
}
}
}
else if (AmmoItem)
SendItemAnimation(other, AmmoItem, SkillThrowing);
if (ProjectileMiss || !other->CheckHitChance(this, SkillThrowing, MainPrimary, chance_mod)){
mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName());
other->Damage(this, 0, SPELL_UNKNOWN, SkillThrowing);
if (LaunchProjectile){
TryProjectileAttack(other, AmmoItem, SkillThrowing, 0, RangeWeapon, nullptr, AmmoSlot);
return;
}
else
other->Damage(this, 0, SPELL_UNKNOWN, SkillThrowing);
} else {
mlog(COMBAT__RANGED, "Throwing attack hit %s.", other->GetName());
@ -1368,8 +1420,13 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
if (!weapon_damage){
if (IsClient() && RangeWeapon)
WDmg = GetWeaponDamage(other, RangeWeapon);
else if (item)
WDmg = GetWeaponDamage(other, item);
else if (AmmoItem)
WDmg = GetWeaponDamage(other, AmmoItem);
if (LaunchProjectile){
TryProjectileAttack(other, AmmoItem, SkillThrowing, WDmg, RangeWeapon, nullptr, AmmoSlot);
return;
}
}
else
WDmg = weapon_damage;
@ -1415,7 +1472,13 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
}
}
if((RangeWeapon != nullptr) && other && (other->GetHP() > -10))
if (LaunchProjectile)
return;
//Throwing item Proc
if (ammo_lost)
TryWeaponProc(nullptr, ammo_lost, other, MainRange);
else if(RangeWeapon && other && !other->HasDied())
TryWeaponProc(RangeWeapon, other, MainRange);
if (HasSkillProcs() && other && !other->HasDied()){
@ -1424,7 +1487,6 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
else
TrySkillProc(other, SkillThrowing, 0, false, MainRange);
}
}
void Mob::SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skillInUse) {