Ejemplo n.º 1
0
void CMagicProcess::CheckExpiredType6Skills(Unit * pTarget)
{
	if (!pTarget->isPlayer()
		|| !TO_USER(pTarget)->isTransformed()
		|| (UNIXTIME - TO_USER(pTarget)->m_tTransformationStartTime) < TO_USER(pTarget)->m_sTransformationDuration)
		return;

	MagicInstance instance;
	instance.pSkillCaster = pTarget;
	instance.Type6Cancel();
}
Ejemplo n.º 2
0
/**
* @brief        Changes an NPC's hitpoints.
*
* @param        amount           The amount to adjust the HP by.
* @param        pAttacker        The attacker.
* @param        bSendToAI        true to update the AI server.
*/
void CNpc::HpChange(int amount, Unit *pAttacker /*= nullptr*/, bool bSendToAI /*= true*/) 
{
        uint16 tid = (pAttacker != nullptr ? pAttacker->GetID() : -1);

        // Implement damage/HP cap.
        if (amount < -MAX_DAMAGE)
                amount = -MAX_DAMAGE;
        else if (amount > MAX_DAMAGE)
                amount = MAX_DAMAGE;

        // Glorious copypasta.
        if (amount < 0 && -amount > m_iHP)
                m_iHP = 0;
        else if (amount >= 0 && m_iHP + amount > m_iMaxHP)
                m_iHP = m_iMaxHP;
        else
                m_iHP += amount;

        // NOTE: This will handle the death notification/looting.
        if (bSendToAI)
                SendHpChangeToAI(tid, amount);

        if (pAttacker != nullptr
                && pAttacker->isPlayer())
                TO_USER(pAttacker)->SendTargetHP(0, GetID(), amount);
}
Ejemplo n.º 3
0
short Unit::GetACDamage(int damage, Unit *pTarget)
{
	// This isn't applicable to NPCs.
	if (isNPC() || pTarget->isNPC())
		return damage;

#ifdef EBENEZER
	if (pTarget->isDead())
		return 0;

	CUser * pUser  = TO_USER(this);
	uint8 weaponSlots[] = { RIGHTHAND, LEFTHAND };

	foreach_array (slot, weaponSlots)
	{
		_ITEM_TABLE * pWeapon = pUser->GetItemPrototype(slot);
		if (pWeapon == nullptr)
			continue;

		if (pWeapon->isDagger())
			damage -= damage * pTarget->m_sDaggerR / 200;
		else if (pWeapon->isSword())
			damage -= damage * pTarget->m_sSwordR / 200;
		else if (pWeapon->isAxe())
			damage -= damage * pTarget->m_sAxeR / 200;
		else if (pWeapon->isMace())
			damage -= damage * pTarget->m_sMaceR / 200;
		else if (pWeapon->isSpear())
			damage -= damage * pTarget->m_sSpearR / 200;
		else if (pWeapon->isBow())
			damage -= damage * pTarget->m_sBowR / 200;
	}
Ejemplo n.º 4
0
/**
* @brief	Executes the death process.
*
* @param	pKiller	The killer.
*/
void CNpc::OnDeathProcess(Unit *pKiller)
{
	CUser * pUser = TO_USER(pKiller);

	if (TO_NPC(this) != nullptr && pUser != nullptr)
	{
		if (pUser->isPlayer())
		{
			if (!m_bMonster)
			{
				switch (m_tNpcType)
				{
				case NPC_BIFROST_MONUMENT:
					pUser->BifrostProcess(pUser);
					break;
				case NPC_PVP_MONUMENT:
					PVPMonumentProcess(pUser);
					break;
				case NPC_BATTLE_MONUMENT:
					BattleMonumentProcess(pUser);
					break;
				case NPC_HUMAN_MONUMENT:
					NationMonumentProcess(pUser);
					break;
				case NPC_KARUS_MONUMENT:
					NationMonumentProcess(pUser);
					break;
				case NPC_CHAOS_STONE:
			         {
			         	if (pUser == nullptr)
			         	return ;
			         	if (pUser->isInPKZone())
			         	ChaosStoneProcess(pUser,5);
			         }
			               break;
				   
				   }
					
				}
			}
			else if (m_bMonster)
			{
				if (m_sSid == 700 || m_sSid == 750)
				{
					if (pUser->CheckExistEvent(STARTER_SEED_QUEST, 1))
						pUser->SaveEvent(STARTER_SEED_QUEST, 2);
				}
				else if (g_pMain->m_MonsterRespawnListArray.GetData(m_sSid) != nullptr) {
					if (pUser->isInPKZone() || GetZoneID() == ZONE_JURAD_MOUNTAIN)
						g_pMain->SpawnEventNpc(g_pMain->m_MonsterRespawnListArray.GetData(m_sSid)->sSid, true, GetZoneID(), GetX(), GetY(), GetZ(), g_pMain->m_MonsterRespawnListArray.GetData(m_sSid)->sCount);
				} else if (m_tNpcType == NPC_CHAOS_STONE && pUser->isInPKZone()) {
					ChaosStoneProcess(pUser,5);
				}
			}

			DateTime time;
			g_pMain->WriteDeathUserLogFile(string_format("[ %s - %d:%d:%d ] Killer=%s,SID=%d,Target=%s,Zone=%d,X=%d,Z=%d\n",m_bMonster ? "MONSTER" : "NPC",time.GetHour(),time.GetMinute(),time.GetSecond(),pKiller->GetName().c_str(),m_sSid,GetName().c_str(),GetZoneID(),uint16(GetX()),uint16(GetZ())));
		}
	}
Ejemplo n.º 5
0
void CMagicProcess::MagicPacket(Packet & pkt, Unit * pCaster /*= nullptr*/)
{
	MagicInstance instance;
	pkt >> instance.bOpcode >> instance.nSkillID;

	instance.pSkill = g_pMain->m_MagictableArray.GetData(instance.nSkillID);
	if (instance.pSkill == nullptr)
	{
		if (pCaster != nullptr)
			TRACE("[%s] Used skill %d but it does not exist.\n", pCaster->GetName().c_str(), instance.nSkillID);

		return;
	}

	pkt >> instance.sCasterID >> instance.sTargetID
		>> instance.sData[0] >> instance.sData[1] >> instance.sData[2] >> instance.sData[3]
	>> instance.sData[4] >> instance.sData[5] >> instance.sData[6];

	// Prevent users from faking other players or NPCs.
	if (pCaster != nullptr // if it's nullptr, it's from AI.
		&& (instance.sCasterID >= NPC_BAND 
		|| instance.sCasterID != pCaster->GetID()))
		return;

	if (instance.bSendSkillFailed)
		instance.bSendSkillFailed = false;

	CUser * pUser = TO_USER(pCaster);

	if (pUser != nullptr) {
		if (pUser->isPlayer()) {
			if (instance.nSkillID < 400000) {
				if (pUser->m_LastSkillID != instance.nSkillID) {
					if (instance.pSkill->bType[0] == pUser->m_LastSkillType || instance.pSkill->bType[1] == pUser->m_LastSkillType)
					{
						if ((UNIXTIME - pUser->m_LastSkillUseTime) <= PLAYER_SKILL_REQUEST_INTERVAL) {
							instance.bSendSkillFailed = true;
						}
					}
				} else if (pUser->m_LastSkillID == instance.nSkillID) {
					if (instance.pSkill->sReCastTime != 0)
					{
						if ((UNIXTIME - pUser->m_LastSkillUseTime) * 1000 <= (instance.pSkill->sReCastTime * 100)) {
							instance.bSendSkillFailed = true;
						}
					}
				}
			}
		}
	}

	instance.bIsRecastingSavedMagic = false;
	instance.Run();
}
Ejemplo n.º 6
0
/**
* @brief	Executes the death process.
*
* @param	pKiller	The killer.
*/
void CNpc::OnDeathProcess(Unit *pKiller)
{
	CUser * pUser = TO_USER(pKiller);

	if (TO_NPC(this) != nullptr && pUser != nullptr)
	{
		if (pUser->isPlayer())
		{
			if (!m_bMonster)
			{
				switch (m_tNpcType)
				{
				case NPC_BIFROST_MONUMENT:
					pUser->BifrostProcess(pUser);
					break;
				case NPC_PVP_MONUMENT:
					PVPMonumentProcess(pUser);
					break;
				case NPC_BATTLE_MONUMENT:
					BattleMonumentProcess(pUser);
					break;
				case NPC_HUMAN_MONUMENT:
					NationMonumentProcess(pUser);
					break;
				case NPC_KARUS_MONUMENT:
					NationMonumentProcess(pUser);
					break;
				}
			}
			else if (m_bMonster)
			{
				if (m_sSid == 700 || m_sSid == 750)
				{
					if (pUser->CheckExistEvent(STARTER_SEED_QUEST, 1))
						pUser->SaveEvent(STARTER_SEED_QUEST, 2);
				}
				else if (g_pMain->m_MonsterRespawnListArray.GetData(m_sSid) != nullptr) {
					if (pUser->isInPKZone() || GetZoneID() == ZONE_JURAD_MOUNTAIN)
						g_pMain->SpawnEventNpc(g_pMain->m_MonsterRespawnListArray.GetData(m_sSid)->sSid, true, GetZoneID(), GetX(), GetY(), GetZ(), g_pMain->m_MonsterRespawnListArray.GetData(m_sSid)->sCount);
				} else if (m_tNpcType == NPC_CHAOS_STONE && pUser->isInPKZone()) {
					ChaosStoneProcess(pUser,5);
				}
			}
		}
	}
}
Ejemplo n.º 7
0
/**
 * @brief	Changes an NPC's hitpoints.
 *
 * @param	amount   	The amount to adjust the HP by.
 * @param	pAttacker	The attacker.
 * @param	bSendToAI	true to update the AI server.
 */
void CNpc::HpChange(int amount, Unit *pAttacker /*= nullptr*/, bool bSendToAI /*= true*/) 
{
	// Glorious copypasta.
	if (amount < 0 && -amount > m_iHP)
		m_iHP = 0;
	else if (amount >= 0 && m_iHP + amount > m_iMaxHP)
		m_iHP = m_iMaxHP;
	else
		m_iHP += amount;

	if (bSendToAI)
	{
		// NOTE: This will handle the death notification/looting.
		Packet result(AG_NPC_HP_CHANGE);
		result << GetID() << pAttacker->GetID() << m_iHP << amount;
		Send_AIServer(&result);
	}

	if (pAttacker != nullptr
		&& pAttacker->isPlayer())
		TO_USER(pAttacker)->SendTargetHP(0, GetID(), amount);
}
Ejemplo n.º 8
0
void CMagicProcess::MagicPacket(Packet & pkt, Unit * pCaster /*= nullptr*/)
{
	if (g_pMain->m_IsMagicTableInUpdateProcess)
		return;

	MagicInstance instance;
	pkt >> instance.bOpcode >> instance.nSkillID;

	instance.pSkill = g_pMain->m_MagictableArray.GetData(instance.nSkillID);
	if (instance.pSkill == nullptr)
	{
		if (pCaster != nullptr)
			TRACE("[%s] Used skill %d but it does not exist.\n", pCaster->GetName().c_str(), instance.nSkillID);

		if (pCaster->isPlayer() && instance.nSkillID < 0)
		{
			DateTime time;
			g_pMain->SendFormattedNotice("%s is currently disconnect for skill hack.",Nation::ALL, pCaster->GetName().c_str());
			g_pMain->WriteCheatLogFile(string_format("[ SkillHack - %d:%d:%d ] %s Disconnected for SkillHack.\n", time.GetHour(),time.GetMinute(),time.GetSecond(), pCaster->GetName().c_str()));
			TO_USER(pCaster)->Disconnect();
		}

		return;
	}

	pkt >> instance.sCasterID >> instance.sTargetID
		>> instance.sData[0] >> instance.sData[1] >> instance.sData[2] >> instance.sData[3]
	>> instance.sData[4] >> instance.sData[5] >> instance.sData[6];

	// Prevent users from faking other players or NPCs.
	if (pCaster != nullptr // if it's nullptr, it's from AI.
		&& (instance.sCasterID >= NPC_BAND 
		|| instance.sCasterID != pCaster->GetID()))
		return;

	instance.bIsRecastingSavedMagic = false;
	instance.Run();
}
Ejemplo n.º 9
0
/**
* @brief	Executes the death action.
*
* @param	pKiller	The killer.
*/
void CNpc::OnDeath(Unit *pKiller)
{
	if (m_NpcState == NPC_DEAD)
		return;

	ASSERT(GetMap() != nullptr);
	ASSERT(GetRegion() != nullptr);

	m_NpcState = NPC_DEAD;

	if (m_byObjectType == SPECIAL_OBJECT)
	{
		_OBJECT_EVENT *pEvent = GetMap()->GetObjectEvent(GetProtoID());
		if (pEvent != nullptr)
			pEvent->byLife = 0;
	}

	Unit::OnDeath(pKiller);

	CNpc * pNpc = TO_NPC(this);
	CUser * pUser = TO_USER(pKiller);

	if (pNpc != nullptr && pUser != nullptr)
	{
		if (pNpc->isMonster() && pUser->isPlayer())
		{
			if (pNpc->m_sSid == 700 || pNpc->m_sSid == 750)
			{
				if (pUser->CheckExistEvent(STARTER_SEED_QUEST, 0) || pUser->CheckExistEvent(STARTER_SEED_QUEST, 1))
					pUser->SaveEvent(STARTER_SEED_QUEST, 2);
			}
		}
	}

	GetRegion()->Remove(TO_NPC(this));
	SetRegion();
}
Ejemplo n.º 10
0
void CMagicProcess::MagicPacket(Packet & pkt, Unit * pCaster /*= nullptr*/)
{
	bool bSkillTestMode = false;

	if (bSkillTestMode)
	{
		if (pCaster->isPlayer())
			if (!TO_USER(pCaster)->isGM())
				return;
	}

	MagicInstance instance;
	pkt >> instance.bOpcode >> instance.nSkillID;

	instance.pSkill = g_pMain->m_MagictableArray.GetData(instance.nSkillID);
	if (instance.pSkill == nullptr)
	{
		if (pCaster != nullptr)
			TRACE("[%s] Used skill %d but it does not exist.\n", pCaster->GetName().c_str(), instance.nSkillID);

		return;
	}

	pkt >> instance.sCasterID >> instance.sTargetID
		>> instance.sData[0] >> instance.sData[1] >> instance.sData[2] >> instance.sData[3]
	>> instance.sData[4] >> instance.sData[5] >> instance.sData[6];

	// Prevent users from faking other players or NPCs.
	if (pCaster != nullptr // if it's nullptr, it's from AI.
		&& (instance.sCasterID >= NPC_BAND 
		|| instance.sCasterID != pCaster->GetID()))
		return;

	instance.bIsRecastingSavedMagic = false;
	instance.Run();
}
Ejemplo n.º 11
0
bool CMagicProcess::RemoveType4Buff(uint8 byBuffType, Unit *pTarget)
{
	// Buff must be added at this point. If it doesn't exist, we can't remove it twice.
	FastGuard lock(pTarget->m_buffLock);
	auto itr = pTarget->m_buffMap.find(byBuffType);
	if (itr == pTarget->m_buffMap.end())
		return false;

	_MAGIC_TABLE * pSkill = g_pMain->m_MagictableArray.GetData(itr->second.m_nSkillID);
	if (pSkill == nullptr)
		return false;

	_MAGIC_TYPE4 * pType = g_pMain->m_Magictype4Array.GetData(pSkill->iNum);
	if (pType == nullptr)
		return false;

	// If this buff persists across logout, it should be removed here too.
	if (pTarget->isPlayer()
		&& pTarget->HasSavedMagic(pSkill->iNum))
		TO_USER(pTarget)->RemoveSavedMagic(pSkill->iNum);


	if (itr->second.isBuff())
		pTarget->m_buffCount--;

	pTarget->m_buffMap.erase(itr);

	switch (byBuffType)
	{
	case BUFF_TYPE_HP_MP:
		pTarget->m_sMaxHPAmount = 0;
		pTarget->m_sMaxMPAmount = 0;
		break;

	case BUFF_TYPE_AC:
	case BUFF_TYPE_WEAPON_AC:
		if (pType->sAC == 0 && pType->sACPct > 0)
			pTarget->m_sACPercent -= (pType->sACPct - 100);
		else
			pTarget->m_sACAmount -= pType->sAC;
		break;

	case BUFF_TYPE_SIZE:
		pTarget->StateChangeServerDirect(3, ABNORMAL_NORMAL);
		break;

	case BUFF_TYPE_DAMAGE:
		pTarget->m_bAttackAmount = 100;
		break;

	case BUFF_TYPE_ATTACK_SPEED:
		pTarget->m_sAttackSpeedAmount -= (pType->bAttackSpeed - 100);
		break;

	case BUFF_TYPE_SPEED:
		pTarget->m_bSpeedAmount = 100;
		break;

	case BUFF_TYPE_STATS:
		if (pTarget->isPlayer())
		{
			TO_USER(pTarget)->SetStatBuff(STAT_STR, 0);
			TO_USER(pTarget)->SetStatBuff(STAT_STA, 0);
			TO_USER(pTarget)->SetStatBuff(STAT_DEX, 0);
			TO_USER(pTarget)->SetStatBuff(STAT_INT, 0);
			TO_USER(pTarget)->SetStatBuff(STAT_CHA, 0);	
		}
		break;

	case BUFF_TYPE_RESISTANCES:
		pTarget->m_bFireRAmount = 0;
		pTarget->m_bColdRAmount = 0;
		pTarget->m_bLightningRAmount = 0;
		pTarget->m_bMagicRAmount = 0;
		pTarget->m_bDiseaseRAmount = 0;
		pTarget->m_bPoisonRAmount = 0;
		break;

	case BUFF_TYPE_ACCURACY:
		pTarget->m_bHitRateAmount = 100;
		pTarget->m_sAvoidRateAmount = 100;
		break;	

	case BUFF_TYPE_MAGIC_POWER:
		pTarget->m_sMagicAttackAmount = 0;
		break;

	case BUFF_TYPE_EXPERIENCE:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_sExpGainAmount = 100;
		break;

	case BUFF_TYPE_WEIGHT:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bMaxWeightAmount = 100;
		break;

	case BUFF_TYPE_WEAPON_DAMAGE:
		// uses pType->Attack
		break;

	case BUFF_TYPE_LOYALTY:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bNPGainAmount = 100;
		break;

	case BUFF_TYPE_NOAH_BONUS:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bNoahGainAmount = 100;
		break;

	case BUFF_TYPE_PREMIUM_MERCHANT:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bPremiumMerchant = false;
		break;

	case BUFF_TYPE_ATTACK_SPEED_ARMOR:
		// NOTE: This officially uses the Attack field (usually used for AP), but the skill is designed to adjust attack speed.
		pTarget->m_sACAmount -= pType->sAC;
		pTarget->m_sAttackSpeedAmount -= (pType->bAttack - 100);
		break;

	case BUFF_TYPE_DAMAGE_DOUBLE:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bPlayerAttackAmount = 100;
		break;

	case BUFF_TYPE_DISABLE_TARGETING:
		pTarget->m_bIsBlinded = false;
		break;

	case BUFF_TYPE_BLIND:
		// Only players can be blinded (at least by the only skill - "Blinding Strafe" - that uses this type).
		if (pTarget->isPlayer())
		{
			pTarget->m_bIsBlinded = false;
			TO_USER(pTarget)->SendUserStatusUpdate(USER_STATUS_POISON, USER_STATUS_CURE);
		}
		break;

	case BUFF_TYPE_FREEZE:
		// Proportional to the target user's current HP.
		pTarget->m_bSpeedAmount = 100;
		break;

	case BUFF_TYPE_INSTANT_MAGIC:
		pTarget->m_bInstantCast = false;
		break;

	case BUFF_TYPE_DECREASE_RESIST:
		pTarget->m_bFireRAmount			= 0;
		pTarget->m_bColdRAmount			= 0;
		pTarget->m_bLightningRAmount	= 0;
		pTarget->m_bMagicRAmount		= 0;
		pTarget->m_bDiseaseRAmount		= 0;
		pTarget->m_bPoisonRAmount		= 0;
		break;

	case BUFF_TYPE_MAGE_ARMOR:
		pTarget->m_bReflectArmorType = 0;
		break;

	case BUFF_TYPE_PROHIBIT_INVIS:
		pTarget->m_bCanStealth = false;
		break;

	case BUFF_TYPE_RESIS_AND_MAGIC_DMG: // Elysian Web
		pTarget->m_bMagicDamageReduction = 100;
		break;

	case BUFF_TYPE_TRIPLEAC_HALFSPEED:	// Wall of Iron
		pTarget->m_sACPercent -= 300; // 300%, or 3x
		pTarget->m_bSpeedAmount = 100;
		break;

	case BUFF_TYPE_BLOCK_CURSE:			// Counter Curse
		pTarget->m_bBlockCurses = false;
		break;

	case BUFF_TYPE_BLOCK_CURSE_REFLECT:	// Curse Refraction
		pTarget->m_bReflectCurses = false;
		break;

	case BUFF_TYPE_MANA_ABSORB:		// Outrage / Frenzy / Mana Shield
		pTarget->m_bManaAbsorb = 0;
		break;

	case BUFF_TYPE_IGNORE_WEAPON:		// Weapon cancellation
		// Disarms the opponent. (rendering them unable to attack)
		break;

	case BUFF_TYPE_VARIOUS_EFFECTS: //... whatever the event item grants.
		// what is tweaked in the database: AC, Attack, MaxHP, resistances
		break;

	case BUFF_TYPE_PASSION_OF_SOUL:		// Passion of the Soul
		// Increase pet's HP by 120
		break;

	case BUFF_TYPE_FIRM_DETERMINATION:	// Firm Determination
		// Increase pet's AC by 20
		break;

	case BUFF_TYPE_SPEED2:				// Cold Wave
		pTarget->m_bSpeedAmount = 100;
		break;

	case BUFF_TYPE_UNK_EXPERIENCE:		// unknown buff type, used for something relating to XP.
		break;

	case BUFF_TYPE_ATTACK_RANGE_ARMOR:	// Inevitable Murderous
		pTarget->m_sACAmount -= 100;
		pTarget->m_bRadiusAmount = 0;
		break;

	case BUFF_TYPE_MIRROR_DAMAGE_PARTY: // Minak's Thorn
		pTarget->m_bMirrorDamage = false;
		pTarget->m_byMirrorAmount = 0;
		break;

	case BUFF_TYPE_DAGGER_BOW_DEFENSE: // Eskrima
		// Inflicts attacks as well as a bleeding curse on the enemy. Decreases 10% Dagger and Bow Defense of the enemy under the bleeding curse buff.
		pTarget->m_byDaggerRAmount = pTarget->m_byBowRAmount = 100; // note: overwrite the percentage for now (nothing else uses it)
		break;

	case BUFF_TYPE_LOYALTY_AMOUNT:		// Santa's Present (gives an extra +2NP per kill, unlike BUFF_TYPE_LOYALTY which uses an percent).
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bSkillNPBonus -= 2;
		break;

	case BUFF_TYPE_NO_RECALL:			// prevents teleportation.
		pTarget->m_bCanTeleport = true;
		break;

	case BUFF_TYPE_REDUCE_TARGET:		// "Reduction" (reduces target's stats, but enlarges their character to make them easier to attack)
		// NOTE: Skill description says "Enlarge enemy, but decrease attack and defense rate by 5%"
		// There's nothing else set in the client to give those stats, and AC's reduced by 15% according to the data...
		// Just working with the TBL data for now (i.e. just the 15% AC reduction).
		if (pTarget->isPlayer())
		{
			pTarget->StateChangeServerDirect(3, ABNORMAL_NORMAL);
			pTarget->m_sACPercent -= (pType->sACPct - 100);
		}
		break;

	case BUFF_TYPE_SILENCE_TARGET:		// Silences the target to prevent them from using any skills (or potions)
		pTarget->m_bCanUseSkills = true;
		break;

	case BUFF_TYPE_NO_POTIONS:			// "No Potion" prevents target from using potions.
		pTarget->m_bCanUsePotions = true;
		break;

	case BUFF_TYPE_KAUL_TRANSFORMATION:	// Transforms the target into a Kaul (a pig thing), preventing you from /town'ing or attacking, but increases defense.
		if (pTarget->isPlayer())
		{
			pTarget->m_bIsKaul = false;
			pTarget->m_sACAmount -= 500;
			pTarget->StateChangeServerDirect(3, TO_USER(pTarget)->m_nOldAbnormalType);
		}
		break;

	case BUFF_TYPE_UNDEAD:				// User becomes undead, increasing defense but preventing the use of potions and converting all health received into damage.
		pTarget->m_bIsUndead = false;
		pTarget->m_sACPercent -= (pType->sACPct - 100);
		break;

	case BUFF_TYPE_UNSIGHT:				// Blocks the caster's sight (not the target's).
		pTarget->m_bIsBlinded = false;
		break;

	case BUFF_TYPE_BLOCK_PHYSICAL_DAMAGE: // Blocks all physical damage.
		pTarget->m_bBlockPhysical = false;
		break;

	case BUFF_TYPE_BLOCK_MAGICAL_DAMAGE: // Blocks all magical/skill damage.
		pTarget->m_bBlockMagic = false;
		break;

	case BUFF_TYPE_UNK_POTION:			// unknown potion, "Return of the Warrior", "Comeback potion", perhaps some sort of revive?
		break;
		
	case BUFF_TYPE_SLEEP:				// Zantman(Sandman), puts enemies to sleep.
		break;

	case BUFF_TYPE_INVISIBILITY_POTION:	// "Unidentified potion"
		break;

	case BUFF_TYPE_GODS_BLESSING:		// Increases your defense/max HP 
		break;

	case BUFF_TYPE_HELP_COMPENSATION:	// Compensation for using the help system (to help, ask for help, both?)
		break;

	default:
		return false;
	}

	if (pTarget->isPlayer())
	{
		if (pSkill->bMoral >= MORAL_ENEMY)
		{
			if (byBuffType == BUFF_TYPE_SPEED || byBuffType == BUFF_TYPE_SPEED2)
				TO_USER(pTarget)->SendUserStatusUpdate(USER_STATUS_SPEED, USER_STATUS_CURE);
		}

		TO_USER(pTarget)->SetUserAbility();

		Packet result(WIZ_MAGIC_PROCESS, uint8(MAGIC_TYPE4_END));
		result << byBuffType;
		TO_USER(pTarget)->Send(&result);
	}

	return true;
}
Ejemplo n.º 12
0
// TO-DO: Clean this up (even using unit code...)
bool CMagicProcess::UserRegionCheck(Unit * pSkillCaster, Unit * pSkillTarget, _MAGIC_TABLE * pSkill, int radius, short mousex /*= 0*/, short mousez /*= 0*/)
{
	if (pSkillCaster->isDead()
		|| pSkillTarget == nullptr)
		return false;

	switch (pSkill->bMoral)
	{
		case MORAL_PARTY_ALL:		// Check that it's your party.
			// NPCs cannot be in parties.
			if (pSkillCaster->isNPC()
				|| pSkillTarget->isNPC())
				return false;

			if (!TO_USER(pSkillTarget)->isInParty())
				return (pSkillTarget == pSkillCaster);

			if (TO_USER(pSkillTarget)->GetPartyID() == TO_USER(pSkillCaster)->GetPartyID()
				&& pSkill->bType[0] != 8)
				goto final_test;
			else if (TO_USER(pSkillTarget)->GetPartyID() == TO_USER(pSkillCaster)->GetPartyID() 
				&& pSkill->bType[0] == 8)
			{
				if (pSkillTarget->GetMap()->isWarZone() && (UNIXTIME - TO_USER(pSkillTarget)->m_tLastRegeneTime < CLAN_SUMMON_TIME))
					return false;

				goto final_test;	
			}

			break;

		// Nation alone cannot dictate whether a unit can attack another.
		// As such, we must check behaviour specific to these entities.
		// For example: same nation players attacking each other in an arena.
		case MORAL_SELF_AREA:
		case MORAL_AREA_ENEMY:
			if (pSkillCaster->CanAttack(pSkillTarget))
				goto final_test;
			break;

		case MORAL_AREA_FRIEND:
			if (pSkillTarget->GetNation() == pSkillCaster->GetNation())
				goto final_test;
			break;

		case MORAL_CLAN_ALL:
			// NPCs cannot be in clans.
			if (pSkillCaster->isNPC()
				|| pSkillTarget->isNPC())
				return false;

			if (!TO_USER(pSkillTarget)->isInClan())
				return (pSkillTarget == pSkillCaster);

			if (TO_USER(pSkillTarget)->GetClanID() == TO_USER(pSkillCaster)->GetClanID() 
				&& pSkill->bType[0] != 8)
				goto final_test;
			else if (TO_USER(pSkillTarget)->GetClanID() == TO_USER(pSkillCaster)->GetClanID() 
				&& pSkill->bType[0] == 8)
			{
				if (pSkillTarget->GetMap()->isWarZone() && (UNIXTIME - TO_USER(pSkillTarget)->m_tLastRegeneTime < CLAN_SUMMON_TIME))
					return false;
				goto final_test;	
			}
			break;
	}
	return false;	

final_test:
	return (radius == 0 || pSkillTarget->isInRangeSlow(mousex, mousez, (float) radius));
}
Ejemplo n.º 13
0
bool CMagicProcess::GrantType4Buff(_MAGIC_TABLE * pSkill, _MAGIC_TYPE4 *pType, Unit * pCaster, Unit *pTarget, bool bIsRecastingSavedMagic /*= false*/)
{
	// Buff mustn't already be added at this point.
	FastGuard lock(pTarget->m_buffLock);
	if (!bIsRecastingSavedMagic
		&& pTarget->m_buffMap.find(pType->bBuffType) != pTarget->m_buffMap.end())
		return false;

	switch (pType->bBuffType)
	{
	case BUFF_TYPE_HP_MP:
		if (pType->sMaxHP == 0 && pType->sMaxHPPct > 0)
			pTarget->m_sMaxHPAmount = (pType->sMaxHPPct - 100) * (pTarget->GetMaxHealth() - pTarget->m_sMaxHPAmount) / 100;
		else
			pTarget->m_sMaxHPAmount = pType->sMaxHP;

		if (pType->sMaxMP == 0 && pType->sMaxMPPct > 0)
			pTarget->m_sMaxMPAmount = (pType->sMaxMPPct - 100) * (pTarget->GetMaxMana() - pTarget->m_sMaxMPAmount) / 100;
		else
			pTarget->m_sMaxMPAmount = pType->sMaxMP;
		break;

	case BUFF_TYPE_AC:
	case BUFF_TYPE_WEAPON_AC:
		if (pType->sAC == 0 && pType->sACPct > 0)
			pTarget->m_sACPercent += (pType->sACPct - 100);
		else
			pTarget->m_sACAmount += pType->sAC;
		break;

	case BUFF_TYPE_SIZE:
		if (pCaster->isPlayer())
		{
			// Unfortunately there's no way to differentiate which does what.
			// Officially it also resorts to checking the skill ID.
			uint8 bEffect = ABNORMAL_NORMAL;
			switch (pSkill->iNum)
			{
			case 490034: // Bezoar
			case 490401: // Maximize Scroll
				bEffect = ABNORMAL_GIANT;
				break;

			case 490035: // Rice cake
			case 490100: // unknown, possibly intended to be "Minimize Scroll"
				bEffect = ABNORMAL_DWARF;
				break;
			}

			if (bEffect != ABNORMAL_NORMAL)
				pTarget->StateChangeServerDirect(3, bEffect);
		}
		break;

	case BUFF_TYPE_DAMAGE:
		pTarget->m_bAttackAmount = pType->bAttack;
		break;

	case BUFF_TYPE_ATTACK_SPEED:
		pTarget->m_sAttackSpeedAmount += (pType->bAttackSpeed - 100);
		break;

	case BUFF_TYPE_SPEED:
		pTarget->m_bSpeedAmount = pType->bSpeed;
		break;

	case BUFF_TYPE_STATS:
		if (pTarget->isPlayer())
		{
			TO_USER(pTarget)->SetStatBuff(STAT_STR, pType->bStr);
			TO_USER(pTarget)->SetStatBuff(STAT_STA, pType->bSta);
			TO_USER(pTarget)->SetStatBuff(STAT_DEX, pType->bDex);
			TO_USER(pTarget)->SetStatBuff(STAT_INT, pType->bIntel);
			TO_USER(pTarget)->SetStatBuff(STAT_CHA, pType->bCha);	
		}
		break;

	case BUFF_TYPE_RESISTANCES:
		pTarget->m_bFireRAmount = pType->bFireR;
		pTarget->m_bColdRAmount = pType->bColdR;
		pTarget->m_bLightningRAmount = pType->bLightningR;
		pTarget->m_bMagicRAmount = pType->bMagicR;
		pTarget->m_bDiseaseRAmount = pType->bDiseaseR;
		pTarget->m_bPoisonRAmount = pType->bPoisonR;
		break;

	case BUFF_TYPE_ACCURACY:
		pTarget->m_bHitRateAmount = pType->bHitRate;
		pTarget->m_sAvoidRateAmount = pType->sAvoidRate;
		break;	

	case BUFF_TYPE_MAGIC_POWER:
		if (pTarget->isPlayer())
			pTarget->m_sMagicAttackAmount = (pType->bMagicAttack - 100) * TO_USER(pTarget)->GetStat(STAT_CHA) / 100;
		break;

	case BUFF_TYPE_EXPERIENCE:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_sExpGainAmount = (uint8) pType->sExpPct;
		break;

	case BUFF_TYPE_WEIGHT:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bMaxWeightAmount = (uint8) pType->sExpPct;
		break;

	case BUFF_TYPE_WEAPON_DAMAGE:
		// uses pType->Attack
		break;

	case BUFF_TYPE_LOYALTY:
		if(pTarget->isPlayer())
			TO_USER(pTarget)->m_bNPGainAmount = (uint8) pType->sExpPct;
		break;

	case BUFF_TYPE_NOAH_BONUS:
		if(pTarget->isPlayer())
			TO_USER(pTarget)->m_bNoahGainAmount = (uint8) pType->sExpPct;
		break;

	case BUFF_TYPE_PREMIUM_MERCHANT:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bPremiumMerchant = true;
		break;

	case BUFF_TYPE_ATTACK_SPEED_ARMOR:
		// NOTE: This officially uses the Attack field (usually used for AP), but the skill is designed to adjust attack speed.
		pTarget->m_sACAmount += pType->sAC;
		pTarget->m_sAttackSpeedAmount += (pType->bAttack - 100); 
		break;

	case BUFF_TYPE_DAMAGE_DOUBLE:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bPlayerAttackAmount = pType->bAttack;
		break;

	case BUFF_TYPE_DISABLE_TARGETING:
		pTarget->m_bIsBlinded = true;
		break;

	case BUFF_TYPE_BLIND:
		// The only skill that uses this buff type is "Blinding Strafe", which states:
		// Description: Shoots an arrow that inflicts 400% damage and blinds the enemy. Does not apply to monsters.
		// As such, we should not blind monsters.
		if (pTarget->isPlayer())
			pTarget->m_bIsBlinded = true;
		break;

	case BUFF_TYPE_FREEZE:
		// Proportional to the target user's current HP.
		pTarget->m_bSpeedAmount = pType->bSpeed;
		break;

	case BUFF_TYPE_INSTANT_MAGIC:
		pTarget->m_bInstantCast = true;
		break;

	case BUFF_TYPE_DECREASE_RESIST:
		pTarget->m_bFireRAmount			= -(pType->bFireR / 100)	*	(pTarget->m_sFireR		- pTarget->m_bFireRAmount);
		pTarget->m_bColdRAmount			= -(pType->bColdR / 100)	*	(pTarget->m_sColdR		- pTarget->m_bColdRAmount);
		pTarget->m_bLightningRAmount	= -(pType->bLightningR / 100) * (pTarget->m_sLightningR - pTarget->m_bLightningRAmount);
		pTarget->m_bMagicRAmount		= -(pType->bMagicR / 100)	*	(pTarget->m_sMagicR		- pTarget->m_bMagicRAmount);
		pTarget->m_bDiseaseRAmount		= -(pType->bDiseaseR / 100) *	(pTarget->m_sDiseaseR	- pTarget->m_bDiseaseRAmount);
		pTarget->m_bPoisonRAmount		= -(pType->bPoisonR / 100)	*	(pTarget->m_sPoisonR	- pTarget->m_bPoisonRAmount);
		break;

	case BUFF_TYPE_MAGE_ARMOR:
		pTarget->m_bReflectArmorType = (pSkill->sSkill % 100);
		break;

	case BUFF_TYPE_PROHIBIT_INVIS:
		pTarget->m_bCanStealth = true;
		break;

	case BUFF_TYPE_RESIS_AND_MAGIC_DMG: // Elysian Web
		pTarget->m_bMagicDamageReduction = (uint8) pType->sExpPct;
		break;

	case BUFF_TYPE_TRIPLEAC_HALFSPEED:	// Wall of Iron
		pTarget->m_sACPercent += 300; // 300%, or 3x
		pTarget->m_bSpeedAmount = pTarget->m_bSpeedAmount / 2;
		if (pTarget->m_bSpeedAmount == 0)
			pTarget->m_bSpeedAmount = 1;
		break;

	case BUFF_TYPE_BLOCK_CURSE:			// Counter Curse
		pTarget->m_bBlockCurses = true;
		break;

	case BUFF_TYPE_BLOCK_CURSE_REFLECT:	// Curse Refraction
		pTarget->m_bReflectCurses = true;
		break;

	case BUFF_TYPE_MANA_ABSORB:		// Outrage / Frenzy / Mana Shield
		pTarget->m_bManaAbsorb = (uint8) pType->sExpPct;
		break;

	case BUFF_TYPE_VARIOUS_EFFECTS: //... whatever the event item grants.
		// what is tweaked in the database: AC, Attack, MaxHP, resistances
		break;

	case BUFF_TYPE_IGNORE_WEAPON:		// Weapon cancellation
		// Disarms the opponent. (rendering them unable to attack)
		break;

	case BUFF_TYPE_PASSION_OF_SOUL:		// Passion of the Soul
		// Increase pet's HP by 120
		break;

	case BUFF_TYPE_FIRM_DETERMINATION:	// Firm Determination
		// Increase pet's AC by 20
		break;

	case BUFF_TYPE_SPEED2:				// Cold Wave
		pTarget->m_bSpeedAmount = (pTarget->m_bSpeedAmount / 100 * 65);
		break;

	case BUFF_TYPE_UNK_EXPERIENCE:		// unknown buff type, used for something relating to XP.
		break;

	case BUFF_TYPE_ATTACK_RANGE_ARMOR:	// Inevitable Murderous
		pTarget->m_sACAmount += 100;
		pTarget->m_bRadiusAmount = pType->bRadius;
		break;

	case BUFF_TYPE_MIRROR_DAMAGE_PARTY: // Minak's Thorn
		pTarget->m_bMirrorDamage = true;
		pTarget->m_byMirrorAmount = (uint8) pType->sSpecialAmount;
		break;

	case BUFF_TYPE_DAGGER_BOW_DEFENSE: // Eskrima
		// Inflicts attacks as well as a bleeding curse on the enemy. Decreases 10% Dagger and Bow Defense of the enemy under the bleeding curse buff.
		// NOTE: overwrite the percentage for now (nothing else uses it)
		// Also: the amount is 20 in the database. Could be that it's divided by 2 (i.e. splitting it between dagger/bow), the skill description's inaccurate
		// or the description roughly reflects the final damage after player damage reduction. For now, we'll just assume it's the latter.
		pTarget->m_byDaggerRAmount = pTarget->m_byBowRAmount = 100 - (uint8) pType->sSpecialAmount;
		break;

	case BUFF_TYPE_LOYALTY_AMOUNT:		// Santa's Present (gives an extra +2NP per kill, unlike BUFF_TYPE_LOYALTY which uses an percent).
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bSkillNPBonus += 2;
		break;

	case BUFF_TYPE_NO_RECALL:			// prevents teleportation.
		pTarget->m_bCanTeleport = false;
		break;

	case BUFF_TYPE_REDUCE_TARGET:		// "Reduction" (reduces target's stats, but enlarges their character to make them easier to attack)
		// NOTE: Skill description says "Enlarge enemy, but decrease attack and defense rate by 5%"
		// There's nothing else set in the client to give those stats, and AC's reduced by 15% according to the data...
		// Just working with the TBL data for now (i.e. just the 15% AC reduction).
		if (pTarget->isPlayer())
		{
			pTarget->StateChangeServerDirect(3, ABNORMAL_GIANT);
			pTarget->m_sACPercent += (pType->sACPct - 100);
		}
		break;

	case BUFF_TYPE_SILENCE_TARGET:		// Silences the target to prevent them from using any skills (or potions)
		pTarget->m_bCanUseSkills = false;
		break;

	case BUFF_TYPE_NO_POTIONS:			// "No Potion" prevents target from using potions.
		pTarget->m_bCanUsePotions = false;
		break;

	case BUFF_TYPE_KAUL_TRANSFORMATION:	// Transforms the target into a Kaul (a pig thing), preventing you from /town'ing or attacking, but increases defense.
		if (pTarget->isPlayer())
		{
			pTarget->m_bIsKaul = true;
			pTarget->m_sACAmount += 500;
			pTarget->StateChangeServerDirect(3, pType->iNum);
		}
		break;

	case BUFF_TYPE_UNDEAD:				// User becomes undead, increasing defense but preventing the use of potions and converting all health received into damage.
		pTarget->m_bIsUndead = true;
		pTarget->m_sACPercent += (pType->sACPct - 100);
		break;

	case BUFF_TYPE_UNSIGHT:				// Blocks the caster's sight (not the target's).
		pTarget->m_bIsBlinded = true;
		break;

	case BUFF_TYPE_BLOCK_PHYSICAL_DAMAGE: // Blocks all physical damage.
		pTarget->m_bBlockPhysical = true;
		break;

	case BUFF_TYPE_BLOCK_MAGICAL_DAMAGE: // Blocks all magical/skill damage.
		pTarget->m_bBlockMagic = true;
		break;

	case BUFF_TYPE_UNK_POTION:			// unknown potion, "Return of the Warrior", "Comeback potion", perhaps some sort of revive?
		break;

	case BUFF_TYPE_SLEEP:				// Zantman(Sandman), puts enemies to sleep.
		break;

	case BUFF_TYPE_INVISIBILITY_POTION:	// "Unidentified potion"
		break;

	case BUFF_TYPE_GODS_BLESSING:		// Increases your defense/max HP 
		break;

	case BUFF_TYPE_HELP_COMPENSATION:	// Compensation for using the help system (to help, ask for help, both?)
		break;

	default:
		return false;
	}
	return true;
}
Ejemplo n.º 14
0
bool CMagicProcess::GrantType4Buff(_MAGIC_TABLE * pSkill, _MAGIC_TYPE4 *pType, Unit * pCaster, Unit *pTarget, bool bIsRecastingSavedMagic /*= false*/)
{
	// Buff mustn't already be added at this point.
	FastGuard lock(pTarget->m_buffLock);
	if (!bIsRecastingSavedMagic
		&& pTarget->m_buffMap.find(pType->bBuffType) != pTarget->m_buffMap.end())
		return false;

	switch (pType->bBuffType)
	{
	case BUFF_TYPE_HP_MP:
		if (pType->sMaxHP == 0 && pType->sMaxHPPct > 0)
			pTarget->m_sMaxHPAmount = (pType->sMaxHPPct - 100) * (pTarget->GetMaxHealth() - pTarget->m_sMaxHPAmount) / 100;
		else
			pTarget->m_sMaxHPAmount = pType->sMaxHP;

		if (pType->sMaxMP == 0 && pType->sMaxMPPct > 0)
			pTarget->m_sMaxMPAmount = (pType->sMaxMPPct - 100) * (pTarget->GetMaxMana() - pTarget->m_sMaxMPAmount) / 100;
		else
			pTarget->m_sMaxMPAmount = pType->sMaxMP;
		break;

	case BUFF_TYPE_AC:
		if (pType->sAC == 0 && pType->sACPct > 0)
			pTarget->m_sACAmount = pTarget->m_sTotalAc * (pType->sACPct - 100) / 100;
		else
			pTarget->m_sACAmount = pType->sAC;
		break;

	case BUFF_TYPE_SIZE:
		if (pCaster->isPlayer())
		{
			// Unfortunately there's no way to differentiate which does what.
			// Officially it also resorts to checking the skill ID.
			uint8 bEffect = ABNORMAL_NORMAL;
			switch (pSkill->iNum)
			{
			case 490034: // Bezoar
			case 490401: // Maximize Scroll
				bEffect = ABNORMAL_GIANT;
				break;

			case 490035: // Rice cake
			case 490100: // unknown, possibly intended to be "Minimize Scroll"
				bEffect = ABNORMAL_DWARF;
				break;
			}

			if (bEffect != ABNORMAL_NORMAL)
				TO_USER(pTarget)->StateChangeServerDirect(3, bEffect);
		}
		break;

	case BUFF_TYPE_DAMAGE:
		pTarget->m_bAttackAmount = pType->bAttack;
		break;

	case BUFF_TYPE_ATTACK_SPEED:
		pTarget->m_bAttackSpeedAmount = pType->bAttackSpeed;
		break;

	case BUFF_TYPE_SPEED:
		pTarget->m_bSpeedAmount = pType->bSpeed;
		break;

	case BUFF_TYPE_STATS:
		if (pTarget->isPlayer())
		{
			TO_USER(pTarget)->SetStatBuff(STAT_STR, pType->bStr);
			TO_USER(pTarget)->SetStatBuff(STAT_STA, pType->bSta);
			TO_USER(pTarget)->SetStatBuff(STAT_DEX, pType->bDex);
			TO_USER(pTarget)->SetStatBuff(STAT_INT, pType->bIntel);
			TO_USER(pTarget)->SetStatBuff(STAT_CHA, pType->bCha);	
		}
		break;

	case BUFF_TYPE_RESISTANCES:
		pTarget->m_bFireRAmount = pType->bFireR;
		pTarget->m_bColdRAmount = pType->bColdR;
		pTarget->m_bLightningRAmount = pType->bLightningR;
		pTarget->m_bMagicRAmount = pType->bMagicR;
		pTarget->m_bDiseaseRAmount = pType->bDiseaseR;
		pTarget->m_bPoisonRAmount = pType->bPoisonR;
		break;

	case BUFF_TYPE_ACCURACY:
		pTarget->m_bHitRateAmount = pType->bHitRate;
		pTarget->m_sAvoidRateAmount = pType->sAvoidRate;
		break;	

	case BUFF_TYPE_MAGIC_POWER:
		if (pTarget->isPlayer())
			pTarget->m_sMagicAttackAmount = (pType->bMagicAttack - 100) * TO_USER(pTarget)->GetStat(STAT_CHA) / 100;
		break;

	case BUFF_TYPE_EXPERIENCE:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bExpGainAmount = pType->bExpPct;
		break;

	case BUFF_TYPE_WEIGHT:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bMaxWeightAmount = pType->bExpPct;
		break;

	case BUFF_TYPE_WEAPON_DAMAGE:
		// uses pType->Attack
		break;

	case BUFF_TYPE_WEAPON_AC:
		if (pType->sAC == 0 && pType->sACPct > 0)
			pTarget->m_sACAmount = pTarget->m_sTotalAc * (pType->sACPct - 100) / 100;
		else
			pTarget->m_sACAmount = pType->sAC;
		break;

	case BUFF_TYPE_LOYALTY:
		if(pTarget->isPlayer())
			TO_USER(pTarget)->m_bNPGainAmount = pType->bExpPct;
		break;

	case BUFF_TYPE_NOAH_BONUS:
		if(pTarget->isPlayer())
			TO_USER(pTarget)->m_bNoahGainAmount = pType->bExpPct;
		break;

	case BUFF_TYPE_PREMIUM_MERCHANT:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bPremiumMerchant = true;
		break;

	case BUFF_TYPE_ATTACK_SPEED_ARMOR:
		pTarget->m_sACAmount += pType->sAC;

		// Prevent total defense from ever going below 0
		if ((pTarget->m_sACAmount + pTarget->m_sTotalAc) < 0)
			pTarget->m_sACAmount = -(pTarget->m_sTotalAc);

		pTarget->m_bAttackAmount = pType->bAttack;
		break;

	case BUFF_TYPE_DAMAGE_DOUBLE:
		pTarget->m_bAttackAmount = pType->bAttack;
		break;

	case BUFF_TYPE_DISABLE_TARGETING:
		pTarget->m_bIsBlinded = true;
		break;

	case BUFF_TYPE_BLIND:
		// The only skill that uses this buff type is "Blinding Strafe", which states:
		// Description: Shoots an arrow that inflicts 400% damage and blinds the enemy. Does not apply to monsters.
		// As such, we should not blind monsters.
		if (pTarget->isPlayer())
			pTarget->m_bIsBlinded = true;
		break;

	case BUFF_TYPE_FREEZE:
		// Proportional to the target user's current HP.
		pTarget->m_bSpeedAmount = pType->bSpeed;
		break;

	case BUFF_TYPE_INSTANT_MAGIC:
		pTarget->m_bInstantCast = true;
		break;

	case BUFF_TYPE_DECREASE_RESIST:
		pTarget->m_bFireRAmount			= -(pType->bFireR / 100)	*	(pTarget->m_sFireR		- pTarget->m_bFireRAmount);
		pTarget->m_bColdRAmount			= -(pType->bColdR / 100)	*	(pTarget->m_sColdR		- pTarget->m_bColdRAmount);
		pTarget->m_bLightningRAmount	= -(pType->bLightningR / 100) * (pTarget->m_sLightningR - pTarget->m_bLightningRAmount);
		pTarget->m_bMagicRAmount		= -(pType->bMagicR / 100)	*	(pTarget->m_sMagicR		- pTarget->m_bMagicRAmount);
		pTarget->m_bDiseaseRAmount		= -(pType->bDiseaseR / 100) *	(pTarget->m_sDiseaseR	- pTarget->m_bDiseaseRAmount);
		pTarget->m_bPoisonRAmount		= -(pType->bPoisonR / 100)	*	(pTarget->m_sPoisonR	- pTarget->m_bPoisonRAmount);
		break;

	case BUFF_TYPE_MAGE_ARMOR:
		pTarget->m_bReflectArmorType = (pSkill->sSkill % 100);
		break;

	case BUFF_TYPE_PROHIBIT_INVIS:
		pTarget->m_bCanStealth = true;
		break;

	case BUFF_TYPE_RESIS_AND_MAGIC_DMG: // Elysian Web
		pTarget->m_bMagicDamageReduction = pType->bExpPct;
		break;

	case BUFF_TYPE_TRIPLEAC_HALFSPEED:	// Wall of Iron
		pTarget->m_sACAmount += pTarget->m_sTotalAc * 2; // TO-DO: Store this value independently for restoration
		pTarget->m_bSpeedAmount = pTarget->m_bSpeedAmount / 2;
		if (pTarget->m_bSpeedAmount = 0)
			pTarget->m_bSpeedAmount = 1;
		break;

	case BUFF_TYPE_BLOCK_CURSE:			// Counter Curse
		// Blocks all curses.
		pTarget->m_bBlockCurse = true;
		break;

	case BUFF_TYPE_BLOCK_CURSE_REFLECT:	// Curse Refraction
		// Blocks all curses and has a chance to reflect the curse back upon the caster.
		break;

	case BUFF_TYPE_MANA_ABSORB:		// Outrage / Frenzy / Mana Shield
		// Uses mana to receive damage (for mana shield its multiplied by 4, 100 damage = 400 mana used)
		break;

	case BUFF_TYPE_VARIOUS_EFFECTS: //... whatever the event item grants.
		// what is tweaked in the database: AC, Attack, MaxHP, resistances
		break;

	case BUFF_TYPE_IGNORE_WEAPON:		// Weapon cancellation
		// Disarms the opponent. (rendering them unable to attack)
		break;

	case BUFF_TYPE_PASSION_OF_SOUL:		// Passion of the Soul
		// Increase pet's HP by 120
		break;

	case BUFF_TYPE_FIRM_DETERMINATION:	// Firm Determination
		// Increase pet's AC by 20
		break;

	case BUFF_TYPE_SPEED2:				// Cold Wave
		pTarget->m_bSpeedAmount = (pTarget->m_bSpeedAmount / 100 * 65);
		break;

	case BUFF_TYPE_UNK_EXPERIENCE:		// unknown buff type, used for something relating to XP.
		break;

	case BUFF_TYPE_ATTACK_RANGE_ARMOR:	// Inevitable Murderous
		pTarget->m_sACAmount += 100;
		// Increase attack range by 1 meter.
		break;

	case BUFF_TYPE_MIRROR_DAMAGE_PARTY: // Minak's Thorn
		// Spreads damage received across party members and mirror's part of the damage.
		break;

	case BUFF_TYPE_DAGGER_BOW_DEFENSE: // Eskrima
		// Inflicts attacks as well as a bleeding curse on the enemy. Decreases 10% Dagger and Bow Defense of the enemy under the bleeding curse buff.
		break;

	case BUFF_TYPE_LOYALTY_AMOUNT:		// Santa's Present (gives an extra +2NP per kill, unlike BUFF_TYPE_LOYALTY which uses an percent).
		break;

	case BUFF_TYPE_NO_RECALL:			// prevents teleportation.
		break;

	case BUFF_TYPE_REDUCE_TARGET:		// "Reduction" (reduces target's stats, but enlarges their character to make them easier to attack)
		break;

	case BUFF_TYPE_SILENCE_TARGET:		// Silences the target to prevent them from using any skills (or potions)
		break;

	case BUFF_TYPE_NO_POTIONS:			// "No Potion" prevents target from using potions.
		break;

	case BUFF_TYPE_KAUL_TRANSFORMATION:	// Transforms the target into a Kaul (a pig thing), preventing you from /town'ing or attacking, but increases defense.
		break;

	case BUFF_TYPE_UNDEAD:				// User becomes undead, increasing defense but preventing the use of potions and converting all health received into damage.
		break;

	case BUFF_TYPE_UNSIGHT:				// Unsure how this is different to "Blind", but skill description simply reads "Blocks your[the target's] sight."
		break;

	case BUFF_TYPE_BLOCK_PHYSICAL_DAMAGE: // Blocks all physical damage.
		break;

	case BUFF_TYPE_BLOCK_MAGICAL_DAMAGE: // Blocks all magical/skill damage.
		break;

	case BUFF_TYPE_UNK_POTION:			// unknown potion, "Return of the Warrior", "Comeback potion", perhaps some sort of revive?
		break;

	case BUFF_TYPE_SLEEP:				// Zantman(Sandman), puts enemies to sleep.
		break;

	case BUFF_TYPE_INVISIBILITY_POTION:	// "Unidentified potion"
		break;

	case BUFF_TYPE_GODS_BLESSING:		// Increases your defense/max HP 
		break;

	case BUFF_TYPE_HELP_COMPENSATION:	// Compensation for using the help system (to help, ask for help, both?)
		break;

	default:
		return false;
	}
	return true;
}
Ejemplo n.º 15
0
void CUser::Attack(Packet & pkt)
{
	int16 sid = -1, tid = -1, damage, delaytime, distance;	
	uint8 bType, bResult = 0;	
	Unit * pTarget = nullptr;

	pkt >> bType >> bResult >> tid >> delaytime >> distance;

	//	delaytime = delaytime / 100.0f;
	//	distance = distance / 10.0f;

	if (isIncapacitated())
		return;

	if (isInSafetyArea())
		return;

	if (m_bInvisibilityType != INVIS_NONE)
	{
		CMagicProcess::RemoveStealth(this, INVIS_DISPEL_ON_MOVE);
		CMagicProcess::RemoveStealth(this, INVIS_DISPEL_ON_ATTACK);
	}

	// If you're holding a weapon, do a client-based (ugh, do not trust!) delay check.
	_ITEM_TABLE *pTable = GetItemPrototype(RIGHTHAND);
	if (pTable != nullptr) 
	{
		if (delaytime < (pTable->m_sDelay + 10) // client adds 0.1 onto the interval (0.1 of 100 is 10)
			|| distance > pTable->m_sRange)
			return;	
	}
	// Empty handed.
	else if (delaytime < 100)
		return;			

	pTarget = g_pMain->GetUnitPtr(tid);
	bResult = ATTACK_FAIL;

	if (pTarget != nullptr 
		&& isInAttackRange(pTarget)
		&& CanAttack(pTarget))
	{
		if (isAttackable(pTarget) && CanCastRHit(GetSocketID()))
		{
			if (isInTempleEventZone())
				if (GetUserGroup() != -1 && !isSameUserGroup(pTarget))
					return;

			CUser *pUser = g_pMain->GetUserPtr(GetSocketID());
			if (pUser != nullptr)
				pUser->m_RHitRepeatList.insert(std::make_pair(GetSocketID(), UNIXTIME));

			damage = GetDamage(pTarget);

			// Can't use R attacks in the Snow War.
			if (GetZoneID() == ZONE_SNOW_BATTLE 
				&& g_pMain->m_byBattleOpen == SNOW_BATTLE)
				damage = 0;

			if (damage > 0)
			{
				pTarget->HpChange(-damage, this);
				if (pTarget->isDead())
					bResult = ATTACK_TARGET_DEAD;
				else
					bResult = ATTACK_SUCCESS;

				// Every attack takes a little of your weapon's durability.
				ItemWoreOut(ATTACK, damage);

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

	Packet result(WIZ_ATTACK, bType);
	result << bResult << GetSocketID() << tid;
	SendToRegion(&result);
}
Ejemplo n.º 16
0
// TO-DO: Clean this up (even using unit code...)
bool CMagicProcess::UserRegionCheck(Unit * pSkillCaster, Unit * pSkillTarget, _MAGIC_TABLE * pSkill, int radius, short mousex /*= 0*/, short mousez /*= 0*/)
{
	if (pSkillCaster->isDead()
		|| pSkillTarget == NULL)
		return false;

	switch (pSkill->bMoral)
	{
		case MORAL_PARTY_ALL:		// Check that it's your party.
			// NPCs cannot be in parties.
			if (pSkillCaster->isNPC()
				|| pSkillTarget->isNPC())
				return false;

			if (!TO_USER(pSkillTarget)->isInParty())
				return (pSkillTarget == pSkillCaster);

			if (TO_USER(pSkillTarget)->m_sPartyIndex == TO_USER(pSkillCaster)->m_sPartyIndex 
				&& pSkill->bType[0] != 8)
				goto final_test;
			else if (TO_USER(pSkillTarget)->m_sPartyIndex == TO_USER(pSkillCaster)->m_sPartyIndex 
				&& pSkill->bType[0] == 8)
			{
				if (pSkillTarget->GetZoneID() == ZONE_BATTLE && (UNIXTIME - TO_USER(pSkillTarget)->m_tLastRegeneTime < CLAN_SUMMON_TIME))
					return false;

				goto final_test;	
			}

			break;

		case MORAL_SELF_AREA:
		case MORAL_AREA_ENEMY:
			if (pSkillTarget->GetNation() != pSkillCaster->GetNation())
				goto final_test;
			break;

		case MORAL_AREA_FRIEND:
			if (pSkillTarget->GetNation() == pSkillCaster->GetNation())
				goto final_test;
			break;

		case MORAL_CLAN_ALL:
			// NPCs cannot be in clans.
			if (pSkillCaster->isNPC()
				|| pSkillTarget->isNPC())
				return false;

			if (!TO_USER(pSkillTarget)->isInClan())
				return (pSkillTarget == pSkillCaster);

			if (TO_USER(pSkillTarget)->GetClanID() == TO_USER(pSkillCaster)->GetClanID() 
				&& pSkill->bType[0] != 8)
				goto final_test;
			else if (TO_USER(pSkillTarget)->GetClanID() == TO_USER(pSkillCaster)->GetClanID() 
				&& pSkill->bType[0] == 8)
			{
				if (pSkillTarget->GetZoneID() == ZONE_BATTLE && (UNIXTIME - TO_USER(pSkillTarget)->m_tLastRegeneTime < CLAN_SUMMON_TIME))
					return false;
				goto final_test;	
			}
			break;
	}
	return false;	

final_test:
	if (pSkillTarget->GetRegion() != pSkillCaster->GetRegion())
		return false;

	if (radius != 0)
	{
		float temp_x = pSkillTarget->GetX() - mousex;
		float temp_z = pSkillTarget->GetZ() - mousez;
		float distance = pow(temp_x, 2.0f) + pow(temp_z, 2.0f);
		if (distance > pow((float)radius, 2.0f)) 
			return false;
	}
	return true;	// Target is in the area.
}
Ejemplo n.º 17
0
bool CMagicProcess::RemoveType4Buff(uint8 byBuffType, CUser *pTarget)
{
	switch (byBuffType)
	{
	case BUFF_TYPE_HP_MP:
		pTarget->m_sMaxHPAmount = 0;
		pTarget->m_sMaxMPAmount = 0;
		break;

	case BUFF_TYPE_AC:
		pTarget->m_sACAmount = 0;
		break;

	case BUFF_TYPE_SIZE:
		pTarget->StateChangeServerDirect(3, ABNORMAL_NORMAL);
		break;

	case BUFF_TYPE_DAMAGE:
		pTarget->m_bAttackAmount = 100;
		break;

	case BUFF_TYPE_ATTACK_SPEED:
		pTarget->m_bAttackSpeedAmount = 100;
		break;

	case BUFF_TYPE_SPEED:
		pTarget->m_bSpeedAmount = 100;
		break;

	case BUFF_TYPE_STATS:
		TO_USER(pTarget)->setStatBuff(STAT_STR, 0);
		TO_USER(pTarget)->setStatBuff(STAT_STA, 0);
		TO_USER(pTarget)->setStatBuff(STAT_DEX, 0);
		TO_USER(pTarget)->setStatBuff(STAT_INT, 0);
		TO_USER(pTarget)->setStatBuff(STAT_CHA, 0);	
		break;

	case BUFF_TYPE_RESISTANCES:
		pTarget->m_bFireRAmount = 0;
		pTarget->m_bColdRAmount = 0;
		pTarget->m_bLightningRAmount = 0;
		pTarget->m_bMagicRAmount = 0;
		pTarget->m_bDiseaseRAmount = 0;
		pTarget->m_bPoisonRAmount = 0;
		break;

	case BUFF_TYPE_ACCURACY:
		pTarget->m_bHitRateAmount = 100;
		pTarget->m_sAvoidRateAmount = 100;
		break;	

	case BUFF_TYPE_MAGIC_POWER:
		pTarget->m_sMagicAttackAmount = 0;
		break;

	case BUFF_TYPE_EXPERIENCE:
		pTarget->m_bExpGainAmount = 100;
		break;

	case BUFF_TYPE_WEIGHT:
		pTarget->m_bMaxWeightAmount = 100;
		break;

	case BUFF_TYPE_WEAPON_DAMAGE:
		// uses pType->Attack
		break;

	case BUFF_TYPE_WEAPON_AC:
		pTarget->m_sACAmount = 0;
		break;

	case BUFF_TYPE_LOYALTY:
		// uses pType->ExpPct
		break;

	case BUFF_TYPE_NOAH_BONUS:
		break;

	case BUFF_TYPE_PREMIUM_MERCHANT:
		TO_USER(pTarget)->m_bPremiumMerchant = false;
		break;

	case BUFF_TYPE_ATTACK_SPEED_ARMOR:
		// should this revert a specific amount? if so, we need to store it so that we know how much.
		// most likely though, it's just recalculated.
		pTarget->m_sACAmount = 0;
		pTarget->m_bAttackAmount = 100;
		break;

	case BUFF_TYPE_DAMAGE_DOUBLE:
		pTarget->m_bAttackAmount = 100;
		break;

	case BUFF_TYPE_DISABLE_TARGETING:
		pTarget->m_bIsBlinded = false;
		break;

	case BUFF_TYPE_BLIND:
		pTarget->m_bIsBlinded = false;
		if (pTarget->isPlayer())
			TO_USER(pTarget)->SendUserStatusUpdate(USER_STATUS_BLIND, USER_STATUS_CURE);
		break;

	case BUFF_TYPE_FREEZE:
		// Proportional to the target user's current HP.
		pTarget->m_bSpeedAmount = 100;
		break;

	case BUFF_TYPE_INSTANT_MAGIC:
		pTarget->m_bInstantCast = false;
		break;

	case BUFF_TYPE_DECREASE_RESIST:
		pTarget->m_bFireRAmount			= 0;
		pTarget->m_bColdRAmount			= 0;
		pTarget->m_bLightningRAmount	= 0;
		pTarget->m_bMagicRAmount		= 0;
		pTarget->m_bDiseaseRAmount		= 0;
		pTarget->m_bPoisonRAmount		= 0;
		break;

	case BUFF_TYPE_MAGE_ARMOR:
		pTarget->m_bReflectArmorType = 0;
		break;

	case BUFF_TYPE_PROHIBIT_INVIS:
		pTarget->m_bCanStealth = false;
		break;

	case BUFF_TYPE_RESIS_AND_MAGIC_DMG: // Elysian Web
		// Increases your magic resistance to block an additional 30% magic damage.
		break;

	case BUFF_TYPE_TRIPLEAC_HALFSPEED:	// Wall of Iron
		pTarget->m_sACAmount -= (pTarget->m_sTotalAc / 3 * 2);
		pTarget->m_bSpeedAmount = 100;
		if (pTarget->m_bSpeedAmount = 0)
			pTarget->m_bSpeedAmount = 1;
		break;

	case BUFF_TYPE_BLOCK_CURSE:			// Counter Curse
		// Blocks all curses.
		break;

	case BUFF_TYPE_BLOCK_CURSE_REFLECT:	// Curse Refraction
		// Blocks all curses and has a chance to reflect the curse back upon the caster.
		break;

	case BUFF_TYPE_MANA_ABSORB:		// Outrage / Frenzy / Mana Shield
		// Uses mana to receive damage (for mana shield its multiplied by 4, 100 damage = 400 mana used)
		break;

	case BUFF_TYPE_IGNORE_WEAPON:		// Weapon cancellation
		// Disarms the opponent. (rendering them unable to attack)
		break;

	case BUFF_TYPE_PASSION_OF_SOUL:		// Passion of the Soul
		// Increase pet's HP by 120
		break;

	case BUFF_TYPE_FIRM_DETERMINATION:	// Firm Determination
		// Increase pet's AC by 20
		break;

	case BUFF_TYPE_SPEED2:				// Cold Wave
		pTarget->m_bSpeedAmount = 100;
		break;

	case BUFF_TYPE_ATTACK_RANGE_ARMOR:	// Inevitable Murderous
		pTarget->m_sACAmount -= 100;
		// Buff type increases attack range by 1 meter.
		break;

	case BUFF_TYPE_MIRROR_DAMAGE_PARTY: // Minak's Thorn
		// Spreads damage received across party members and mirror's part of the damage.
		break;

	default:
		return false;
	}

	pTarget->SetSlotItemValue();
	pTarget->SetUserAbility();
	pTarget->SendItemMove(2);
	pTarget->Send2AI_UserUpdateInfo();

	pTarget->m_sDuration[byBuffType - 1] = 0;
	pTarget->m_tStartTime[byBuffType - 1] = 0;
	pTarget->m_bType4Buff[byBuffType - 1] = 0;

	Packet result(WIZ_MAGIC_PROCESS, uint8(MAGIC_TYPE4_END));
	result << byBuffType;
	pTarget->Send(&result);

	return true;
}
Ejemplo n.º 18
0
bool CMagicProcess::GrantType4Buff(_MAGIC_TABLE * pSkill, _MAGIC_TYPE4 *pType, Unit * pCaster, CUser *pTarget)
{
	switch (pType->bBuffType)
	{
	case BUFF_TYPE_HP_MP:
		if (pType->sMaxHP == 0 && pType->sMaxHPPct > 0)
			pTarget->m_sMaxHPAmount = (pType->sMaxHPPct - 100) * (pTarget->GetMaxHealth() - pTarget->m_sMaxHPAmount) / 100;
		else
			pTarget->m_sMaxHPAmount = pType->sMaxHP;

		if (pType->sMaxMP == 0 && pType->sMaxMPPct > 0)
			pTarget->m_sMaxMPAmount = (pType->sMaxMPPct - 100) * (pTarget->m_iMaxMp - pTarget->m_sMaxMPAmount) / 100;
		else
			pTarget->m_sMaxMPAmount = pType->sMaxMP;
		break;

	case BUFF_TYPE_AC:
		if (pType->sAC == 0 && pType->sACPct > 0)
			pTarget->m_sACAmount = pTarget->m_sTotalAc * (pType->sACPct - 100) / 100;
		else
			pTarget->m_sACAmount = pType->sAC;
		break;

	case BUFF_TYPE_SIZE:
		if (pCaster->isPlayer())
			TO_USER(pCaster)->StateChangeServerDirect(3, ABNORMAL_NORMAL);
		break;

	case BUFF_TYPE_DAMAGE:
		pTarget->m_bAttackAmount = pType->bAttack;
		break;

	case BUFF_TYPE_ATTACK_SPEED:
		pTarget->m_bAttackSpeedAmount = pType->bAttackSpeed;
		break;

	case BUFF_TYPE_SPEED:
		pTarget->m_bSpeedAmount = pType->bSpeed;
		break;

	case BUFF_TYPE_STATS:
		if (pCaster->isPlayer())
		{
			TO_USER(pTarget)->setStatBuff(STAT_STR, pType->bStr);
			TO_USER(pTarget)->setStatBuff(STAT_STA, pType->bSta);
			TO_USER(pTarget)->setStatBuff(STAT_DEX, pType->bDex);
			TO_USER(pTarget)->setStatBuff(STAT_INT, pType->bIntel);
			TO_USER(pTarget)->setStatBuff(STAT_CHA, pType->bCha);	
		}
		break;

	case BUFF_TYPE_RESISTANCES:
		pTarget->m_bFireRAmount = pType->bFireR;
		pTarget->m_bColdRAmount = pType->bColdR;
		pTarget->m_bLightningRAmount = pType->bLightningR;
		pTarget->m_bMagicRAmount = pType->bMagicR;
		pTarget->m_bDiseaseRAmount = pType->bDiseaseR;
		pTarget->m_bPoisonRAmount = pType->bPoisonR;
		break;

	case BUFF_TYPE_ACCURACY:
		pTarget->m_bHitRateAmount = pType->bHitRate;
		pTarget->m_sAvoidRateAmount = pType->sAvoidRate;
		break;	

	case BUFF_TYPE_MAGIC_POWER:
		pTarget->m_sMagicAttackAmount = (pType->bMagicAttack - 100) * TO_USER(pTarget)->getStat(STAT_CHA) / 100;
		break;

	case BUFF_TYPE_EXPERIENCE:
		pTarget->m_bExpGainAmount = pType->bExpPct;
		break;

	case BUFF_TYPE_WEIGHT:
		pTarget->m_bMaxWeightAmount = pType->bExpPct;
		break;

	case BUFF_TYPE_WEAPON_DAMAGE:
		// uses pType->Attack
		break;

	case BUFF_TYPE_WEAPON_AC:
		if (pType->sAC == 0 && pType->sACPct > 0)
			pTarget->m_sACAmount = pTarget->m_sTotalAc * (pType->sACPct - 100) / 100;
		else
			pTarget->m_sACAmount = pType->sAC;
		break;

	case BUFF_TYPE_LOYALTY:
		// uses pType->ExpPct
		break;

	case BUFF_TYPE_NOAH_BONUS:
		break;

	case BUFF_TYPE_PREMIUM_MERCHANT:
		TO_USER(pTarget)->m_bPremiumMerchant = true;
		break;

	case BUFF_TYPE_ATTACK_SPEED_ARMOR:
		pTarget->m_sACAmount -= pType->sAC;
		pTarget->m_bAttackAmount = pType->bAttack;
		break;

	case BUFF_TYPE_DAMAGE_DOUBLE:
		pTarget->m_bAttackAmount = pType->bAttack;
		break;

	case BUFF_TYPE_DISABLE_TARGETING:
		pTarget->m_bIsBlinded = true;
		break;

	case BUFF_TYPE_BLIND:
		pTarget->m_bIsBlinded = true;
		if (pTarget->isPlayer())
			TO_USER(pTarget)->SendUserStatusUpdate(USER_STATUS_BLIND, USER_STATUS_INFLICT);
		break;

	case BUFF_TYPE_FREEZE:
		// Proportional to the target user's current HP.
		pTarget->m_bSpeedAmount = pType->bSpeed;
		break;

	case BUFF_TYPE_INSTANT_MAGIC:
		pTarget->m_bInstantCast = true;
		break;

	case BUFF_TYPE_DECREASE_RESIST:
		pTarget->m_bFireRAmount			= -(pType->bFireR / 100)	*	(pTarget->m_bFireR		- pTarget->m_bFireRAmount);
		pTarget->m_bColdRAmount			= -(pType->bColdR / 100)	*	(pTarget->m_bColdR		- pTarget->m_bColdRAmount);
		pTarget->m_bLightningRAmount	= -(pType->bLightningR / 100) * (pTarget->m_bLightningR - pTarget->m_bLightningRAmount);
		pTarget->m_bMagicRAmount		= -(pType->bMagicR / 100)	*	(pTarget->m_bMagicR		- pTarget->m_bMagicRAmount);
		pTarget->m_bDiseaseRAmount		= -(pType->bDiseaseR / 100) *	(pTarget->m_bDiseaseR	- pTarget->m_bDiseaseRAmount);
		pTarget->m_bPoisonRAmount		= -(pType->bPoisonR / 100)	*	(pTarget->m_bPoisonR	- pTarget->m_bPoisonRAmount);
		break;

	case BUFF_TYPE_MAGE_ARMOR:
		pTarget->m_bReflectArmorType = (pSkill->sSkill % 100);
		break;

	case BUFF_TYPE_PROHIBIT_INVIS:
		pTarget->m_bCanStealth = true;
		break;

	case BUFF_TYPE_RESIS_AND_MAGIC_DMG: // Elysian Web
		// Increases your magic resistance to block an additional 30% magic damage.
		break;

	case BUFF_TYPE_TRIPLEAC_HALFSPEED:	// Wall of Iron
		pTarget->m_sACAmount += pTarget->m_sTotalAc * 2;
		pTarget->m_bSpeedAmount = pTarget->m_bSpeedAmount / 2;
		if (pTarget->m_bSpeedAmount = 0)
			pTarget->m_bSpeedAmount = 1;
		break;

	case BUFF_TYPE_BLOCK_CURSE:			// Counter Curse
		// Blocks all curses.
		break;

	case BUFF_TYPE_BLOCK_CURSE_REFLECT:	// Curse Refraction
		// Blocks all curses and has a chance to reflect the curse back upon the caster.
		break;

	case BUFF_TYPE_MANA_ABSORB:		// Outrage / Frenzy / Mana Shield
		// Uses mana to receive damage (for mana shield its multiplied by 4, 100 damage = 400 mana used)
		break;

	case BUFF_TYPE_IGNORE_WEAPON:		// Weapon cancellation
		// Disarms the opponent. (rendering them unable to attack)
		break;

	case BUFF_TYPE_PASSION_OF_SOUL:		// Passion of the Soul
		// Increase pet's HP by 120
		break;

	case BUFF_TYPE_FIRM_DETERMINATION:	// Firm Determination
		// Increase pet's AC by 20
		break;

	case BUFF_TYPE_SPEED2:				// Cold Wave
		pTarget->m_bSpeedAmount = (pTarget->m_bSpeedAmount / 100 * 65);
		break;

	case BUFF_TYPE_ATTACK_RANGE_ARMOR:	// Inevitable Murderous
		pTarget->m_sACAmount += 100;
		// Increase attack range by 1 meter.
		break;

	case BUFF_TYPE_MIRROR_DAMAGE_PARTY: // Minak's Thorn
		// Spreads damage received across party members and mirror's part of the damage.
		break;

	default:
		return false;
	}
	return true;
}
Ejemplo n.º 19
0
bool CMagicProcess::RemoveType4Buff(uint8 byBuffType, Unit *pTarget)
{
	// Buff must be added at this point. If it doesn't exist, we can't remove it twice.
	FastGuard lock(pTarget->m_buffLock);
	auto itr = pTarget->m_buffMap.find(byBuffType);
	if (itr == pTarget->m_buffMap.end())
		return false;

	_MAGIC_TABLE * pSkill = g_pMain->m_MagictableArray.GetData(itr->second.m_nSkillID);
	if (pSkill == nullptr)
		return false;

	// If this buff persists across logout, it should be removed here too.
	if (pTarget->isPlayer()
		&& pTarget->HasSavedMagic(pSkill->iNum))
		TO_USER(pTarget)->RemoveSavedMagic(pSkill->iNum);

	pTarget->m_buffMap.erase(itr);

	switch (byBuffType)
	{
	case BUFF_TYPE_HP_MP:
		pTarget->m_sMaxHPAmount = 0;
		pTarget->m_sMaxMPAmount = 0;
		break;

	case BUFF_TYPE_AC:
		pTarget->m_sACAmount = 0;
		break;

	case BUFF_TYPE_SIZE:
		pTarget->StateChangeServerDirect(3, ABNORMAL_NORMAL);
		break;

	case BUFF_TYPE_DAMAGE:
		pTarget->m_bAttackAmount = 100;
		break;

	case BUFF_TYPE_ATTACK_SPEED:
		pTarget->m_bAttackSpeedAmount = 100;
		break;

	case BUFF_TYPE_SPEED:
		pTarget->m_bSpeedAmount = 100;
		break;

	case BUFF_TYPE_STATS:
		if (pTarget->isPlayer())
		{
			TO_USER(pTarget)->SetStatBuff(STAT_STR, 0);
			TO_USER(pTarget)->SetStatBuff(STAT_STA, 0);
			TO_USER(pTarget)->SetStatBuff(STAT_DEX, 0);
			TO_USER(pTarget)->SetStatBuff(STAT_INT, 0);
			TO_USER(pTarget)->SetStatBuff(STAT_CHA, 0);	
		}
		break;

	case BUFF_TYPE_RESISTANCES:
		pTarget->m_bFireRAmount = 0;
		pTarget->m_bColdRAmount = 0;
		pTarget->m_bLightningRAmount = 0;
		pTarget->m_bMagicRAmount = 0;
		pTarget->m_bDiseaseRAmount = 0;
		pTarget->m_bPoisonRAmount = 0;
		break;

	case BUFF_TYPE_ACCURACY:
		pTarget->m_bHitRateAmount = 100;
		pTarget->m_sAvoidRateAmount = 100;
		break;	

	case BUFF_TYPE_MAGIC_POWER:
		pTarget->m_sMagicAttackAmount = 0;
		break;

	case BUFF_TYPE_EXPERIENCE:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bExpGainAmount = 100;
		break;

	case BUFF_TYPE_WEIGHT:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bMaxWeightAmount = 100;
		break;

	case BUFF_TYPE_WEAPON_DAMAGE:
		// uses pType->Attack
		break;

	case BUFF_TYPE_WEAPON_AC:
		pTarget->m_sACAmount = 0;
		break;

	case BUFF_TYPE_LOYALTY:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bNPGainAmount = 100;
		break;

	case BUFF_TYPE_NOAH_BONUS:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bNoahGainAmount = 100;
		break;

	case BUFF_TYPE_PREMIUM_MERCHANT:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bPremiumMerchant = false;
		break;

	case BUFF_TYPE_ATTACK_SPEED_ARMOR:
		// should this revert a specific amount? if so, we need to store it so that we know how much.
		// most likely though, it's just recalculated.
		pTarget->m_sACAmount = 0;
		pTarget->m_bAttackAmount = 100;
		break;

	case BUFF_TYPE_DAMAGE_DOUBLE:
		pTarget->m_bAttackAmount = 100;
		break;

	case BUFF_TYPE_DISABLE_TARGETING:
		pTarget->m_bIsBlinded = false;
		break;

	case BUFF_TYPE_BLIND:
		// Only players can be blinded (at least by the only skill - "Blinding Strafe" - that uses this type).
		if (pTarget->isPlayer())
		{
			pTarget->m_bIsBlinded = false;
			TO_USER(pTarget)->SendUserStatusUpdate(USER_STATUS_POISON, USER_STATUS_CURE);
		}
		break;

	case BUFF_TYPE_FREEZE:
		// Proportional to the target user's current HP.
		pTarget->m_bSpeedAmount = 100;
		break;

	case BUFF_TYPE_INSTANT_MAGIC:
		pTarget->m_bInstantCast = false;
		break;

	case BUFF_TYPE_DECREASE_RESIST:
		pTarget->m_bFireRAmount			= 0;
		pTarget->m_bColdRAmount			= 0;
		pTarget->m_bLightningRAmount	= 0;
		pTarget->m_bMagicRAmount		= 0;
		pTarget->m_bDiseaseRAmount		= 0;
		pTarget->m_bPoisonRAmount		= 0;
		break;

	case BUFF_TYPE_MAGE_ARMOR:
		pTarget->m_bReflectArmorType = 0;
		break;

	case BUFF_TYPE_PROHIBIT_INVIS:
		pTarget->m_bCanStealth = false;
		break;

	case BUFF_TYPE_RESIS_AND_MAGIC_DMG: // Elysian Web
		pTarget->m_bMagicDamageReduction = 100;
		break;

	case BUFF_TYPE_TRIPLEAC_HALFSPEED:	// Wall of Iron
		pTarget->m_sACAmount -= pTarget->m_sTotalAc * 2; // TO-DO: Store this value independently for restoration
		pTarget->m_bSpeedAmount = 100;
		if (pTarget->m_bSpeedAmount = 0)
			pTarget->m_bSpeedAmount = 1;
		break;

	case BUFF_TYPE_BLOCK_CURSE:			// Counter Curse
		// Blocks all curses.
		pTarget->m_bBlockCurse = false;
		break;

	case BUFF_TYPE_BLOCK_CURSE_REFLECT:	// Curse Refraction
		// Blocks all curses and has a chance to reflect the curse back upon the caster.
		break;

	case BUFF_TYPE_MANA_ABSORB:		// Outrage / Frenzy / Mana Shield
		// Uses mana to receive damage (for mana shield its multiplied by 4, 100 damage = 400 mana used)
		break;

	case BUFF_TYPE_IGNORE_WEAPON:		// Weapon cancellation
		// Disarms the opponent. (rendering them unable to attack)
		break;

	case BUFF_TYPE_VARIOUS_EFFECTS: //... whatever the event item grants.
		// what is tweaked in the database: AC, Attack, MaxHP, resistances
		break;

	case BUFF_TYPE_PASSION_OF_SOUL:		// Passion of the Soul
		// Increase pet's HP by 120
		break;

	case BUFF_TYPE_FIRM_DETERMINATION:	// Firm Determination
		// Increase pet's AC by 20
		break;

	case BUFF_TYPE_SPEED2:				// Cold Wave
		pTarget->m_bSpeedAmount = 100;
		break;

	case BUFF_TYPE_UNK_EXPERIENCE:		// unknown buff type, used for something relating to XP.
		break;

	case BUFF_TYPE_ATTACK_RANGE_ARMOR:	// Inevitable Murderous
		pTarget->m_sACAmount -= 100;
		// Buff type increases attack range by 1 meter.
		break;

	case BUFF_TYPE_MIRROR_DAMAGE_PARTY: // Minak's Thorn
		// Spreads damage received across party members and mirror's part of the damage.
		break;

	case BUFF_TYPE_DAGGER_BOW_DEFENSE: // Eskrima
		// Inflicts attacks as well as a bleeding curse on the enemy. Decreases 10% Dagger and Bow Defense of the enemy under the bleeding curse buff.
		break;

	case BUFF_TYPE_LOYALTY_AMOUNT:		// Santa's Present (gives an extra +2NP per kill, unlike BUFF_TYPE_LOYALTY which uses an percent).
		break;

	case BUFF_TYPE_NO_RECALL:			// prevents teleportation.
		break;

	case BUFF_TYPE_REDUCE_TARGET:		// "Reduction" (reduces target's stats, but enlarges their character to make them easier to attack)
		break;

	case BUFF_TYPE_SILENCE_TARGET:		// Silences the target to prevent them from using any skills (or potions)
		break;

	case BUFF_TYPE_NO_POTIONS:			// "No Potion" prevents target from using potions.
		break;

	case BUFF_TYPE_KAUL_TRANSFORMATION:	// Transforms the target into a Kaul (a pig thing), preventing you from /town'ing or attacking, but increases defense.
		break;

	case BUFF_TYPE_UNDEAD:				// User becomes undead, increasing defense but preventing the use of potions and converting all health received into damage.
		break;

	case BUFF_TYPE_UNSIGHT:				// Unsure how this is different to "Blind", but skill description simply reads "Blocks your[the target's] sight."
		break;

	case BUFF_TYPE_BLOCK_PHYSICAL_DAMAGE: // Blocks all physical damage.
		break;

	case BUFF_TYPE_BLOCK_MAGICAL_DAMAGE: // Blocks all magical/skill damage.
		break;

	case BUFF_TYPE_UNK_POTION:			// unknown potion, "Return of the Warrior", "Comeback potion", perhaps some sort of revive?
		break;
		
	case BUFF_TYPE_SLEEP:				// Zantman(Sandman), puts enemies to sleep.
		break;

	case BUFF_TYPE_INVISIBILITY_POTION:	// "Unidentified potion"
		break;

	case BUFF_TYPE_GODS_BLESSING:		// Increases your defense/max HP 
		break;

	case BUFF_TYPE_HELP_COMPENSATION:	// Compensation for using the help system (to help, ask for help, both?)
		break;

	default:
		return false;
	}

	if (pTarget->isPlayer())
	{
		if (pSkill->bMoral >= MORAL_ENEMY)
		{
			if (byBuffType == BUFF_TYPE_SPEED || byBuffType == BUFF_TYPE_SPEED2)
				TO_USER(pTarget)->SendUserStatusUpdate(USER_STATUS_SPEED, USER_STATUS_CURE);
		}

		TO_USER(pTarget)->SetSlotItemValue();
		TO_USER(pTarget)->SetUserAbility();

		Packet result(WIZ_MAGIC_PROCESS, uint8(MAGIC_TYPE4_END));
		result << byBuffType;
		TO_USER(pTarget)->Send(&result);
	}

	return true;
}