Index: src/map/ai/ai_char_normal.cpp =================================================================== --- src/map/ai/ai_char_normal.cpp (revision 1676) +++ src/map/ai/ai_char_normal.cpp (working copy) @@ -836,7 +836,7 @@ } } damage = (damage + PItem->getDamage() + battleutils::GetFSTR(m_PChar,m_PBattleSubTarget,SLOT_RANGED)) * pdif; - Action.param = battleutils::TakePhysicalDamage(m_PChar, m_PBattleSubTarget, damage, false, SLOT_RANGED, 1); + Action.param = battleutils::TakePhysicalDamage(m_PChar, m_PBattleSubTarget, damage, false, SLOT_RANGED, 1, NULL); if(PItem != NULL){//not a throwing item, check the ammo for dmg/etc battleutils::HandleRangedAdditionalEffect(m_PChar,m_PBattleSubTarget,&Action); @@ -1781,12 +1781,30 @@ m_PChar->health.tp = 0; } + + //incase a TA party member is available + CBattleEntity* taChar = NULL; + + //trick attack agi bonus for thf main job + if(m_PChar->GetMJob() == JOB_THF && m_PChar->StatusEffectContainer->HasStatusEffect(EFFECT_TRICK_ATTACK)) + { + taChar = battleutils::getAvailableTrickAttackChar(m_PChar,m_PBattleTarget); + if(taChar != NULL) damage += m_PChar->AGI(); + } + + //check if other jobs have trick attack active to change enmity lateron + if(taChar == NULL && m_PChar->StatusEffectContainer->HasStatusEffect(EFFECT_TRICK_ATTACK)) + { + taChar = battleutils::getAvailableTrickAttackChar(m_PChar,m_PBattleTarget); + } + + if(!battleutils::isValidSelfTargetWeaponskill(m_PWeaponSkill->getID())){ uint8 damslot = SLOT_MAIN; if(m_PWeaponSkill->getID()>=192 && m_PWeaponSkill->getID()<=218){//ranged WS IDs damslot = SLOT_RANGED; } - damage = battleutils::TakePhysicalDamage(m_PChar, m_PBattleSubTarget, damage, false, damslot, tpHitsLanded); + damage = battleutils::TakePhysicalDamage(m_PChar, m_PBattleSubTarget, damage, false, damslot, tpHitsLanded, taChar); m_PBattleSubTarget->StatusEffectContainer->DelStatusEffectsByFlag(EFFECTFLAG_DAMAGE); m_PChar->StatusEffectContainer->DelStatusEffect(EFFECT_BOOST); //TODO: REMOVE THIS, BOOST EFFECT IN DB IS WRONG, MISSING EFFECTFLAG_DAMAGE } @@ -1916,7 +1934,7 @@ m_PChar->health.tp = wsTP; damage = luautils::OnUseWeaponSkill(m_PChar, m_PBattleSubTarget, &tpHitsLanded, &extraHitsLanded); m_PChar->health.tp = afterWsTP; - AoEAction.param = battleutils::TakePhysicalDamage(m_PChar, PTarget, damage, false, SLOT_MAIN, 0); + AoEAction.param = battleutils::TakePhysicalDamage(m_PChar, PTarget, damage, false, SLOT_MAIN, 0, taChar); if(damage==0) { AoEAction.reaction = REACTION_EVADE; @@ -2097,6 +2115,8 @@ uint32 numattacksLeftHand = 0; uint32 numKickAttacks = 0; + CBattleEntity* taChar = NULL; + uint16 subType = m_PChar->m_Weapons[SLOT_SUB]->getDmgType(); if ((subType > 0 && subType < 4))//sub weapon is equipped! @@ -2165,6 +2185,7 @@ else if ( rand()%100 < hitRate) { bool ignoreSneakAttack = (i != 0); // Sneak attack critical effect should only be given on the first swing. + bool ignoreTrickAttack = (i != 0); bool isCritical = (rand()%100 < battleutils::GetCritHitRate(m_PChar, m_PBattleTarget, ignoreSneakAttack)); float DamageRatio = battleutils::GetDamageRatio(m_PChar,m_PBattleTarget,isCritical); @@ -2193,6 +2214,22 @@ } + + //trick attack agi bonus for thf main job + if(m_PChar->GetMJob() == JOB_THF && (!ignoreTrickAttack) && m_PChar->StatusEffectContainer->HasStatusEffect(EFFECT_TRICK_ATTACK)) + { + taChar = battleutils::getAvailableTrickAttackChar(m_PChar,m_PBattleTarget); + if(taChar != NULL) bonusDMG = m_PChar->AGI(); + } + + //check if other jobs have trick attack active to change enmity lateron + if(taChar == NULL && m_PChar->StatusEffectContainer->HasStatusEffect(EFFECT_TRICK_ATTACK) && (!ignoreTrickAttack)) + { + taChar = battleutils::getAvailableTrickAttackChar(m_PChar,m_PBattleTarget); + } + + + damage = (uint16)(((PWeapon->getDamage() + bonusDMG + battleutils::GetFSTR(m_PChar, m_PBattleTarget,fstrslot)) * DamageRatio)); @@ -2234,7 +2271,7 @@ if (Action.reaction == REACTION_HIT) { - Action.param = battleutils::TakePhysicalDamage(m_PChar, m_PBattleTarget, damage, isBlocked, fstrslot, 1); + Action.param = battleutils::TakePhysicalDamage(m_PChar, m_PBattleTarget, damage, isBlocked, fstrslot, 1, taChar); } else { Index: src/map/ai/ai_mob_dummy.cpp =================================================================== --- src/map/ai/ai_mob_dummy.cpp (revision 1676) +++ src/map/ai/ai_mob_dummy.cpp (working copy) @@ -1025,7 +1025,7 @@ if(!isCountered) { - Action.param = battleutils::TakePhysicalDamage(m_PMob, m_PBattleTarget, damage, isBlocked ,SLOT_MAIN, 1); + Action.param = battleutils::TakePhysicalDamage(m_PMob, m_PBattleTarget, damage, isBlocked ,SLOT_MAIN, 1, NULL); m_PMob->PEnmityContainer->UpdateEnmityFromAttack(m_PBattleTarget, Action.param); // Block skill up @@ -1039,7 +1039,7 @@ } else { - Action.param = battleutils::TakePhysicalDamage(m_PBattleTarget, m_PMob, damage, false, SLOT_MAIN, 1); + Action.param = battleutils::TakePhysicalDamage(m_PBattleTarget, m_PMob, damage, false, SLOT_MAIN, 1, NULL); } m_PMob->m_ActionList.push_back(Action); Index: src/map/ai/ai_pet_dummy.cpp =================================================================== --- src/map/ai/ai_pet_dummy.cpp (revision 1676) +++ src/map/ai/ai_pet_dummy.cpp (working copy) @@ -595,7 +595,7 @@ bool isBlocked = (rand()%100 < battleutils::GetBlockRate(m_PPet,m_PBattleTarget)); if(isBlocked){ Action.reaction = REACTION_BLOCK; } - Action.param = battleutils::TakePhysicalDamage(m_PPet, m_PBattleTarget, damage, isBlocked, SLOT_MAIN, 1); + Action.param = battleutils::TakePhysicalDamage(m_PPet, m_PBattleTarget, damage, isBlocked, SLOT_MAIN, 1, NULL); m_PPet->m_ActionList.push_back(Action); Index: src/map/battleutils.cpp =================================================================== --- src/map/battleutils.cpp (revision 1676) +++ src/map/battleutils.cpp (working copy) @@ -38,6 +38,8 @@ #include "charutils.h" #include "battleutils.h" #include "map.h" +#include "party.h" +#include "alliance.h" #include "spell.h" #include "trait.h" #include "weapon_skill.h" @@ -1119,7 +1121,7 @@ * * ************************************************************************/ -uint16 TakePhysicalDamage(CBattleEntity* PAttacker, CBattleEntity* PDefender, int16 damage, bool isBlocked, uint8 slot, uint16 tpMultiplier) +uint16 TakePhysicalDamage(CBattleEntity* PAttacker, CBattleEntity* PDefender, int16 damage, bool isBlocked, uint8 slot, uint16 tpMultiplier, CBattleEntity* taChar) { if (PDefender->StatusEffectContainer->HasStatusEffect(EFFECT_INVINCIBLE) || PDefender->StatusEffectContainer->HasStatusEffect(EFFECT_INVINCIBLE, 0)) @@ -1219,7 +1221,11 @@ { PDefender->addTP(TP); } - ((CMobEntity*)PDefender)->PEnmityContainer->UpdateEnmityFromDamage(PAttacker, damage); + if(taChar == NULL){ + ((CMobEntity*)PDefender)->PEnmityContainer->UpdateEnmityFromDamage(PAttacker, damage); + }else{ + ((CMobEntity*)PDefender)->PEnmityContainer->UpdateEnmityFromDamage(taChar, damage); + } } break; case TYPE_PET: @@ -2336,4 +2342,48 @@ } // end switch } + + + + +CBattleEntity* getAvailableTrickAttackChar(CBattleEntity* taUser, CBattleEntity* PMob) +{ + if (taUser->PParty != NULL){ + if (taUser->PParty->m_PAlliance != NULL){ + for(uint8 a = 0; a < taUser->PParty->m_PAlliance->partyList.size(); ++a){ + for(uint8 i = 0; i < taUser->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i){ + if(abs(taUser->PParty->m_PAlliance->partyList.at(a)->members.at(i)->loc.p.rotation - taUser->loc.p.rotation) < 23 && + abs(PMob->loc.p.rotation - taUser->PParty->m_PAlliance->partyList.at(a)->members.at(i)->loc.p.rotation) < 23){ + + float distancePartyChar = distance(taUser->PParty->m_PAlliance->partyList.at(a)->members.at(i)->loc.p,PMob->loc.p); + float distanceTaChar = distance(taUser->loc.p,PMob->loc.p); + + //is the party char closer to the mob than the TA user? + if(distancePartyChar < distanceTaChar){ + return taUser->PParty->m_PAlliance->partyList.at(a)->members.at(i); + } + } + } + } + }else{//no alliance + for(uint8 i = 0; i < taUser->PParty->members.size(); ++i){ + if(abs(taUser->PParty->members.at(i)->loc.p.rotation - taUser->loc.p.rotation) < 23 && + abs(PMob->loc.p.rotation - taUser->PParty->members.at(i)->loc.p.rotation) < 23){ + + float distancePartyChar = distance(taUser->PParty->members.at(i)->loc.p,PMob->loc.p); + float distanceTaChar = distance(taUser->loc.p,PMob->loc.p); + //is the party char closer to the mob than the TA user? + if(distancePartyChar < distanceTaChar){ + return taUser->PParty->members.at(i); + } + } + } + } + } +//no Trick attack party member available +return NULL; +} + + + }; Index: src/map/battleutils.h =================================================================== --- src/map/battleutils.h (revision 1676) +++ src/map/battleutils.h (working copy) @@ -108,7 +108,7 @@ uint8 GetGuardRate(CBattleEntity* PAttacker, CBattleEntity* PDefender); float GetDamageRatio(CBattleEntity* PAttacker, CBattleEntity* PDefender, bool isCritical); uint16 TakeMagicDamage(CBattleEntity* PAttacker, CBattleEntity* PDefender); - uint16 TakePhysicalDamage(CBattleEntity* PAttacker, CBattleEntity* PDefender, int16 damage, bool isBlocked, uint8 slot, uint16 tpMultiplier); + uint16 TakePhysicalDamage(CBattleEntity* PAttacker, CBattleEntity* PDefender, int16 damage, bool isBlocked, uint8 slot, uint16 tpMultiplier, CBattleEntity* taChar); uint16 TakeSkillchainDamage(CBattleEntity* PAttacker, CBattleEntity* PDefender, uint16 lastSkillDamage); uint32 MagicCalculateCure(CBattleEntity* PCaster, CBattleEntity* PTarget, CSpell* PSpell, int8 targetNumber, CZone* PZone); bool SingSong(CBattleEntity* PCaster,CBattleEntity* PTarget,CSpell* PSpell); @@ -134,7 +134,7 @@ void MakeEntityStandUp(CBattleEntity* PEntity); bool IsEngauged(CBattleEntity* PEntity); - + CBattleEntity* getAvailableTrickAttackChar(CBattleEntity* taUser, CBattleEntity* PMob); bool HasNinjaTool(CBattleEntity* PEntity, CSpell* PSpell, bool ConsumeTool); };