void CUser::LoginProcess(Packet & pkt) { // Enforce only one login request per session // It's common for players to spam this at the server list when a response isn't received immediately. if (!m_strAccountID.empty()) return; Packet result(WIZ_LOGIN); CUser * pUser; std::string strAccountID, strPasswd; pkt >> strAccountID >> strPasswd; if (strAccountID.empty() || strAccountID.size() > MAX_ID_SIZE || strPasswd.empty() || strPasswd.size() > MAX_PW_SIZE) goto fail_return; pUser = g_pMain->GetUserPtr(strAccountID, TYPE_ACCOUNT); if (pUser && (pUser->GetSocketID() != GetSocketID())) { pUser->Disconnect(); goto fail_return; } result << strPasswd; m_strAccountID = strAccountID; g_pMain->AddDatabaseRequest(result, this); return; fail_return: result << uint8(-1); Send(&result); }
void CUser::SelCharToAgent(Packet & pkt) { Packet result(WIZ_SEL_CHAR); std::string strUserID, strAccountID; uint8 bInit; pkt >> strAccountID >> strUserID >> bInit; if (strAccountID.empty() || strAccountID.size() > MAX_ID_SIZE || strUserID.empty() || strUserID.size() > MAX_ID_SIZE || strAccountID != m_strAccountID) { Disconnect(); return; } // Disconnect any currently logged in sessions. CUser *pUser = g_pMain->GetUserPtr(strUserID, TYPE_CHARACTER); if (pUser && (pUser->GetSocketID() != GetSocketID())) { pUser->Disconnect(); // And reject the login attempt (otherwise we'll probably desync char data) result << uint8(0); Send(&result); return; } result << strUserID << bInit; g_pMain->AddDatabaseRequest(result, this); }
void CUser::ChatTargetSelect(Packet & pkt) { uint8 type = pkt.read<uint8>(); // TO-DO: Replace this with an enum // Attempt to find target player in-game if (type == 1) { Packet result(WIZ_CHAT_TARGET, type); std::string strUserID; pkt >> strUserID; if (strUserID.empty() || strUserID.size() > MAX_ID_SIZE) return; CUser *pUser = g_pMain->GetUserPtr(strUserID, TYPE_CHARACTER); if (pUser == nullptr || pUser == this) { result << int16(0); } else if (pUser->isBlockingPrivateChat()) { result << int16(-1); } else { m_sPrivateChatUser = pUser->GetSocketID(); result << int16(1) << pUser->GetName(); } Send(&result); }
void CUser::PartyProcess(char *pBuf) { int index = 0, idlength = 0, memberid = -1; char strid[MAX_ID_SIZE+1]; memset( strid, 0x00, MAX_ID_SIZE+1 ); BYTE subcommand, result; CUser* pUser = NULL; subcommand = GetByte( pBuf, index ); switch( subcommand ) { case PARTY_CREATE: idlength = GetShort( pBuf, index ); if (idlength <= 0 || idlength > MAX_ID_SIZE) return ; GetString( strid, pBuf, idlength, index ); pUser = m_pMain->GetUserPtr(strid, TYPE_CHARACTER); if( pUser ) { memberid = pUser->GetSocketID(); PartyRequest( memberid, TRUE ); } break; case PARTY_PERMIT: result = GetByte( pBuf, index ); if( result ) PartyInsert(); else PartyCancel(); break; case PARTY_INSERT: idlength = GetShort( pBuf, index ); if (idlength <= 0 || idlength > MAX_ID_SIZE) return ; GetString( strid, pBuf, idlength, index ); pUser = m_pMain->GetUserPtr(strid, TYPE_CHARACTER); if( pUser ) { memberid = pUser->GetSocketID(); PartyRequest( memberid, FALSE ); } break; case PARTY_REMOVE: memberid = GetShort( pBuf, index ); PartyRemove( memberid ); break; case PARTY_DELETE: PartyDelete(); break; } }
void CUdpSocket::RecvDestroyKnights( char* pBuf ) { int send_index = 0, knightsindex = 0, index = 0, flag = 0; char send_buff[128]; memset( send_buff, 0x00, 128 ); char finalstr[128]; memset( finalstr, 0x00, 128 ); CKnights* pKnights = NULL; CUser* pTUser = NULL; knightsindex = GetShort( pBuf, index ); pKnights = m_pMain->m_KnightsArray.GetData( knightsindex ); if( !pKnights ) { TRACE("UDP - ### RecvDestoryKnights Fail == index = %d ###\n", knightsindex); return; } flag = pKnights->m_byFlag; // 클랜이나 기사단이 파괴된 메시지를 보내고 유저 데이타를 초기화 if( flag == CLAN_TYPE) sprintf( finalstr, "#### %s 클랜이 해체되었습니다 ####", pKnights->m_strName ); else if( flag == KNIGHTS_TYPE ) sprintf( finalstr, "#### %s 기사단이 해체되었습니다 ####", pKnights->m_strName ); memset( send_buff, 0x00, 128 ); send_index = 0; SetByte( send_buff, WIZ_CHAT, send_index ); SetByte( send_buff, KNIGHTS_CHAT, send_index ); SetByte( send_buff, 1, send_index ); SetShort( send_buff, -1, send_index ); SetShort( send_buff, strlen(finalstr), send_index ); SetString( send_buff, finalstr, strlen(finalstr), send_index ); m_pMain->Send_KnightsMember( knightsindex, send_buff, send_index ); for (int i = 0; i < MAX_USER; i++) { pTUser = m_pMain->GetUnsafeUserPtr(i); if (pTUser == NULL || pTUser->m_pUserData->m_bKnights != knightsindex) continue; pTUser->m_pUserData->m_bKnights = 0; pTUser->m_pUserData->m_bFame = 0; m_pMain->m_KnightsManager.RemoveKnightsUser( knightsindex, pTUser->m_pUserData->m_id ); memset( send_buff, 0x00, 128 ); send_index = 0; SetByte( send_buff, WIZ_KNIGHTS_PROCESS, send_index ); SetByte( send_buff, KNIGHTS_MODIFY_FAME, send_index ); SetByte( send_buff, 0x01, send_index ); SetShort( send_buff, pTUser->GetSocketID(), send_index ); SetShort( send_buff, pTUser->m_pUserData->m_bKnights, send_index ); SetByte( send_buff, pTUser->m_pUserData->m_bFame, send_index ); m_pMain->Send_Region( send_buff, send_index, pTUser->GetMap(), pTUser->m_RegionX, pTUser->m_RegionZ, NULL, false ); } m_pMain->m_KnightsArray.DeleteData( knightsindex ); //TRACE("UDP - RecvDestoryKnights - index=%d\n", knightsindex); }
void CUser::SelCharToAgent(char *pBuf) { int index = 0, send_index = 0, retvalue = 0; char userid[MAX_ID_SIZE+1], accountid[MAX_ID_SIZE+1]; memset( userid, NULL, MAX_ID_SIZE+1 ); memset( accountid, NULL, MAX_ID_SIZE+1 ); char send_buff[256]; memset( send_buff, NULL, 256); CUser* pUser = NULL; CTime t = CTime::GetCurrentTime(); BYTE bInit = 0x01; if (!GetKOString(pBuf, accountid, index, MAX_ID_SIZE) || !GetKOString(pBuf, userid, index, MAX_ID_SIZE)) goto fail_return; bInit = GetByte( pBuf, index ); if( _strnicmp( accountid, m_strAccountID, MAX_ID_SIZE ) != 0 ) { Close(); return; } pUser = m_pMain->GetUserPtr(userid, TYPE_CHARACTER); if( pUser && (pUser->GetSocketID() != GetSocketID()) ) { pUser->Close(); goto fail_return; } SetByte( send_buff, WIZ_SEL_CHAR, send_index ); SetShort( send_buff, m_Sid, send_index ); SetKOString(send_buff, m_strAccountID, send_index); SetKOString(send_buff, userid, send_index); SetByte( send_buff, bInit, send_index ); m_pMain->WriteLog("[SelCharToAgent : %d:%d:%d] - acname=%s, name=%s, TH: %lu, Rear : %d\r\n", t.GetHour(), t.GetMinute(), t.GetSecond(), m_strAccountID, userid, GetCurrentThreadId(), m_pMain->m_LoggerSendQueue.GetRearPointer()); retvalue = m_pMain->m_LoggerSendQueue.PutData( send_buff, send_index ); if (retvalue < SMQ_FULL) return; DEBUG_LOG("SelChar Send Fail : %d", retvalue); fail_return: send_index = 0; SetByte( send_buff, WIZ_SEL_CHAR, send_index ); SetByte( send_buff, 0x00, send_index ); Send( send_buff, send_index ); }
void CUser::PartyBBSRegister(char *pBuf) { CUser* pUser = NULL; int index = 0, send_index = 0; // Basic Initializations. BYTE result = 0; short bbs_len = 0; char send_buff[256]; memset(send_buff, NULL, 256); int i = 0, counter = 0; if (m_sPartyIndex != -1) goto fail_return; // You are already in a party! if (m_bNeedParty == 2) goto fail_return; // You are already on the BBS! m_bNeedParty = 2; // Success! Now you officially need a party!!! result = 1; SetByte(send_buff, 2, send_index); // Send new 'Need Party Status' to region!!! SetByte(send_buff, m_bNeedParty, send_index); StateChange(send_buff); send_index = 0; memset(send_buff, NULL, 256); // Now, let's find out which page the user is on. for (i = 0 ; i < MAX_USER ; i++) { pUser = m_pMain->GetUnsafeUserPtr(i); if (pUser == NULL || pUser->getNation() != getNation() || pUser->m_bNeedParty == 1) continue; if( !( ( pUser->m_pUserData->m_bLevel <= (int)(m_pUserData->m_bLevel * 1.5) && pUser->m_pUserData->m_bLevel >= (int)(m_pUserData->m_bLevel * 1.5)) || ( pUser->m_pUserData->m_bLevel <= (m_pUserData->m_bLevel+8) && pUser->m_pUserData->m_bLevel >= ((int)(m_pUserData->m_bLevel)-8) ) ) ) continue; if (pUser->GetSocketID() == GetSocketID()) break; counter++; } SetShort(send_buff, counter / MAX_BBS_PAGE, send_index); PartyBBSNeeded(send_buff, PARTY_BBS_REGISTER); return; fail_return: SetByte(send_buff, WIZ_PARTY_BBS, send_index); SetByte(send_buff, PARTY_BBS_REGISTER, send_index); SetByte(send_buff, result, send_index); Send(send_buff, send_index); return; }
void CUdpSocket::RecvModifyFame( char* pBuf, BYTE command ) { int index = 0, send_index = 0, knightsindex = 0, idlen = 0, vicechief = 0; char send_buff[128]; memset( send_buff, 0x00, 128 ); char finalstr[128]; memset( finalstr, 0x00, 128 ); char userid[MAX_ID_SIZE+1]; memset( userid, 0x00, MAX_ID_SIZE+1 ); CUser* pTUser = NULL; CKnights* pKnights = NULL; knightsindex = GetShort( pBuf, index ); idlen = GetShort( pBuf, index ); GetString( userid, pBuf, idlen, index ); pTUser = m_pMain->GetUserPtr(userid, TYPE_CHARACTER); pKnights = m_pMain->m_KnightsArray.GetData( knightsindex ); switch( command ) { case KNIGHTS_REMOVE: if( pTUser ) { pTUser->m_pUserData->m_bKnights = 0; pTUser->m_pUserData->m_bFame = 0; sprintf( finalstr, "#### %s님이 추방되셨습니다. ####", pTUser->m_pUserData->m_id ); m_pMain->m_KnightsManager.RemoveKnightsUser( knightsindex, pTUser->m_pUserData->m_id ); } else { m_pMain->m_KnightsManager.RemoveKnightsUser( knightsindex, userid ); } break; case KNIGHTS_ADMIT: if( pTUser ) pTUser->m_pUserData->m_bFame = KNIGHT; break; case KNIGHTS_REJECT: if( pTUser ) { pTUser->m_pUserData->m_bKnights = 0; pTUser->m_pUserData->m_bFame = 0; m_pMain->m_KnightsManager.RemoveKnightsUser( knightsindex, pTUser->m_pUserData->m_id ); } break; case KNIGHTS_CHIEF+0x10: if( pTUser ) { pTUser->m_pUserData->m_bFame = CHIEF; m_pMain->m_KnightsManager.ModifyKnightsUser( knightsindex, pTUser->m_pUserData->m_id ); sprintf( finalstr, "#### %s님이 단장으로 임명되셨습니다. ####", pTUser->m_pUserData->m_id ); } break; case KNIGHTS_VICECHIEF+0x10: if( pTUser ) { pTUser->m_pUserData->m_bFame = VICECHIEF; m_pMain->m_KnightsManager.ModifyKnightsUser( knightsindex, pTUser->m_pUserData->m_id ); sprintf( finalstr, "#### %s님이 부단장으로 임명되셨습니다. ####", pTUser->m_pUserData->m_id ); } break; case KNIGHTS_OFFICER+0x10: if( pTUser ) pTUser->m_pUserData->m_bFame = OFFICER; break; case KNIGHTS_PUNISH+0x10: if( pTUser ) pTUser->m_pUserData->m_bFame = PUNISH; break; } if( pTUser ) { //TRACE("UDP - RecvModifyFame - command=%d, nid=%d, name=%s, index=%d, fame=%d\n", command, pTUser->GetSocketID(), pTUser->m_pUserData->m_id, knightsindex, pTUser->m_pUserData->m_bFame); memset( send_buff, 0x00, 128 ); send_index = 0; SetByte( send_buff, WIZ_KNIGHTS_PROCESS, send_index ); SetByte( send_buff, KNIGHTS_MODIFY_FAME, send_index ); SetByte( send_buff, 0x01, send_index ); if( command == KNIGHTS_REMOVE ) { SetShort( send_buff, pTUser->GetSocketID(), send_index ); SetShort( send_buff, pTUser->m_pUserData->m_bKnights, send_index ); SetByte( send_buff, pTUser->m_pUserData->m_bFame, send_index ); m_pMain->Send_Region( send_buff, send_index, pTUser->GetMap(), pTUser->m_RegionX, pTUser->m_RegionZ, NULL, false ); } else { SetShort( send_buff, pTUser->GetSocketID(), send_index ); SetShort( send_buff, pTUser->m_pUserData->m_bKnights, send_index ); SetByte( send_buff, pTUser->m_pUserData->m_bFame, send_index ); pTUser->Send( send_buff, send_index ); } if( command == KNIGHTS_REMOVE ) { memset( send_buff, 0x00, 128 ); send_index = 0; SetByte( send_buff, WIZ_CHAT, send_index ); SetByte( send_buff, KNIGHTS_CHAT, send_index ); SetByte( send_buff, 1, send_index ); SetShort( send_buff, -1, send_index ); SetShort( send_buff, strlen(finalstr), send_index ); SetString( send_buff, finalstr, strlen(finalstr), send_index ); pTUser->Send( send_buff, send_index ); } } memset( send_buff, 0x00, 128 ); send_index = 0; SetByte( send_buff, WIZ_CHAT, send_index ); SetByte( send_buff, KNIGHTS_CHAT, send_index ); SetByte( send_buff, 1, send_index ); SetShort( send_buff, -1, send_index ); SetShort( send_buff, strlen(finalstr), send_index ); SetString( send_buff, finalstr, strlen(finalstr), send_index ); m_pMain->Send_KnightsMember( knightsindex, send_buff, send_index ); }
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); } } }