void CAISocket::RecvUserExp(char* pBuf) { int index = 0; int nid = 0; short sExp = 0; short sLoyalty = 0; nid = GetShort(pBuf,index); sExp = GetShort(pBuf,index); sLoyalty = GetShort(pBuf,index); CUser* pUser = m_pMain->GetUserPtr(nid); if(pUser == NULL) return; if(sExp < 0 || sLoyalty < 0) { TRACE("#### AISocket - RecvUserExp : exp=%d, loyalty=%d,, 잘못된 경험치가 온다,, 수정해!!\n", sExp, sLoyalty); return; } pUser->m_pUserData->m_iLoyalty += sLoyalty; pUser->ExpChange(sExp); if( sLoyalty > 0 ) { char send_buff[128]; int send_index = 0; SetByte( send_buff, WIZ_LOYALTY_CHANGE, send_index ); SetDWORD( send_buff, pUser->m_pUserData->m_iLoyalty, send_index ); pUser->Send( send_buff, send_index ); } }
void CUser::MagicType1(uint32 magicid, uint16 sid, uint16 tid, uint16 data1, uint16 data2, uint16 data3, uint16 data4, uint16 data5, uint16 data6, uint16 data7) { int16 damage = GetDamage(tid, magicid); //Get the amount of damage that will be inflicted. _MAGIC_TABLE* pMagic = m_pMain->m_MagictableArray.GetData( magicid ); //Checking if the skill exists has already happened. _MAGIC_TYPE1* pMagic_Type1 = m_pMain->m_Magictype1Array.GetData( magicid ); if( !pMagic_Type1 ) //Shouldn't be necessary unless there's a mismatch in the database. return; CUser* pTUser = m_pMain->GetUserPtr(tid); // Get target info. if (!pTUser || pTUser->isDead()) return; pTUser->HpChange( -damage ); // Reduce target health point. if( pTUser->isDead() ) { // Check if the target is dead. pTUser->m_bResHpType = USER_DEAD; // Target status is officially dead now. if(sid >= NPC_BAND) pTUser->ExpChange( -pTUser->m_iMaxExp/100 ); // Reduce target's experience if the source was an NPC. if( m_sPartyIndex == -1 ) { // If the user is not in a party allocate all the National Points to the user, ifnot, divide it between the party. LoyaltyChange(tid); } else { LoyaltyDivide(tid); } GoldChange(tid, 0); //Reward the killer with the money he deserves. pTUser->InitType3(); // Re-initialize buffs on the dead person pTUser->InitType4(); // Re-initialize buffs on the dead person pTUser->m_sWhoKilledMe = sid; } SendTargetHP( 0, tid, -damage ); // Change the HP of the target. if(pMagic->bType2 > 0 && pMagic->bType2 != 1) MagicType(pMagic->bType2); //If the skill has a second effect, be sure to cast that one too. packet_send: if (pMagic->bType2 == 0 || pMagic->bType2 == 1) { Packet result(WIZ_MAGIC_PROCESS); result << MAGIC_EFFECTING << magicid << sid << tid << data1 << data2 << data3; if (damage == 0) { result << int16(-104); } else { result << uint16(0); } m_pMain->Send_Region( &result, GetMap(), m_RegionX, m_RegionZ ); } return; }
void CAISocket::RecvUserExp(Packet & pkt) { uint16 tid, sExp, sLoyalty; pkt >> tid >> sExp >> sLoyalty; CUser* pUser = g_pMain->GetUserPtr(tid); if (pUser == NULL) return; if (sExp > 0) pUser->ExpChange(sExp); if (sLoyalty > 0) pUser->SendLoyaltyChange(sLoyalty); }
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); } } }
void CAISocket::RecvNpcAttack(char* pBuf) { int index = 0, send_index = 0, sid = -1, tid = -1, nHP = 0, temp_damage = 0; BYTE type, result, byAttackType = 0; float fDir=0.0f; short damage = 0; CNpc* pNpc = NULL, *pMon = NULL; CUser* pUser = NULL; char pOutBuf[1024]; _OBJECT_EVENT* pEvent = NULL; type = GetByte(pBuf,index); result = GetByte(pBuf,index); sid = GetShort(pBuf,index); tid = GetShort(pBuf,index); damage = GetShort(pBuf,index); nHP = GetDWORD(pBuf,index); byAttackType = GetByte(pBuf, index); //TRACE("CAISocket-RecvNpcAttack : sid=%s, tid=%d, zone_num=%d\n", sid, tid, m_iZoneNum); if(type == 0x01) // user attack -> npc { pNpc = m_pMain->m_arNpcArray.GetData(tid); if(!pNpc) return; pNpc->m_iHP -= damage; if( pNpc->m_iHP < 0 ) pNpc->m_iHP = 0; if(result == 0x04) { // 마법으로 죽는경우 SetByte( pOutBuf, WIZ_DEAD, send_index ); SetShort( pOutBuf, tid, send_index ); m_pMain->Send_Region(pOutBuf, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false); } else { SetByte(pOutBuf, WIZ_ATTACK, send_index); SetByte( pOutBuf, byAttackType, send_index ); // 직접:1, 마법:2, 지속마법:3 //if(result == 0x04) // 마법으로 죽는경우 // SetByte( pOutBuf, 0x02, send_index ); //else // 단순공격으로 죽는경우 SetByte( pOutBuf, result, send_index ); SetShort( pOutBuf, sid, send_index ); SetShort( pOutBuf, tid, send_index ); m_pMain->Send_Region(pOutBuf, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false); } pUser = m_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(result == 0x02 || result == 0x04) // 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 == 0x02) // npc attack -> user { pNpc = m_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 = m_pMain->GetUserPtr(tid); if(pUser == NULL) return; // sungyong 2002. 02.04 /* if( sHP <= 0 && pUser->m_pUserData->m_sHp > 0 ) { TRACE("Npc Attack : id=%s, result=%d, AI_HP=%d, GM_HP=%d\n", pUser->m_pUserData->m_id, result, sHP, pUser->m_pUserData->m_sHp); if(result == 0x02) pUser->HpChange(-1000, 1); } else pUser->HpChange(-damage, 1); */ // ~sungyong 2002. 02.04 if( pUser->m_MagicProcess.m_bMagicState == CASTING ) pUser->m_MagicProcess.IsAvailable( 0, -1, -1, MAGIC_EFFECTING ,0,0,0 ); pUser->HpChange(-damage, 1, true); pUser->ItemWoreOut(DEFENCE, damage); SetByte(pOutBuf, WIZ_ATTACK, send_index); SetByte( pOutBuf, byAttackType, send_index ); if(result == 0x03) SetByte( pOutBuf, 0x00, send_index ); else SetByte( pOutBuf, result, send_index ); SetShort( pOutBuf, sid, send_index ); SetShort( pOutBuf, tid, send_index ); m_pMain->Send_Region(pOutBuf, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false); // TRACE("RecvNpcAttack : id=%s, result=%d, AI_HP=%d, GM_HP=%d\n", pUser->m_pUserData->m_id, result, sHP, pUser->m_pUserData->m_sHp); //TRACE("RecvNpcAttack ==> sid = %d, tid = %d, result = %d\n", sid, tid, result); if(result == 0x02) { // user dead if (pUser->m_bResHpType == USER_DEAD) return; // 유저에게는 바로 데드 패킷을 날림... (한 번 더 보냄, 유령을 없애기 위해서) send_index = 0; SetByte(pOutBuf, WIZ_DEAD, send_index); SetShort(pOutBuf, pUser->GetSocketID(), send_index); m_pMain->Send_Region(pOutBuf, send_index, pUser->GetMap(), pUser->m_RegionX, pUser->m_RegionZ); 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); send_index = 0; if( pUser->m_pUserData->m_bFame == COMMAND_CAPTAIN ) { // 지휘권한이 있는 유저가 죽는다면,, 지휘 권한 박탈 pUser->m_pUserData->m_bFame = CHIEF; SetByte( pOutBuf, WIZ_AUTHORITY_CHANGE, send_index ); SetByte( pOutBuf, COMMAND_AUTHORITY, send_index ); SetShort( pOutBuf, pUser->GetSocketID(), send_index ); SetByte( pOutBuf, pUser->m_pUserData->m_bFame, send_index ); m_pMain->Send_Region( pOutBuf, send_index, pUser->GetMap(), pUser->m_RegionX, pUser->m_RegionZ ); // sungyong tw pUser->Send( pOutBuf, send_index ); // ~sungyong tw TRACE("---> AISocket->RecvNpcAttack() Dead Captain Deprive - %s\n", pUser->m_pUserData->m_id); if( pUser->m_pUserData->m_bNation == KARUS ) m_pMain->Announcement( KARUS_CAPTAIN_DEPRIVE_NOTIFY, KARUS ); else if( pUser->m_pUserData->m_bNation == ELMORAD ) m_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 = m_pMain->m_arNpcArray.GetData(tid); if(!pMon) return; pMon->m_iHP -= damage; if( pMon->m_iHP < 0 ) pMon->m_iHP = 0; send_index = 0; SetByte(pOutBuf, WIZ_ATTACK, send_index); SetByte( pOutBuf, byAttackType, send_index ); SetByte( pOutBuf, result, send_index ); SetShort( pOutBuf, sid, send_index ); SetShort( pOutBuf, tid, send_index ); if(result == 0x02) { // 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; } } m_pMain->Send_Region(pOutBuf, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false); } } }