bool CHARACTER::Attack(LPCHARACTER pkVictim, BYTE bType)
{
#ifdef FIX_ATTACK_SAFEZONE
SECTREE *sectree = NULL;
SECTREE *vsectree = NULL;
sectree = GetSectree();
vsectree = pkVictim->GetSectree();
if (sectree && vsectree){
if (sectree->IsAttr(GetX(), GetY(), ATTR_BANPK) || vsectree->IsAttr(pkVictim->GetX(), pkVictim->GetY(), ATTR_BANPK)) {
if (GetDesc()) {
LogManager::instance().HackLog("ANTISAFEZONE", this);
GetDesc()->DelayedDisconnect(3);
}
}
}
#endif
#ifdef ENABLE_SUPPORT_SYSTEM
if (pkVictim && pkVictim->IsSupport())
{
ChatPacket(CHAT_TYPE_INFO, "Nu poti ataca!");
return false;
}
#endif
if (!CanMove())
return false;
// CASTLE
if (IS_CASTLE_MAP(GetMapIndex()) && false == castle_can_attack(this, pkVictim))
return false;
// CASTLE
// @fixme131 kirito
if (!battle_is_attackable(this, pkVictim))
return false;
DWORD dwCurrentTime = get_dword_time();
if (IsPC())
{
if (IS_SPEED_HACK(this, pkVictim, dwCurrentTime))
return false;
if (bType == 0 && dwCurrentTime < GetSkipComboAttackByTime())
return false;
}
else
{
MonsterChat(MONSTER_CHAT_ATTACK);
}
int iRet;
if(iRet != BATTLE_NONE)
{
pkVictim->SetSyncOwner(this);
if (pkVictim->CanBeginFight())
pkVictim->BeginFight(this);
}
if (bType == 0)
{
//
// 일반 공격
//
switch (GetMobBattleType())
{
case BATTLE_TYPE_MELEE:
case BATTLE_TYPE_POWER:
case BATTLE_TYPE_TANKER:
case BATTLE_TYPE_SUPER_POWER:
case BATTLE_TYPE_SUPER_TANKER:
iRet = battle_melee_attack(this, pkVictim);
break;
case BATTLE_TYPE_RANGE:
FlyTarget(pkVictim->GetVID(), pkVictim->GetX(), pkVictim->GetY(), HEADER_CG_FLY_TARGETING);
iRet = Shoot(0) ? BATTLE_DAMAGE : BATTLE_NONE;
break;
case BATTLE_TYPE_MAGIC:
FlyTarget(pkVictim->GetVID(), pkVictim->GetX(), pkVictim->GetY(), HEADER_CG_FLY_TARGETING);
iRet = Shoot(1) ? BATTLE_DAMAGE : BATTLE_NONE;
break;
default:
sys_err("Unhandled battle type %d", GetMobBattleType());
iRet = BATTLE_NONE;
break;
}
}
else
{
if (IsPC() == true)
{
if (dwCurrentTime - m_dwLastSkillTime > 1500)
{
sys_log(1, "HACK: Too long skill using term. Name(%s) PID(%u) delta(%u)",
GetName(), GetPlayerID(), (dwCurrentTime - m_dwLastSkillTime));
return false;
}
}
sys_log(1, "Attack call ComputeSkill %d %s", bType, pkVictim?pkVictim->GetName():"");
iRet = ComputeSkill(bType, pkVictim);
}
if (iRet == BATTLE_DAMAGE || iRet == BATTLE_DEAD)
{
OnMove(true);
pkVictim->OnMove();
// only pc sets victim null. For npc, state machine will reset this.
if (BATTLE_DEAD == iRet && IsPC())
SetVictim(NULL);
return true;
}
return false;
}
The function is identical to a server on which it works