Esempio n. 1
0
void CUser::HealMagic()
{
    int region_x = (int)(m_curx / VIEW_DIST);
    int region_z = (int)(m_curz / VIEW_DIST);

    MAP* pMap = GetMap();
    if (pMap == nullptr) return;
    int min_x = region_x - 1;
    if(min_x < 0) min_x = 0;
    int min_z = region_z - 1;
    if(min_z < 0) min_z = 0;
    int max_x = region_x + 1;
    if(max_x > pMap->GetXRegionMax()) max_x = pMap->GetXRegionMax();
    int max_z = region_z + 1;
    if(min_z > pMap->GetZRegionMax()) min_z = pMap->GetZRegionMax();

    int search_x = max_x - min_x + 1;
    int search_z = max_z - min_z + 1;

    int i, j;

    for(i = 0; i < search_x; i++)	{
        for(j = 0; j < search_z; j++)	{
            HealAreaCheck( min_x+i, min_z+j );
        }
    }
}
Esempio n. 2
0
short CMagicProcess::AreaAttack(int magictype, int magicid, int moral, int data1, int data2, int data3, int dexpoint, int righthand_damage)
{
	_MAGIC_TYPE3* pType3 = nullptr;
	_MAGIC_TYPE4* pType4 = nullptr;
	int radius = 0; 

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

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

	int region_x = data1 / VIEW_DIST;
	int region_z = data3 / VIEW_DIST;

	MAP* pMap = m_pSrcUser->GetMap();
	if(pMap == nullptr) return 0;

	int min_x = region_x - 1;	if(min_x < 0) min_x = 0;
	int min_z = region_z - 1;	if(min_z < 0) min_z = 0;
	int max_x = region_x + 1;	if(max_x > pMap->GetXRegionMax()) max_x = pMap->GetXRegionMax();
	int max_z = region_z + 1;	if(min_z > pMap->GetZRegionMax()) min_z = pMap->GetZRegionMax();

	int search_x = max_x - min_x + 1;		
	int search_z = max_z - min_z + 1;	
	
	int i, j;

	for(i = 0; i < search_x; i++)	{
		for(j = 0; j < search_z; j++)	{
			AreaAttackDamage(magictype, min_x+i, min_z+j, magicid, moral, data1, data2, data3, dexpoint, righthand_damage);
		}
	}

	//damage = GetMagicDamage(tid, pType->sFirstDamage, pType->bAttribute);

	return 1;
}
Esempio n. 3
0
void CUser::HealAreaCheck(int rx, int rz)
{
	MAP* pMap = GetMap();
	if (pMap == NULL) return;
	// 자신의 region에 있는 NpcArray을 먼저 검색하여,, 가까운 거리에 Monster가 있는지를 판단..
	if(rx < 0 || rz < 0 || rx > pMap->GetXRegionMax() || rz > pMap->GetZRegionMax())	{
		TRACE("#### CUser-HealAreaCheck() Fail : [nid=%d, name=%s], nRX=%d, nRZ=%d #####\n", m_iUserId, m_strUserID, rx, rz);
		return;
	}

	float fRadius = 10.0f;				// 30m

	__Vector3 vStart, vEnd;
	CNpc* pNpc = NULL ;      // Pointer initialization!
	float fDis = 0.0f;
	vStart.Set(m_curx, (float)0, m_curz);
	int send_index=0, result = 1, count = 0; 

	EnterCriticalSection( &g_region_critical );
	CRegion *pRegion = &pMap->m_ppRegion[rx][rz];
	int total_mon = pRegion->m_RegionNpcArray.GetSize();
	int *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_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가 반경안에 있을 경우...
				pNpc->ChangeTarget(1004, this);
			}	
		}
	}

	if (pNpcIDList)
		delete [] pNpcIDList;
}
Esempio n. 4
0
void CUser::Dead(int tid, int nDamage)
{
    if (m_bLive == USER_DEAD)
        return;

    m_sHP = 0;
    m_bLive = USER_DEAD;

    InitNpcAttack();

    MAP* pMap = GetMap();
    if (pMap == nullptr
            || m_sRegionX < 0 || m_sRegionZ < 0
            || m_sRegionX > pMap->GetXRegionMax() || m_sRegionZ > pMap->GetZRegionMax())
        return;

    pMap->RegionUserRemove(m_sRegionX, m_sRegionZ, m_iUserId);

    TRACE("*** User Dead = %d, %s ***\n", m_iUserId, m_strUserID);
    if (tid > 0)
        SendAttackSuccess(m_iUserId+USER_BAND, ATTACK_TARGET_DEAD, nDamage, m_sHP, 1, 2, tid /*sid*/);
}
Esempio n. 5
0
bool CGameSocket::SetUid(float x, float z, int id, int speed)
{
	int x1 = (int)x / TILE_SIZE;
	int z1 = (int)z / TILE_SIZE;
	int nRX = (int)x / VIEW_DIST;
	int nRZ = (int)z / VIEW_DIST;

	CUser* pUser = g_pMain->GetUserPtr(id);
	if(pUser == nullptr) 
	{
		TRACE("#### User등록 실패 sid = %d ####\n", id);
		return false;
	}

	MAP* pMap = pUser->GetMap();
	if (pMap == nullptr)
	{
		TRACE("#### User not in valid zone, sid = %d ####\n", id);
		return false;
	}
	
	if(x1 < 0 || z1 < 0 || x1 >= pMap->GetMapSize() || z1 >= pMap->GetMapSize())
	{
		TRACE("#### GameSocket ,, SetUid Fail : [nid=%d, name=%s], x1=%d, z1=%d #####\n", id, pUser->GetName().c_str(), x1, z1);
		return false;
	}
	if(nRX > pMap->GetXRegionMax() || nRZ > pMap->GetZRegionMax())
	{
		TRACE("#### GameSocket , SetUid Fail : [nid=%d, name=%s], nRX=%d, nRZ=%d #####\n", id, pUser->GetName().c_str(), nRX, nRZ);
		return false;
	}

	// if(pMap->m_pMap[x1][z1].m_sEvent == 0) return false;

	if (pUser != nullptr)
	{
		if (pUser->m_bLive == AI_USER_DEAD || pUser->m_sHP <= 0)
			return false;
		
		///// attack ~ 
		if( speed != 0 )	{
			pUser->m_curx = pUser->m_fWill_x;
			pUser->m_curz = pUser->m_fWill_z;
			pUser->m_fWill_x = x;
			pUser->m_fWill_z = z;
		}
		else	{
			pUser->m_curx = pUser->m_fWill_x = x;
			pUser->m_curz = pUser->m_fWill_z = z;
		}
		/////~ attack 

		if(pUser->m_sRegionX != nRX || pUser->m_sRegionZ != nRZ)
		{
			pMap->RegionUserRemove(pUser->m_sRegionX, pUser->m_sRegionZ, id);
			pUser->m_sRegionX = nRX;		pUser->m_sRegionZ = nRZ;
			pMap->RegionUserAdd(pUser->m_sRegionX, pUser->m_sRegionZ, id);
		}
	}

	// dungeon work
	int room = pMap->IsRoomCheck( x, z );

	return true;
}
Esempio n. 6
0
void CGameSocket::RecvUserInOut(Packet & pkt)
{
	std::string strUserID;
	uint8 bType;
	uint16 uid;
	float fX, fZ;
	pkt.SByte();
	pkt >> bType >> uid >> strUserID >> fX >> fZ;
	if (fX < 0 || fZ < 0)
	{
		TRACE("Error:: RecvUserInOut(),, uid = %d, fX=%.2f, fZ=%.2f\n", uid, fX, fZ);
		return;
	}

	int region_x = 0, region_z=0;
	int x1 = (int)fX / TILE_SIZE;
	int z1 = (int)fZ / TILE_SIZE;
	region_x = (int)fX / VIEW_DIST; 
	region_z = (int)fZ / VIEW_DIST;

	// 수정할것,,, : 지금 존 번호를 0으로 했는데.. 유저의 존 정보의 번호를 읽어야,, 함,,
	MAP* pMap = nullptr;
	CUser* pUser = g_pMain->GetUserPtr(uid);

	if(pUser != nullptr)
	{
	//	TRACE("##### Fail : ^^& RecvUserInOut() [name = %s]. state=%d, hp=%d\n", pUser->GetName().c_str(), pUser->m_bLive, pUser->m_sHP);
		
		if(pUser->m_bLive == AI_USER_DEAD || pUser->m_sHP <= 0)
		{
			if(pUser->m_sHP > 0)
			{
				pUser->m_bLive = true;
				TRACE("##### CGameSocket-RecvUserInOut Fail : UserHeal  [id=%s, bLive=%d, hp=%d], fX=%.2f, fZ=%.2f ######\n", pUser->GetName().c_str(), pUser->m_bLive, pUser->m_sHP, fX, fZ);
			}
			else
			{
				TRACE("##### CGameSocket-RecvUserInOut Fail : UserDead  [id=%s, bLive=%d, hp=%d], fX=%.2f, fZ=%.2f ######\n", pUser->GetName().c_str(), pUser->m_bLive, pUser->m_sHP, fX, fZ);
				// 죽은 유저이므로 게임서버에 죽은 처리를 한다...
				//Send_UserError(uid);
				//return;
			}
		}

		pMap = pUser->GetMap();

		if(pMap == nullptr)
		{
			TRACE("#### Fail : pMap == nullptr ####\n");
			return;
		}

		if(x1 < 0 || z1 < 0 || x1 >= pMap->GetMapSize() || z1 >= pMap->GetMapSize())
		{
			TRACE("#### RecvUserInOut Fail : [name=%s], x1=%d, z1=%d #####\n", pUser->GetName().c_str(), region_x, region_z);
			return;
		}

		//if(pMap->m_pMap[x1][z1].m_sEvent == 0) return;
		if(region_x > pMap->GetXRegionMax() || region_z > pMap->GetZRegionMax())
		{
			TRACE("#### GameSocket-RecvUserInOut() Fail : [name=%s], nRX=%d, nRZ=%d #####\n", pUser->GetName().c_str(), region_x, region_z);
			return;
		}

		pUser->m_curx = pUser->m_fWill_x = fX;
		pUser->m_curz = pUser->m_fWill_z = fZ;

		// leaving a region
		if (bType == 2)	
		{
			pMap->RegionUserRemove(region_x, region_z, uid);
		}
		// entering a region
		else if (pUser->m_sRegionX != region_x || pUser->m_sRegionZ != region_z)	
		{
			pUser->m_sRegionX = region_x;		
			pUser->m_sRegionZ = region_z;

			pMap->RegionUserAdd(region_x, region_z, uid);
		}
	}
}
Esempio n. 7
0
void CGameSocket::RecvUserInOut(Packet & pkt)
{
	std::string strUserID;
	uint8 bType;
	uint16 uid;
	float fX, fZ;
	pkt.SByte();
	pkt >> bType >> uid >> strUserID >> fX >> fZ;
	if (fX < 0 || fZ < 0)
	{
		TRACE("Error:: RecvUserInOut(),, uid = %d, fX=%.2f, fZ=%.2f\n", uid, fX, fZ);
		return;
	}

	int region_x = 0, region_z=0;
	int x1 = (int)fX / TILE_SIZE;
	int z1 = (int)fZ / TILE_SIZE;
	region_x = (int)fX / VIEW_DIST; 
	region_z = (int)fZ / VIEW_DIST;

	MAP* pMap = nullptr;
	CUser* pUser = g_pMain->GetUserPtr(uid);
	if (pUser == nullptr)
		return;

	pMap = pUser->GetMap();
	if (pMap == nullptr)
	{
		TRACE("#### Fail : pMap == nullptr ####\n");
		return;
	}

	if (x1 < 0 || z1 < 0 || x1 >= pMap->GetMapSize() || z1 >= pMap->GetMapSize())
	{
		TRACE("#### RecvUserInOut Fail : [name=%s], x1=%d, z1=%d #####\n", pUser->GetName().c_str(), region_x, region_z);
		return;
	}

	//if (pMap->m_pMap[x1][z1].m_sEvent == 0) return;
	if (region_x > pMap->GetXRegionMax() || region_z > pMap->GetZRegionMax())
	{
		TRACE("#### GameSocket-RecvUserInOut() Fail : [name=%s], nRX=%d, nRZ=%d #####\n", pUser->GetName().c_str(), region_x, region_z);
		return;
	}

	pUser->m_curx = pUser->m_fWill_x = fX;
	pUser->m_curz = pUser->m_fWill_z = fZ;

	// leaving a region
	if (bType == 2)	
	{
		pMap->RegionUserRemove(region_x, region_z, uid);
	}
	// entering a region
	else if (pUser->m_sRegionX != region_x || pUser->m_sRegionZ != region_z)	
	{
		pUser->m_sRegionX = region_x;		
		pUser->m_sRegionZ = region_z;

		pMap->RegionUserAdd(region_x, region_z, uid);
	}
}
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;
	}
}
Esempio n. 9
0
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 == nullptr) 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 = nullptr;
	_MAGIC_TYPE4* pType4 = nullptr;
	_MAGIC_TABLE* pMagic = nullptr;

	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 = nullptr ;      // Pointer initialization!
	float fDis = 0.0f;
	vStart.Set((float)data1, (float)0, (float)data3);
	int count = 0, total_mon = 0, attack_type=0;
	int* pNpcIDList = nullptr;
	bool bResult = true;

	pMap->m_lock.Acquire();
	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;
	pMap->m_lock.Release();

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

		if (pNpc == nullptr || pNpc->m_NpcState == NPC_DEAD)
			continue;

		if( m_pSrcUser->m_bNation == pNpc->m_byGroup ) continue;
		vEnd.Set(pNpc->GetX(), pNpc->GetY(), pNpc->GetZ()); 
		fDis = pNpc->GetDistance(vStart, vEnd);

		if(fDis > fRadius)
			continue;

		if (magictype == 3)
		{
			damage = GetMagicDamage(pNpc->GetID(), target_damage, attribute, dexpoint, righthand_damage);
			TRACE("Area magictype3 ,, magicid=%d, damage=%d\n", magicid, damage);
			if(damage >= 0)	{
				bResult = 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_iUserId + USER_BAND) == false)	{
					m_pSrcUser->SendAttackSuccess(pNpc->GetID(), MAGIC_ATTACK_TARGET_DEAD, damage, pNpc->m_iHP);
				}
				else	{
					m_pSrcUser->SendAttackSuccess(pNpc->GetID(), ATTACK_SUCCESS, damage, pNpc->m_iHP);
				}
			}

			// 패킷 전송.....
			//if ( pMagic->bType[1] == 0 || pMagic->bType[1] == 3 ) 
			{
				Packet result(AG_MAGIC_ATTACK_RESULT, uint8(MAGIC_EFFECTING));
				result	<< magicid << m_pSrcUser->m_iUserId << pNpc->GetID()
						<< uint16(data1) << uint16(bResult) << uint16(data3)
						<< uint16(moral) << uint16(0) << uint16(0);
				g_pMain->Send(&result);
			}
		}
		else if(magictype == 4)	{	// 타잎 4일 경우...
			bResult = true;
			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].tStartTime = UNIXTIME;
						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 :
					bResult = false;
					break;
			}

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

			Packet result(AG_MAGIC_ATTACK_RESULT, uint8(MAGIC_EFFECTING));
			result	<< magicid << m_pSrcUser->m_iUserId << pNpc->GetID()
					<< uint16(data1) << uint16(bResult) << uint16(data3)
					<< uint16(0) << uint16(0) << uint16(0);
			g_pMain->Send(&result);
		}
	}

	if(pNpcIDList)	{
		delete [] pNpcIDList;
		pNpcIDList = nullptr;
	}
}
Esempio n. 10
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	*/
}
Esempio n. 11
0
BOOL CGameSocket::SetUid(float x, float z, int id, int speed)
{
	int x1 = (int)x / TILE_SIZE;
	int z1 = (int)z / TILE_SIZE;
	int nRX = (int)x / VIEW_DIST;
	int nRZ = (int)z / VIEW_DIST;

	CUser* pUser = m_pMain->GetUserPtr(id);
	if(pUser == NULL) 
	{
		TRACE("#### User등록 실패 sid = %d ####\n", id);
		return FALSE;
	}

	MAP* pMap = pUser->GetMap();
	if (pMap == NULL)
	{
		TRACE("#### User not in valid zone, sid = %d ####\n", id);
		return FALSE;
	}
	
	if(x1 < 0 || z1 < 0 || x1 > pMap->m_sizeMap.cx || z1 > pMap->m_sizeMap.cy)
	{
		TRACE("#### GameSocket ,, SetUid Fail : [nid=%d, name=%s], x1=%d, z1=%d #####\n", id, pUser->m_strUserID, x1, z1);
		return FALSE;
	}
	if(nRX > pMap->GetXRegionMax() || nRZ > pMap->GetZRegionMax())
	{
		TRACE("#### GameSocket , SetUid Fail : [nid=%d, name=%s], nRX=%d, nRZ=%d #####\n", id, pUser->m_strUserID, nRX, nRZ);
		return FALSE;
	}
	// map 이동이 불가능이면 User등록 실패..
	// if(pMap->m_pMap[x1][z1].m_sEvent == 0) return FALSE;

	if(pUser != NULL)
	{
		if(pUser->m_bLive == USER_DEAD || pUser->m_sHP <= 0)
		{
			if(pUser->m_sHP > 0)
			{
				pUser->m_bLive = USER_LIVE;
				TRACE("##### CGameSocket-SetUid Fail : User가 Heal된 경우.. [id=%s, bLive=%d, hp=%d] ######\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP);
			}
			else
			{
				TRACE("##### CGameSocket-SetUid Fail : UserDead  [id=%s, bLive=%d, hp=%d] ######\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP);
				//Send_UserError(id);
				return FALSE;
			}
		}
		
		///// attack ~ 
		if( speed != 0 )	{
			pUser->m_curx = pUser->m_fWill_x;
			pUser->m_curz = pUser->m_fWill_z;
			pUser->m_fWill_x = x;
			pUser->m_fWill_z = z;
		}
		else	{
			pUser->m_curx = pUser->m_fWill_x = x;
			pUser->m_curz = pUser->m_fWill_z = z;
		}
		/////~ attack 

		//TRACE("GameSocket : SetUid()--> uid = %d, x=%f, z=%f \n", id, x, z);
		if(pUser->m_sRegionX != nRX || pUser->m_sRegionZ != nRZ)
		{
			//TRACE("*** SetUid()-> User(%s, %d)를 Region에 삭제,, zone=%d, index=%d, region_x=%d, y=%d\n", pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, pUser->m_sRegionX, pUser->m_sRegionZ);
			pMap->RegionUserRemove(pUser->m_sRegionX, pUser->m_sRegionZ, id);
			pUser->m_sRegionX = nRX;		pUser->m_sRegionZ = nRZ;
			pMap->RegionUserAdd(pUser->m_sRegionX, pUser->m_sRegionZ, id);
			//TRACE("*** SetUid()-> User(%s, %d)를 Region에 등록,, zone=%d, index=%d, region_x=%d, y=%d\n", pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, nRX, nRZ);
		}
	}

	// dungeon work
	// if( pUser->m_curZone == 던젼 ) 
	int room = pMap->IsRoomCheck( x, z );

	return TRUE;
}
Esempio n. 12
0
void CGameSocket::RecvUserInOut(char* pBuf)
{
	int index = 0;
	BYTE bType=-1;
	short uid=-1, len=0;
	char strName[MAX_ID_SIZE+1];
	memset(strName, 0x00, MAX_ID_SIZE+1);
	float fX=-1, fZ=-1;

	bType = GetByte( pBuf, index );
	uid = GetShort( pBuf, index );
	len = GetShort( pBuf, index );
	GetString(strName, pBuf, len, index);
	fX = Getfloat(pBuf, index);
	fZ = Getfloat(pBuf, index);

	if(fX < 0 || fZ < 0)
	{
		TRACE("Error:: RecvUserInOut(),, uid = %d, fX=%.2f, fZ=%.2f\n", uid, fX, fZ);
		return;
	}
//	TRACE("RecvUserInOut(),, uid = %d\n", uid);

	int region_x = 0, region_z=0;
	int x1 = (int)fX / TILE_SIZE;
	int z1 = (int)fZ / TILE_SIZE;
	region_x = (int)fX / VIEW_DIST; 
	region_z = (int)fZ / VIEW_DIST;

	// 수정할것,,, : 지금 존 번호를 0으로 했는데.. 유저의 존 정보의 번호를 읽어야,, 함,,
	MAP* pMap = NULL;
	//m_pMain->g_arZone[pUser->m_curZone];

	CUser* pUser = m_pMain->GetUserPtr(uid);

//	TRACE("^^& RecvUserInOut( type=%d )-> User(%s, %d),, zone=%d, index=%d, region_x=%d, y=%d\n", bType, pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, region_x, region_z);

	if(pUser != NULL)
	{
	//	TRACE("##### Fail : ^^& RecvUserInOut() [name = %s]. state=%d, hp=%d\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP);
		BOOL bFlag = FALSE;
		
		if(pUser->m_bLive == USER_DEAD || pUser->m_sHP <= 0)
		{
			if(pUser->m_sHP > 0)
			{
				pUser->m_bLive = TRUE;
				TRACE("##### CGameSocket-RecvUserInOut Fail : UserHeal  [id=%s, bLive=%d, hp=%d], fX=%.2f, fZ=%.2f ######\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP, fX, fZ);
			}
			else
			{
				TRACE("##### CGameSocket-RecvUserInOut Fail : UserDead  [id=%s, bLive=%d, hp=%d], fX=%.2f, fZ=%.2f ######\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP, fX, fZ);
				// 죽은 유저이므로 게임서버에 죽은 처리를 한다...
				//Send_UserError(uid);
				//return;
			}
		}

		pMap = pUser->GetMap();

		if(pMap == NULL)
		{
			TRACE("#### Fail : pMap == NULL ####\n");
			return;
		}

		if(x1 < 0 || z1 < 0 || x1 > pMap->m_sizeMap.cx || z1 > pMap->m_sizeMap.cy)
		{
			TRACE("#### RecvUserInOut Fail : [name=%s], x1=%d, z1=%d #####\n", pUser->m_strUserID, region_x, region_z);
			return;
		}
		// map 이동이 불가능이면 User등록 실패..
		//if(pMap->m_pMap[x1][z1].m_sEvent == 0) return;
		if(region_x > pMap->GetXRegionMax() || region_z > pMap->GetZRegionMax())
		{
			TRACE("#### GameSocket-RecvUserInOut() Fail : [name=%s], nRX=%d, nRZ=%d #####\n", pUser->m_strUserID, region_x, region_z);
			return;
		}

		//strcpy(pUser->m_strUserID, strName);
		pUser->m_curx = pUser->m_fWill_x = fX;
		pUser->m_curz = pUser->m_fWill_z = fZ;

		//bFlag = pUser->IsOpIDCheck(strName);
		//if(bFlag)	pUser->m_byIsOP = 1;

		if(bType == 2)	{		// region out
			// 기존의 region정보에서 User의 정보 삭제..
			pMap->RegionUserRemove(region_x, region_z, uid);
			//TRACE("^^& RecvUserInOut()-> User(%s, %d)를 Region에서 삭제..,, zone=%d, index=%d, region_x=%d, y=%d\n", pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, region_x, region_z);
		}
		else	{				// region in
			if(pUser->m_sRegionX != region_x || pUser->m_sRegionZ != region_z)	{
				pUser->m_sRegionX = region_x;		pUser->m_sRegionZ = region_z;
				pMap->RegionUserAdd(region_x, region_z, uid);
				//TRACE("^^& RecvUserInOut()-> User(%s, %d)를 Region에 등록,, zone=%d, index=%d, region_x=%d, y=%d\n", pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, region_x, region_z);
			}
		}
	}
}
Esempio n. 13
0
void CGameSocket::RecvUserInOut(Packet & pkt)
{
	std::string strUserID;
	uint8 bType;
	uint16 uid;
	float fX, fZ;
	pkt.SByte();
	pkt >> bType >> uid >> strUserID >> fX >> fZ;
	if (fX < 0 || fZ < 0)
	{
		TRACE("Error:: RecvUserInOut(),, uid = %d, fX=%.2f, fZ=%.2f\n", uid, fX, fZ);
		return;
	}

	int region_x = 0, region_z=0;
	int x1 = (int)fX / TILE_SIZE;
	int z1 = (int)fZ / TILE_SIZE;
	region_x = (int)fX / VIEW_DIST; 
	region_z = (int)fZ / VIEW_DIST;

	// 수정할것,,, : 지금 존 번호를 0으로 했는데.. 유저의 존 정보의 번호를 읽어야,, 함,,
	MAP* pMap = NULL;
	//g_pMain->g_arZone[pUser->m_curZone];

	CUser* pUser = g_pMain->GetUserPtr(uid);

//	TRACE("^^& RecvUserInOut( type=%d )-> User(%s, %d),, zone=%d, index=%d, region_x=%d, y=%d\n", bType, pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, region_x, region_z);

	if(pUser != NULL)
	{
	//	TRACE("##### Fail : ^^& RecvUserInOut() [name = %s]. state=%d, hp=%d\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP);
		BOOL bFlag = FALSE;
		
		if(pUser->m_bLive == USER_DEAD || pUser->m_sHP <= 0)
		{
			if(pUser->m_sHP > 0)
			{
				pUser->m_bLive = TRUE;
				TRACE("##### CGameSocket-RecvUserInOut Fail : UserHeal  [id=%s, bLive=%d, hp=%d], fX=%.2f, fZ=%.2f ######\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP, fX, fZ);
			}
			else
			{
				TRACE("##### CGameSocket-RecvUserInOut Fail : UserDead  [id=%s, bLive=%d, hp=%d], fX=%.2f, fZ=%.2f ######\n", pUser->m_strUserID, pUser->m_bLive, pUser->m_sHP, fX, fZ);
				// 죽은 유저이므로 게임서버에 죽은 처리를 한다...
				//Send_UserError(uid);
				//return;
			}
		}

		pMap = pUser->GetMap();

		if(pMap == NULL)
		{
			TRACE("#### Fail : pMap == NULL ####\n");
			return;
		}

		if(x1 < 0 || z1 < 0 || x1 > pMap->m_sizeMap.cx || z1 > pMap->m_sizeMap.cy)
		{
			TRACE("#### RecvUserInOut Fail : [name=%s], x1=%d, z1=%d #####\n", pUser->m_strUserID, region_x, region_z);
			return;
		}
		// map 이동이 불가능이면 User등록 실패..
		//if(pMap->m_pMap[x1][z1].m_sEvent == 0) return;
		if(region_x > pMap->GetXRegionMax() || region_z > pMap->GetZRegionMax())
		{
			TRACE("#### GameSocket-RecvUserInOut() Fail : [name=%s], nRX=%d, nRZ=%d #####\n", pUser->m_strUserID, region_x, region_z);
			return;
		}

		//strcpy(pUser->m_strUserID, strName);
		pUser->m_curx = pUser->m_fWill_x = fX;
		pUser->m_curz = pUser->m_fWill_z = fZ;

		if(bType == 2)	{		// region out
			// 기존의 region정보에서 User의 정보 삭제..
			pMap->RegionUserRemove(region_x, region_z, uid);
			//TRACE("^^& RecvUserInOut()-> User(%s, %d)를 Region에서 삭제..,, zone=%d, index=%d, region_x=%d, y=%d\n", pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, region_x, region_z);
		}
		else	{				// region in
			if(pUser->m_sRegionX != region_x || pUser->m_sRegionZ != region_z)	{
				pUser->m_sRegionX = region_x;		pUser->m_sRegionZ = region_z;
				pMap->RegionUserAdd(region_x, region_z, uid);
				//TRACE("^^& RecvUserInOut()-> User(%s, %d)를 Region에 등록,, zone=%d, index=%d, region_x=%d, y=%d\n", pUser->m_strUserID, pUser->m_iUserId, pUser->m_curZone, pUser->m_sZoneIndex, region_x, region_z);
			}
		}
	}
}