Exemple #1
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;
	}
bool CMagicProcess::RemoveType4Buff(uint8 byBuffType, Unit *pTarget, bool bRemoveSavedMagic /*= true*/)
{
	// 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 (bRemoveSavedMagic
		&& 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:
		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_bAddFireR		= 0;
		pTarget->m_bAddColdR		= 0;
		pTarget->m_bAddLightningR	= 0;
		pTarget->m_bAddMagicR		= 0;
		pTarget->m_bAddDiseaseR		= 0;
		pTarget->m_bAddPoisonR		= 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:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bAddWeaponDamage = 0;
		break;

	case BUFF_TYPE_WEAPON_AC:
		if (pType->sAC == 0 && pType->sACPct > 0)
			TO_USER(pTarget)->m_bPctArmourAc -= (pType->sACPct - 100);
		else
			TO_USER(pTarget)->m_sAddArmourAc -= pType->sAC;
		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_bPctFireR		= 100;
		pTarget->m_bPctColdR		= 100;
		pTarget->m_bPctLightningR	= 100;
		pTarget->m_bPctMagicR		= 100;
		pTarget->m_bPctDiseaseR		= 100;
		pTarget->m_bPctPoisonR		= 100;
		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
#if defined(GAMESERVER)
		if (pTarget->isPlayer())
		{
			CUser * pTUser = TO_USER(pTarget);
			_ITEM_DATA * pLeftItem, * pRightItem;

			_ITEM_TABLE * pLeftHand  = pTUser->GetItemPrototype(LEFTHAND, pLeftItem),
				* pRightHand = pTUser->GetItemPrototype(RIGHTHAND, pRightItem);

			pTUser->m_bWeaponsDisabled = false;

			if (pLeftHand != nullptr)
				pTUser->UserLookChange(LEFTHAND, pLeftItem->nNum, pLeftItem->sDuration);

			if (pRightHand != nullptr)
				pTUser->UserLookChange(RIGHTHAND, pRightItem->nNum, pRightItem->sDuration);
		}
#endif
		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_STUN : // Lighting Skill
		pTarget->m_bSpeedAmount = 100;
		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_DURATION_EXPIRED));
		result << byBuffType;
		TO_USER(pTarget)->Send(&result);
	}

#if defined(GAMESERVER) // update the target data in the AI server.
	UpdateAIServer(pType->iNum, AISkillOpcodeRemoveBuff, pTarget);
#endif

	return true;
}
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_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
				bEffect = ABNORMAL_GIANT;
				break;

			case 490401: // Maximize Scroll
				bEffect = ABNORMAL_GIANT_TARGET; // NOTE: not sure why, but this is what it uses officially.
				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_bAddFireR = pType->bFireR;
		pTarget->m_bAddColdR = pType->bColdR;
		pTarget->m_bAddLightningR = pType->bLightningR;
		pTarget->m_bAddMagicR = pType->bMagicR;
		pTarget->m_bAddDiseaseR = pType->bDiseaseR;
		pTarget->m_bAddPoisonR = 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:
		if (pTarget->isPlayer())
			TO_USER(pTarget)->m_bAddWeaponDamage = pType->bAttack;
		break;

	case BUFF_TYPE_WEAPON_AC:
		if (pTarget->isPlayer())
		{
			if (pType->sAC == 0 && pType->sACPct > 0)
				TO_USER(pTarget)->m_bPctArmourAc += (pType->sACPct - 100);
			else
				TO_USER(pTarget)->m_sAddArmourAc += pType->sAC;
		}
		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_bPctFireR		= (100 - pType->bFireR);
		pTarget->m_bPctColdR		= (100 - pType->bColdR);
		pTarget->m_bPctLightningR	= (100 - pType->bLightningR);
		pTarget->m_bPctMagicR		= (100 - pType->bMagicR);
		pTarget->m_bPctDiseaseR		= (100 - pType->bDiseaseR);
		pTarget->m_bPctPoisonR		= (100 - pType->bPoisonR);
		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)
#if defined(GAMESERVER)
		if (pTarget->isPlayer())
		{
			CUser * pTUser = TO_USER(pTarget);

			pTUser->m_bWeaponsDisabled = true;
			pTUser->UserLookChange(RIGHTHAND, 0, 0);

			_ITEM_TABLE * pLeftHand = pTUser->GetItemPrototype(LEFTHAND);
			if (pLeftHand != nullptr && !pLeftHand->isShield())
				pTUser->UserLookChange(LEFTHAND, 0, 0);
		}
#endif
		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 * pType->bSpeed);
		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_STUN:
		pTarget->m_bSpeedAmount = pType->bSpeed; 
		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_TARGET);
			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;
	}

#if defined(GAMESERVER)		// update the target data in the AI server.
	UpdateAIServer(pSkill->iNum, AISkillOpcodeBuff, pCaster, pTarget, bIsRecastingSavedMagic);
#elif defined(AI_SERVER)	// on the AI server's side, add the buff to the target's buff map.
	_BUFF_TYPE4_INFO buffInfo;
	buffInfo.m_nSkillID = pSkill->iNum;
	pTarget->AddType4Buff(pType->bBuffType, buffInfo);
#endif

	return true;
}