Example #1
0
void CAISocket::RecvNpcDead(char* pBuf)
{
	int index = 0, send_index = 0;
	int nid = 0;
	char send_buff[256];
	_OBJECT_EVENT* pEvent = NULL;

	nid = GetShort(pBuf,index);


	if(nid >= NPC_BAND)		{
		CNpc* pNpc = m_pMain->m_arNpcArray.GetData(nid);
		if(!pNpc)	return;

		C3DMap* pMap = pNpc->GetMap();
		if (pMap == NULL)
			return;

		if( pNpc->m_byObjectType == SPECIAL_OBJECT )	{
			pEvent = pMap->GetObjectEvent( pNpc->m_sSid );
			if( pEvent )	pEvent->byLife = 0;
		}

		//pNpc->NpcInOut( NPC_OUT );
		//TRACE("RecvNpcDead - (%d,%s)\n", pNpc->m_sNid, pNpc->m_strName);

		pMap->RegionNpcRemove(pNpc->m_sRegion_X, pNpc->m_sRegion_Z, nid);
		//TRACE("--- RecvNpcDead : Npc를 Region에서 삭제처리.. ,, zone=%d, region_x=%d, y=%d\n", pNpc->m_sZoneIndex, pNpc->m_sRegion_X, pNpc->m_sRegion_Z);

		SetByte( send_buff, WIZ_DEAD, send_index );
		SetShort( send_buff, nid, send_index );
		m_pMain->Send_Region(send_buff, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false);

		pNpc->m_sRegion_X = 0;		pNpc->m_sRegion_Z = 0;
	}
}
void CUser::MoveProcess(char *pBuf )
{
	ASSERT(GetMap() != NULL);
	if( m_bWarp ) return;
		
	int index = 0, send_index = 0, region = 0;
	WORD will_x, will_z;
	short will_y, speed=0;
	float real_x, real_z, real_y;
	BYTE echo;
	char send_buff[32];

	will_x = GetShort( pBuf, index );
	will_z = GetShort( pBuf, index );
	will_y = GetShort( pBuf, index );

	speed = GetShort( pBuf, index );
	echo = GetByte( pBuf, index );

	real_x = will_x/10.0f; real_z = will_z/10.0f; real_y = will_y/10.0f;

	if (GetMap()->IsValidPosition(real_x, real_z, real_y) == FALSE) 
		return;

	if (isDead() && speed != 0)
		TRACE("### MoveProcess Fail : name=%s(%d), m_bResHpType=%d, hp=%d, speed=%d, x=%d, z=%d ###\n", m_pUserData->m_id, m_Sid, m_bResHpType, m_pUserData->m_sHp, speed, (int)m_pUserData->m_curx, (int)m_pUserData->m_curz);

	if( speed != 0 ) {
		m_pUserData->m_curx = m_fWill_x;	// ????? ??? ?????g?? ??????g?? ????...
		m_pUserData->m_curz = m_fWill_z;
		m_pUserData->m_cury = m_fWill_y;

		m_fWill_x = will_x/10.0f;	// ?????g?? ???....
		m_fWill_z = will_z/10.0f;
		m_fWill_y = will_y/10.0f;
	}
	else {
		m_pUserData->m_curx = m_fWill_x = will_x/10.0f;	// ?????g == ???? ??g...
		m_pUserData->m_curz = m_fWill_z = will_z/10.0f;
		m_pUserData->m_cury = m_fWill_y = will_y/10.0f;
	}

	SetByte( send_buff, WIZ_MOVE, send_index );
	SetShort( send_buff, m_Sid, send_index );
	SetShort( send_buff, will_x, send_index );
	SetShort( send_buff, will_z, send_index );
	SetShort( send_buff, will_y, send_index );
	SetShort( send_buff, speed, send_index );
	SetByte( send_buff, echo, send_index );

	RegisterRegion();
	m_pMain->Send_Region( send_buff, send_index, GetMap(), m_RegionX, m_RegionZ, NULL, false );

	GetMap()->CheckEvent( real_x, real_z, this );

	send_index = 0;
	SetByte( send_buff, AG_USER_MOVE, send_index );
	SetShort( send_buff, m_Sid, send_index );
	Setfloat( send_buff, m_fWill_x, send_index );
	Setfloat( send_buff, m_fWill_z, send_index );
	Setfloat( send_buff, m_fWill_y, send_index );
	SetShort( send_buff, speed, send_index );
	
	m_pMain->Send_AIServer(send_buff, send_index);
}
void CUser::MarketBBSRegister(char *pBuf)
{
	CUser* pUser = NULL;	// Basic Initializations. 	
	int index = 0, send_index = 0; BYTE result = 0;	BYTE sub_result = 1;			 
	char send_buff[256]; memset( send_buff, NULL, 256 );
	short title_len = 0; short message_len = 0; BYTE buysell_index = 0; 
	int  i = 0, j = 0; int page_index = 0;

	buysell_index = GetByte(pBuf, index);	// Buy or sell?

	if (buysell_index == MARKET_BBS_BUY) {
		if (m_pUserData->m_iGold < BUY_POST_PRICE) {
			sub_result = 2;
			goto fail_return;
		}
	}
	else if (buysell_index == MARKET_BBS_SELL) {
		if (m_pUserData->m_iGold < SELL_POST_PRICE) {
			sub_result = 2;
			goto fail_return;
		}
	}
		
	for (i = 0 ; i < MAX_BBS_POST ; i++) {
		if (buysell_index == MARKET_BBS_BUY) {			// Buy 
			if (m_pMain->m_sBuyID[i] == -1) {
				m_pMain->m_sBuyID[i] = m_Sid;
				title_len = GetShort(pBuf, index);		
				GetString(m_pMain->m_strBuyTitle[i], pBuf, title_len, index);		
				message_len = GetShort(pBuf, index);
				GetString(m_pMain->m_strBuyMessage[i], pBuf, message_len, index);
				m_pMain->m_iBuyPrice[i] = GetDWORD(pBuf, index);
				m_pMain->m_fBuyStartTime[i] = TimeGet();
				result = 1;
				break;
			}
		}
		else if (buysell_index == MARKET_BBS_SELL) {	// Sell
			if (m_pMain->m_sSellID[i] == -1) {
				m_pMain->m_sSellID[i] = m_Sid;
				title_len = GetShort(pBuf, index);	
				GetString(m_pMain->m_strSellTitle[i], pBuf, title_len, index);		
				message_len = GetShort(pBuf, index);
				GetString(m_pMain->m_strSellMessage[i], pBuf, message_len, index);
				m_pMain->m_iSellPrice[i] = GetDWORD(pBuf, index);				
				m_pMain->m_fSellStartTime[i] = TimeGet();
				result = 1;
				break;
			}
		}
		else goto fail_return;							// Error 
	}
	
	if (result == 0) goto fail_return;	// No spaces available

	SetByte( send_buff, WIZ_GOLD_CHANGE, send_index );		// Money removal packet...
	SetByte( send_buff, 0x02, send_index );
	if (buysell_index == MARKET_BBS_BUY) {
		m_pUserData->m_iGold -= BUY_POST_PRICE;
		SetDWORD( send_buff, BUY_POST_PRICE, send_index );
	}
	else if (buysell_index == MARKET_BBS_SELL) {
		m_pUserData->m_iGold -= SELL_POST_PRICE;		
		SetDWORD( send_buff, SELL_POST_PRICE, send_index );	
	}
	SetDWORD( send_buff, m_pUserData->m_iGold, send_index );
	Send( send_buff, send_index );

	page_index = i / MAX_BBS_PAGE;
	send_index = 0; memset( send_buff, NULL, 256 );
	SetByte(send_buff, buysell_index, send_index);
	SetShort(send_buff, page_index, send_index);
	MarketBBSReport(send_buff, MARKET_BBS_REGISTER);	
	return;

fail_return:
	send_index = 0; memset( send_buff, NULL, 256 );
	SetByte(send_buff, WIZ_MARKET_BBS, send_index);
	SetByte(send_buff, MARKET_BBS_REGISTER, send_index);
	SetByte(send_buff, buysell_index, send_index);
	SetByte(send_buff, result, send_index);
	SetByte(send_buff, sub_result, send_index);
	Send(send_buff, send_index);
	return;			
}
void CUser::ZoneChange(int zone, float x, float z)
{
	m_bZoneChangeFlag = TRUE;

	int send_index = 0, zoneindex = 0;
	char send_buff[128];
	C3DMap* pMap = NULL;
	_ZONE_SERVERINFO *pInfo = NULL;

	if( g_serverdown_flag ) return;

	pMap = m_pMain->GetZoneByID(zone);
	if (!pMap) 
		return;

	m_pMap = pMap;
	if( pMap->m_bType == 2 ) {	// If Target zone is frontier zone.
		if( m_pUserData->m_bLevel < 20 && m_pMain->m_byBattleOpen != SNOW_BATTLE)
			return;
	}

	if( m_pMain->m_byBattleOpen == NATION_BATTLE )	{		// Battle zone open
		if( m_pUserData->m_bZone == BATTLE_ZONE )	{
			if( pMap->m_bType == 1 && m_pUserData->m_bNation != zone )	{	// ???? ?????? ???? ????..
				if( m_pUserData->m_bNation == KARUS && !m_pMain->m_byElmoradOpenFlag )	{
					TRACE("#### ZoneChange Fail ,,, id=%s, nation=%d, flag=%d\n", m_pUserData->m_id, m_pUserData->m_bNation, m_pMain->m_byElmoradOpenFlag);
					return;
				}
				else if( m_pUserData->m_bNation == ELMORAD && !m_pMain->m_byKarusOpenFlag )	{
					TRACE("#### ZoneChange Fail ,,, id=%s, nation=%d, flag=%d\n", m_pUserData->m_id, m_pUserData->m_bNation, m_pMain->m_byKarusOpenFlag);
					return;
				}
			}
		}
		else if( pMap->m_bType == 1 && m_pUserData->m_bNation != zone ) {		// ???? ?????? ???? ????..
			return;
		}
//
		else if( pMap->m_bType == 2 && zone == ZONE_FRONTIER ) {	 // You can't go to frontier zone when Battlezone is open.
			int temp_index = 0;
			char temp_buff[3];

			SetByte( temp_buff, WIZ_WARP_LIST, temp_index );
			SetByte( temp_buff, 2, temp_index );
			SetByte( temp_buff,0, temp_index );
			Send(temp_buff, temp_index);
//
			return;
		}
//
	}
	else if( m_pMain->m_byBattleOpen == SNOW_BATTLE )	{					// Snow Battle zone open
		if( pMap->m_bType == 1 && m_pUserData->m_bNation != zone ) {		// ???? ?????? ???? ????..
			return;
		}
		else if( pMap->m_bType == 2 && (zone == ZONE_FRONTIER || zone == ZONE_BATTLE ) ) {			// You can't go to frontier zone when Battlezone is open.
			return;
		}
	}
	else	{					// Battle zone close
		if( pMap->m_bType == 1 && m_pUserData->m_bNation != zone && (zone < 10 || zone > 20))		// ???? ?????? ???? ????..
			return;
	}

	m_bWarp = 0x01;

	UserInOut( USER_OUT );

	if( m_pUserData->m_bZone == ZONE_SNOW_BATTLE )	{
		//TRACE("ZoneChange - name=%s\n", m_pUserData->m_id);
		SetMaxHp( 1 );
	}

	m_pUserData->m_bZone = zone;
	m_pUserData->m_curx = m_fWill_x = x;
	m_pUserData->m_curz = m_fWill_z = z;

	if( m_pUserData->m_bZone == ZONE_SNOW_BATTLE )	{
		//TRACE("ZoneChange - name=%s\n", m_pUserData->m_id);
		SetMaxHp();
	}

	PartyRemove(m_Sid);	// ??????? Z?????? ó??

	//TRACE("ZoneChange ,,, id=%s, nation=%d, zone=%d, x=%.2f, z=%.2f\n", m_pUserData->m_id, m_pUserData->m_bNation, zone, x, z);
	
	if( m_pMain->m_nServerNo != pMap->m_nServerNo ) {
		pInfo = m_pMain->m_ServerArray.GetData( pMap->m_nServerNo );
		if( !pInfo ) 
			return;

		UserDataSaveToAgent();
		
		CTime t = CTime::GetCurrentTime();
		m_pMain->WriteLog("[ZoneChange : %d-%d-%d] - sid=%d, acname=%s, name=%s, zone=%d, x=%d, z=%d \r\n", t.GetHour(), t.GetMinute(), t.GetSecond(), m_Sid, m_strAccountID, m_pUserData->m_id, zone, (int)x, (int)z);

		m_pUserData->m_bLogout = 2;	// server change flag
		SendServerChange(pInfo->strServerIP, 2);
		return;
	}
	
	m_pUserData->m_sBind = -1;		// Bind Point Clear...
	
	m_RegionX = (int)(m_pUserData->m_curx / VIEW_DISTANCE);
	m_RegionZ = (int)(m_pUserData->m_curz / VIEW_DISTANCE);

	SetByte( send_buff, WIZ_ZONE_CHANGE, send_index );
	SetByte( send_buff, 0x03, send_index );
	SetByte( send_buff, m_pUserData->m_bZone, send_index );
	SetShort( send_buff, (WORD)m_pUserData->m_curx*10, send_index );
	SetShort( send_buff, (WORD)m_pUserData->m_curz*10, send_index );
	SetShort( send_buff, (short)m_pUserData->m_cury*10, send_index );
	SetByte( send_buff, m_pMain->m_byOldVictory, send_index );
	Send( send_buff, send_index );

	if (!m_bZoneChangeSameZone) {
		m_sWhoKilledMe = -1;
		m_iLostExp = 0;
		m_bRegeneType = 0;
		m_fLastRegeneTime = 0.0f;
		m_pUserData->m_sBind = -1;
		InitType3();
		InitType4();
	}	

	if (m_bZoneChangeSameZone) {
		m_bZoneChangeSameZone = FALSE;
	}

	send_index = 0;
	SetByte( send_buff, AG_ZONE_CHANGE, send_index );
	SetShort( send_buff, m_Sid, send_index );
	SetByte( send_buff, getZoneID(), send_index );

	m_pMain->Send_AIServer(send_buff, send_index);

	m_bZoneChangeFlag = FALSE;
}
void CUser::NewCharToAgent(char *pBuf)
{
	int index = 0, idlen = 0, send_index = 0, retvalue = 0;
	int charindex = 0, race = 0, Class = 0, hair = 0, face = 0, str = 0, sta = 0, dex = 0, intel = 0, cha = 0;
	char charid[MAX_ID_SIZE+1];
	memset( charid, NULL, MAX_ID_SIZE+1 );
	char send_buff[256];
	memset( send_buff, NULL, 256);
	BYTE result;
	int sum = 0;
	_CLASS_COEFFICIENT* p_TableCoefficient = NULL;

	charindex = GetByte( pBuf, index );
	if (!GetKOString(pBuf, charid, index, MAX_ID_SIZE))
	{
		result = 0x05;
		goto fail_return;
	}

	race = GetByte( pBuf, index );
	Class = GetShort( pBuf, index );
	face = GetByte( pBuf, index );

	hair = GetDWORD( pBuf, index );

	str = GetByte( pBuf, index );
	sta = GetByte( pBuf, index );
	dex = GetByte( pBuf, index );
	intel = GetByte( pBuf, index );
	cha = GetByte( pBuf, index );

	if( charindex > 4 || charindex < 0 ) {
		result = 0x01;
		goto fail_return;
	}

	if( !IsValidName( charid ) ) {
		result = 0x05;
		goto fail_return;
	}

	p_TableCoefficient = m_pMain->m_CoefficientArray.GetData( Class );
	if( !p_TableCoefficient ) {
		result = 0x02;
		goto fail_return;
	}

	sum = str + sta + dex + intel + cha;
	if( sum > 300 ) {
		result = 0x02;
		goto fail_return;
	}

	if (str < 50 || sta < 50 || dex < 50 || intel < 50 || cha < 50) {
		result = 0x11;
		goto fail_return;		
	}

	SetByte( send_buff, WIZ_NEW_CHAR, send_index );
	SetShort( send_buff, m_Sid, send_index );
	SetKOString( send_buff, m_strAccountID, send_index );
	SetByte( send_buff, charindex, send_index );
	SetKOString(send_buff, charid, send_index);
	SetByte( send_buff, race, send_index );
	SetShort( send_buff, Class, send_index );
	SetByte( send_buff, face, send_index );
	SetDWORD( send_buff, hair, send_index );
	SetByte( send_buff, str, send_index );
	SetByte( send_buff, sta, send_index );
	SetByte( send_buff, dex, send_index );
	SetByte( send_buff, intel, send_index );
	SetByte( send_buff, cha, send_index );
	
	retvalue = m_pMain->m_LoggerSendQueue.PutData( send_buff, send_index );
	if (retvalue < SMQ_FULL)
		return;

	DEBUG_LOG("NewChar Send Fail : %d", retvalue);

fail_return:
	send_index = 0;
	SetByte( send_buff, WIZ_NEW_CHAR, send_index );
	SetByte( send_buff, result, send_index );
	Send( send_buff, send_index );
}
Example #6
0
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 CMagicProcess::AreaAttackDamage(int magictype, int rx, int rz, int magicid, int moral, int data1, int data2, int data3, int dexpoint, int righthand_damage)
{
	MAP* pMap = m_pSrcUser->GetMap();
	if (pMap == NULL) return;
	// 자신의 region에 있는 UserArray을 먼저 검색하여,, 가까운 거리에 유저가 있는지를 판단..
	if(rx < 0 || rz < 0 || rx > pMap->GetXRegionMax() || rz > pMap->GetZRegionMax())	{
		TRACE("#### CMagicProcess-AreaAttackDamage() Fail : [nid=%d, name=%s], nRX=%d, nRZ=%d #####\n", m_pSrcUser->m_iUserId, m_pSrcUser->m_strUserID, rx, rz);
		return;
	}

	_MAGIC_TYPE3* pType3 = NULL;
	_MAGIC_TYPE4* pType4 = NULL;
	_MAGIC_TABLE* pMagic = NULL;

	int damage = 0, tid = 0, target_damage = 0, attribute = 0;
	float fRadius = 0; 

	pMagic = g_pMain->m_MagictableArray.GetData( magicid );   // Get main magic table.
	if( !pMagic )	{
		TRACE("#### CMagicProcess-AreaAttackDamage Fail : magic maintable error ,, magicid=%d\n", magicid);
		return;
	}

	if(magictype == 3)	{
		pType3 = g_pMain->m_Magictype3Array.GetData( magicid );      // Get magic skill table type 3.
		if( !pType3 )	{
			TRACE("#### CMagicProcess-AreaAttackDamage Fail : magic table3 error ,, magicid=%d\n", magicid);
			return;
		}
		target_damage = pType3->sFirstDamage;
		attribute = pType3->bAttribute;
		fRadius = (float)pType3->bRadius;
	}
	else if(magictype == 4)	{
		pType4 = g_pMain->m_Magictype4Array.GetData( magicid );      // Get magic skill table type 3.
		if( !pType4 )	{
			TRACE("#### CMagicProcess-AreaAttackDamage Fail : magic table4 error ,, magicid=%d\n", magicid);
			return;
		}
		fRadius = (float)pType4->bRadius;
	}

	if( fRadius <= 0 )	{
		TRACE("#### CMagicProcess-AreaAttackDamage Fail : magicid=%d, radius = %d\n", magicid, fRadius);
		return;
	}


	__Vector3 vStart, vEnd;
	CNpc* pNpc = NULL ;      // Pointer initialization!
	float fDis = 0.0f;
	vStart.Set((float)data1, (float)0, (float)data3);
	char send_buff[256];
	int send_index=0, result = 1, count = 0, total_mon = 0, attack_type=0;; 
	int* pNpcIDList = NULL;

	EnterCriticalSection( &g_region_critical );

	CRegion *pRegion = &pMap->m_ppRegion[rx][rz];
	total_mon = pRegion->m_RegionNpcArray.GetSize();
	pNpcIDList = new int[total_mon];

	foreach_stlmap (itr, pRegion->m_RegionNpcArray)
		pNpcIDList[count++] = *itr->second;

	LeaveCriticalSection(&g_region_critical);

	for(int i = 0 ; i < total_mon; i++ ) {
		int nid = pNpcIDList[i];
		if( nid < NPC_BAND ) continue;
		pNpc = (CNpc*)g_pMain->m_arNpc.GetData(nid - NPC_BAND);

		if( pNpc != NULL && pNpc->m_NpcState != NPC_DEAD)	{
			if( m_pSrcUser->m_bNation == pNpc->m_byGroup ) continue;
			vEnd.Set(pNpc->m_fCurX, pNpc->m_fCurY, pNpc->m_fCurZ); 
			fDis = pNpc->GetDistance(vStart, vEnd);

			if(fDis <= fRadius)	{	// NPC가 반경안에 있을 경우...
				if(magictype == 3)	{	// 타잎 3일 경우...
					damage = GetMagicDamage(pNpc->m_sNid+NPC_BAND, target_damage, attribute, dexpoint, righthand_damage);
					TRACE("Area magictype3 ,, magicid=%d, damage=%d\n", magicid, damage);
					if(damage >= 0)	{
						result = pNpc->SetHMagicDamage(damage);
					}
					else	{
						damage = abs(damage);
						if(pType3->bAttribute == 3)   attack_type = 3; // 기절시키는 마법이라면.....
						else attack_type = magicid;

						if(pNpc->SetDamage(attack_type, damage, m_pSrcUser->m_strUserID, m_pSrcUser->m_iUserId + USER_BAND) == FALSE)	{
							// Npc가 죽은 경우,,
							pNpc->SendExpToUserList(); // 경험치 분배!!
							pNpc->SendDead();
							m_pSrcUser->SendAttackSuccess(pNpc->m_sNid+NPC_BAND, MAGIC_ATTACK_TARGET_DEAD, damage, pNpc->m_iHP);
						}
						else	{
							m_pSrcUser->SendAttackSuccess(pNpc->m_sNid+NPC_BAND, ATTACK_SUCCESS, damage, pNpc->m_iHP);
						}
					}

					send_index = 0;	
					// 패킷 전송.....
					//if ( pMagic->bType[1] == 0 || pMagic->bType[1] == 3 ) 
					{
						SetByte( send_buff, AG_MAGIC_ATTACK_RESULT, send_index );
						SetByte( send_buff, MAGIC_EFFECTING, send_index );
						SetDWORD( send_buff, magicid, send_index );
						SetShort( send_buff, m_pSrcUser->m_iUserId, send_index );
						SetShort( send_buff, pNpc->m_sNid+NPC_BAND, send_index );
						SetShort( send_buff, data1, send_index );	
						SetShort( send_buff, result, send_index );	
						SetShort( send_buff, data3, send_index );	
						SetShort( send_buff, moral, send_index );
						SetShort( send_buff, 0, send_index );
						SetShort( send_buff, 0, send_index );

						g_pMain->Send( send_buff, send_index );
					}
				}
				else if(magictype == 4)	{	// 타잎 4일 경우...
					send_index = 0;		result = 1;
					switch (pType4->bBuffType) {	// Depending on which buff-type it is.....
						case 1 :				// HP 올리기..
							break;

						case 2 :				// 방어력 올리기..
							break;

						case 4 :				// 공격력 올리기..
							break;

						case 5 :				// 공격 속도 올리기..
							break;

						case 6 :				// 이동 속도 올리기..
							//if (pNpc->m_MagicType4[pType4->bBuffType-1].sDurationTime > 0) {
							//	result = 0 ;
							//}
							//else {
								pNpc->m_MagicType4[pType4->bBuffType-1].byAmount = pType4->bSpeed;
								pNpc->m_MagicType4[pType4->bBuffType-1].sDurationTime = pType4->sDuration;
								pNpc->m_MagicType4[pType4->bBuffType-1].fStartTime = TimeGet();
								pNpc->m_fSpeed_1 = (float)(pNpc->m_fOldSpeed_1 * ((double)pType4->bSpeed / 100));
								pNpc->m_fSpeed_2 = (float)(pNpc->m_fOldSpeed_2 * ((double)pType4->bSpeed / 100));
							//}
							break;

						case 7 :				// 능력치 올리기...
							break;

						case 8 :				// 저항력 올리기...
							break;

						case 9 :				// 공격 성공율 및 회피 성공율 올리기..
							break;	

						default :
							result = 0 ;
							break;
					}

					TRACE("Area magictype4 ,, magicid=%d\n", magicid);

					SetByte( send_buff, AG_MAGIC_ATTACK_RESULT, send_index );
					SetByte( send_buff, MAGIC_EFFECTING, send_index );
					SetDWORD( send_buff, magicid, send_index );
					SetShort( send_buff, m_pSrcUser->m_iUserId, send_index );
					SetShort( send_buff, pNpc->m_sNid+NPC_BAND, send_index );
					SetShort( send_buff, data1, send_index );	
					SetShort( send_buff, result, send_index );	
					SetShort( send_buff, data3, send_index );	
					SetShort( send_buff, 0, send_index );
					SetShort( send_buff, 0, send_index );
					SetShort( send_buff, 0, send_index );
					g_pMain->Send( send_buff, send_index );
				}
			}	
		}
	}

	if(pNpcIDList)	{
		delete [] pNpcIDList;
		pNpcIDList = NULL;
	}
}
void CMagicProcess::ExecuteType3(int magicid, int tid, int data1, int data2, int data3, int moral, int dexpoint, int righthand_damage )   // Applied when a magical attack, healing, and mana restoration is done.
{	
	int damage = 0, result = 1, send_index=0, attack_type = 0; 
	char send_buff[256];
	_MAGIC_TYPE3* pType = NULL;
	CNpc* pNpc = NULL ;      // Pointer initialization!

	_MAGIC_TABLE* pMagic = NULL;
	pMagic = g_pMain->m_MagictableArray.GetData( magicid );   // Get main magic table.
	if( !pMagic ) return; 

	if(tid == -1)	{	// 지역 공격
		result = AreaAttack(3, magicid, moral, data1, data2, data3, dexpoint, righthand_damage);
		//if(result == 0)		goto packet_send;
		//else 
			return;
	}

	pNpc = g_pMain->m_arNpc.GetData(tid-NPC_BAND);
	if(pNpc == NULL || pNpc->m_NpcState == NPC_DEAD || pNpc->m_iHP == 0)	{
		result = 0;
		goto packet_send;
	}
	
	pType = g_pMain->m_Magictype3Array.GetData( magicid );      // Get magic skill table type 3.
	if( !pType ) return;
	
//	if (pType->sFirstDamage < 0) {
	if ((pType->sFirstDamage < 0) && (pType->bDirectType == 1) && (magicid < 400000)) {
		damage = GetMagicDamage(tid, pType->sFirstDamage, pType->bAttribute, dexpoint, righthand_damage) ;
	}
	else {
		damage = pType->sFirstDamage ;
	}

	//TRACE("magictype3 ,, magicid=%d, damage=%d\n", magicid, damage);
	
	if (pType->bDuration == 0)    { // Non-Durational Spells.
		if (pType->bDirectType == 1) {    // Health Point related !
			//damage = pType->sFirstDamage;     // Reduce target health point
//			if(damage >= 0)	{
			if(damage > 0)	{
				result = pNpc->SetHMagicDamage(damage);
			}
			else	{
				damage = abs(damage);
				if(pType->bAttribute == 3)   attack_type = 3; // 기절시키는 마법이라면.....
				else attack_type = magicid;

				if(pNpc->SetDamage(attack_type, damage, m_pSrcUser->m_strUserID, m_pSrcUser->m_iUserId + USER_BAND) == FALSE)	{
					// Npc가 죽은 경우,,
					pNpc->SendExpToUserList(); // 경험치 분배!!
					pNpc->SendDead();
					m_pSrcUser->SendAttackSuccess(tid, MAGIC_ATTACK_TARGET_DEAD, damage, pNpc->m_iHP, MAGIC_ATTACK);
				}
				else	{
					// 공격 결과 전송
					m_pSrcUser->SendAttackSuccess(tid, ATTACK_SUCCESS, damage, pNpc->m_iHP, MAGIC_ATTACK);
				}
			}
		}
		else if ( pType->bDirectType == 2 || pType->bDirectType == 3 )    // Magic or Skill Point related !
			pNpc->MSpChange(pType->bDirectType, pType->sFirstDamage);     // Change the SP or the MP of the target.
		else if( pType->bDirectType == 4 )     // Armor Durability related.
			pNpc->ItemWoreOut( DEFENCE, pType->sFirstDamage);     // Reduce Slot Item Durability
	}
	else if (pType->bDuration != 0)   {  // Durational Spells! Remember, durational spells only involve HPs.
		if(damage >= 0)	{
		}
		else	{
			damage = abs(damage);
			if(pType->bAttribute == 3)   attack_type = 3; // 기절시키는 마법이라면.....
			else attack_type = magicid;
				
			if(pNpc->SetDamage(attack_type, damage, m_pSrcUser->m_strUserID, m_pSrcUser->m_iUserId + USER_BAND) == FALSE)	{
				// Npc가 죽은 경우,,
				pNpc->SendExpToUserList(); // 경험치 분배!!
				pNpc->SendDead();
				m_pSrcUser->SendAttackSuccess(tid, MAGIC_ATTACK_TARGET_DEAD, damage, pNpc->m_iHP);
			}
			else	{
				// 공격 결과 전송
				m_pSrcUser->SendAttackSuccess(tid, ATTACK_SUCCESS, damage, pNpc->m_iHP);
			}
		}

		damage = GetMagicDamage(tid, pType->sTimeDamage, pType->bAttribute, dexpoint, righthand_damage);
		// The duration magic routine.
		for(int i=0; i<MAX_MAGIC_TYPE3; i++)	{
			if(pNpc->m_MagicType3[i].sHPAttackUserID == -1 && pNpc->m_MagicType3[i].byHPDuration == 0)	{
				pNpc->m_MagicType3[i].sHPAttackUserID = m_pSrcUser->m_iUserId;
				pNpc->m_MagicType3[i].fStartTime = TimeGet();
				pNpc->m_MagicType3[i].byHPDuration = pType->bDuration;
				pNpc->m_MagicType3[i].byHPInterval = 2;
				pNpc->m_MagicType3[i].sHPAmount = damage / (pType->bDuration / 2);
				break;
			}
		}	
	} 

packet_send:
	//if ( pMagic->bType[1] == 0 || pMagic->bType[1] == 3 ) 
	{
		SetByte( send_buff, AG_MAGIC_ATTACK_RESULT, send_index );
		SetByte( send_buff, MAGIC_EFFECTING, send_index );
		SetDWORD( send_buff, magicid, send_index );
		SetShort( send_buff, m_pSrcUser->m_iUserId, send_index );
		SetShort( send_buff, tid, send_index );
		SetShort( send_buff, data1, send_index );	
		SetShort( send_buff, result, send_index );	
		SetShort( send_buff, data3, send_index );	
		SetShort( send_buff, moral, send_index );
		SetShort( send_buff, 0, send_index );
		SetShort( send_buff, 0, send_index );
		g_pMain->Send( send_buff, send_index );
	}
	
}
void CUser::ItemMove(char *pBuf)
{
	int index = 0, itemid = 0, srcpos = -1, destpos = -1;
	int send_index = 0;
	char send_buff[128];
	memset( send_buff, NULL, 128 );
	_ITEM_TABLE* pTable = NULL;
	BYTE dir;

	dir = GetByte( pBuf, index );
	itemid = GetDWORD( pBuf, index );
	srcpos = GetByte( pBuf, index );
	destpos = GetByte( pBuf, index );

	if( m_sExchangeUser != -1 ) goto fail_return;
	pTable = m_pMain->m_ItemtableArray.GetData( itemid );
	if( !pTable )
		goto fail_return;
//	if( dir == ITEM_INVEN_SLOT && ((pTable->m_sWeight + m_sItemWeight) > m_sMaxWeight) )
//		goto fail_return;
	if( dir > 0x04 || srcpos >= SLOT_MAX+HAVE_MAX || destpos >= SLOT_MAX+HAVE_MAX )
		goto fail_return;
	if( (dir == ITEM_INVEN_SLOT || dir == ITEM_SLOT_SLOT ) && destpos > SLOT_MAX )
		goto fail_return;
	if( dir == ITEM_SLOT_INVEN && srcpos > SLOT_MAX )
		goto fail_return;
	if( dir == ITEM_INVEN_SLOT && destpos == RESERVED )
		goto fail_return;
	if( dir == ITEM_SLOT_INVEN && srcpos == RESERVED )
		goto fail_return;
	if( dir == ITEM_INVEN_SLOT || dir == ITEM_SLOT_SLOT ) {
		if( pTable->m_bRace != 0 ) {
			if( pTable->m_bRace != m_pUserData->m_bRace )
				goto fail_return;
		}
		if( !ItemEquipAvailable( pTable ) )
			goto fail_return;
	}

	switch( dir ) {
	case ITEM_INVEN_SLOT:
		if( itemid != m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum )
			goto fail_return;
		if( !IsValidSlotPos( pTable, destpos ) )
			goto fail_return;
		else if( pTable->m_bSlot == 0x01 || (pTable->m_bSlot == 0x00 && destpos == RIGHTHAND) ) {	// ???????? ????(??? ?????? ??? ???????? ?g?? ?????) ?e? ?????? ?µ???? ??? üu
			if(m_pUserData->m_sItemArray[LEFTHAND].nNum != 0) {
				_ITEM_TABLE* pTable2 = m_pMain->m_ItemtableArray.GetData( m_pUserData->m_sItemArray[LEFTHAND].nNum );
				if( pTable2 ) {
					if( pTable2->m_bSlot == 0x04 ) {
						m_pUserData->m_sItemArray[RIGHTHAND].nNum = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum;	// ?????? ???..
						m_pUserData->m_sItemArray[RIGHTHAND].sDuration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
						m_pUserData->m_sItemArray[RIGHTHAND].sCount = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount;
						m_pUserData->m_sItemArray[RIGHTHAND].nSerialNum = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;
						if( m_pUserData->m_sItemArray[RIGHTHAND].nSerialNum == 0 )
							m_pUserData->m_sItemArray[RIGHTHAND].nSerialNum = m_pMain->GenerateItemSerial();
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[LEFTHAND].nNum; // ?????? ?????? ??????.
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[LEFTHAND].sDuration;
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[LEFTHAND].sCount;
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[LEFTHAND].nSerialNum;
						if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 )
							m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
						m_pUserData->m_sItemArray[LEFTHAND].nNum = 0;			// ???? ?????? ????...
						m_pUserData->m_sItemArray[LEFTHAND].sDuration = 0;
						m_pUserData->m_sItemArray[LEFTHAND].sCount = 0;
						m_pUserData->m_sItemArray[LEFTHAND].nSerialNum = 0;
					}
					else {
						short duration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
						__int64 serial = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;

						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[destpos].nNum;	// Swaping
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[destpos].sDuration;
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[destpos].sCount;
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[destpos].nSerialNum;
						if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum != 0 && m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 )
							m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
						m_pUserData->m_sItemArray[destpos].nNum = itemid;
						m_pUserData->m_sItemArray[destpos].sDuration = duration;
						m_pUserData->m_sItemArray[destpos].sCount = 1;
						m_pUserData->m_sItemArray[destpos].nSerialNum = serial;
						if( m_pUserData->m_sItemArray[destpos].nSerialNum == 0 ) 
							m_pUserData->m_sItemArray[destpos].nSerialNum = m_pMain->GenerateItemSerial();
					}
				}
			}
			else {
				short duration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
				__int64 serial = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;

				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[destpos].nNum;	// Swaping
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[destpos].sDuration;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[destpos].sCount;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[destpos].nSerialNum;
				if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum != 0 && m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 )
					m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
				m_pUserData->m_sItemArray[destpos].nNum = itemid;
				m_pUserData->m_sItemArray[destpos].sDuration = duration;
				m_pUserData->m_sItemArray[destpos].sCount = 1;
				m_pUserData->m_sItemArray[destpos].nSerialNum = serial;
				if( m_pUserData->m_sItemArray[destpos].nSerialNum == 0 )
					m_pUserData->m_sItemArray[destpos].nSerialNum = m_pMain->GenerateItemSerial();
			}
		}
		else if( pTable->m_bSlot == 0x02 || (pTable->m_bSlot == 0x00 && destpos == LEFTHAND) ) {	// ?????? ????(??? ?????? ??? ???????? ?g?? ???) ?e? ?????? ?µ???? ??? üu
			if(m_pUserData->m_sItemArray[RIGHTHAND].nNum != 0) {
				_ITEM_TABLE* pTable2 = m_pMain->m_ItemtableArray.GetData(m_pUserData->m_sItemArray[RIGHTHAND].nNum);
				if( pTable2 ) {
					if( pTable2->m_bSlot == 0x03 ) {
						m_pUserData->m_sItemArray[LEFTHAND].nNum = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum;
						m_pUserData->m_sItemArray[LEFTHAND].sDuration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
						m_pUserData->m_sItemArray[LEFTHAND].sCount = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount;
						m_pUserData->m_sItemArray[LEFTHAND].nSerialNum = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;
						if( m_pUserData->m_sItemArray[LEFTHAND].nSerialNum == 0 )
							m_pUserData->m_sItemArray[LEFTHAND].nSerialNum = m_pMain->GenerateItemSerial();
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[RIGHTHAND].nNum; // ???????? ?????? ??????.
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[RIGHTHAND].sDuration;
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[RIGHTHAND].sCount;
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[RIGHTHAND].nSerialNum;
						if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 ) 
							m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
						m_pUserData->m_sItemArray[RIGHTHAND].nNum = 0;
						m_pUserData->m_sItemArray[RIGHTHAND].sDuration = 0;
						m_pUserData->m_sItemArray[RIGHTHAND].sCount = 0;
						m_pUserData->m_sItemArray[RIGHTHAND].nSerialNum = 0;
					}
					else {
						short duration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
						__int64 serial = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;

						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[destpos].nNum;	// Swaping
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[destpos].sDuration;
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[destpos].sCount;
						m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[destpos].nSerialNum;
						if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum != 0 && m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 )
							m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
						m_pUserData->m_sItemArray[destpos].nNum = itemid;
						m_pUserData->m_sItemArray[destpos].sDuration = duration;
						m_pUserData->m_sItemArray[destpos].sCount = 1;
						m_pUserData->m_sItemArray[destpos].nSerialNum = serial;
						if( m_pUserData->m_sItemArray[destpos].nSerialNum == 0 )
							m_pUserData->m_sItemArray[destpos].nSerialNum = m_pMain->GenerateItemSerial();
					}
				}
			}
			else {
				short duration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
				__int64 serial = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;

				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[destpos].nNum;	// Swaping
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[destpos].sDuration;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[destpos].sCount;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[destpos].nSerialNum;
				if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum != 0 && m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 )
					m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
				m_pUserData->m_sItemArray[destpos].nNum = itemid;
				m_pUserData->m_sItemArray[destpos].sDuration = duration;
				m_pUserData->m_sItemArray[destpos].sCount = 1;
				m_pUserData->m_sItemArray[destpos].nSerialNum = serial;
				if( m_pUserData->m_sItemArray[destpos].nSerialNum == 0 )
					m_pUserData->m_sItemArray[destpos].nSerialNum = m_pMain->GenerateItemSerial();
			}
		}
		else if( pTable->m_bSlot == 0x03 ) {	// ?µ? ?????? ????? ????
			if( m_pUserData->m_sItemArray[LEFTHAND].nNum != 0 && m_pUserData->m_sItemArray[RIGHTHAND].nNum != 0 )
				goto fail_return;
			else if( m_pUserData->m_sItemArray[LEFTHAND].nNum != 0 ) {
				m_pUserData->m_sItemArray[RIGHTHAND].nNum = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum;
				m_pUserData->m_sItemArray[RIGHTHAND].sDuration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
				m_pUserData->m_sItemArray[RIGHTHAND].sCount = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount;
				m_pUserData->m_sItemArray[RIGHTHAND].nSerialNum = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;
				if( m_pUserData->m_sItemArray[RIGHTHAND].nSerialNum == 0 )
					m_pUserData->m_sItemArray[RIGHTHAND].nSerialNum = m_pMain->GenerateItemSerial();
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[LEFTHAND].nNum;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[LEFTHAND].sDuration;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[LEFTHAND].sCount;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[LEFTHAND].nSerialNum;
				if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 )
					m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
				m_pUserData->m_sItemArray[LEFTHAND].nNum = 0;
				m_pUserData->m_sItemArray[LEFTHAND].sDuration = 0;
				m_pUserData->m_sItemArray[LEFTHAND].sCount = 0;
				m_pUserData->m_sItemArray[LEFTHAND].nSerialNum = 0;
			}
			else {
				short duration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
				__int64 serial = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;

				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[destpos].nNum;	// Swaping
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[destpos].sDuration;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[destpos].sCount;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[destpos].nSerialNum;
				if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum != 0 && m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 ) 
					m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
				m_pUserData->m_sItemArray[destpos].nNum = itemid;
				m_pUserData->m_sItemArray[destpos].sDuration = duration;
				m_pUserData->m_sItemArray[destpos].sCount = 1;
				m_pUserData->m_sItemArray[destpos].nSerialNum = serial;
				if( m_pUserData->m_sItemArray[destpos].nSerialNum == 0 )
					m_pUserData->m_sItemArray[destpos].nSerialNum = m_pMain->GenerateItemSerial();
			}
		}
		else if ( pTable->m_bSlot == 0x04 ) {	// ?µ? ?????? ??? ????
			if( m_pUserData->m_sItemArray[LEFTHAND].nNum != 0 && m_pUserData->m_sItemArray[RIGHTHAND].nNum != 0 )
				goto fail_return;
			else if( m_pUserData->m_sItemArray[RIGHTHAND].nNum != 0 ) {
				m_pUserData->m_sItemArray[LEFTHAND].nNum = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum;
				m_pUserData->m_sItemArray[LEFTHAND].sDuration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
				m_pUserData->m_sItemArray[LEFTHAND].sCount = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount;
				m_pUserData->m_sItemArray[LEFTHAND].nSerialNum = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;
				if( m_pUserData->m_sItemArray[LEFTHAND].nSerialNum == 0 )
					m_pUserData->m_sItemArray[LEFTHAND].nSerialNum = m_pMain->GenerateItemSerial();
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[RIGHTHAND].nNum;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[RIGHTHAND].sDuration;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[RIGHTHAND].sCount;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[RIGHTHAND].nSerialNum;
				if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 )
					m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
				m_pUserData->m_sItemArray[RIGHTHAND].nNum = 0;
				m_pUserData->m_sItemArray[RIGHTHAND].sDuration = 0;
				m_pUserData->m_sItemArray[RIGHTHAND].sCount = 0;
				m_pUserData->m_sItemArray[RIGHTHAND].nSerialNum = 0;
			}
			else {
				short duration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
				__int64 serial = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;

				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[destpos].nNum;	// Swaping
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[destpos].sDuration;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[destpos].sCount;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[destpos].nSerialNum;
				if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum != 0 && m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 )
					m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
				m_pUserData->m_sItemArray[destpos].nNum = itemid;
				m_pUserData->m_sItemArray[destpos].sDuration = duration;
				m_pUserData->m_sItemArray[destpos].sCount = 1;
				m_pUserData->m_sItemArray[destpos].nSerialNum = serial;
				if( m_pUserData->m_sItemArray[destpos].nSerialNum == 0 )
					m_pUserData->m_sItemArray[destpos].nSerialNum = m_pMain->GenerateItemSerial();
			}
		}
		else {
			short duration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
			__int64 serial = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;

			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[destpos].nNum;	// Swaping
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[destpos].sDuration;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[destpos].sCount;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[destpos].nSerialNum;
			if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum != 0 && m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 )
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
			m_pUserData->m_sItemArray[destpos].nNum = itemid;
			m_pUserData->m_sItemArray[destpos].sDuration = duration;
			m_pUserData->m_sItemArray[destpos].sCount = 1;
			m_pUserData->m_sItemArray[destpos].nSerialNum = serial;
			if( m_pUserData->m_sItemArray[destpos].nSerialNum == 0 )
				m_pUserData->m_sItemArray[destpos].nSerialNum = m_pMain->GenerateItemSerial();
		}
		break;
	case ITEM_SLOT_INVEN:
		if( itemid != m_pUserData->m_sItemArray[srcpos].nNum )
			goto fail_return;
		if( m_pUserData->m_sItemArray[SLOT_MAX+destpos].nNum != 0 )
			goto fail_return;

		m_pUserData->m_sItemArray[SLOT_MAX+destpos].nNum = m_pUserData->m_sItemArray[srcpos].nNum;
		m_pUserData->m_sItemArray[SLOT_MAX+destpos].sDuration = m_pUserData->m_sItemArray[srcpos].sDuration;
		m_pUserData->m_sItemArray[SLOT_MAX+destpos].sCount = m_pUserData->m_sItemArray[srcpos].sCount;
		m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum = m_pUserData->m_sItemArray[srcpos].nSerialNum;
		if( m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum == 0 ) 
			m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum = m_pMain->GenerateItemSerial();
		m_pUserData->m_sItemArray[srcpos].nNum = 0;
		m_pUserData->m_sItemArray[srcpos].sDuration = 0;
		m_pUserData->m_sItemArray[srcpos].sCount = 0;
		m_pUserData->m_sItemArray[srcpos].nSerialNum = 0;
		break;
	case ITEM_INVEN_INVEN:
		if( itemid != m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum )
			goto fail_return;
		{
			short duration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
			short itemcount = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount;
			__int64 serial = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;
			_ITEM_TABLE* pTable2 = NULL;

			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[SLOT_MAX+destpos].nNum;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[SLOT_MAX+destpos].sDuration;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[SLOT_MAX+destpos].sCount;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum;
			if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum == 0 ) {
				pTable2 = m_pMain->m_ItemtableArray.GetData(m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum);
				if( pTable && pTable->m_bCountable == 0 )
					m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pMain->GenerateItemSerial();
			}

			m_pUserData->m_sItemArray[SLOT_MAX+destpos].nNum = itemid;
			m_pUserData->m_sItemArray[SLOT_MAX+destpos].sDuration = duration;
			m_pUserData->m_sItemArray[SLOT_MAX+destpos].sCount = itemcount;
			m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum = serial;
			if( m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum == 0 ) {
				pTable2 = m_pMain->m_ItemtableArray.GetData(m_pUserData->m_sItemArray[SLOT_MAX+destpos].nNum);
				if( pTable && pTable->m_bCountable == 0 )
					m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum = m_pMain->GenerateItemSerial();
			}
		}
		break;
	case ITEM_SLOT_SLOT:
		if( itemid != m_pUserData->m_sItemArray[srcpos].nNum )
			goto fail_return;
		if( !IsValidSlotPos( pTable, destpos ) )
			goto fail_return;

		if( m_pUserData->m_sItemArray[destpos].nNum != 0 ) {
			_ITEM_TABLE* pTable2 = m_pMain->m_ItemtableArray.GetData( m_pUserData->m_sItemArray[destpos].nNum );	// dest slot exist some item
			if( pTable2 ) {
				if( pTable2->m_bSlot != 0x00 )
					goto fail_return;
				else {
					short duration = m_pUserData->m_sItemArray[srcpos].sDuration;
					short count = m_pUserData->m_sItemArray[srcpos].sCount;
					__int64 serial = m_pUserData->m_sItemArray[srcpos].nSerialNum;
					m_pUserData->m_sItemArray[srcpos].nNum = m_pUserData->m_sItemArray[destpos].nNum;				// Swaping
					m_pUserData->m_sItemArray[srcpos].sDuration = m_pUserData->m_sItemArray[destpos].sDuration;		// Swaping
					m_pUserData->m_sItemArray[srcpos].sCount = m_pUserData->m_sItemArray[destpos].sCount;			// Swaping
					m_pUserData->m_sItemArray[srcpos].nSerialNum = m_pUserData->m_sItemArray[destpos].nSerialNum;	// Swaping
					if( m_pUserData->m_sItemArray[srcpos].nSerialNum == 0 )
						m_pUserData->m_sItemArray[srcpos].nSerialNum = m_pMain->GenerateItemSerial();
					m_pUserData->m_sItemArray[destpos].nNum = itemid;
					m_pUserData->m_sItemArray[destpos].sDuration = duration;
					m_pUserData->m_sItemArray[destpos].sCount = count;
					m_pUserData->m_sItemArray[destpos].nSerialNum = serial;
					if( m_pUserData->m_sItemArray[destpos].nSerialNum == 0 )
						m_pUserData->m_sItemArray[destpos].nSerialNum = m_pMain->GenerateItemSerial();
				}
			}
		}
		else {
			short duration = m_pUserData->m_sItemArray[srcpos].sDuration;
			short count = m_pUserData->m_sItemArray[srcpos].sCount;
			__int64 serial = m_pUserData->m_sItemArray[srcpos].nSerialNum;
			m_pUserData->m_sItemArray[srcpos].nNum = m_pUserData->m_sItemArray[destpos].nNum;				// Swaping
			m_pUserData->m_sItemArray[srcpos].sDuration = m_pUserData->m_sItemArray[destpos].sDuration;		// Swaping
			m_pUserData->m_sItemArray[srcpos].sCount = m_pUserData->m_sItemArray[destpos].sCount;			// Swaping
			m_pUserData->m_sItemArray[srcpos].nSerialNum = m_pUserData->m_sItemArray[destpos].nSerialNum;	// Swaping
			m_pUserData->m_sItemArray[destpos].nNum = itemid;
			m_pUserData->m_sItemArray[destpos].sDuration = duration;
			m_pUserData->m_sItemArray[destpos].sCount = count;
			m_pUserData->m_sItemArray[destpos].nSerialNum = serial;
			if( m_pUserData->m_sItemArray[destpos].nSerialNum == 0 )
				m_pUserData->m_sItemArray[destpos].nSerialNum = m_pMain->GenerateItemSerial();
		}
		break;
	}

	if( dir != ITEM_INVEN_INVEN ) {	// ?????? ???? ????? ???..
		SetSlotItemValue();
		SetUserAbility();
	}
