Código:
bool CDarkSpirit::Attack(LPOBJ lpObj,LPOBJ lpTarget,CSkill* lpSkill,bool send,BYTE flag,BYTE action) // OK{
#pragma region ATTACK_CHECK
if(lpObj->Index == lpTarget->Index)
{
return 0;
}
if(lpObj->Type == OBJECT_USER && gObjIsConnectedGP(lpObj->Index) == 0)
{
return 0;
}
if(lpTarget->Type == OBJECT_USER && gObjIsConnectedGP(lpTarget->Index) == 0)
{
return 0;
}
if(gMap[lpObj->Map].CheckAttr(lpObj->X,lpObj->Y,1) != 0 || gMap[lpTarget->Map].CheckAttr(lpTarget->X,lpTarget->Y,1) != 0)
{
return 0;
}
#if(GAMESERVER_UPDATE>=402)
if(gDuel.GetDuelArenaBySpectator(lpObj->Index) != 0 || gDuel.GetDuelArenaBySpectator(lpTarget->Index) != 0)
{
return 0;
}
#endif
if(gCrywolf.GetCrywolfState() == CRYWOLF_STATE_READY || gCrywolf.GetCrywolfState() == CRYWOLF_STATE_END)
{
if(lpTarget->Type == OBJECT_MONSTER && lpTarget->Map == MAP_CRYWOLF)
{
return 0;
}
}
if(lpObj->GuildNumber > 0 && lpObj->Guild != 0 && lpObj->Guild->WarState != 0)
{
if(lpObj->Guild->WarType == 1 && GetBattleSoccerGoalMove(0) == 0)
{
return 1;
}
if(lpObj->Guild->WarType == 0 && lpTarget->Type == OBJECT_MONSTER)
{
return 0;
}
}
if(lpTarget->Type == OBJECT_NPC || lpTarget->Live == 0 || lpTarget->State != OBJECT_PLAYING || lpTarget->Teleport != 0)
{
return 0;
}
if(lpTarget->Type == OBJECT_MONSTER)
{
if((lpTarget->Class >= 100 && lpTarget->Class <= 110) || lpTarget->Class == 523) // Trap
{
return 0;
}
if(lpTarget->Class == 221 || lpTarget->Class == 222) // Siege
{
return 0;
}
}
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_MONSTER)
{
if(OBJECT_RANGE(lpObj->SummonIndex) != 0)
{
if(lpObj->SummonIndex == lpTarget->Index)
{
return 0;
}
}
}
int SummonIndex = lpObj->Index;
if(lpObj->Type == OBJECT_MONSTER && OBJECT_RANGE(lpObj->SummonIndex) != 0)
{
SummonIndex = lpObj->SummonIndex;
}
int SummonTargetIndex = lpTarget->Index;
if(lpTarget->Type == OBJECT_MONSTER && OBJECT_RANGE(lpTarget->SummonIndex) != 0)
{
SummonTargetIndex = lpTarget->SummonIndex;
}
if(gAttack.CheckPlayerTarget(&gObj[SummonIndex],&gObj[SummonTargetIndex]) == 0)
{
return 0;
}
#pragma endregion
#pragma region ATTACK_RETURN
int skill = ((lpSkill==0)?SKILL_NONE:lpSkill->m_skill);
if(lpObj->Type == OBJECT_USER)
{
lpObj->HPAutoRecuperationTime = GetTickCount();
lpObj->MPAutoRecuperationTime = GetTickCount();
lpObj->BPAutoRecuperationTime = GetTickCount();
lpObj->SDAutoRecuperationTime = GetTickCount();
}
if(lpTarget->Type == OBJECT_USER)
{
lpTarget->HPAutoRecuperationTime = GetTickCount();
lpTarget->MPAutoRecuperationTime = GetTickCount();
lpTarget->BPAutoRecuperationTime = GetTickCount();
lpTarget->SDAutoRecuperationTime = GetTickCount();
}
if(OBJECT_RANGE(lpObj->SummonIndex) != 0)
{
gObjSummonSetEnemy(lpObj,lpTarget->Index);
}
if(lpObj->Type == OBJECT_USER)
{
gDarkSpirit[lpObj->Index].SetTarget(lpTarget->Index);
}
bool duel = gDuel.CheckDuel(lpObj,lpTarget);
if(lpObj->Type == OBJECT_USER && duel != 0)
{
lpObj->DuelTickCount = GetTickCount();
}
if(lpTarget->Type == OBJECT_USER && duel != 0)
{
lpTarget->DuelTickCount = GetTickCount();
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_ORDER_OF_PROTECTION) != 0 && lpSkill == 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_ORDER_OF_PROTECTION) != 0 && lpSkill != 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_PHYSI_DAMAGE_IMMUNITY) != 0 && lpSkill == 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_MAGIC_DAMAGE_IMMUNITY) != 0 && lpSkill != 0)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(lpTarget->Type == OBJECT_MONSTER)
{
if(lpTarget->Class == 200 && lpSkill == 0)
{
gObjMonsterStateProc(lpTarget,6,lpObj->Index,0);
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(lpTarget->Class == 200 && lpSkill != 0)
{
gObjMonsterStateProc(lpTarget,7,lpObj->Index,0);
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_MONSTER_PHYSI_DAMAGE_IMMUNITY) != 0 && skill == SKILL_NONE)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(gEffectManager.CheckEffect(lpTarget,EFFECT_MONSTER_MAGIC_DAMAGE_IMMUNITY) != 0 && skill != SKILL_NONE)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
if(lpTarget->MonsterSkillElementOption.CheckImmuneTime() != 0)
{
if(lpTarget->MonsterSkillElementOption.m_SkillElementImmuneNumber == skill)
{
gAttack.MissSend(lpObj,lpTarget,lpSkill,send,0);
return 1;
}
}
}
#pragma endregion
#pragma region DAMAGE_CALC
flag = 0;
BYTE miss = 0;
WORD effect = 0;
if((lpObj->Type != OBJECT_USER || lpTarget->Type != OBJECT_USER) && this->MissCheck(lpObj,lpTarget,lpSkill,send,&miss) == 0)
{
return 1;
}
if((lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_USER) && gAttack.MissCheckPvP(lpObj,lpTarget,lpSkill,send,0,&miss) == 0)
{
return 1;
}
long long defense = this->GetTargetDefense(lpObj,lpTarget,&effect);
long long damage = this->GetAttackDamage(lpObj,lpTarget,lpSkill,&effect,defense);
if(miss != 0)
{
damage = (damage*30)/100;
}
if(action != 0)
{
damage = (damage*60)/100;
}
for(int n=0;n < MAX_DAMAGE_REDUCTION;n++)
{
damage -= (damage*lpTarget->DamageReduction[n])/100;
}
if(lpTarget->EffectOption.AddDamageReduction > 0)
{
damage -= (damage*lpTarget->EffectOption.AddDamageReduction)/100;
}
if((GetTickCount()-lpTarget->ShieldDamageReductionTime) < ((DWORD)(gServerInfo.m_DefenseTimeConstA*1000)))
{
damage -= (damage*lpTarget->ShieldDamageReduction)/100;
}
gAttack.WingSprite(0,lpTarget,&damage);
gAttack.HelperSprite(0,lpTarget,&damage);
int MinDamage = (lpObj->Level+lpObj->MasterLevel)/10;
MinDamage = ((MinDamage<1)?1:MinDamage);
damage = ((damage<MinDamage)?MinDamage:damage);
this->DarkSpiritSprite(lpObj,damage);
gAttack.DamageSprite(lpTarget,damage);
#if(GAMESERVER_UPDATE>=602)
if((GetLargeRand()%100) < gMasterSkillTree.GetMasterSkillValue(lpObj,MASTER_SKILL_ADD_DARK_SPIRIT_DOUBLE_DAMAGE_RATE))
{
effect |= 0x40;
damage += damage;
}
#endif
#pragma endregion
#pragma region DAMAGE_CONFIG
if(lpObj->Type == OBJECT_USER)
{
if(lpTarget->Type == OBJECT_USER)
{
damage = (damage*gServerInfo.m_GeneralDamageRatePvP)/100;
damage = (damage*gServerInfo.m_DamageRatePvP[lpObj->Class])/100;
damage = (damage*gServerInfo.m_DamageRateTo[lpObj->Class][lpTarget->Class])/100;
if(duel != 0)
{
damage = (damage*gServerInfo.m_DuelDamageRate)/100;
}
else if(gGensSystem.CheckGens(lpObj,lpTarget) != 0)
{
damage = (damage*gServerInfo.m_GensDamageRate)/100;
}
else if(CC_MAP_RANGE(lpObj->Map) != 0 && CC_MAP_RANGE(lpTarget->Map) != 0)
{
damage = (damage*gServerInfo.m_ChaosCastleDamageRate)/100;
}
else if(IT_MAP_RANGE(lpObj->Map) != 0 && IT_MAP_RANGE(lpTarget->Map) != 0)
{
damage = (damage*gServerInfo.m_IllusionTempleDamageRate)/100;
}
}
else
{
damage = (damage*gServerInfo.m_GeneralDamageRatePvM)/100;
damage = (damage*gServerInfo.m_DamageRatePvM[lpObj->Class])/100;
}
}
#pragma endregion
#pragma region DAMAGE_FINISH
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_MONSTER)
{
}
damage = ((damage<0)?0:damage);
#pragma endregion
#pragma region DAMAGE_APPLY
int ShieldDamage = 0;
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_USER)
{
ShieldDamage = gAttack.GetShieldDamage(lpObj,lpTarget,damage);
if(lpTarget->Life < (damage-ShieldDamage))
{
lpTarget->Life = 0;
}
else
{
lpTarget->Life -= damage-ShieldDamage;
}
if(lpTarget->Shield < ShieldDamage)
{
lpTarget->Shield = 0;
}
else
{
lpTarget->Shield -= ShieldDamage;
}
}
else
{
if(lpTarget->Life < damage)
{
lpTarget->Life = 0;
}
else
{
lpTarget->Life -= damage;
}
}
if(lpTarget->Type == OBJECT_MONSTER)
{
lpTarget->LastAttackerID = lpObj->Index;
gObjAddMsgSendDelay(lpTarget,0,lpObj->Index,100,0);
if(lpTarget->CurrentAI != 0)
{
lpTarget->Agro.IncAgro(lpObj->Index,(damage/50));
}
}
#pragma endregion
#pragma region CHECK_SELF_DEFENSE
if(damage > 0)
{
if(lpObj->Type == OBJECT_USER && lpTarget->Type == OBJECT_USER && lpObj->Index != lpTarget->Index)
{
bool CheckSelfDefense = 1;
if(effect == 4)
{
CheckSelfDefense = 0;
}
if(gDuel.CheckDuel(lpObj,lpTarget) != 0)
{
CheckSelfDefense = 0;
}
if(gGensSystem.CheckGens(lpObj,lpTarget) != 0)
{
CheckSelfDefense = 0;
}
if(CC_MAP_RANGE(lpObj->Map) != 0 && CC_MAP_RANGE(lpTarget->Map) != 0)
{
CheckSelfDefense = 0;
}
if(IT_MAP_RANGE(lpObj->Map) != 0 && IT_MAP_RANGE(lpTarget->Map) != 0)
{
CheckSelfDefense = 0;
}
if(gMapManager.GetMapNonOutlaw(lpObj->Map) != 0)
{
CheckSelfDefense = 0;
}
if(CheckSelfDefense != 0)
{
gObjCheckSelfDefense(lpObj,lpTarget->Index);
}
}
gAttack.ArmorDurabilityDown(lpObj,lpTarget);
}
lpObj->Rest = 0;
#pragma endregion
#pragma region ATTACK_FINISH
if(damage > 0)
{
gEffectManager.DelEffect(lpTarget,EFFECT_SLEEP);
if(lpTarget->Type == OBJECT_USER)
{
if(effect != 4)
{
if((lpTarget->DamageReflect+lpTarget->EffectOption.AddDamageReflect) > 0)
{
gObjAddMsgSendDelay(lpTarget,10,lpObj->Index,10,((damage*(lpTarget->DamageReflect+lpTarget->EffectOption.AddDamageReflect))/100));
}
if((GetLargeRand()%100) < lpTarget->DefensiveFullBPRestoreRate)
{
lpTarget->BP = lpTarget->MaxBP+lpTarget->AddBP;
GCManaSend(lpTarget->Index,0xFF,(int)lpTarget->Mana,lpTarget->BP);
}
}
int effect = 1;
}
gObjectManager.CharacterLifeCheck(lpObj,lpTarget,(damage-ShieldDamage),0,flag,effect,skill,ShieldDamage/*,0*/);
}
else
{
GCDamageSend(lpObj->Index,lpTarget->Index,0,0,effect,0);
}
if(lpObj->Type == OBJECT_USER && lpObj->Life <= 0 && lpObj->CheckLifeTime <= 0)
{
lpObj->AttackObj = lpTarget;
lpObj->AttackerKilled = ((lpTarget->Type==OBJECT_USER)?1:0);
lpObj->CheckLifeTime = 3;
}
#pragma endregion
return 1;
}