Exemple #1
0
void CAISocket::RecvNpcMoveResult(Packet & pkt)
{
	uint8 flag;			// 01(INFO_MODIFY), 02(INFO_DELETE)	
	uint16 sNid;
	float fX, fY, fZ, fSecForMetor;
	pkt >> flag >> sNid >> fX >> fZ >> fY >> fSecForMetor;

	CNpc * pNpc = g_pMain->GetNpcPtr(sNid);
	if (pNpc == nullptr)
		return;

	if (pNpc->isDead())
	{
		Packet result(AG_NPC_HP_REQ);
		result << sNid << pNpc->m_iHP;
		Send(&result);
	}

	pNpc->MoveResult(fX, fY, fZ, fSecForMetor);
}
Exemple #2
0
void CAISocket::RecvNpcAttack(Packet & pkt)
{
	CNpc * pAttacker;
	Unit * pTarget;
	uint16 sAttackerID, sTargetID;
	int16 sDamage;
	uint8 bResult = ATTACK_FAIL;

	pkt >> sAttackerID >> sTargetID;

	pAttacker = g_pMain->GetNpcPtr(sAttackerID);
	pTarget = g_pMain->GetUnitPtr(sTargetID);

	if (pAttacker == nullptr
		|| pAttacker->isPlayer()
		|| pTarget == nullptr
		|| pAttacker->isDead()
		|| pTarget->isDead())
		return;

	// TO-DO: Wrap this up into its own virtual method
	sDamage = pAttacker->GetDamage(pTarget);
	if (sDamage > 0)
	{
		pTarget->HpChange(-(sDamage), pAttacker);
		if (pTarget->isDead())
			bResult = ATTACK_TARGET_DEAD;
		else
			bResult = ATTACK_SUCCESS;

		// Every hit takes a little of the defender's armour durability.
		if (pTarget->isPlayer())
			TO_USER(pTarget)->ItemWoreOut(DEFENCE, sDamage);
	}

	Packet result(WIZ_ATTACK, uint8(DIRECT_ATTACK));
	result << bResult << sAttackerID << sTargetID;
	pAttacker->SendToRegion(&result);
}
short CMagicProcess::GetMagicDamage(int tid, int total_hit, int attribute, int dexpoint, int righthand_damage)
{
	short damage = 0, temp_hit = 0 ; 
	int random = 0, total_r = 0 ;
	uint8 result;
	bool bSign = true;

	if( tid < NPC_BAND || tid > INVALID_BAND) return 0;     // Check if target id is valid.

	CNpc* pNpc = g_pMain->m_arNpc.GetData(tid);
	if (pNpc == nullptr || pNpc->isDead()
		|| pNpc->isNonAttackingObject())
		return 0;
	
	//result = m_pSrcUser->GetHitRate(m_pSrcUser->m_fHitrate / pNpc->m_sEvadeRate ); 
	result = SUCCESS;
		
	if (result != FAIL) {		// In case of SUCCESS (and SUCCESS only!) .... 
		switch (attribute) {
			case FIRE_R	:
				total_r = pNpc->m_byFireR;
				break;
			case COLD_R :
				total_r = pNpc->m_byColdR;
				break;
			case LIGHTNING_R :
				total_r = pNpc->m_byLightningR ;
				break;
			case MAGIC_R :
				total_r = pNpc->m_byMagicR ;
				break;
			case DISEASE_R :
				total_r = pNpc->m_byDiseaseR ;
				break;
			case POISON_R :			
				total_r = pNpc->m_byPoisonR ;
				break;
		}	

		total_hit = (total_hit * (dexpoint  + 20)) / 170;

		if(total_hit < 0)	{
			total_hit = abs(total_hit);
			bSign = false;
		}
		
		damage = (short)(total_hit - (0.7f * total_hit * total_r / 200)) ;
		random = myrand (0, damage) ;
		damage = (short)((0.7f * (total_hit - (0.9f * total_hit * total_r / 200))) + 0.2f * random);
//		damage = damage + (3 * righthand_damage);
		damage = damage + righthand_damage;
	}
	else damage = 0 ;

	if (!bSign && damage != 0)	{
		damage = -damage;
	}

	// Apply boost for skills matching weather type.
	// This isn't actually used officially, but I think it's neat...
	GetWeatherDamage(damage, attribute);
		
	//return 1;
	return damage;
}
Exemple #4
0
void CUser::ClientEvent(uint16 sNpcID)
{
	// Ensure AI's loaded
	if (!g_pMain->m_bPointCheckFlag
		|| isDead())
		return;

	int32 iEventID = 0;
	CNpc *pNpc = g_pMain->GetNpcPtr(sNpcID);
	if (pNpc == nullptr
		|| !isInRange(pNpc, MAX_NPC_RANGE))
		return;

	m_sEventNid = sNpcID;
	m_sEventSid = pNpc->GetProtoID(); // For convenience purposes with Lua scripts.

	if (pNpc->GetProtoID() == SAW_BLADE_SSID)
	{
		HpChange(-5000 / 10);
		return;
	}
	else if (pNpc->GetProtoID() == CHAOS_CUBE_SSID && !pNpc->isDead())
	{ 
		uint8 nEventRoomUserCount = g_pMain->TempleEventGetRoomUsers(GetEventRoom());
		uint8 nItemRewardRankFirst = nEventRoomUserCount / 3;
		uint8 nItemRewardRankSecond = (nEventRoomUserCount  - 1) * 2;

		int32 nUserRank = GetPlayerRank(RANK_TYPE_CHAOS_DUNGEON);
		uint32 nItemID = 0;

		if (nUserRank == 0)
			nItemID = ITEM_KILLING_BLADE;
		else if (nUserRank < nItemRewardRankFirst)
			nItemID = ITEM_LIGHT_PIT;
		else if (nUserRank >= nItemRewardRankFirst && nUserRank <= nItemRewardRankSecond)
			nItemID = ITEM_DRAIN_RESTORE;
		else if (nUserRank > nItemRewardRankSecond)
			nItemID = ITEM_KILLING_BLADE;

		GiveItem(nItemID);
		g_pMain->ShowNpcEffect(GetSocketID(),251,GetZoneID());
		g_pMain->KillNpc(sNpcID);
		return;
	}
	else if (pNpc->GetType() == NPC_KISS)
	{
		KissUser();
		return;
	}

	Guard lock(g_pMain->m_questNpcLock);
	QuestNpcList::iterator itr = g_pMain->m_QuestNpcList.find(pNpc->GetProtoID());
	if (itr == g_pMain->m_QuestNpcList.end())
		return;

	QuestHelperList & pList = itr->second;
	_QUEST_HELPER * pHelper = nullptr;
	foreach (itr, pList)
	{
		if ((*itr) == nullptr
			|| (*itr)->sEventDataIndex
			|| (*itr)->bEventStatus
			|| ((*itr)->bNation != 3 && (*itr)->bNation != GetNation())
			|| ((*itr)->bClass != 5 && !JobGroupCheck((*itr)->bClass)))
			continue;

		pHelper = (*itr);
		break;
	}

	if (pHelper == nullptr)
		return;

	QuestV2RunEvent(pHelper, pHelper->nEventTriggerIndex);
}