/*
	SetByte( send_buff, WIZ_ITEM_MOVE, send_index );
	SetByte( send_buff, 0x01, send_index );
	SetShort( send_buff, m_sTotalHit, send_index );
	SetShort( send_buff, m_sTotalAc, send_index );
	SetShort( send_buff, m_sMaxWeight, send_index );
	SetShort( send_buff, m_iMaxHp, send_index );
	SetShort( send_buff, m_iMaxMp, send_index );
	SetByte( send_buff, m_sItemStr, send_index );
	SetByte( send_buff, m_sItemSta, send_index );
	SetByte( send_buff, m_sItemDex, send_index );
	SetByte( send_buff, m_sItemIntel, send_index );
	SetByte( send_buff, m_sItemCham, send_index );
	SetByte( send_buff, m_bFireR, send_index );
	SetByte( send_buff, m_bColdR, send_index );
	SetByte( send_buff, m_bLightningR, send_index );
	SetByte( send_buff, m_bMagicR, send_index );
	SetByte( send_buff, m_bDiseaseR, send_index );
	SetByte( send_buff, m_bPoisonR, send_index );
	Send( send_buff, send_index );

	BYTE	m_bStrAmount;
	BYTE	m_bStaAmount;
	BYTE	m_bDexAmount;
	BYTE	m_bIntelAmount;
	BYTE	m_bChaAmount;
*/

	SetByte( send_buff, WIZ_ITEM_MOVE, send_index );
	SetByte( send_buff, 0x01, send_index );
	SetShort( send_buff, m_sTotalHit, send_index );
	SetShort( send_buff, m_sTotalAc, send_index );
	SetShort( send_buff, m_sMaxWeight, send_index );
	SetShort( send_buff, m_iMaxHp, send_index );
	SetShort( send_buff, m_iMaxMp, send_index );
	SetByte( send_buff, m_sItemStr + m_bStrAmount, send_index );		
	SetByte( send_buff, m_sItemSta + m_bStaAmount, send_index );		
	SetByte( send_buff, m_sItemDex + m_bDexAmount, send_index );		
	SetByte( send_buff, m_sItemIntel + m_bIntelAmount, send_index );	
	SetByte( send_buff, m_sItemCham + m_bChaAmount, send_index );		
	SetByte( send_buff, m_bFireR, send_index );
	SetByte( send_buff, m_bColdR, send_index );
	SetByte( send_buff, m_bLightningR, send_index );
	SetByte( send_buff, m_bMagicR, send_index );
	SetByte( send_buff, m_bDiseaseR, send_index );
	SetByte( send_buff, m_bPoisonR, send_index );
	Send( send_buff, send_index );
