void CAISocket::RecvNpcMoveResult(Packet & pkt) { uint8 flag; // 01(INFO_MODIFY), 02(INFO_DELETE) uint16 sNid; float fX, fY, fZ, fSecForMetor; pkt >> flag >> sNid >> fX >> fZ >> fY >> fSecForMetor; CNpc * pNpc = g_pMain->GetNpcPtr(sNid); if (pNpc == nullptr) return; if (pNpc->isDead()) { Packet result(AG_NPC_HP_REQ); result << sNid << pNpc->m_iHP; Send(&result); } pNpc->MoveResult(fX, fY, fZ, fSecForMetor); }
void CAISocket::RecvNpcAttack(Packet & pkt) { CNpc * pAttacker; Unit * pTarget; uint16 sAttackerID, sTargetID; int16 sDamage; uint8 bResult = ATTACK_FAIL; pkt >> sAttackerID >> sTargetID; pAttacker = g_pMain->GetNpcPtr(sAttackerID); pTarget = g_pMain->GetUnitPtr(sTargetID); if (pAttacker == nullptr || pAttacker->isPlayer() || pTarget == nullptr || pAttacker->isDead() || pTarget->isDead()) return; // TO-DO: Wrap this up into its own virtual method sDamage = pAttacker->GetDamage(pTarget); if (sDamage > 0) { pTarget->HpChange(-(sDamage), pAttacker); if (pTarget->isDead()) bResult = ATTACK_TARGET_DEAD; else bResult = ATTACK_SUCCESS; // Every hit takes a little of the defender's armour durability. if (pTarget->isPlayer()) TO_USER(pTarget)->ItemWoreOut(DEFENCE, sDamage); } Packet result(WIZ_ATTACK, uint8(DIRECT_ATTACK)); result << bResult << sAttackerID << sTargetID; pAttacker->SendToRegion(&result); }
short CMagicProcess::GetMagicDamage(int tid, int total_hit, int attribute, int dexpoint, int righthand_damage) { short damage = 0, temp_hit = 0 ; int random = 0, total_r = 0 ; uint8 result; bool bSign = true; if( tid < NPC_BAND || tid > INVALID_BAND) return 0; // Check if target id is valid. CNpc* pNpc = g_pMain->m_arNpc.GetData(tid); if (pNpc == nullptr || pNpc->isDead() || pNpc->isNonAttackingObject()) return 0; //result = m_pSrcUser->GetHitRate(m_pSrcUser->m_fHitrate / pNpc->m_sEvadeRate ); result = SUCCESS; if (result != FAIL) { // In case of SUCCESS (and SUCCESS only!) .... switch (attribute) { case FIRE_R : total_r = pNpc->m_byFireR; break; case COLD_R : total_r = pNpc->m_byColdR; break; case LIGHTNING_R : total_r = pNpc->m_byLightningR ; break; case MAGIC_R : total_r = pNpc->m_byMagicR ; break; case DISEASE_R : total_r = pNpc->m_byDiseaseR ; break; case POISON_R : total_r = pNpc->m_byPoisonR ; break; } total_hit = (total_hit * (dexpoint + 20)) / 170; if(total_hit < 0) { total_hit = abs(total_hit); bSign = false; } damage = (short)(total_hit - (0.7f * total_hit * total_r / 200)) ; random = myrand (0, damage) ; damage = (short)((0.7f * (total_hit - (0.9f * total_hit * total_r / 200))) + 0.2f * random); // damage = damage + (3 * righthand_damage); damage = damage + righthand_damage; } else damage = 0 ; if (!bSign && damage != 0) { damage = -damage; } // Apply boost for skills matching weather type. // This isn't actually used officially, but I think it's neat... GetWeatherDamage(damage, attribute); //return 1; return damage; }
void CUser::ClientEvent(uint16 sNpcID) { // Ensure AI's loaded if (!g_pMain->m_bPointCheckFlag || isDead()) return; int32 iEventID = 0; CNpc *pNpc = g_pMain->GetNpcPtr(sNpcID); if (pNpc == nullptr || !isInRange(pNpc, MAX_NPC_RANGE)) return; m_sEventNid = sNpcID; m_sEventSid = pNpc->GetProtoID(); // For convenience purposes with Lua scripts. if (pNpc->GetProtoID() == SAW_BLADE_SSID) { HpChange(-5000 / 10); return; } else if (pNpc->GetProtoID() == CHAOS_CUBE_SSID && !pNpc->isDead()) { uint8 nEventRoomUserCount = g_pMain->TempleEventGetRoomUsers(GetEventRoom()); uint8 nItemRewardRankFirst = nEventRoomUserCount / 3; uint8 nItemRewardRankSecond = (nEventRoomUserCount - 1) * 2; int32 nUserRank = GetPlayerRank(RANK_TYPE_CHAOS_DUNGEON); uint32 nItemID = 0; if (nUserRank == 0) nItemID = ITEM_KILLING_BLADE; else if (nUserRank < nItemRewardRankFirst) nItemID = ITEM_LIGHT_PIT; else if (nUserRank >= nItemRewardRankFirst && nUserRank <= nItemRewardRankSecond) nItemID = ITEM_DRAIN_RESTORE; else if (nUserRank > nItemRewardRankSecond) nItemID = ITEM_KILLING_BLADE; GiveItem(nItemID); g_pMain->ShowNpcEffect(GetSocketID(),251,GetZoneID()); g_pMain->KillNpc(sNpcID); return; } else if (pNpc->GetType() == NPC_KISS) { KissUser(); return; } Guard lock(g_pMain->m_questNpcLock); QuestNpcList::iterator itr = g_pMain->m_QuestNpcList.find(pNpc->GetProtoID()); if (itr == g_pMain->m_QuestNpcList.end()) return; QuestHelperList & pList = itr->second; _QUEST_HELPER * pHelper = nullptr; foreach (itr, pList) { if ((*itr) == nullptr || (*itr)->sEventDataIndex || (*itr)->bEventStatus || ((*itr)->bNation != 3 && (*itr)->bNation != GetNation()) || ((*itr)->bClass != 5 && !JobGroupCheck((*itr)->bClass))) continue; pHelper = (*itr); break; } if (pHelper == nullptr) return; QuestV2RunEvent(pHelper, pHelper->nEventTriggerIndex); }