void CUser::SelectCharacter(Packet & pkt) { Packet result(WIZ_SEL_CHAR); uint8 bResult, bInit; if (isBanned()) { Disconnect(); return; } pkt >> bResult >> bInit; result << bResult; if (bResult == 0 || !GetZoneID()) goto fail_return; m_pMap = g_pMain->GetZoneByID(GetZoneID()); if (GetMap() == nullptr) goto fail_return; if (g_pMain->m_nServerNo != GetMap()->m_nServerNo) { _ZONE_SERVERINFO *pInfo = g_pMain->m_ServerArray.GetData(GetMap()->m_nServerNo); if (pInfo == nullptr) goto fail_return; SendServerChange(pInfo->strServerIP, bInit); return; } if (!g_pMain->isWarOpen() && GetFame() == COMMAND_CAPTAIN) m_bFame = CHIEF; // Disallow players from relogging in the opposite nation's home zone when an invasion's not running. if (((GetZoneID() != GetNation() && GetZoneID() <= ZONE_ELMORAD && !g_pMain->m_byBattleOpen) // also disallow players from logging back into war zones that aren't currently active... || (GetMap()->isWarZone() && !g_pMain->m_byBattleOpen) // Chaos, bdw and juraid montuain || isInTempleEventZone() // Ronark Land, Ardream, RLB, Bifrost, Krowaz Dominion. || (g_pMain->m_byBattleOpen && (GetZoneID() == ZONE_RONARK_LAND || GetZoneID() == ZONE_ARDREAM || GetZoneID() == ZONE_RONARK_LAND_BASE || GetZoneID() == ZONE_BIFROST || GetZoneID() == ZONE_KROWAZ_DOMINION))) && !isGM()) { NativeZoneReturn(); Disconnect(); return; } SetLogInInfoToDB(bInit); result << GetZoneID() << GetSPosX() << GetSPosZ() << GetSPosY() << g_pMain->m_byOldVictory; m_bSelectedCharacter = true; Send(&result); SetUserAbility(false); if (GetLevel() > MAX_LEVEL) { Disconnect(); return; } m_iMaxExp = g_pMain->GetExpByLevel(GetLevel()); SetRegion(GetNewRegionX(), GetNewRegionZ()); if (GetClanID() == -1) { SetClanID(0); m_bFame = 0; return; } else if (GetClanID() != 0 && GetZoneID() > 2) { result.Initialize(WIZ_KNIGHTS_PROCESS); result << uint8(KNIGHTS_LIST_REQ) << GetClanID(); g_pMain->AddDatabaseRequest(result, this); } return; fail_return: Send(&result); }
void CUser::Attack(Packet & pkt) { int16 sid = -1, tid = -1, damage, delaytime, distance; uint8 bType, bResult = 0; Unit * pTarget = nullptr; pkt >> bType >> bResult >> tid >> delaytime >> distance; // delaytime = delaytime / 100.0f; // distance = distance / 10.0f; if (isIncapacitated()) return; if (isInSafetyArea()) return; if (m_bInvisibilityType != INVIS_NONE) { CMagicProcess::RemoveStealth(this, INVIS_DISPEL_ON_MOVE); CMagicProcess::RemoveStealth(this, INVIS_DISPEL_ON_ATTACK); } // If you're holding a weapon, do a client-based (ugh, do not trust!) delay check. _ITEM_TABLE *pTable = GetItemPrototype(RIGHTHAND); if (pTable != nullptr) { if (delaytime < (pTable->m_sDelay + 10) // client adds 0.1 onto the interval (0.1 of 100 is 10) || distance > pTable->m_sRange) return; } // Empty handed. else if (delaytime < 100) return; pTarget = g_pMain->GetUnitPtr(tid); bResult = ATTACK_FAIL; if (pTarget != nullptr && isInAttackRange(pTarget) && CanAttack(pTarget)) { if (isAttackable(pTarget) && CanCastRHit(GetSocketID())) { if (isInTempleEventZone()) if (GetUserGroup() != -1 && !isSameUserGroup(pTarget)) return; CUser *pUser = g_pMain->GetUserPtr(GetSocketID()); if (pUser != nullptr) pUser->m_RHitRepeatList.insert(std::make_pair(GetSocketID(), UNIXTIME)); damage = GetDamage(pTarget); // Can't use R attacks in the Snow War. if (GetZoneID() == ZONE_SNOW_BATTLE && g_pMain->m_byBattleOpen == SNOW_BATTLE) damage = 0; if (damage > 0) { pTarget->HpChange(-damage, this); if (pTarget->isDead()) bResult = ATTACK_TARGET_DEAD; else bResult = ATTACK_SUCCESS; // Every attack takes a little of your weapon's durability. ItemWoreOut(ATTACK, damage); // Every hit takes a little of the defender's armour durability. if (pTarget->isPlayer()) TO_USER(pTarget)->ItemWoreOut(DEFENCE, damage); } } } Packet result(WIZ_ATTACK, bType); result << bResult << GetSocketID() << tid; SendToRegion(&result); }