//
	SendItemWeight();

	if( (dir == ITEM_INVEN_SLOT ) && ( destpos == HEAD || destpos == BREAST || destpos == SHOULDER || destpos == LEFTHAND || destpos == RIGHTHAND || destpos == LEG || destpos == GLOVE || destpos == FOOT) ) 
		UserLookChange( destpos, itemid, m_pUserData->m_sItemArray[destpos].sDuration );	
	if( (dir == ITEM_SLOT_INVEN ) && ( srcpos == HEAD || srcpos == BREAST || srcpos == SHOULDER || srcpos == LEFTHAND || srcpos == RIGHTHAND || srcpos == LEG || srcpos == GLOVE || srcpos == FOOT) ) 
		UserLookChange( srcpos, 0, 0 );	

	Send2AI_UserUpdateInfo();

	return;

fail_return:
	send_index = 0;
	SetByte( send_buff, WIZ_ITEM_MOVE, send_index );
	SetByte( send_buff, 0x00, send_index );
	Send( send_buff, send_index );
}
Example #10
0
void CAISocket::RecvNpcGiveItem(char* pBuf)
{
	int index = 0, send_index = 0;
	char send_buff[1024];
	short sUid, sNid, sZone, regionx, regionz;
	float fX, fZ, fY;
	BYTE byCount;
	int nItemNumber[NPC_HAVE_ITEM_LIST];
	short sCount[NPC_HAVE_ITEM_LIST];
	_ZONE_ITEM* pItem = NULL;
	C3DMap* pMap = NULL;
	CUser* pUser = NULL;

	sUid = GetShort(pBuf,index);	// Item을 가져갈 사람의 아이디... (이것을 참조해서 작업하셈~)
	sNid = GetShort(pBuf,index);
	sZone = GetShort(pBuf, index);
	regionx = GetShort( pBuf, index );
	regionz = GetShort( pBuf, index );
	fX = Getfloat(pBuf,index);
	fZ = Getfloat(pBuf,index);
	fY = Getfloat(pBuf,index);
	byCount = GetByte(pBuf,index);
	for(int i=0; i<byCount; i++)
	{
		nItemNumber[i] = GetDWORD(pBuf, index);
		sCount[i] = GetShort(pBuf,index);
	}

	if( sUid < 0 || sUid >= MAX_USER ) return;
	pMap = m_pMain->GetZoneByID(sZone);
	if (pMap == NULL)
		return;

	pItem = new _ZONE_ITEM;
	for(int i=0; i<6; i++) {
		pItem->itemid[i] = 0;
		pItem->count[i] = 0;
	}
	pItem->bundle_index = pMap->m_wBundle;
	pItem->time = TimeGet();
	pItem->x = fX;
	pItem->z = fZ;
	pItem->y = fY;
	for(int i=0; i<byCount; i++) {
		if( m_pMain->m_ItemtableArray.GetData(nItemNumber[i]) ) {
			pItem->itemid[i] = nItemNumber[i];
			pItem->count[i] = sCount[i];
		}
	}

	if (!pMap->RegionItemAdd(regionx, regionz, pItem ))
	{
		delete pItem;
		return;
	}

	pUser = m_pMain->GetUserPtr(sUid);
	if (pUser == NULL) 
		return;
	
	send_index = 0;

	SetByte( send_buff, WIZ_ITEM_DROP, send_index );
	SetShort( send_buff, sNid, send_index );
	SetDWORD( send_buff, pItem->bundle_index, send_index );
	if( pUser->m_sPartyIndex == -1 )
		pUser->Send( send_buff, send_index );
	else
		m_pMain->Send_PartyMember( pUser->m_sPartyIndex, send_buff, send_index );
}
Example #11
0
void CAISocket::RecvMagicAttackResult(char* pBuf)
{
	int index = 0, send_index = 1, sid = -1, tid = -1, magicid=0;
	BYTE byCommand; 
	short data0, data1, data2, data3, data4, data5;

	CNpc* pNpc = NULL;
	CUser* pUser = NULL;
	char send_buff[1024];

	//byType = GetByte(pBuf,index);				// who ( 1:mon->user 2:mon->mon )
	//byAttackType = GetByte(pBuf,index);			// attack type ( 1:long attack, 2:magic attack
	byCommand = GetByte(pBuf,index);			// magic type ( 1:casting, 2:flying, 3:effecting, 4:fail )
	magicid = GetDWORD(pBuf,index);
	sid = GetShort(pBuf,index);
	tid = GetShort(pBuf,index);
	data0 = GetShort(pBuf,index);
	data1 = GetShort(pBuf,index);
	data2 = GetShort(pBuf,index);
	data3 = GetShort(pBuf,index);
	data4 = GetShort(pBuf,index);
	data5 = GetShort(pBuf,index);

	SetByte( send_buff, byCommand, send_index );
	SetDWORD( send_buff, magicid, send_index );
	SetShort( send_buff, sid, send_index );
	SetShort( send_buff, tid, send_index );
	SetShort( send_buff, data0, send_index );
	SetShort( send_buff, data1, send_index );
	SetShort( send_buff, data2, send_index );
	SetShort( send_buff, data3, send_index );
	SetShort( send_buff, data4, send_index );
	SetShort( send_buff, data5, send_index );

	if(byCommand == 0x01)	{		// casting
		pNpc = m_pMain->m_arNpcArray.GetData(sid);
		if(!pNpc)	return;
		index = 0;
		SetByte( send_buff, WIZ_MAGIC_PROCESS, index );
		m_pMain->Send_Region(send_buff, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false);
	}
	else if(byCommand == 0x03)	{	// effecting
		//pNpc = m_pMain->m_arNpcArray.GetData(tid);
		//if(!pNpc)	return;
		if( sid >= USER_BAND && sid < NPC_BAND)	{
			pUser = m_pMain->GetUserPtr(sid);
			if (pUser == NULL || pUser->isDead())
				return;

			index = 0;
			SetByte( send_buff, WIZ_MAGIC_PROCESS, index );
			m_pMain->Send_Region(send_buff, send_index, pUser->GetMap(), pUser->m_RegionX, pUser->m_RegionZ, NULL, false);
		}
		else if(sid >= NPC_BAND)	{
			if(tid >= NPC_BAND)	{
				pNpc = m_pMain->m_arNpcArray.GetData(tid);
				if(!pNpc)	return;
				index = 0;
				SetByte( send_buff, WIZ_MAGIC_PROCESS, index );
				m_pMain->Send_Region(send_buff, send_index, pNpc->GetMap(), pNpc->m_sRegion_X, pNpc->m_sRegion_Z, NULL, false);
				return;
			}
			send_index = 0;
			SetByte( send_buff, byCommand, send_index );
			SetDWORD( send_buff, magicid, send_index );
			SetShort( send_buff, sid, send_index );
			SetShort( send_buff, tid, send_index );
			SetShort( send_buff, data0, send_index );
			SetShort( send_buff, data1, send_index );
			SetShort( send_buff, data2, send_index );
			SetShort( send_buff, data3, send_index );
			SetShort( send_buff, data4, send_index );
			SetShort( send_buff, data5, send_index );
			m_MagicProcess.MagicPacket(send_buff, send_index);
		}
	}
	
}
Example #12
0
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);
		}
	}
}
Example #13
0
void CAISocket::RecvBattleEvent(char* pBuf)
{
	int index = 0, send_index = 0, udp_index = 0, retvalue = 0;
	int nType = 0, nResult = 0, nLen = 0;
	char strMaxUserName[MAX_ID_SIZE+1], strKnightsName[MAX_ID_SIZE+1];
	char chatstr[1024], finalstr[1024], send_buff[1024], udp_buff[1024];
	CUser* pUser = NULL;
	CKnights* pKnights = NULL;

	nType = GetByte( pBuf, index );
	nResult = GetByte(pBuf, index);

	if( nType == BATTLE_EVENT_OPEN )	{
	}
	else if( nType == BATTLE_MAP_EVENT_RESULT )	{
		if( m_pMain->m_byBattleOpen == NO_BATTLE )	{
			TRACE("#### RecvBattleEvent Fail : battleopen = %d, type = %d\n", m_pMain->m_byBattleOpen, nType);
			return;
		}
		if( nResult == KARUS )	{
			//TRACE("--> RecvBattleEvent : 카루스 땅으로 넘어갈 수 있어\n");
			m_pMain->m_byKarusOpenFlag = 1;		// 카루스 땅으로 넘어갈 수 있어
		}
		else if( nResult == ELMORAD )	{
			//TRACE("--> RecvBattleEvent : 엘모 땅으로 넘어갈 수 있어\n");
			m_pMain->m_byElmoradOpenFlag = 1;	// 엘모 땅으로 넘어갈 수 있어
		}

		SetByte( udp_buff, UDP_BATTLE_EVENT_PACKET, udp_index );
		SetByte( udp_buff, nType, udp_index );
		SetByte( udp_buff, nResult, udp_index );
	}
	else if( nType == BATTLE_EVENT_RESULT )	{
		if( m_pMain->m_byBattleOpen == NO_BATTLE )	{
			TRACE("#### RecvBattleEvent Fail : battleopen = %d, type=%d\n", m_pMain->m_byBattleOpen, nType);
			return;
		}
		if( nResult == KARUS )	{
			//TRACE("--> RecvBattleEvent : 카루스가 승리하였습니다.\n");
		}
		else if( nResult == ELMORAD )	{
			//TRACE("--> RecvBattleEvent : 엘모라드가 승리하였습니다.\n");
		}

		nLen = GetByte(pBuf, index);

		if( nLen > 0 && nLen < MAX_ID_SIZE+1 )	{
			GetString( strMaxUserName, pBuf, nLen, index );
			if( m_pMain->m_byBattleSave == 0 )	{
				send_index = 0;			// 승리국가를 sql에 저장
				SetByte( send_buff, WIZ_BATTLE_EVENT, send_index );
				SetByte( send_buff, nType, send_index );
				SetByte( send_buff, nResult, send_index );
				SetByte( send_buff, nLen, send_index );
				SetString( send_buff, strMaxUserName, nLen, send_index );
				retvalue = m_pMain->m_LoggerSendQueue.PutData( send_buff, send_index );
				if (retvalue >= SMQ_FULL)
					DEBUG_LOG("WIZ_BATTLE_EVENT Send Fail : %d, %d", retvalue, nType);
				m_pMain->m_byBattleSave = 1;
			}
		}

		m_pMain->m_bVictory = nResult;
		m_pMain->m_byOldVictory = nResult;
		m_pMain->m_byKarusOpenFlag = 0;		// 카루스 땅으로 넘어갈 수 없도록
		m_pMain->m_byElmoradOpenFlag = 0;	// 엘모 땅으로 넘어갈 수 없도록
		m_pMain->m_byBanishFlag = 1;

		SetByte( udp_buff, UDP_BATTLE_EVENT_PACKET, udp_index );	// udp로 다른서버에 정보 전달
		SetByte( udp_buff, nType, udp_index );
		SetByte( udp_buff, nResult, udp_index );
	}
	else if( nType == BATTLE_EVENT_MAX_USER )	{
		if (GetKOString(pBuf, strMaxUserName, index, MAX_ID_SIZE, sizeof(BYTE)))
		{
			pUser = m_pMain->GetUserPtr(strMaxUserName, TYPE_CHARACTER);
			if( pUser )	{
				pKnights = m_pMain->m_KnightsArray.GetData( pUser->m_pUserData->m_bKnights );
				if( pKnights )	{
					strcpy_s( strKnightsName, sizeof(strKnightsName), pKnights->m_strName );
				}
			}

			int nResourceID = 0;
			switch (nResult)
			{
			case 1: // captain
				nResourceID = IDS_KILL_CAPTAIN;
				break;
			case 2: // keeper

			case 7: // warders?
			case 8:
				nResourceID = IDS_KILL_GATEKEEPER;
				break;

			case 3: // Karus sentry
				nResourceID = IDS_KILL_KARUS_GUARD1;
				break;
			case 4: // Karus sentry
				nResourceID = IDS_KILL_KARUS_GUARD2;
				break;
			case 5: // El Morad sentry
				nResourceID = IDS_KILL_ELMO_GUARD1;
				break;
			case 6: // El Morad sentry
				nResourceID = IDS_KILL_ELMO_GUARD2;
				break;
			}

			if (nResourceID == 0)
			{
				TRACE("RecvBattleEvent: could not establish resource for result %d", nResult);
				return;
			}

			_snprintf(chatstr, sizeof(chatstr), m_pMain->GetServerResource(nResourceID), strKnightsName, strMaxUserName);

			send_index = 0;
			sprintf( finalstr, m_pMain->GetServerResource(IDP_ANNOUNCEMENT), chatstr );
			SetByte( send_buff, WIZ_CHAT, send_index );
			SetByte( send_buff, WAR_SYSTEM_CHAT, send_index );
			SetByte( send_buff, 1, send_index );
			SetShort( send_buff, -1, send_index );
			SetKOString( send_buff, finalstr, send_index );
			m_pMain->Send_All( send_buff, send_index );

			send_index = 0;
			SetByte( send_buff, WIZ_CHAT, send_index );
			SetByte( send_buff, PUBLIC_CHAT, send_index );
			SetByte( send_buff, 1, send_index );
			SetShort( send_buff, -1, send_index );
			SetKOString( send_buff, finalstr, send_index );
			m_pMain->Send_All( send_buff, send_index );

			SetByte( udp_buff, UDP_BATTLE_EVENT_PACKET, udp_index );
			SetByte( udp_buff, nType, udp_index );
			SetByte( udp_buff, nResult, udp_index );
			SetKOString(udp_buff, strKnightsName, udp_index);
			SetKOString(udp_buff, strMaxUserName, udp_index);
		}
	}

	m_pMain->Send_UDP_All( udp_buff, udp_index );
}
void CUser::PartyRequest(int memberid, BOOL bCreate)
{
	int index = 0, send_index = 0, result = -1, i=0;
	CUser* pUser = NULL;
	_PARTY_GROUP* pParty = NULL;
	char send_buff[256]; memset( send_buff, 0x00, 256 );

	pUser = m_pMain->GetUserPtr(memberid);
	if (pUser == NULL
		|| pUser->m_sPartyIndex != -1) goto fail_return;

	if (getNation() != pUser->getNation())
	{
		result = -3;
		goto fail_return;
	}

	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) ) 
		 )
	  )  {
		result = -2;
		goto fail_return;
	}

	if( !bCreate ) {	// ????? ????? ?????? ???
		pParty = m_pMain->m_PartyArray.GetData(m_sPartyIndex);
		if( !pParty ) goto fail_return;
		for(i=0; i<8; i++) {
			if( pParty->uid[i] < 0 ) 
				break;
		}
		if( i==8 ) goto fail_return;	// ??? ??? Full
	}

	if( bCreate ) {
		if( m_sPartyIndex != -1 ) goto fail_return;	// can't create a party ifw e're already in one
		if (!m_pMain->CreateParty(this))
			goto fail_return;

		// AI Server
		send_index = 0; memset( send_buff, 0x00, 256 );
		SetByte( send_buff, AG_USER_PARTY, send_index );
		SetByte( send_buff, PARTY_CREATE, send_index );
		SetShort( send_buff, pParty->wIndex, send_index );
		SetShort( send_buff, pParty->uid[0], send_index );
		//SetShort( send_buff, pParty->sHp[0], send_index );
		//SetByte( send_buff, pParty->bLevel[0], send_index );
		//SetShort( send_buff, pParty->sClass[0], send_index );
		m_pMain->Send_AIServer(m_pUserData->m_bZone, send_buff, send_index);
	}

	pUser->m_sPartyIndex = m_sPartyIndex;

