void CUser::ExchangeReq(Packet & pkt) { Packet result(WIZ_EXCHANGE); if (isDead()) goto fail_return; else if (isTrading()) { ExchangeCancel(); return; } uint16 destid = pkt.read<uint16>(); CUser* pUser = g_pMain->GetUserPtr(destid); if (pUser == NULL || pUser->isTrading() || (pUser->GetNation() != GetNation() && pUser->GetZoneID() != 21 && GetZoneID() != 21) || pUser->GetZoneID() != GetZoneID()) goto fail_return; m_sExchangeUser = destid; pUser->m_sExchangeUser = GetSocketID(); result << uint8(EXCHANGE_REQ) << GetSocketID(); pUser->Send(&result); return; fail_return: result << uint8(EXCHANGE_CANCEL); Send(&result); }
void CUser::Attack(Packet & pkt) { Packet result; int16 sid = -1, tid = -1, damage, delaytime, distance; uint8 bType, bResult; CUser* pTUser = NULL; pkt >> bType >> bResult >> tid >> delaytime >> distance; // delaytime = delaytime / 100.0f; // distance = distance / 10.0f; if (isBlinking() || isDead()) return; _ITEM_TABLE *pTable = GetItemPrototype(RIGHTHAND); if (pTable == NULL) return; // If you're holding a weapon, do a client-based (ugh, do not trust!) delay check. if (pTable && (delaytime < pTable->m_sDelay || distance > pTable->m_sRange)) return; // Empty handed. else if (delaytime < 100) return; // We're attacking a player... if (tid < NPC_BAND) { pTUser = g_pMain->GetUserPtr(tid); if (pTUser == NULL || pTUser->isDead() || pTUser->isBlinking() || (pTUser->GetNation() == GetNation() && GetZoneID() != 48 /* TO-DO: implement better checks */) || !isAttackZone()) bResult = 0; else { damage = GetDamage(pTUser, NULL); if (GetZoneID() == ZONE_SNOW_BATTLE && g_pMain->m_byBattleOpen == SNOW_BATTLE) damage = 0; if (damage <= 0) bResult = 0; else { // TO-DO: Move all this redundant code into appropriate event-based methods so that all the other cases don't have to copypasta (and forget stuff). pTUser->HpChange(-damage, this); if (pTUser->isDead()) bResult = 2; ItemWoreOut(ATTACK, damage); pTUser->ItemWoreOut(DEFENCE, damage); SendTargetHP(0, tid, -damage); } } } // We're attacking an NPC... else if (tid >= NPC_BAND) { // AI hasn't loaded yet if (g_pMain->m_bPointCheckFlag == FALSE) return; CNpc *pNpc = g_pMain->m_arNpcArray.GetData(tid); if (pNpc != NULL && pNpc->isAlive() && (pNpc->GetNation() == 0 || pNpc->GetNation() == GetNation())) { result.SetOpcode(AG_ATTACK_REQ); result << bType << bResult << GetSocketID() << tid << uint16(m_sTotalHit * m_bAttackAmount / 100) << uint16(m_sTotalAc + m_sACAmount) << m_sTotalHitrate /* this is actually a float. screwed up naming... */ << m_sTotalEvasionrate /* also a float */ << m_sItemAc << m_bMagicTypeLeftHand << m_bMagicTypeRightHand << m_sMagicAmountLeftHand << m_sMagicAmountRightHand; g_pMain->Send_AIServer(&result); return; } } result.SetOpcode(WIZ_ATTACK); result << bType << bResult << GetSocketID() << tid; SendToRegion(&result); if (tid < NPC_BAND && bResult == 2 // 2 means a player died. && pTUser) { pTUser->Send(&result); TRACE("*** User Attack Dead, id=%s, result=%d, type=%d, HP=%d\n", pTUser->m_pUserData->m_id, bResult, pTUser->m_bResHpType, pTUser->m_pUserData->m_sHp); } }
void CAISocket::RecvBattleEvent(Packet & pkt) { string chatstr, strMaxUserName, strKnightsName; CUser* pUser = nullptr; CKnights* pKnights = nullptr; uint8 bType, bResult; pkt >> bType >> bResult; if (bType == BATTLE_EVENT_OPEN) { } else if (bType == BATTLE_MAP_EVENT_RESULT) { if (g_pMain->m_byBattleOpen == NO_BATTLE) { TRACE("#### RecvBattleEvent Fail : battleopen = %d, type = %d\n", g_pMain->m_byBattleOpen, bType); return; } if (bResult == KARUS) g_pMain->m_byKarusOpenFlag = true; else if (bResult == ELMORAD) g_pMain->m_byElmoradOpenFlag = true; } else if (bType == BATTLE_EVENT_RESULT) { if (g_pMain->m_byBattleOpen == NO_BATTLE) { TRACE("#### RecvBattleEvent Fail : battleopen = %d, type=%d\n", g_pMain->m_byBattleOpen, bType); return; } pkt.SByte(); pkt >> strMaxUserName; if (!strMaxUserName.empty() && !g_pMain->m_byBattleSave) { Packet result(WIZ_BATTLE_EVENT, bType); result.SByte(); result << bResult << strMaxUserName; g_pMain->AddDatabaseRequest(result); g_pMain->m_byBattleSave = true; } pUser = g_pMain->GetUserPtr(strMaxUserName, TYPE_CHARACTER); if (pUser != nullptr) { g_pMain->m_bVictory = pUser->GetNation(); g_pMain->m_byOldVictory = pUser->GetNation(); } else { g_pMain->m_bVictory = bResult; g_pMain->m_byOldVictory = bResult; } g_pMain->m_byKarusOpenFlag = false; g_pMain->m_byElmoradOpenFlag = false; g_pMain->m_byBanishFlag = true; } else if (bType == BATTLE_EVENT_MAX_USER)