void CAISocket::RecvMagicAttackResult(Packet & pkt) { uint32 magicid; uint16 sid, tid; uint8 byCommand; /* This is all so redundant... When everything's switched over to pass in Packets we can just pass it through directly! As it is now.. we still need a length (which we can hardcode, but meh) */ pkt >> byCommand >> magicid >> sid >> tid; pkt.SetOpcode(WIZ_MAGIC_PROCESS); if (byCommand == MAGIC_CASTING || (byCommand == MAGIC_EFFECTING && sid >= NPC_BAND && tid >= NPC_BAND)) { CNpc *pNpc = g_pMain->m_arNpcArray.GetData(sid); if (!pNpc) return; pNpc->SendToRegion(&pkt); } else if (byCommand == MAGIC_EFFECTING) { if (sid >= USER_BAND && sid < NPC_BAND) { CUser *pUser = g_pMain->GetUserPtr(sid); if (pUser == NULL || pUser->isDead()) return; pUser->SendToRegion(&pkt); return; } // If we're an NPC, casting a skill (rather, it's finished casting) on a player... pkt.rpos(0); m_MagicProcess.MagicPacket(pkt); } }
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); }
void CAISocket::RecvNpcAttack(Packet & pkt) { int nHP = 0, temp_damage = 0; int16 sid, tid; BYTE type, bResult, byAttackType = 0; float fDir=0.0f; short damage = 0; CNpc* pNpc = NULL, *pMon = NULL; CUser* pUser = NULL; _OBJECT_EVENT* pEvent = NULL; pkt >> type >> bResult >> sid >> tid >> damage >> nHP >> byAttackType; //TRACE("CAISocket-RecvNpcAttack : sid=%s, tid=%d, zone_num=%d\n", sid, tid, m_iZoneNum); if(type == 0x01) // user attack -> npc { pNpc = g_pMain->m_arNpcArray.GetData(tid); if(!pNpc) return; pNpc->m_iHP -= damage; if( pNpc->m_iHP < 0 ) pNpc->m_iHP = 0; pUser = g_pMain->GetUserPtr(sid); // NPC died if (bResult == 2 || bResult == 4) pNpc->OnDeath(pUser); else { Packet result(WIZ_ATTACK, byAttackType); result << bResult << sid << tid; pNpc->SendToRegion(&result); } if (pUser != NULL) { pUser->SendTargetHP( 0, tid, -damage ); if( byAttackType != MAGIC_ATTACK && byAttackType != DURATION_ATTACK) { pUser->ItemWoreOut(ATTACK, damage); temp_damage = damage * pUser->m_bMagicTypeLeftHand / 100 ; switch (pUser->m_bMagicTypeLeftHand) { // LEFT HAND!!! case ITEM_TYPE_HP_DRAIN : // HP Drain pUser->HpChange(temp_damage); break; case ITEM_TYPE_MP_DRAIN : // MP Drain pUser->MSpChange(temp_damage); break; } temp_damage = 0; // reset data; temp_damage = damage * pUser->m_bMagicTypeRightHand / 100 ; switch (pUser->m_bMagicTypeRightHand) { // LEFT HAND!!! case ITEM_TYPE_HP_DRAIN : // HP Drain pUser->HpChange(temp_damage); break; case ITEM_TYPE_MP_DRAIN : // MP Drain pUser->MSpChange(temp_damage); break; } // } } } else if (type == 2) // npc attack -> user { pNpc = g_pMain->m_arNpcArray.GetData(sid); if(!pNpc) return; //TRACE("CAISocket-RecvNpcAttack 222 : sid=%s, tid=%d, zone_num=%d\n", sid, tid, m_iZoneNum); if( tid >= USER_BAND && tid < NPC_BAND) { pUser = g_pMain->GetUserPtr(tid); if(pUser == NULL) return; pUser->HpChange(-damage, pNpc, false); pUser->ItemWoreOut(DEFENCE, damage); Packet result(WIZ_ATTACK, byAttackType); result << uint8(bResult == 3 ? 0 : bResult) << sid << tid; pNpc->SendToRegion(&result); //TRACE("RecvNpcAttack ==> sid = %d, tid = %d, result = %d\n", sid, tid, result); } else if (tid >= NPC_BAND) // npc attack -> monster { pMon = g_pMain->m_arNpcArray.GetData(tid); if(!pMon) return; pMon->m_iHP -= damage; if( pMon->m_iHP < 0 ) pMon->m_iHP = 0; Packet result(WIZ_ATTACK, byAttackType); result << bResult << sid << tid; pNpc->SendToRegion(&result); if (bResult == 2) { // npc dead pMon->OnDeath(pNpc); } } } }
void CAISocket::RecvNpcAttack(Packet & pkt) { int nHP = 0, temp_damage = 0; int16 sid, tid; BYTE type, bResult, byAttackType = 0; float fDir=0.0f; short damage = 0; CNpc* pNpc = NULL, *pMon = NULL; CUser* pUser = NULL; _OBJECT_EVENT* pEvent = NULL; pkt >> type >> bResult >> sid >> tid >> damage >> nHP >> byAttackType; //TRACE("CAISocket-RecvNpcAttack : sid=%s, tid=%d, zone_num=%d\n", sid, tid, m_iZoneNum); if(type == 0x01) // user attack -> npc { pNpc = g_pMain->m_arNpcArray.GetData(tid); if(!pNpc) return; pNpc->m_iHP -= damage; if( pNpc->m_iHP < 0 ) pNpc->m_iHP = 0; // NPC died if (bResult == 4) pNpc->OnDeath(); else { Packet result(WIZ_ATTACK, byAttackType); result << bResult << sid << tid; pNpc->SendToRegion(&result); } pUser = g_pMain->GetUserPtr(sid); if (pUser != NULL) { pUser->SendTargetHP( 0, tid, -damage ); if( byAttackType != MAGIC_ATTACK && byAttackType != DURATION_ATTACK) { pUser->ItemWoreOut(ATTACK, damage); // LEFT HAND!!! by Yookozuna temp_damage = damage * pUser->m_bMagicTypeLeftHand / 100 ; switch (pUser->m_bMagicTypeLeftHand) { // LEFT HAND!!! case ITEM_TYPE_HP_DRAIN : // HP Drain pUser->HpChange(temp_damage, 0); break; case ITEM_TYPE_MP_DRAIN : // MP Drain pUser->MSpChange(temp_damage); break; } temp_damage = 0; // reset data; // RIGHT HAND!!! by Yookozuna temp_damage = damage * pUser->m_bMagicTypeRightHand / 100 ; switch (pUser->m_bMagicTypeRightHand) { // LEFT HAND!!! case ITEM_TYPE_HP_DRAIN : // HP Drain pUser->HpChange(temp_damage, 0); break; case ITEM_TYPE_MP_DRAIN : // MP Drain pUser->MSpChange(temp_damage); break; } // } } if (bResult == 2 || bResult== 4) // npc dead { pNpc->GetMap()->RegionNpcRemove(pNpc->m_sRegion_X, pNpc->m_sRegion_Z, tid); // TRACE("--- Npc Dead : Npc�� Region���� ����ó��.. ,, region_x=%d, y=%d\n", pNpc->m_sRegion_X, pNpc->m_sRegion_Z); pNpc->m_sRegion_X = 0; pNpc->m_sRegion_Z = 0; pNpc->m_NpcState = NPC_DEAD; if( pNpc->m_byObjectType == SPECIAL_OBJECT ) { pEvent = pNpc->GetMap()->GetObjectEvent( pNpc->m_sSid ); if( pEvent ) pEvent->byLife = 0; } if (pNpc->m_tNpcType == 2 && pUser != NULL) // EXP pUser->GiveItem(900001000, 1); } } else if (type == 2) // npc attack -> user { pNpc = g_pMain->m_arNpcArray.GetData(sid); if(!pNpc) return; //TRACE("CAISocket-RecvNpcAttack 222 : sid=%s, tid=%d, zone_num=%d\n", sid, tid, m_iZoneNum); if( tid >= USER_BAND && tid < NPC_BAND) { pUser = g_pMain->GetUserPtr(tid); if(pUser == NULL) return; pUser->HpChange(-damage, 1, true); pUser->ItemWoreOut(DEFENCE, damage); Packet result(WIZ_ATTACK, byAttackType); result << uint8(bResult == 3 ? 0 : bResult) << sid << tid; pNpc->SendToRegion(&result); //TRACE("RecvNpcAttack ==> sid = %d, tid = %d, result = %d\n", sid, tid, result); // user dead if (bResult == 2) { if (pUser->m_bResHpType == USER_DEAD) return; pUser->OnDeath(); pUser->m_bResHpType = USER_DEAD; DEBUG_LOG("*** User Dead, id=%s, result=%d, AI_HP=%d, GM_HP=%d, x=%d, z=%d", pUser->m_pUserData->m_id, result, nHP, pUser->m_pUserData->m_sHp, (int)pUser->m_pUserData->m_curx, (int)pUser->m_pUserData->m_curz); if( pUser->m_pUserData->m_bFame == COMMAND_CAPTAIN ) { // ���ֱ����� �ִ� ������ �״´ٸ�,, ���� ���� ��Ż pUser->ChangeFame(CHIEF); TRACE("---> AISocket->RecvNpcAttack() Dead Captain Deprive - %s\n", pUser->m_pUserData->m_id); if (pUser->getNation() == KARUS) g_pMain->Announcement( KARUS_CAPTAIN_DEPRIVE_NOTIFY, KARUS ); else if (pUser->getNation() == ELMORAD) g_pMain->Announcement( ELMORAD_CAPTAIN_DEPRIVE_NOTIFY, ELMORAD ); } if(pNpc->m_tNpcType == NPC_PATROL_GUARD) { // ������ �״� ��������.. pUser->ExpChange( -pUser->m_iMaxExp/100 ); //TRACE("RecvNpcAttack : ����ġ�� 1%���� id = %s\n", pUser->m_pUserData->m_id); } else { // if( pUser->m_pUserData->m_bZone != pUser->m_pUserData->m_bNation && pUser->m_pUserData->m_bZone < 3) { pUser->ExpChange(-pUser->m_iMaxExp / 100); //TRACE("������ 1%�� ��ٴϱ��� ��.��"); } // else { pUser->ExpChange( -pUser->m_iMaxExp/20 ); } //TRACE("RecvNpcAttack : ����ġ�� 5%���� id = %s\n", pUser->m_pUserData->m_id); } } } else if(tid >= NPC_BAND) // npc attack -> monster { pMon = g_pMain->m_arNpcArray.GetData(tid); if(!pMon) return; pMon->m_iHP -= damage; if( pMon->m_iHP < 0 ) pMon->m_iHP = 0; Packet result(WIZ_ATTACK, byAttackType); result << bResult << sid << tid; if (bResult == 2) { // npc dead pNpc->GetMap()->RegionNpcRemove(pMon->m_sRegion_X, pMon->m_sRegion_Z, tid); // TRACE("--- Npc Dead : Npc�� Region���� ����ó��.. ,, region_x=%d, y=%d\n", pMon->m_sRegion_X, pMon->m_sRegion_Z); pMon->m_sRegion_X = 0; pMon->m_sRegion_Z = 0; pMon->m_NpcState = NPC_DEAD; if( pNpc->m_byObjectType == SPECIAL_OBJECT ) { pEvent = pNpc->GetMap()->GetObjectEvent( pMon->m_sSid ); if( pEvent ) pEvent->byLife = 0; } } pNpc->SendToRegion(&result); } } }