/*	??? BBS?? ??? ???...
	if (pUser->m_bNeedParty == 2 && pUser->m_sPartyIndex != -1) {
		pUser->m_bNeedParty = 1;	// ?? ?? ??? ????? ??????? ??? ^^;
		memset( send_buff, 0x00, 256 ); send_index = 0;	
		SetByte(send_buff, 2, send_index);
		SetByte(send_buff, pUser->m_bNeedParty, send_index);
		pUser->StateChange(send_buff);
	}

	if (m_bNeedParty == 2 && m_sPartyIndex != -1) {
		m_bNeedParty = 1;	// ?? ?? ??? ????? ??????? ??? ^^;
		memset( send_buff, 0x00, 256 ); send_index = 0;	
		SetByte(send_buff, 2, send_index);
		SetByte(send_buff, m_bNeedParty, send_index);
		StateChange(send_buff);
	}	
*/
	send_index = 0; memset( send_buff, 0x00, 256 );
	SetByte( send_buff, WIZ_PARTY, send_index );
	SetByte( send_buff, PARTY_PERMIT, send_index );
	SetShort( send_buff, m_Sid, send_index );
	SetKOString(send_buff, m_pUserData->m_id, send_index);
	pUser->Send( send_buff, send_index );
	return;

fail_return:
	SetByte( send_buff, WIZ_PARTY, send_index );
	SetByte( send_buff, PARTY_INSERT, send_index );
	SetShort( send_buff, result, send_index );
	Send( send_buff, send_index );
}
void CUser::WarehouseProcess(char *pBuf)
{
	int index = 0, send_index = 0, itemid = 0, srcpos = -1, destpos = -1, page = -1, reference_pos = -1;
	DWORD count = 0;
	char send_buff[2048]; memset( send_buff, 0x00, 2048 );
	_ITEM_TABLE* pTable = NULL;
	BYTE command = 0;
	command = GetByte( pBuf, index );

	// â?? ??j?...
	if (isDead())
	{
		TRACE("### WarehouseProcess Fail : name=%s(%d), m_bResHpType=%d, hp=%d, x=%d, z=%d ###\n", m_pUserData->m_id, m_Sid, m_bResHpType, m_pUserData->m_sHp, (int)m_pUserData->m_curx, (int)m_pUserData->m_curz);
		return;
	}
	if( m_sExchangeUser != -1 ) goto fail_return;

	if( command == WAREHOUSE_OPEN )	{
		SetByte( send_buff, WIZ_WAREHOUSE, send_index );
		SetByte( send_buff, WAREHOUSE_OPEN, send_index );
		SetDWORD( send_buff, m_pUserData->m_iBank, send_index );
		for(int i=0; i<WAREHOUSE_MAX; i++ ) {
			SetDWORD( send_buff, m_pUserData->m_sWarehouseArray[i].nNum, send_index );
			SetShort( send_buff, m_pUserData->m_sWarehouseArray[i].sDuration, send_index );
			SetShort( send_buff, m_pUserData->m_sWarehouseArray[i].sCount, send_index );
		}
		SendCompressingPacket( send_buff, send_index );	
		return;
	}

	itemid = GetDWORD( pBuf, index );
	page = GetByte( pBuf, index );
	srcpos = GetByte( pBuf, index );
	destpos = GetByte( pBuf, index );
	pTable = m_pMain->m_ItemtableArray.GetData( itemid );
	if( !pTable ) goto fail_return;
	reference_pos = 24 * page;

	switch( command ) {
	case WAREHOUSE_INPUT:
		count = GetDWORD( pBuf, index );
		if( itemid == ITEM_GOLD ) {
			if( m_pUserData->m_iBank+count > 2100000000 ) goto fail_return;
			if( m_pUserData->m_iGold-count < 0 ) goto fail_return;
			m_pUserData->m_iBank += count;
			m_pUserData->m_iGold -= count;
			break;
		}
		if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum != itemid ) goto fail_return;
		if( reference_pos+destpos > WAREHOUSE_MAX ) goto fail_return;
		if( m_pUserData->m_sWarehouseArray[reference_pos+destpos].nNum && !pTable->m_bCountable ) goto fail_return;
		if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount < count ) goto fail_return;
		m_pUserData->m_sWarehouseArray[reference_pos+destpos].nNum = itemid;
		m_pUserData->m_sWarehouseArray[reference_pos+destpos].sDuration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
		m_pUserData->m_sWarehouseArray[reference_pos+destpos].nSerialNum = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;
		if( pTable->m_bCountable == 0 && m_pUserData->m_sWarehouseArray[reference_pos+destpos].nSerialNum == 0 )
			m_pUserData->m_sWarehouseArray[reference_pos+destpos].nSerialNum = m_pMain->GenerateItemSerial();

		if( pTable->m_bCountable ) {
			m_pUserData->m_sWarehouseArray[reference_pos+destpos].sCount += count;
		}
		else {
			m_pUserData->m_sWarehouseArray[reference_pos+destpos].sCount = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount;
		}

		if( !pTable->m_bCountable ) {
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = 0;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = 0;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = 0;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = 0;
		}
		else {
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount -= count;
			if( m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount <= 0 ) {
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = 0;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = 0;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = 0;
				m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = 0;
			}
		}

		SendItemWeight();
		ItemLogToAgent( m_pUserData->m_Accountid, m_pUserData->m_id, ITEM_WAREHOUSE_PUT, 0, itemid, count, m_pUserData->m_sWarehouseArray[reference_pos+destpos].sDuration );
		break;
	case WAREHOUSE_OUTPUT:
		count = GetDWORD( pBuf, index );

		if( itemid == ITEM_GOLD ) {
			if( m_pUserData->m_iGold+count > 2100000000 ) goto fail_return;
			if( m_pUserData->m_iBank-count < 0 ) goto fail_return;
			m_pUserData->m_iGold += count;
			m_pUserData->m_iBank -= count;
			break;
		}
//
		if (pTable->m_bCountable) {	// Check weight of countable item.
			if (((pTable->m_sWeight * count)   + m_sItemWeight) > m_sMaxWeight) {			
				goto fail_return;
			}
		}
		else {	// Check weight of non-countable item.
			if ((pTable->m_sWeight + m_sItemWeight) > m_sMaxWeight) {
				goto fail_return;
			}
		}		
//
		if( reference_pos+srcpos > WAREHOUSE_MAX ) goto fail_return;
		if( m_pUserData->m_sWarehouseArray[reference_pos+srcpos].nNum != itemid ) goto fail_return;
		if( m_pUserData->m_sItemArray[SLOT_MAX+destpos].nNum && !pTable->m_bCountable ) goto fail_return;
		if( m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sCount < count ) goto fail_return;
		m_pUserData->m_sItemArray[SLOT_MAX+destpos].nNum = itemid;
		m_pUserData->m_sItemArray[SLOT_MAX+destpos].sDuration = m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sDuration;
		m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum = m_pUserData->m_sWarehouseArray[reference_pos+srcpos].nSerialNum;
		if( pTable->m_bCountable )
			m_pUserData->m_sItemArray[SLOT_MAX+destpos].sCount += count;
		else {
			if( m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum == 0 )
				m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum = m_pMain->GenerateItemSerial();
			m_pUserData->m_sItemArray[SLOT_MAX+destpos].sCount = m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sCount;
		}
		if( !pTable->m_bCountable ) {
			m_pUserData->m_sWarehouseArray[reference_pos+srcpos].nNum = 0;
			m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sDuration = 0;
			m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sCount = 0;
			m_pUserData->m_sWarehouseArray[reference_pos+srcpos].nSerialNum = 0;
		}
		else {
			m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sCount -= count;
			if( m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sCount <= 0 ) {
				m_pUserData->m_sWarehouseArray[reference_pos+srcpos].nNum = 0;
				m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sDuration = 0;
				m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sCount = 0;
				m_pUserData->m_sWarehouseArray[reference_pos+srcpos].nSerialNum = 0;
			}
		}

		SendItemWeight();		
		ItemLogToAgent( m_pUserData->m_id, m_pUserData->m_Accountid, ITEM_WAREHOUSE_GET, 0, itemid, count, m_pUserData->m_sItemArray[SLOT_MAX+destpos].sDuration );
		//TRACE("WARE OUTPUT : %s %s %d %d %d %d %d", m_pUserData->m_id, m_pUserData->m_Accountid, ITEM_WAREHOUSE_GET, 0, itemid, count, m_pUserData->m_sItemArray[SLOT_MAX+destpos].sDuration );
		break;
	case WAREHOUSE_MOVE:
		if( reference_pos+srcpos > WAREHOUSE_MAX ) goto fail_return;
		if( m_pUserData->m_sWarehouseArray[reference_pos+srcpos].nNum != itemid ) goto fail_return;
		if( m_pUserData->m_sWarehouseArray[reference_pos+destpos].nNum ) goto fail_return;
		m_pUserData->m_sWarehouseArray[reference_pos+destpos].nNum = itemid;
		m_pUserData->m_sWarehouseArray[reference_pos+destpos].sDuration = m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sDuration;
		m_pUserData->m_sWarehouseArray[reference_pos+destpos].sCount = m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sCount;
		m_pUserData->m_sWarehouseArray[reference_pos+destpos].nSerialNum = m_pUserData->m_sWarehouseArray[reference_pos+srcpos].nSerialNum;

		m_pUserData->m_sWarehouseArray[reference_pos+srcpos].nNum = 0;
		m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sDuration = 0;
		m_pUserData->m_sWarehouseArray[reference_pos+srcpos].sCount = 0;
		m_pUserData->m_sWarehouseArray[reference_pos+srcpos].nSerialNum = 0;
		break;
	case WAREHOUSE_INVENMOVE:
		if( itemid != m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum )
			goto fail_return;
		{
			short duration = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration;
			short itemcount = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount;
			__int64 serial = m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nNum = m_pUserData->m_sItemArray[SLOT_MAX+destpos].nNum;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sDuration = m_pUserData->m_sItemArray[SLOT_MAX+destpos].sDuration;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].sCount = m_pUserData->m_sItemArray[SLOT_MAX+destpos].sCount;
			m_pUserData->m_sItemArray[SLOT_MAX+srcpos].nSerialNum = m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum;

			m_pUserData->m_sItemArray[SLOT_MAX+destpos].nNum = itemid;
			m_pUserData->m_sItemArray[SLOT_MAX+destpos].sDuration = duration;
			m_pUserData->m_sItemArray[SLOT_MAX+destpos].sCount = itemcount;
			m_pUserData->m_sItemArray[SLOT_MAX+destpos].nSerialNum = serial;
		}
		break;
	}

	m_pUserData->m_bWarehouse = 1;

	SetByte( send_buff, WIZ_WAREHOUSE, send_index );
	SetByte( send_buff, command, send_index );
	SetByte( send_buff, 0x01, send_index );
	Send( send_buff, send_index );
	return;
fail_return:
	SetByte( send_buff, WIZ_WAREHOUSE, send_index );
	SetByte( send_buff, command, send_index );
	SetByte( send_buff, 0x00, send_index );
	Send( send_buff, send_index );
}
BYTE CMagicProcess::ExecuteType2(int magicid, int tid, int data1, int data2, int data3)
{
	int damage = 0, send_index = 0, result = 1 ; // Variable initialization. result == 1 : success, 0 : fail
	char send_buff[128]; 
	
	damage = m_pSrcUser->GetDamage(tid, magicid);  // Get damage points of enemy.	
//	if(damage <= 0)	damage = 1;
	//TRACE("magictype2 ,, magicid=%d, damage=%d\n", magicid, damage);
	
	if (damage > 0){
		CNpc* pNpc = NULL ;      // Pointer initialization!
		pNpc = g_pMain->m_arNpc.GetData(tid-NPC_BAND);
		if(pNpc == NULL || pNpc->m_NpcState == NPC_DEAD || pNpc->m_iHP == 0)	{
			result = 0;
			goto packet_send;
		}

		if(pNpc->SetDamage(magicid, damage, m_pSrcUser->m_strUserID, m_pSrcUser->m_iUserId + USER_BAND) == FALSE)	{
			SetByte( send_buff, AG_MAGIC_ATTACK_RESULT, send_index );
			SetByte( send_buff, MAGIC_EFFECTING, send_index );
			SetDWORD( send_buff, magicid, send_index );
			SetShort( send_buff, m_pSrcUser->m_iUserId, send_index );
			SetShort( send_buff, tid, send_index );
			SetShort( send_buff, data1, send_index );	
			SetShort( send_buff, result, send_index );	
			SetShort( send_buff, data3, send_index );	
			SetShort( send_buff, 0, send_index );
			SetShort( send_buff, 0, send_index );
			SetShort( send_buff, 0, send_index );

			if (damage == 0) {
				SetShort( send_buff, -104, send_index );
			}
			else {
				SetShort( send_buff, 0, send_index );
			}

			g_pMain->Send( send_buff, send_index );
			// Npc가 죽은 경우,,
			pNpc->SendExpToUserList(); // 경험치 분배!!
			pNpc->SendDead();
			m_pSrcUser->SendAttackSuccess(tid, MAGIC_ATTACK_TARGET_DEAD, damage, pNpc->m_iHP);
			//m_pSrcUser->SendAttackSuccess(tid, ATTACK_TARGET_DEAD, damage, pNpc->m_iHP);

			return result;
		}
		else	{
			// 공격 결과 전송
			m_pSrcUser->SendAttackSuccess(tid, ATTACK_SUCCESS, damage, pNpc->m_iHP);
		}
	}
//	else
//		result = 0;

packet_send:
	SetByte( send_buff, AG_MAGIC_ATTACK_RESULT, send_index );
	SetByte( send_buff, MAGIC_EFFECTING, send_index );
	SetDWORD( send_buff, magicid, send_index );
	SetShort( send_buff, m_pSrcUser->m_iUserId, send_index );
	SetShort( send_buff, tid, send_index );
	SetShort( send_buff, data1, send_index );	
	SetShort( send_buff, result, send_index );	
	SetShort( send_buff, data3, send_index );	
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );

	if (damage == 0) {
		SetShort( send_buff, -104, send_index );
	}
	else {
		SetShort( send_buff, 0, send_index );
	}

	g_pMain->Send( send_buff, send_index );

	return result;
}
Example #17
0
void CUser::Dead(int tid, int nDamage)
{
	if(m_bLive == USER_DEAD) return;

	// 이 부분에서 update를 해야 함,,  게임서버에서,, 처리하도록,,,
	m_sHP = 0;
	m_bLive = USER_DEAD;

	InitNpcAttack();

	// region에서 삭제...
	MAP* pMap = GetMap();
	if(pMap == NULL)	{
		TRACE("#### CUser-Dead() Fail : [nid=%d, name=%s], pMap == NULL #####\n", m_iUserId, m_strUserID);
		return;
	}
	// map에 region에서 나의 정보 삭제..
	if(m_sRegionX < 0 || m_sRegionZ < 0 || m_sRegionX > pMap->GetXRegionMax() || m_sRegionZ > pMap->GetZRegionMax())	{
		TRACE("#### CUser-Dead() Fail : [nid=%d, name=%s], x1=%d, z1=%d #####\n", m_iUserId, m_strUserID, m_sRegionX, m_sRegionZ);
		return;
	}
	//pMap->m_ppRegion[m_sRegionX][m_sRegionZ].DeleteUser(m_iUserId);
	pMap->RegionUserRemove(m_sRegionX, m_sRegionZ, m_iUserId);
	//TRACE("*** User Dead()-> User(%s, %d)를 Region에 삭제,, region_x=%d, y=%d\n", m_strUserID, m_iUserId, m_sRegionX, m_sRegionZ);

	m_sRegionX = -1;		m_sRegionZ = -1;

	int send_index = 0;
	int sid = -1, targid = -1;
	BYTE type, result;
	char buff[256];
	memset( buff, 0x00, 256 );

	wsprintf(buff, "*** User Dead = %d, %s ***", m_iUserId, m_strUserID);
	TimeTrace(buff);
	//TRACE("*** User Dead = %d, %s ********\n", m_iUserId, m_strUserID);
	memset( buff, 0x00, 256 );

	float rx=0.0f, ry=0.0f, rz=0.0f;

	type = 0x02;
	result = ATTACK_TARGET_DEAD;
	sid = tid;
	targid = m_iUserId+USER_BAND;

	SetByte( buff, AG_ATTACK_RESULT, send_index );
	SetByte( buff, type, send_index );
	SetByte( buff, result, send_index );
	SetShort( buff, sid, send_index );
	SetShort( buff, targid, send_index );
	SetShort( buff, nDamage, send_index );
	SetDWORD( buff, m_sHP, send_index );
	//SetShort( buff, m_sMaxHP, send_index );

	//TRACE("Npc - SendAttackSuccess()-User Dead : [sid=%d, tid=%d, result=%d], damage=%d, hp = %d\n", sid, targid, result, nDamage, m_sHP);

	if(tid > 0)
		SendAll(buff, send_index);   // thread 에서 send

/*	SetByte(buff, AG_DEAD, send_index );
	SetShort(buff, m_iUserId, send_index );
	Setfloat(buff, m_curx, send_index);
	Setfloat(buff, m_curz, send_index);

	SendAll(buff, send_index);   // thread 에서 send	*/
}
void CMagicProcess::ExecuteType4(int magicid, int sid, int tid, int data1, int data2, int data3, int moral )
{
	int damage = 0, send_index = 0, result = 1;     // Variable initialization. result == 1 : success, 0 : fail
	char send_buff[128];

	_MAGIC_TYPE4* pType = NULL;
	CNpc* pNpc = NULL ;      // Pointer initialization!

	if(tid == -1)	{	// 지역 공격
		result = AreaAttack(4, magicid, moral, data1, data2, data3, 0, 0);
		if(result == 0)		goto fail_return;
		else return;
	}

	pNpc = g_pMain->m_arNpc.GetData(tid-NPC_BAND);
	if(pNpc == NULL || pNpc->m_NpcState == NPC_DEAD || pNpc->m_iHP == 0)	{
		result = 0;
		goto fail_return;
	}

	pType = g_pMain->m_Magictype4Array.GetData( magicid );     // Get magic skill table type 4.
	if( !pType ) return;

	//TRACE("magictype4 ,, magicid=%d\n", magicid);

	switch (pType->bBuffType) {	// Depending on which buff-type it is.....
		case 1 :				// HP 올리기..
			break;

		case 2 :				// 방어력 올리기..
			break;

		case 4 :				// 공격력 올리기..
			break;

		case 5 :				// 공격 속도 올리기..
			break;

		case 6 :				// 이동 속도 올리기..
//			if (pNpc->m_MagicType4[pType->bBuffType-1].sDurationTime > 0) {
//				result = 0 ;
//				goto fail_return ;					
//			}
//			else {
				pNpc->m_MagicType4[pType->bBuffType-1].byAmount = pType->bSpeed;
				pNpc->m_MagicType4[pType->bBuffType-1].sDurationTime = pType->sDuration;
				pNpc->m_MagicType4[pType->bBuffType-1].fStartTime = TimeGet();
				pNpc->m_fSpeed_1 = (float)(pNpc->m_fOldSpeed_1 * ((double)pType->bSpeed / 100));
				pNpc->m_fSpeed_2 = (float)(pNpc->m_fOldSpeed_2 * ((double)pType->bSpeed / 100));
				//TRACE("executeType4 ,, speed1=%.2f, %.2f,, type=%d, cur=%.2f, %.2f\n", pNpc->m_fOldSpeed_1, pNpc->m_fOldSpeed_2, pType->bSpeed, pNpc->m_fSpeed_1, pNpc->m_fSpeed_2);
//			}
			break;

		case 7 :				// 능력치 올리기...
			break;

		case 8 :				// 저항력 올리기...
			break;

		case 9 :				// 공격 성공율 및 회피 성공율 올리기..
			break;	

		default :
			result = 0 ;
			goto fail_return;
	}

	SetByte( send_buff, AG_MAGIC_ATTACK_RESULT, send_index );
	SetByte( send_buff, MAGIC_EFFECTING, send_index );
	SetDWORD( send_buff, magicid, send_index );
	SetShort( send_buff, sid, send_index );
	SetShort( send_buff, tid, send_index );
	SetShort( send_buff, data1, send_index );	
	SetShort( send_buff, result, send_index );	
	SetShort( send_buff, data3, send_index );	
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	g_pMain->Send( send_buff, send_index );
	return;

fail_return:
	SetByte( send_buff, AG_MAGIC_ATTACK_RESULT, send_index );
	SetByte( send_buff, MAGIC_FAIL, send_index );
	SetDWORD( send_buff, magicid, send_index );
	SetShort( send_buff, sid, send_index );
	SetShort( send_buff, tid, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	g_pMain->Send( send_buff, send_index );
}
_MAGIC_TABLE* CNpcMagicProcess::IsAvailable(int magicid, int tid, BYTE type )
{
	CUser* pUser = NULL;
	CNpc* pNpc = NULL;
	_MAGIC_TABLE* pTable = NULL;

	int modulator = 0, Class = 0, send_index = 0, moral = 0;

	char send_buff[128];
	if( !m_pSrcNpc ) return FALSE;

	pTable = g_pMain->m_MagictableArray.GetData( magicid );     // Get main magic table.
	if( !pTable ) goto fail_return;            

	if( tid >= 0 && tid < MAX_USER )     // Compare morals between source and target character.       
	{
		pUser = g_pMain->GetUserPtr(tid);
		if( !pUser || pUser->m_bLive == USER_DEAD ) goto fail_return;
		moral = pUser->m_bNation;
	}
	else if( tid >= NPC_BAND )     // Compare morals between source and target NPC.            
	{
		pNpc = g_pMain->m_arNpc.GetData(tid - NPC_BAND);
		if( !pNpc || pNpc->m_NpcState == NPC_DEAD ) goto fail_return;
		moral = pNpc->m_byGroup;
	}
	else if ( tid == -1) {  // Party Moral check routine.
		if (pTable->bMoral == MORAL_AREA_ENEMY) {
			if( m_pSrcNpc->m_byGroup == 0) {	// Switch morals. 작업할것 : 몬스터는 국가라는 개념이 없기 때문에.. 나중에 NPC가 이 마법을 사용하면 문제가 됨
				moral = 2 ;
			}
			else {
				moral = 1 ;
			}
		}
		else {
			moral = m_pSrcNpc->m_byGroup;	
		}
	}
	else moral = m_pSrcNpc->m_byGroup ;
	
	switch( pTable->bMoral ) {	// tid >= 0 case only
	case MORAL_SELF:
		if( tid != (m_pSrcNpc->m_sNid+NPC_BAND) ) goto fail_return;
		break;
	case MORAL_FRIEND_WITHME:
		if( m_pSrcNpc->m_byGroup != moral ) goto fail_return;
		break;
	case MORAL_FRIEND_EXCEPTME:
		if( m_pSrcNpc->m_byGroup != moral ) goto fail_return;
		if( tid == (m_pSrcNpc->m_sNid+NPC_BAND) ) goto fail_return;
		break;
	case MORAL_PARTY:
	case MORAL_PARTY_ALL:
		
		break;
	case MORAL_NPC:
		if( !pNpc ) goto fail_return;
		if( pNpc->m_byGroup != moral ) goto fail_return;
		break;
	case MORAL_ENEMY:
		if( m_pSrcNpc->m_byGroup == moral ) goto fail_return;
		break;
	}

/*	if( type == MAGIC_CASTING )     // Just ordinary spell casting.
	{
		//if( m_bMagicState == CASTING ) goto fail_return;
		//if( pTable->bCastTime == 0 )  goto fail_return;
		m_bMagicState = CASTING;
	}
	else
		if( m_bMagicState == NONE /*&& pTable->bCastTime != 0*/ //) goto fail_return;
	
	if( type == MAGIC_EFFECTING )     // Make sure you subtract MPs (SPs) after you use spell (skill).
	{
		// MP만 달다록 처리한당.. Npc는 SP가 없음..
		//if( pTable->sMsp > m_pSrcNpc->m_sMP )
		//	goto fail_return;
		//m_pSrcNpc->MSpChange(2, -(pTable->sMsp) );
		//m_bMagicState = NONE;
	} 

	return pTable;      // Magic was successful! 

fail_return:    // In case the magic failed. 
	send_index = 0;
	SetByte( send_buff, AG_MAGIC_ATTACK_RESULT, send_index );
	SetByte( send_buff, MAGIC_FAIL, send_index );
	SetDWORD( send_buff, magicid, send_index );
	SetShort( send_buff, m_pSrcNpc->m_sNid+NPC_BAND, send_index );
	SetShort( send_buff, tid, send_index );
	if( type == MAGIC_CASTING )
		SetShort( send_buff, -100, send_index );
	else
		SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );
	SetShort( send_buff, 0, send_index );

/*	if( m_bMagicState == CASTING )
		g_pMain->Send_Region( send_buff, send_index, m_pSrcUser->m_pUserData->m_bZone, m_pSrcUser->m_RegionX, m_pSrcUser->m_RegionZ );
	else m_pSrcUser->Send( send_buff, send_index );	*/

	m_pSrcNpc->SendAll(send_buff, send_index);

	m_bMagicState = NONE;

	return NULL;     // Magic was a failure!
}
Example #20
0
void CUdpSocket::RecvBattleEvent(char *pBuf)
{
	int index = 0, send_index = 0, udp_index = 0;
	int nType = 0, nResult = 0, nLen = 0, nKillKarus = 0, nElmoKill = 0;
	char strMaxUserName[MAX_ID_SIZE+1];	memset( strMaxUserName, 0x00, MAX_ID_SIZE+1 );
	char strKnightsName[MAX_ID_SIZE+1];	memset( strKnightsName, 0x00, MAX_ID_SIZE+1 );
	char chatstr[256]; memset( chatstr, NULL, 1024 );
	char finalstr[1024]; memset( finalstr, NULL, 1024);
	char send_buff[1024]; memset( send_buff, NULL, 1024);

	std::string buff;

	nType = GetByte( pBuf, index );
	nResult = GetByte(pBuf, index);

	if( nType == BATTLE_EVENT_OPEN )	{
	}
	else if( nType == BATTLE_MAP_EVENT_RESULT )	{
		if( m_pMain->m_byBattleOpen == NO_BATTLE )	{
			TRACE("#### UDP RecvBattleEvent Fail : battleopen = %d, type = %d\n", m_pMain->m_byBattleOpen, nType);
			return;
		}
		if( nResult == KARUS )	{
			//TRACE("--> UDP RecvBattleEvent : 카루스 땅으로 넘어갈 수 있어\n");
			m_pMain->m_byKarusOpenFlag = 1;		// 카루스 땅으로 넘어갈 수 있어
		}
		else if( nResult == ELMORAD )	{
			//TRACE("--> UDP  RecvBattleEvent : 엘모 땅으로 넘어갈 수 있어\n");
			m_pMain->m_byElmoradOpenFlag = 1;	// 엘모 땅으로 넘어갈 수 있어
		}
	}
	else if( nType == BATTLE_EVENT_RESULT )	{
		if( m_pMain->m_byBattleOpen == NO_BATTLE )	{
			TRACE("####  UDP  RecvBattleEvent Fail : battleopen = %d, type=%d\n", m_pMain->m_byBattleOpen, nType);
			return;
		}
		if( nResult == KARUS )	{
			//TRACE("-->  UDP RecvBattleEvent : 카루스가 승리하였습니다.\n");
		}
		else if( nResult == ELMORAD )	{
			//TRACE("-->  UDP RecvBattleEvent : 엘모라드가 승리하였습니다.\n");
		}

		m_pMain->m_bVictory = nResult;
		m_pMain->m_byOldVictory = nResult;
		m_pMain->m_byKarusOpenFlag = 0;		// 카루스 땅으로 넘어갈 수 없도록
		m_pMain->m_byElmoradOpenFlag = 0;	// 엘모 땅으로 넘어갈 수 없도록
		m_pMain->m_byBanishFlag = 1;
	}
	else if( nType == BATTLE_EVENT_MAX_USER )	{
		nLen = GetByte(pBuf, index);
		if (!GetKOString(pBuf, strKnightsName, index, MAX_ID_SIZE)
			|| GetKOString(pBuf, strMaxUserName, index, MAX_ID_SIZE))
			return;

		int nResourceID = 0;
		switch (nResult)
		{
		case 1: // captain
			nResourceID = IDS_KILL_CAPTAIN;
			break;
		case 2: // keeper

		case 7: // warders?
		case 8:
			nResourceID = IDS_KILL_GATEKEEPER;
			break;

		case 3: // Karus sentry
			nResourceID = IDS_KILL_KARUS_GUARD1;
			break;
		case 4: // Karus sentry
			nResourceID = IDS_KILL_KARUS_GUARD2;
			break;
		case 5: // El Morad sentry
			nResourceID = IDS_KILL_ELMO_GUARD1;
			break;
		case 6: // El Morad sentry
			nResourceID = IDS_KILL_ELMO_GUARD2;
			break;
		}

		if (nResourceID == 0)
		{
			TRACE("RecvBattleEvent: could not establish resource for result %d", nResult);
			return;
		}

		_snprintf(finalstr, sizeof(finalstr), m_pMain->GetServerResource(nResourceID), strKnightsName, strMaxUserName);

		SetByte( send_buff, WIZ_CHAT, send_index );
		SetByte( send_buff, WAR_SYSTEM_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_All( send_buff, send_index );

		memset( send_buff, NULL, 256 );		send_index = 0;
		SetByte( send_buff, WIZ_CHAT, send_index );
		SetByte( send_buff, PUBLIC_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_All( send_buff, send_index );
	}
	else if( nType == BATTLE_EVENT_KILL_USER )	{
		if( nResult == 1 )	{
			nKillKarus = GetShort( pBuf, index );
			nElmoKill = GetShort( pBuf, index );
			m_pMain->m_sKarusDead = m_pMain->m_sKarusDead + nKillKarus;
			m_pMain->m_sElmoradDead = m_pMain->m_sElmoradDead + nElmoKill;

			//TRACE("-->  UDP RecvBattleEvent type = 1 : 적국 유저 죽인수 : karus=%d->%d, elmo=%d->%d\n", nKillKarus, m_pMain->m_sKarusDead, nElmoKill, m_pMain->m_sElmoradDead);

			SetByte( send_buff, UDP_BATTLE_EVENT_PACKET, send_index );
			SetByte( send_buff, BATTLE_EVENT_KILL_USER, send_index );
			SetByte( send_buff, 2, send_index );						// karus의 정보 전송
			SetShort( send_buff, m_pMain->m_sKarusDead, send_index );
			SetShort( send_buff, m_pMain->m_sElmoradDead, send_index );
			m_pMain->Send_UDP_All( send_buff, send_index );
		}
		else if( nResult == 2 )	{
			nKillKarus = GetShort( pBuf, index );
			nElmoKill = GetShort( pBuf, index );

			//TRACE("-->  UDP RecvBattleEvent type = 2 : 적국 유저 죽인수 : karus=%d->%d, elmo=%d->%d\n", m_pMain->m_sKarusDead, nKillKarus, m_pMain->m_sElmoradDead, nElmoKill);

			m_pMain->m_sKarusDead = nKillKarus;
			m_pMain->m_sElmoradDead = nElmoKill;
		}
	}

}
void CNpcMagicProcess::ExecuteType3(int magicid, int tid, int data1, int data2, int data3, int moral )  // Applied when a magical attack, healing, and mana restoration is done.
{	
	int damage = 0, result = 1, send_index=0, attack_type = 0; 
	char send_buff[256];
	_MAGIC_TYPE3* pType = NULL;
	CNpc* pNpc = NULL ;      // Pointer initialization!
	int dexpoint = 0;

	_MAGIC_TABLE* pMagic = NULL;
	pMagic = g_pMain->m_MagictableArray.GetData( magicid );   // Get main magic table.
	if( !pMagic ) return; 

	if(tid == -1)	{	// 지역 공격,, 몬스터의 지역공격은 게임서버에서 처리한다.. 유저들을 상대로..
		goto packet_send;
	}

	pNpc = g_pMain->m_arNpc.GetData(tid-NPC_BAND);
	if(pNpc == NULL || pNpc->m_NpcState == NPC_DEAD || pNpc->m_iHP == 0)	{
		result = 0;
		goto packet_send;
	}
	
	pType = g_pMain->m_Magictype3Array.GetData( magicid );      // Get magic skill table type 3.
	if( !pType ) return;
	
	damage = GetMagicDamage(tid, pType->sFirstDamage, pType->bAttribute, dexpoint);
//	if(damage == 0)	damage = -1;

	//TRACE("magictype3 ,, magicid=%d, damage=%d\n", magicid, damage);
	
	if (pType->bDuration == 0)    { // Non-Durational Spells.
		if (pType->bDirectType == 1) {    // Health Point related !
			if(damage > 0)	{
				result = pNpc->SetHMagicDamage(damage);
			}
			else	{
				damage = abs(damage);
/*				if(pType->bAttribute == 3)   attack_type = 3; // 기절시키는 마법이라면.....
				else attack_type = magicid;

				if(pNpc->SetDamage(attack_type, damage, m_pSrcUser->m_strUserID, m_pSrcUser->m_iUserId + USER_BAND) == FALSE)	{
					// Npc가 죽은 경우,,
					pNpc->SendExpToUserList(); // 경험치 분배!!
					pNpc->SendDead();
					m_pSrcUser->SendAttackSuccess(tid, MAGIC_ATTACK_TARGET_DEAD, damage, pNpc->m_iHP, MAGIC_ATTACK);
				}
				else	{
					// 공격 결과 전송
					m_pSrcUser->SendAttackSuccess(tid, ATTACK_SUCCESS, damage, pNpc->m_iHP, MAGIC_ATTACK);
				}	*/
			}
		}
	}
	else if (pType->bDuration != 0)   {  // Durational Spells! Remember, durational spells only involve HPs.
	} 

packet_send:
	//if ( pMagic->bType[1] == 0 || pMagic->bType[1] == 3 ) 
	{
		SetByte( send_buff, AG_MAGIC_ATTACK_RESULT, send_index );
		SetByte( send_buff, MAGIC_EFFECTING, send_index );
		SetDWORD( send_buff, magicid, send_index );
		SetShort( send_buff, m_pSrcNpc->m_sNid+NPC_BAND, send_index );
		SetShort( send_buff, tid, send_index );
		SetShort( send_buff, data1, send_index );	
		SetShort( send_buff, result, send_index );	
		SetShort( send_buff, data3, send_index );	
		SetShort( send_buff, moral, send_index );
		SetShort( send_buff, 0, send_index );
		SetShort( send_buff, 0, send_index );
		m_pSrcNpc->SendAll(send_buff, send_index);
	}
}
void CUser::SelectCharacter(char *pBuf)
{
	int index = 0, send_index = 0, zoneindex = -1, retvalue = 0;
	char send_buff[MAX_SEND_SIZE];
	memset(send_buff, NULL, sizeof(send_buff));
	BYTE result, bInit;
	C3DMap* pMap = NULL;
	_ZONE_SERVERINFO *pInfo	= NULL;
	CKnights* pKnights = NULL;

	result = GetByte( pBuf, index );
	bInit = GetByte( pBuf, index );

	if (result == 0 || !getZoneID()) goto fail_return;

	pMap = m_pMap = m_pMain->GetZoneByID(getZoneID());
	if (pMap == NULL)
		goto fail_return;

	if( m_pMain->m_nServerNo != pMap->m_nServerNo ) {
		pInfo = m_pMain->m_ServerArray.GetData( pMap->m_nServerNo );
		if( !pInfo ) 
			goto fail_return;

		SetByte( send_buff, WIZ_SERVER_CHANGE, send_index );
		SetKOString(send_buff, pInfo->strServerIP, send_index);
		SetByte( send_buff, bInit, send_index );
		SetByte( send_buff, m_pUserData->m_bZone, send_index );
		SetByte( send_buff, m_pMain->m_byOldVictory, send_index );
		Send( send_buff, send_index );
		return;
	}

	if( m_pUserData->m_bAuthority == 0xff ) {
		Close();
		return;
	}

	if( m_pMain->m_byBattleOpen == NO_BATTLE && m_pUserData->m_bFame == COMMAND_CAPTAIN )	{
		m_pUserData->m_bFame = CHIEF;
	}

	if(m_pUserData->m_bZone != m_pUserData->m_bNation && m_pUserData->m_bZone < 3 && !m_pMain->m_byBattleOpen) {
		NativeZoneReturn();
		Close();
		return;
	}

	if(m_pUserData->m_bZone == ZONE_BATTLE && ( m_pMain->m_byBattleOpen != NATION_BATTLE) ) {
		NativeZoneReturn();
		Close();
		return;
	}
	if(m_pUserData->m_bZone == ZONE_SNOW_BATTLE && ( m_pMain->m_byBattleOpen != SNOW_BATTLE) ) {
		NativeZoneReturn();
		Close();
		return;
	}
	
	if(m_pUserData->m_bZone == ZONE_FRONTIER && m_pMain->m_byBattleOpen) {
		NativeZoneReturn();
		Close();
		return;
	}
//
	SetLogInInfoToDB(bInit);	// Write User Login Info To DB for Kicking out or Billing

	SetByte( send_buff, WIZ_SEL_CHAR, send_index );
	SetByte( send_buff, result, send_index );
	SetByte( send_buff, getZoneID(), send_index );
	SetShort( send_buff, (WORD)m_pUserData->m_curx*10, send_index );
	SetShort( send_buff, (WORD)m_pUserData->m_curz*10, send_index );
	SetShort( send_buff, (short)m_pUserData->m_cury*10, send_index );
	SetByte( send_buff, m_pMain->m_byOldVictory, send_index );

	m_bSelectedCharacter = true;
	Send( send_buff, send_index );


	SetDetailData();

	//TRACE("SelectCharacter 111 - id=%s, knights=%d, fame=%d\n", m_pUserData->m_id, m_pUserData->m_bKnights, m_pUserData->m_bFame);

	if( m_pUserData->m_bZone > 2)	
	{
		if( m_pUserData->m_bKnights == -1)	{	// ???? ???
			m_pUserData->m_bKnights = 0;
			m_pUserData->m_bFame = 0;
			//TRACE("SelectCharacter - id=%s, knights=%d, fame=%d\n", m_pUserData->m_id, m_pUserData->m_bKnights, m_pUserData->m_bFame);
			return;
		}
		else if( m_pUserData->m_bKnights != 0 )	{
			pKnights = m_pMain->m_KnightsArray.GetData( m_pUserData->m_bKnights );
			if( pKnights )	{
				m_pMain->m_KnightsManager.SetKnightsUser( m_pUserData->m_bKnights, m_pUserData->m_id );
			}
			else	{
				//TRACE("SelectCharacter - ???? ????T ??û,, id=%s, knights=%d, fame=%d\n", m_pUserData->m_id, m_pUserData->m_bKnights, m_pUserData->m_bFame);
				memset( send_buff, 0x00, 256);	send_index = 0;
				SetByte( send_buff, WIZ_KNIGHTS_PROCESS, send_index );
				SetByte( send_buff, KNIGHTS_LIST_REQ+0x10, send_index );
				SetShort( send_buff, GetSocketID(), send_index );
				SetShort( send_buff, m_pUserData->m_bKnights, send_index );
				retvalue = m_pMain->m_LoggerSendQueue.PutData( send_buff, send_index );
				if (retvalue >= SMQ_FULL)
					DEBUG_LOG("KNIGHTS_LIST_REQ Packet Drop!!!");

				pKnights = m_pMain->m_KnightsArray.GetData( m_pUserData->m_bKnights );
				if( pKnights )	{
					//TRACE("SelectCharacter - ???? ????T ???,, id=%s, knights=%d, fame=%d\n", m_pUserData->m_id, m_pUserData->m_bKnights, m_pUserData->m_bFame);
					m_pMain->m_KnightsManager.SetKnightsUser( m_pUserData->m_bKnights, m_pUserData->m_id );
				}
			}
		}
	}
	else	{	
		if( m_pUserData->m_bKnights == -1)	{	// ???? ???
			m_pUserData->m_bKnights = 0;
			m_pUserData->m_bFame = 0;
			//TRACE("SelectCharacter - id=%s, knights=%d, fame=%d\n", m_pUserData->m_id, m_pUserData->m_bKnights, m_pUserData->m_bFame);
			return;
		}
		else if( m_pUserData->m_bKnights != 0 )	{
			pKnights = m_pMain->m_KnightsArray.GetData( m_pUserData->m_bKnights );
			if( pKnights )	{
				m_pMain->m_KnightsManager.SetKnightsUser( m_pUserData->m_bKnights, m_pUserData->m_id );
			}
			else {			// ?????? ?i???? ??????.. 
				m_pUserData->m_bKnights = 0;
				m_pUserData->m_bFame = 0;
			}
		}
	}

	//TRACE("SelectCharacter - id=%s, knights=%d, fame=%d\n", m_pUserData->m_id, m_pUserData->m_bKnights, m_pUserData->m_bFame);
	return;

fail_return:
	SetByte( send_buff, WIZ_SEL_CHAR, send_index );
	SetByte( send_buff, 0x00, send_index );
	Send( send_buff, send_index );
}
void CUser::PartyInsert()	// ?????? ??? ???.  ????? ??Y?? ???°??? ???
{
	int send_index = 0, i = 0;
	CUser* pUser = NULL;
	_PARTY_GROUP* pParty = NULL;
	char send_buff[256]; memset( send_buff, 0x00, 256 );
	if( m_sPartyIndex == -1 ) return;

	pParty = m_pMain->m_PartyArray.GetData( m_sPartyIndex );
	if( !pParty ) {				// ????? ???
		m_sPartyIndex = -1;
		return;
	}
	
	for(int i=0; i<8; i++) {	// Send your info to the rest of the party members.
		if (pParty->uid[i] == GetSocketID())
			continue;

		pUser = m_pMain->GetUserPtr(pParty->uid[i]);
		if (pUser == NULL)
			continue;

		memset( send_buff, 0x00, 256 ); send_index = 0;
		SetByte( send_buff, WIZ_PARTY, send_index );
		SetByte( send_buff, PARTY_INSERT, send_index );
		SetShort( send_buff, pParty->uid[i], send_index );
		SetKOString(send_buff, pUser->m_pUserData->m_id, send_index);
		SetShort( send_buff, pParty->sMaxHp[i], send_index );
		SetShort( send_buff, pParty->sHp[i], send_index );
		SetByte( send_buff, pParty->bLevel[i], send_index );
		SetShort( send_buff, pParty->sClass[i], send_index );
		SetShort( send_buff, pUser->m_iMaxMp, send_index );
		SetShort( send_buff, pUser->m_pUserData->m_sMp, send_index );
		Send( send_buff, send_index );
	}

	for(i=0; i<8; i++ ) {
		if( pParty->uid[i] == -1 ) {
			pParty->uid[i] = m_Sid;
			pParty->sMaxHp[i] = m_iMaxHp;
			pParty->sHp[i] = m_pUserData->m_sHp;
			pParty->bLevel[i] = m_pUserData->m_bLevel;
			pParty->sClass[i] = m_pUserData->m_sClass;
			break;
		}
	}

	pUser = m_pMain->GetUserPtr(pParty->uid[0]);
	if (pUser == NULL)
		return;

	if (pUser->m_bNeedParty == 2 && pUser->m_sPartyIndex != -1) {
		pUser->m_bNeedParty = 1;
		memset( send_buff, 0x00, 256 ); send_index = 0;	
		SetByte(send_buff, 2, send_index);
		SetByte(send_buff, pUser->m_bNeedParty, send_index);
		pUser->StateChange(send_buff);
	}

	if (m_bNeedParty == 2 && m_sPartyIndex != -1) {		
		m_bNeedParty = 1;	
		memset( send_buff, 0x00, 256 ); send_index = 0;	
		SetByte(send_buff, 2, send_index);
		SetByte(send_buff, m_bNeedParty, send_index);
		StateChange(send_buff);
	}

	memset( send_buff, 0x00, 256 ); send_index = 0;
	SetByte( send_buff, WIZ_PARTY, send_index );
	SetByte( send_buff, PARTY_INSERT, send_index );
	SetShort( send_buff, m_Sid, send_index );
	SetKOString( send_buff, m_pUserData->m_id, send_index );
	SetShort( send_buff, m_iMaxHp, send_index );		
	SetShort( send_buff, m_pUserData->m_sHp, send_index );
	SetByte( send_buff, m_pUserData->m_bLevel, send_index );
	SetShort( send_buff, m_pUserData->m_sClass, send_index );
	SetShort( send_buff, m_iMaxMp, send_index );
	SetShort( send_buff, m_pUserData->m_sMp, send_index );
	m_pMain->Send_PartyMember( m_sPartyIndex, send_buff, send_index );

	// AI Server
	BYTE byIndex = i;
	send_index = 0; memset( send_buff, 0x00, 256 );
	SetByte( send_buff, AG_USER_PARTY, send_index );
	SetByte( send_buff, PARTY_INSERT, send_index );
	SetShort( send_buff, pParty->wIndex, send_index );
	SetByte( send_buff, byIndex, send_index );
	SetShort( send_buff, pParty->uid[i], send_index );
	//SetShort( send_buff, pParty->sHp[i], send_index );
	//SetByte( send_buff, pParty->bLevel[i], send_index );
	//SetShort( send_buff, pParty->sClass[i], send_index );
	m_pMain->Send_AIServer(m_pUserData->m_bZone, send_buff, send_index);
}
void CUser::ClassChange(char *pBuf)
{
	int index = 0, classcode = 0, send_index = 0, type=0, sub_type = 0, money = 0, old_money=0;
	char send_buff[128]; memset( send_buff, NULL, 128 );
	BOOL bSuccess = FALSE;

	type = GetByte( pBuf, index );

	if (type == CLASS_CHANGE_REQ)	
	{
		ClassChangeReq();
		return;
	}
	else if (type == ALL_POINT_CHANGE)	
	{
		AllPointChange();
		return;
	}
	else if (type == ALL_SKILLPT_CHANGE)	
	{
		AllSkillPointChange();
		return;
	}
	else if (type == CHANGE_MONEY_REQ)	
	{
		sub_type = GetByte( pBuf, index );

		money = pow(( m_pUserData->m_bLevel * 2 ), 3.4);
		money = ( money / 100 )*100;
		if( m_pUserData->m_bLevel < 30)		money = money * 0.4;
		else if( m_pUserData->m_bLevel >= 30 && m_pUserData->m_bLevel < 60 ) money = money * 1;
		else if( m_pUserData->m_bLevel >= 60 && m_pUserData->m_bLevel <= 90 ) money = money * 1.5;

		if( sub_type == 1 )		{
			if( m_pMain->m_sDiscount == 1 && m_pMain->m_byOldVictory == m_pUserData->m_bNation )		{
				old_money = money;
				money = money * 0.5;
				//TRACE("^^ ClassChange -  point Discount ,, money=%d->%d\n", old_money, money);
			}

			if( m_pMain->m_sDiscount == 2 )		{	
				old_money = money;
				money = money * 0.5;
			}

			SetByte( send_buff, WIZ_CLASS_CHANGE, send_index );
			SetByte( send_buff, CHANGE_MONEY_REQ, send_index );
			SetDWORD( send_buff, money, send_index );
			Send( send_buff, send_index );
		}
		else if( sub_type == 2 )		{	
			money = money * 1.5;			
			if( m_pMain->m_sDiscount == 1 && m_pMain->m_byOldVictory == m_pUserData->m_bNation )		{
				old_money = money;
				money = money * 0.5;
				//TRACE("^^ ClassChange -  skillpoint Discount ,, money=%d->%d\n", old_money, money);
			}

			if( m_pMain->m_sDiscount == 2 )		{	
				old_money = money;
				money = money * 0.5;
			}
			
			SetByte( send_buff, WIZ_CLASS_CHANGE, send_index );
			SetByte( send_buff, CHANGE_MONEY_REQ, send_index );
			SetDWORD( send_buff, money, send_index );
			Send( send_buff, send_index );
		}
		return;
	}

	classcode = GetByte( pBuf, index );

	switch( m_pUserData->m_sClass ) {
	case KARUWARRRIOR:
		if( classcode == BERSERKER || classcode == GUARDIAN )
			bSuccess = TRUE;
		break;
	case KARUROGUE:
		if( classcode == HUNTER || classcode == PENETRATOR )
			bSuccess = TRUE;
		break;
	case KARUWIZARD:
		if( classcode == SORSERER || classcode == NECROMANCER )
			bSuccess = TRUE;
		break;
	case KARUPRIEST:
		if( classcode == SHAMAN || classcode == DARKPRIEST )
			bSuccess = TRUE;
		break;
	case ELMORWARRRIOR:
		if( classcode == BLADE || classcode == PROTECTOR )
			bSuccess = TRUE;
		break;
	case ELMOROGUE:
		if( classcode == RANGER || classcode == ASSASSIN )
			bSuccess = TRUE;
		break;
	case ELMOWIZARD:
		if( classcode == MAGE || classcode == ENCHANTER )
			bSuccess = TRUE;
		break;
	case ELMOPRIEST:
		if( classcode == CLERIC || classcode == DRUID )
			bSuccess = TRUE;
		break;
	}

	memset( send_buff, NULL, 128 );	send_index = 0;
	if( !bSuccess ) {
		SetByte( send_buff, WIZ_CLASS_CHANGE, send_index );
		SetByte( send_buff, CLASS_CHANGE_RESULT, send_index );
		SetByte( send_buff, 0x00, send_index );
		Send( send_buff, send_index );
	}
	else {
		m_pUserData->m_sClass = classcode;
		if( m_sPartyIndex != -1 ) {
			SetByte( send_buff, WIZ_PARTY, send_index );
			SetByte( send_buff, PARTY_CLASSCHANGE, send_index );
			SetShort( send_buff, m_Sid, send_index );
			SetShort( send_buff, m_pUserData->m_sClass, send_index );
			m_pMain->Send_PartyMember(m_sPartyIndex, send_buff, send_index);
		}
	}
}
void CUser::PartyRemove(int memberid)
{
	int index = 0, send_index = 0, count = 0, i = 0;
	CUser* pUser = NULL;
	_PARTY_GROUP* pParty = NULL;

	if (m_sPartyIndex == -1) 
		return;

	pUser = m_pMain->GetUserPtr(memberid);
	if (pUser == NULL)
		return;

	pParty = m_pMain->m_PartyArray.GetData(m_sPartyIndex);
	if (!pParty) 
	{
		pUser->m_sPartyIndex = -1;
		m_sPartyIndex = -1;
		return;
	}

	if (memberid != GetSocketID())
	{		
		if (pParty->uid[0] != GetSocketID()) 
			return;
	}
	else 
	{
		if (pParty->uid[0] == memberid)
		{
			PartyDelete();
			return;
		}
	}

	for( i=0; i<8; i++ ) {
		if( pParty->uid[i] != -1 ) {
			if( pParty->uid[i] == memberid ) {
				count--;
			}
			count++;
		}
	}
	if( count == 1 ) {		// ???? ??? ??? ??? ??? ????
		PartyDelete();
		return;
	}

	char send_buff[256]; memset( send_buff, 0x00, 256 );
	SetByte( send_buff, WIZ_PARTY, send_index );
	SetByte( send_buff, PARTY_REMOVE, send_index );
	SetShort( send_buff, memberid, send_index );
	m_pMain->Send_PartyMember( m_sPartyIndex, send_buff, send_index );	// ????? ???? ??e??????..??w? ???????? ??Y?? ????.

	for( i=0; i<8; i++ ) {			// ????? ???? ??? ???? ??? ????T???? ????.
		if( pParty->uid[i] != -1 ) {
			if( pParty->uid[i] == memberid ) {
				pParty->uid[i] = -1;
				pParty->sHp[i] = 0;
				pParty->bLevel[i] = 0;
				pParty->sClass[i] = 0;
				pUser->m_sPartyIndex = -1;
			}
		}
	}
	// AI Server
	send_index = 0; memset( send_buff, 0x00, 256 );
	SetByte( send_buff, AG_USER_PARTY, send_index );
	SetByte( send_buff, PARTY_REMOVE, send_index );
	SetShort( send_buff, pParty->wIndex, send_index );
	SetShort( send_buff, memberid, send_index );
	m_pMain->Send_AIServer(m_pUserData->m_bZone, send_buff, send_index);
}
void CUser::MarketBBSReport(char *pBuf, BYTE type)
{
	CUser* pUser = NULL;	// Basic Initializations. 	
	int index = 0, send_index = 0;				
	BYTE result = 0; BYTE sub_result = 1; short bbs_len = 0;
	char send_buff[8192]; memset(send_buff, NULL, 8192);

	short page_index = 0; BYTE buysell_index = 0;
	short start_counter = 0; short valid_counter = 0 ;
	int  i = 0, j = 0; short BBS_Counter = 0;

	short title_length = 0;
	short message_length = 0;
	
	buysell_index = GetByte(pBuf, index);	// Buy or sell?
	page_index = GetShort(pBuf, index);		// Which message should I delete? 

	start_counter = page_index * MAX_BBS_PAGE;
	
	if (type == MARKET_BBS_OPEN) {
		start_counter = 0;
		page_index = 0;
	}

	if ( start_counter < 0 ) goto fail_return;
	if ( start_counter > MAX_BBS_POST ) goto fail_return;

	result = 1;

	SetByte(send_buff, WIZ_MARKET_BBS, send_index);
	SetByte(send_buff, type, send_index);
	SetByte(send_buff, buysell_index, send_index);
	SetByte(send_buff, result, send_index);

	for (i = 0 ; i < MAX_BBS_POST ; i++) {
		if (buysell_index == MARKET_BBS_BUY) {
			if (m_pMain->m_sBuyID[i] == -1) continue;

			pUser = m_pMain->GetUserPtr(m_pMain->m_sBuyID[i]);
			if (pUser == NULL)
			{
				MarketBBSBuyDelete(i);
				continue ;	
			}

			BBS_Counter++;		// Increment number of total messages.
				
			if (i < start_counter) continue;	// Range check codes.
			if (valid_counter >= MAX_BBS_PAGE) continue;

			SetShort(send_buff, m_pMain->m_sBuyID[i], send_index);

			SetShort(send_buff, strlen(pUser->m_pUserData->m_id), send_index);	
			SetString(send_buff, pUser->m_pUserData->m_id, strlen(pUser->m_pUserData->m_id), send_index);

			title_length = strlen(m_pMain->m_strBuyTitle[i]);
			if (title_length > MAX_BBS_TITLE) {
				title_length = MAX_BBS_TITLE;
			}

			SetShort(send_buff, title_length, send_index);
			SetString(send_buff, m_pMain->m_strBuyTitle[i], title_length, send_index);
//			SetShort(send_buff, strlen(m_pMain->m_strBuyTitle[i]), send_index);
//			SetString(send_buff, m_pMain->m_strBuyTitle[i], strlen(m_pMain->m_strBuyTitle[i]), send_index);

			message_length = strlen(m_pMain->m_strBuyMessage[i]);
			if (message_length > MAX_BBS_MESSAGE) {
				message_length = MAX_BBS_MESSAGE ;
			}

			SetShort(send_buff, message_length, send_index);
			SetString(send_buff, m_pMain->m_strBuyMessage[i], message_length, send_index);
//			SetShort(send_buff, strlen(m_pMain->m_strBuyMessage[i]), send_index);
//			SetString(send_buff, m_pMain->m_strBuyMessage[i], strlen(m_pMain->m_strBuyMessage[i]), send_index);

			SetDWORD(send_buff, m_pMain->m_iBuyPrice[i], send_index);
			SetShort(send_buff, i, send_index);

			valid_counter++;			
		}
		else if (buysell_index == MARKET_BBS_SELL) {
			if (m_pMain->m_sSellID[i] == -1) continue;

			pUser = m_pMain->GetUserPtr(m_pMain->m_sSellID[i]);
			if (pUser == NULL)
			{
				MarketBBSSellDelete(i);
				continue ;	
			}

			BBS_Counter++;
			
			if (i < start_counter) continue;	// Range check codes.
			if (valid_counter >= MAX_BBS_PAGE) continue;
		
			SetShort(send_buff, m_pMain->m_sSellID[i], send_index);

			SetShort(send_buff, strlen(pUser->m_pUserData->m_id), send_index);	
			SetString(send_buff, pUser->m_pUserData->m_id, strlen(pUser->m_pUserData->m_id), send_index);

			title_length = strlen(m_pMain->m_strSellTitle[i]);
			if (title_length > MAX_BBS_TITLE) {
				title_length = MAX_BBS_TITLE;
			}

			SetShort(send_buff, title_length, send_index);
			SetString(send_buff, m_pMain->m_strSellTitle[i], title_length, send_index);
//			SetShort(send_buff, strlen(m_pMain->m_strSellTitle[i]), send_index);
//			SetString(send_buff, m_pMain->m_strSellTitle[i], strlen(m_pMain->m_strSellTitle[i]), send_index);

			message_length = strlen(m_pMain->m_strSellMessage[i]);
			if (message_length > MAX_BBS_MESSAGE) {
				message_length = MAX_BBS_MESSAGE ;
			}

			SetShort(send_buff, message_length, send_index);
			SetString(send_buff, m_pMain->m_strSellMessage[i], message_length, send_index);
//			SetShort(send_buff, strlen(m_pMain->m_strSellMessage[i]), send_index);
//			SetString(send_buff, m_pMain->m_strSellMessage[i], strlen(m_pMain->m_strSellMessage[i]), send_index);

			SetDWORD(send_buff, m_pMain->m_iSellPrice[i], send_index);
			SetShort(send_buff, i, send_index);

			valid_counter++;	// Increment number of messages on the requested page			
		}	
	}
//
	if (valid_counter == 0 && page_index > 0) {
		goto fail_return1;
	}
//
	if (valid_counter < MAX_BBS_PAGE) {	// You still need to fill up slots.
		for (j = valid_counter ; j < MAX_BBS_PAGE ; j++) {		
			SetShort(send_buff, -1, send_index);
			SetShort(send_buff, 0, send_index);	
			SetString(send_buff, NULL, 0, send_index);
			SetShort(send_buff, 0, send_index);
			SetString(send_buff, NULL, 0, send_index);
			SetShort(send_buff, 0, send_index);
			SetString(send_buff, NULL, 0, send_index);
			SetDWORD(send_buff, 0, send_index);
			SetShort(send_buff, -1, send_index);

			valid_counter++;
		}
	}

	SetShort(send_buff, page_index, send_index);
	SetShort(send_buff, BBS_Counter, send_index);
	Send(send_buff, send_index);
	return;

fail_return:
	send_index = 0; memset(send_buff, NULL, 8192);
	SetByte(send_buff, WIZ_MARKET_BBS, send_index);
	SetByte(send_buff, MARKET_BBS_REPORT, send_index);
	SetByte(send_buff, buysell_index, send_index);
	SetByte(send_buff, result, send_index);
	SetByte(send_buff, sub_result, send_index);
	Send(send_buff, send_index);
	return;

fail_return1:
	send_index = 0; memset(send_buff, NULL, 8192); 	
	SetShort(send_buff, buysell_index, send_index);
	SetShort(send_buff, page_index - 1, send_index);
	MarketBBSReport(send_buff, type);	
	return;
}
void CUser::PartyBBSNeeded(char *pBuf, BYTE type)
{
	CUser* pUser = NULL;	// Basic Initializations. 	
	int index = 0, send_index = 0;				
	BYTE result = 0; short bbs_len = 0;
	char send_buff[256]; memset( send_buff, NULL, 256 );
	short page_index = 0; short start_counter = 0; BYTE valid_counter = 0 ;
	int  i = 0, j = 0; short BBS_Counter = 0;
	
	page_index = GetShort(pBuf, index);
	start_counter = page_index * MAX_BBS_PAGE;

	if ( start_counter < 0 ) goto fail_return;
	if ( start_counter > MAX_USER ) goto fail_return;

	result = 1;

	SetByte(send_buff, WIZ_PARTY_BBS, send_index);
	SetByte(send_buff, type, send_index);
	SetByte(send_buff, result, send_index);

	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;

		BBS_Counter++;

		if (i < start_counter) continue;	// Range check codes.
		if (valid_counter >= MAX_BBS_PAGE) continue;

		SetKOString(send_buff, pUser->m_pUserData->m_id, send_index);
		SetByte(send_buff, pUser->m_pUserData->m_bLevel, send_index);
		SetShort(send_buff, pUser->m_pUserData->m_sClass, send_index);

		valid_counter++;		// Increment counters.
//		BBS_Counter++;		
	}

	if ( valid_counter < MAX_BBS_PAGE ) {	// You still need to fill up ten slots.
		for (j = valid_counter ; j < MAX_BBS_PAGE ; j++) {
			SetShort(send_buff, 0, send_index);
			SetString(send_buff, NULL, 0, send_index);
			SetByte(send_buff, 0, send_index);
			SetShort(send_buff, 0, send_index);
		}
	}

	SetShort(send_buff, page_index, send_index);
	SetShort(send_buff, BBS_Counter, send_index);
	Send(send_buff, send_index);
	return;

fail_return:
	SetByte(send_buff, WIZ_PARTY_BBS, send_index);
	SetByte(send_buff, PARTY_BBS_NEEDED, send_index);
	SetByte(send_buff, result, send_index);
	Send(send_buff, send_index);
	return;		
}
BOOL CUser::GiveItem(int itemid, short count, bool send_packet /*= true*/)
{
	int pos = 255;
	int send_index = 0 ;					
	char send_buff[128];

	_ITEM_TABLE* pTable = NULL;				// This checks if such an item exists.
	pTable = m_pMain->m_ItemtableArray.GetData( itemid );
	if( !pTable ) return FALSE;	
	
	pos = GetEmptySlot( itemid, pTable->m_bCountable );

	if( pos != 0xFF ) {	// Common Item
		if( pos >= HAVE_MAX ) return FALSE;

		if( m_pUserData->m_sItemArray[SLOT_MAX+pos].nNum != 0 ) {	
			if( pTable->m_bCountable != 1) return FALSE;
			else if( m_pUserData->m_sItemArray[SLOT_MAX+pos].nNum != itemid ) return FALSE;
		}
/*	
		if (pTable->m_bCountable) {	// Check weight of countable item.
			if (((pTable->m_sWeight * count) + m_sItemWeight) > m_sMaxWeight) {			
				return FALSE;
			}
		}
		else {	// Check weight of non-countable item.
			if ((pTable->m_sWeight + m_sItemWeight) > m_sMaxWeight) {
				return FALSE;
			}
		}
*/
		m_pUserData->m_sItemArray[SLOT_MAX+pos].nNum = itemid;	// Add item to inventory. 

		if( pTable->m_bCountable) {	// Apply number of items to a countable item.
			m_pUserData->m_sItemArray[SLOT_MAX+pos].sCount += count;
			if( m_pUserData->m_sItemArray[SLOT_MAX+pos].sCount > MAX_ITEM_COUNT ) {
				m_pUserData->m_sItemArray[SLOT_MAX+pos].sCount = MAX_ITEM_COUNT;
			}
		}
		else {		// Just add uncountable item to inventory.
			m_pUserData->m_sItemArray[SLOT_MAX+pos].sCount = 1;
		}
		
		m_pUserData->m_sItemArray[SLOT_MAX+pos].sDuration = pTable->m_sDuration;	// Apply duration to item.
	}
	else {
		return FALSE;	// No empty slots.
	}


	SendItemWeight();	// Change weight first -- do this regardless.
	if (send_packet)
	{
		SetByte( send_buff, WIZ_ITEM_COUNT_CHANGE, send_index );	
		SetShort( send_buff, 0x01, send_index );	// The number of for-loops
		SetByte( send_buff, 0x01, send_index );
		SetByte( send_buff, pos, send_index );
		SetDWORD( send_buff, itemid, send_index );	// The ID of item.
		SetDWORD( send_buff, m_pUserData->m_sItemArray[SLOT_MAX+pos].sCount, send_index );
		Send( send_buff, send_index );
	}
	return TRUE;
}
void CUser::GetUserInfo(char *buff, int & buff_index)
{
	CKnights* pKnights = NULL;

	SetKOString(buff, m_pUserData->m_id, buff_index, 1);
	SetByte(buff, m_pUserData->m_bNation, buff_index);
	SetByte(buff, m_pUserData->m_bCity, buff_index); // probably isn't this, but it'll at least serve as filler if it's not
	SetShort(buff, m_pUserData->m_bKnights, buff_index);
	SetByte(buff, m_pUserData->m_bFame, buff_index);

	pKnights = m_pMain->m_KnightsArray.GetData(m_pUserData->m_bKnights);
	if (pKnights == NULL || m_pUserData->m_bKnights <= 0)
	{
		SetShort(buff, 0, buff_index );
		SetByte(buff, 0, buff_index );
		SetByte(buff, 0, buff_index );
	}
	else 
	{
		SetKOString(buff, pKnights->m_strName, buff_index);
		SetByte(buff, pKnights->m_byGrade, buff_index);  // knights grade
		SetByte(buff, pKnights->m_byRanking, buff_index);  // knights grade
	}	

	SetByte(buff, m_pUserData->m_bLevel, buff_index);
	SetByte(buff, m_pUserData->m_bRace, buff_index);
	SetShort(buff, m_pUserData->m_sClass, buff_index);
	SetShort(buff, (WORD)(m_pUserData->m_curx*10), buff_index);
	SetShort(buff, (WORD)(m_pUserData->m_curz*10), buff_index);
	SetShort(buff, (WORD)(m_pUserData->m_cury*10), buff_index);
	SetByte(buff, m_pUserData->m_bFace, buff_index);

	SetDWORD(buff, m_pUserData->m_nHair, buff_index);

	SetByte(buff, m_bResHpType, buff_index);

	SetDWORD(buff, m_bAbnormalType, buff_index);
	SetByte(buff, m_bNeedParty, buff_index);
	SetByte(buff, m_pUserData->m_bAuthority, buff_index);

	SetDWORD(buff, m_pUserData->m_sItemArray[BREAST].nNum, buff_index);
	SetShort(buff, m_pUserData->m_sItemArray[BREAST].sDuration, buff_index);
	SetDWORD(buff, m_pUserData->m_sItemArray[LEG].nNum, buff_index);
	SetShort(buff, m_pUserData->m_sItemArray[LEG].sDuration, buff_index);
	SetDWORD(buff, m_pUserData->m_sItemArray[HEAD].nNum, buff_index);
	SetShort(buff, m_pUserData->m_sItemArray[HEAD].sDuration, buff_index);
	SetDWORD(buff, m_pUserData->m_sItemArray[GLOVE].nNum, buff_index);
	SetShort(buff, m_pUserData->m_sItemArray[GLOVE].sDuration, buff_index);
	SetDWORD(buff, m_pUserData->m_sItemArray[FOOT].nNum, buff_index);
	SetShort(buff, m_pUserData->m_sItemArray[FOOT].sDuration, buff_index);
	SetDWORD(buff, m_pUserData->m_sItemArray[SHOULDER].nNum, buff_index);
	SetShort(buff, m_pUserData->m_sItemArray[SHOULDER].sDuration, buff_index);
	SetDWORD(buff, m_pUserData->m_sItemArray[RIGHTHAND].nNum, buff_index);
	SetShort(buff, m_pUserData->m_sItemArray[RIGHTHAND].sDuration, buff_index);
	SetDWORD(buff, m_pUserData->m_sItemArray[LEFTHAND].nNum, buff_index);
	SetShort(buff, m_pUserData->m_sItemArray[LEFTHAND].sDuration, buff_index);
}