Exemplo n.º 1
0
/* Angelox: This is why the pets ghost - pets were being spawned too far away from its npc owner and some
into walls or objects (+10), this sometimes creates the "ghost" effect. I changed to +2 (as close as I 
could get while it still looked good). I also noticed this can happen if an NPC is spawned on the same spot of another or in a related bad spot.*/
Pet::Pet(NPCType *type_data, Mob *owner, PetType type, int16 spell_id, sint16 power)
: NPC(type_data, 0, owner->GetX()+2, owner->GetY()+2, owner->GetZ(), owner->GetHeading(), FlyMode3)
{
	GiveNPCTypeData(type_data);
	typeofpet = type;
	petpower = power;
	SetOwnerID(owner->GetID());
	SetPetSpellID(spell_id);
	taunting = true;
}
Exemplo n.º 2
0
/* This is why the pets ghost - pets were being spawned too far away from its npc owner and some
into walls or objects (+10), this sometimes creates the "ghost" effect. I changed to +2 (as close as I
could get while it still looked good). I also noticed this can happen if an NPC is spawned on the same spot of another or in a related bad spot.*/
Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power)
: NPC(type_data, 0, owner->GetPosition() + glm::vec4(2.0f, 2.0f, 0.0f, 0.0f), FlyMode3)
{
	GiveNPCTypeData(type_data);
	typeofpet = type;
	petpower = power;
	SetOwnerID(owner->GetID());
	SetPetSpellID(spell_id);
	taunting = true;

	// Class should use npc constructor to set light properties
}
Exemplo n.º 3
0
///////////////////////////////////////////////////
// Quagmire - that case above getting to long and spells are gonna have a lot of cases of their own
// Cofruben - Reorganised this a little.
void Mob::SpellEffect(Mob* caster, Spell* spell, int8 caster_level, bool partialResist)
{
	//Spells not loaded!
	if(!spells_handler.SpellsLoaded())
		return;
	//Spell not loaded!
	if(!spell)
		return;
	//Yeahlight: Caster was not supplied
	if(!caster)
		return;

	int i = 0;
	const int16	spell_id		= spell->GetSpellID();
	const char*	teleport_zone	= spell->GetSpellTeleportZone();
	
	// 1. Is it a buff? If so, handle its time based effects.
	if (spell->IsBuffSpell())
		spells_handler.HandleBuffSpellEffects(caster, this, spell);
	
	// 2. Handle its single-time effect.
	for (i = 0; i < EFFECT_COUNT; i++)
	{
		TSpellEffect effect_id = spell->GetSpellEffectID(i);
		if(effect_id == SE_Blank || effect_id == 0xFF)
			continue;
		int8   formula = spell->GetSpellFormula(i);
		sint16 base    = spell->GetSpellBase(i);
		sint16 max     = spell->GetSpellMax(i);	
		sint32 amount  = spells_handler.CalcSpellValue(spell, i, caster_level);
		//Yeahlight: This is an NPC and had a detremental spell casted upon it
		if(this->IsNPC() && (spell->IsDetrimentalSpell() || spell->IsUtilitySpell()))
		{
			CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): aggroing %s because of the spell effect!", spell->GetSpellName(), this->GetName());
			//Yeahlight: Generate hate based on the spells's effect type
			sint16 tempHate = GetSpellHate(effect_id, spell->GetMinLevel(), false, amount);
			if(tempHate)
			{
				this->CastToNPC()->AddToHateList(caster, 0, tempHate);
			}
		}
		switch(effect_id)
		{
			case SE_CurrentHP:
			case SE_CurrentHPOnce:
			{
				sint32 OldHP = this->GetHP();
				sint32 damage = amount;
				//Yeahlight: Partial resist calculations
				if(partialResist)
				{
					damage = damage / 2;
					damage = damage * (float)((float)(rand()%90 + 10) / 100.00f);
					if(caster->IsClient() && caster->CastToClient()->GetDebugMe())
						caster->Message(YELLOW, "Debug: Your direct damage spell resist has been upgrade to a partial resist.");
				}
				this->ChangeHP(caster, damage, spell_id);
				sint32 NewHP = this->GetHP();
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You changed %s's hp by %+i.", spell->GetSpellName(), this->GetName(), damage);
				break;
			}
			case SE_MovementSpeed:
			{
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a Movement Speed spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_AttackSpeed:
			{
				//Yeahlight: There should not be any work to be done here
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a Attack Speed spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Invisibility: 
			{
				this->SetInvisible(true);
				//Yeahlight: Castee has a pet; remove it
				if(GetPet())
				{
					Mob* myPet = GetPet();
					//Yeahlight: Castee's pet is an NPC
					if(myPet->IsNPC())
					{
						//Yeahlight: Castee's pet is a charmed NPC
						if(myPet->CastToNPC()->IsCharmed())
						{
							myPet->CastToNPC()->BuffFadeByEffect(SE_Charm);
						}
						//Yeahlight: Castee's pet is a summoned NPC
						else
						{
							myPet->Depop();
						}
					}
					//Yeahlight: Castee's pet is a charmed PC
					else if(myPet->IsClient() && myPet->CastToClient()->IsCharmed())
					{
						myPet->CastToClient()->BuffFadeByEffect(SE_Charm);
					}
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted an invisibility spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_CurrentMana:
			{
				SetMana(GetMana() + amount);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a mana recovery spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_AddFaction:
			{
				//Yeahlight: Only continue if the target is an NPC and the caster is a PC
				if(this->IsNPC() && caster->IsClient())
				{
					caster->CastToClient()->SetCharacterFactionLevelModifier(this->CastToNPC()->GetPrimaryFactionID(), amount);
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted an add faction spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Stun:
			{
				if (IsClient())
				{
					CastToClient()->Stun(base);
				}
				else if(IsNPC())
				{
					//Yeahlight: NPC is immune to stun effects
					if(CastToNPC()->GetCannotBeStunned())
					{
						if(caster->IsClient())
						{
							caster->Message(RED, "Your target is immune to the stun portion of this effect");
						}
					}
					else
					{
						CastToNPC()->Stun(base);
					}
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a stun spell, amount: %i.", spell->GetSpellName(), base);
				break;
			}
			case SE_Charm:
			{
				//Yeahlight: Can only charm a non-pet and the caster may only have one pet
				if(this->GetOwner() == NULL && caster->GetPet() == NULL && caster != this)
				{
					//Yeahlight: Flag the NPC as a pet
					if(this->IsNPC())
					{
						caster->SetPet(this);
						this->SetOwnerID(caster->GetID());
						this->CastToNPC()->SetCharmed(true);
						this->SetPetOrder(SPO_Follow);
						if(caster->IsClient())
							caster->CastToClient()->SendCharmPermissions();
						this->CastToNPC()->WhipeHateList();
						this->CastToNPC()->StartTaunting();
					}
					else if(this->IsClient())
					{
						if(caster->IsNPC())
						{
							caster->SetPet(this);
							this->SetOwnerID(caster->GetID());
							Mob* myTarget = caster->CastToNPC()->GetHateTop();
							if(!myTarget)
								myTarget = caster->CastToMob();
							this->SetTarget(myTarget);
							this->animation = 0;
							this->delta_heading = 0;
							this->delta_x = 0;
							this->delta_y = 0;
							this->delta_z = 0;
							this->SendPosUpdate(true, PC_UPDATE_RANGE, false);
							this->CastToClient()->charmPositionUpdate_timer->Start(200);
							this->CastToClient()->SetCharmed(true);
							this->SendAppearancePacket(this->GetID(), SAT_Position_Update, SAPP_Lose_Control, false);
							this->SetPetOrder(SPO_Follow);
						}
						else if(caster->IsClient())
						{
							caster->SetPet(this);
							this->SetOwnerID(caster->GetID());
							this->SetTarget(caster);
							this->animation = 0;
							this->delta_heading = 0;
							this->delta_x = 0;
							this->delta_y = 0;
							this->delta_z = 0;
							this->SendPosUpdate(true, PC_UPDATE_RANGE, false);
							this->CastToClient()->charmPositionUpdate_timer->Start(200);
							this->CastToClient()->SetCharmed(true);
							this->SendAppearancePacket(this->GetID(), SAT_Position_Update, SAPP_Lose_Control, false);
							this->SetPetOrder(SPO_Follow);
							caster->CastToClient()->SendCharmPermissions();
						}
					}
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a charm spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Fear:
			{
				//Yeahlight: Victim is a PC
				if(this->IsClient())
				{
					this->CastToClient()->SetFeared(true);
					this->SendAppearancePacket(this->GetID(), SAT_Position_Update, SAPP_Lose_Control, false);
					this->CastToClient()->GetFearDestination(GetX(), GetY(), GetZ());
				}
				//Yeahlight: Victim is an NPC
				else if(this->IsNPC())
				{
					this->CastToNPC()->SetFeared(true);
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a fear spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Stamina:
			{
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a stamina spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_BindAffinity:
			{
				//Yeahlight: Target of the bind affinity spell is a client
				if(this->IsClient())
				{
					this->CastToClient()->SetBindPoint();
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a Bind Affinity spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Gate:
			{
				if(IsClient())
					CastToClient()->GoToBind();
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a gate spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_CancelMagic:
			{
				for(int i = 0; i < 15; i++)
				{
					//Yeahlight: Buff must exist and the buff may not have any poison or disease counters
					if(buffs[i].spell && buffs[i].spell->IsValidSpell() && buffs[i].casterlevel <= (caster_level + base) && buffs[i].spell->GetDiseaseCounters() == 0 && buffs[i].spell->GetPoisonCounters() == 0)
					{	
						this->BuffFadeBySlot(i, true);
						break;
					}
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a cancel magic spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_InvisVsUndead:
			{
				this->SetInvisibleUndead(true);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted an Invis VS Undead spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_InvisVsAnimals:
			{
				this->SetInvisibleAnimal(true);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted an Invis VS Animal spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Mez:
			{
				// Pinedepain // When a mezz spell is casted, we mesmerize this mob
				Mesmerize();
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a mesmerize spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_SummonItem:
			{
				if(this->IsClient())
				{
					if(amount == 0)
						this->CastToClient()->SummonItem(base, 1);
					else
						this->CastToClient()->SummonItem(base, (amount > 20) ? 20 : amount);
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a summon item spell: %i.", spell->GetSpellName(), base);
				break;
			}
			case SE_NecPet:
			case SE_SummonPet:
			{
				if (this->GetPetID() != 0) {
					Message(RED, "You\'ve already got a pet.");
					break;
				}
				this->MakePet(teleport_zone);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a Summon pet / nec pet spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_DivineAura:
			{
				this->SetInvulnerable(true);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a Divine Aura, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_ShadowStep:
			{
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a Shadow Step spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Rune:
			{
				//Yeahlight: Flag entity with rune for damage calculations
				hasRuneOn = true;
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a Rune spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Levitate:
			{
				this->SendAppearancePacket(0, SAT_Levitate, 2, true);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a levitate spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_SummonCorpse:
			{
				bool permit = false;
				Mob* corpseOwner = target;
				//Yeahlight: The target of this spell is not a PC or the caster is targeting themself
				if(!target || (target && !target->IsClient()) || target == this)
				{
					corpseOwner = this;
					permit = true;
				}
				//Yeahlight: Can only summon a PC's corpse
				if(corpseOwner && corpseOwner->IsClient())
				{
					//Yeahlight: PCs must be grouped to summon a corpse
					if(!permit)
					{
						Group* targetGroup = entity_list.GetGroupByClient(corpseOwner->CastToClient());
						Group* myGroup = NULL;
						if(this->IsClient())
							myGroup = entity_list.GetGroupByClient(this->CastToClient());
						//Yeahlight: Caster is in a group and they share the same group as the target
						if(myGroup != NULL && myGroup == targetGroup)
							permit = true;
					}
					//Yeahlight: Caster may proceed with the summon
					if(permit)
					{
						Corpse *corpse = entity_list.GetCorpseByOwner(corpseOwner->CastToClient());
						//Yeahlight: Corpse has been located
						if(corpse)
						{
							corpse->Summon(corpseOwner->CastToClient(), caster->CastToClient(), true);
							CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a summon corpse spell: %s.", spell->GetSpellName(), this->GetName());
						}
						//Yeahlight: There is no corpse available
						else
						{
							//Yeahlight: Caster failed to locate his/her corpse
							if(caster == corpseOwner)
							{
								caster->Message(RED, "You do not have a corpse in this zone.");
							}
							//Yeahlight: Caster failed to locate their target's corpse
							else
							{
								caster->Message(RED, "Your target does not have a corpse in this zone.");
							}
							CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): Summon corpse: you can't sense the corpse: %i.", spell->GetSpellName());
						}
					}
					else
					{
						//Yeahlight: TODO: This is not the correct message
						Message(RED, "You and your target must be in the same group to perform this action.");
					}
				}
				break;
			}
			case SE_Illusion:
			{
				SendIllusionPacket(base, GetDefaultGender(base, GetBaseGender()), GetTexture(), GetHelmTexture());
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted an illusion spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Identify:
			{
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted an identify spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_WipeHateList:
			{
				//Yeahlight: NOTE: Do NOT wipe the rampage list here; that never goes away until the mob resets
				if(this->IsNPC())
				{
					//Yeahlight: TODO: I don't remember this message, look into this
					entity_list.MessageClose(this, true, DEFAULT_MESSAGE_RANGE, DARK_BLUE, "My mind fogs. Who are my friends? Who are my enemies?... it was all so clear a moment ago...");
					this->CastToNPC()->WhipeHateList();
					CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a whipe hate list spell, amount: %i.", spell->GetSpellName(), amount);
				}
				break;
			}
			case SE_SpinTarget:
			{
				Spin(caster, spell);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a spin target spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_EyeOfZomm:
			{
				//Yeahlignt: Only produce eyes of zomm for PCs
				if(this->IsClient())
				{
					if(this->CastToClient()->myEyeOfZomm == 0)
						MakeEyeOfZomm(this);
					else
						Message(RED, "You may only have one eye of zomm out at a time!");
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a Eye Of Zomm spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_ReclaimPet:
			{
				//Yeahlight: Target of the spell is an uncharmed NPC, has an owner and the owner is the caster of the spell
				if(IsNPC() && CastToNPC()->IsCharmed() == false && GetOwnerID() && caster->GetID() == GetOwnerID())
				{
					//Yeahlight: TODO: Research this formula
					caster->SetMana(caster->GetMana()+(GetLevel()*4));
					if(caster->IsClient())
					{
						caster->CastToClient()->SetPet(0);
					}
					SetOwnerID(0);
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a reclaim pet spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_FeignDeath:
			{
				if(this->IsClient())
					this->CastToClient()->FeignDeath(this->CastToClient()->GetSkill(ABJURATION));
				break;
			}
			case SE_VoiceGraft:
			{
				//Yeahlight: Only allow voice graft to be casted on NPCs (we don't want PCs griefing other charmed PCs with /say)
				if(IsNPC() && caster->IsClient() && CastToNPC()->GetOwner() == caster)
				{
					caster->CastToClient()->SetVoiceGrafting(true);
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a voice graft spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Revive:
			{
				//Yeahlight: Handled in client_process.cpp
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a revive spell, amount: %i, corpse: %s.", spell->GetSpellName(), amount, this->GetName());
				break;
			}
			case SE_Teleport:
			{
				char teleport_zone_char[64];
				if(this->IsClient())
					strcpy(teleport_zone_char, teleport_zone);
					this->CastToClient()->MovePC(teleport_zone_char, spell->GetSpellBase(1), spell->GetSpellBase(0), spell->GetSpellBase(2), false, false);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a teleport spell to %s (%f, %f, %f).", spell->GetSpellName(), teleport_zone, spell->GetSpellBase(1), spell->GetSpellBase(0), spell->GetSpellBase(2));
				break;
			}
			case SE_Translocate:
			{
				bool permit = false;
				Mob* translocatee = CastToMob();

				//Enraged: The target of this spell is an NPC.
				//if(translocatee && !translocatee->IsClient())
				//{
				//	//Enraged: TODO: This is not the correct message?
				//	Message(RED, "You cannot cast that spell on your current target.");
				//	break;
				//}

				//Enraged: The target of this spell is the caster.
				//TODO: Can players target themselves with translocate spells?
				if(translocatee && (translocatee == this))
					permit = true;

				//Enraged: Check if the targetted client is in the casters group.
				//TODO: Translocate only worked on group players, right?
				if(!permit && translocatee)
				{
					Group* translocateeGroup = entity_list.GetGroupByClient(translocatee->CastToClient());
					Group* casterGroup = NULL;
					if(this->IsClient())
						casterGroup = entity_list.GetGroupByClient(this->CastToClient());
					//Enraged: The translocatee is in a group and they share the same group as the target
					if(casterGroup != NULL && casterGroup == translocateeGroup)
						permit = true;
				}

				//Enraged: Target is clear to be translocated.
				if(permit)
				{
					CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a translocation spell on %s.", spell->GetSpellName(), translocatee->GetName());
					//TODO: Translocate code here
					translocatee->CastToClient()->SendTranslocateConfirmation(caster, spell);
				}
				else
				{
					//The translocatee was not in the casters group.
					//Enraged: TODO: This is not the correct message
					Message(RED, "You can only cast that spell on players in your group.");
				}
				break;
			}
			case SE_InfraVision:
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted an infravision spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_UltraVision:
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted an ultravision spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_BindSight:
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a bind sight spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_SeeInvis:
				SetCanSeeThroughInvis(true);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a see invis spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_WaterBreathing:
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted an water breathing spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_SenseDead:
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a sense dead spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_SenseSummoned:
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a sense summoned spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_TrueNorth: 
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a true north spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_SenseAnimals:
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a sense animals spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_DamageShield:
				//Yeahlight: There should not be any work to be done here
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a damage shield spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_Sentinel:
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a sentinel spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_LocateCorpse:
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a locate corpse spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_ModelSize:
			{
				//Yeahlight: Grow/Shrink
				float newSize = (GetSize() * (float)base) / 100.00f;
				//Yeahlight: Size of a gnome (minimum)
				if(newSize < 3)
					newSize = 3;
				//Yeahlight: Size of an ogre (maximum)
				else if(newSize > 9)
					newSize = 9;
				this->size = newSize;
				this->SendAppearancePacket(GetID(), SAT_Size, GetSize(), true);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a model size spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Root:
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a root spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_Blind:
				//Yeahlight: Handled client side
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a blind spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			case SE_DiseaseCounter:
			{
				//Yeahlight: Spell is a cure disease spell
				if(amount < 0)
				{
					//Yeahlight: Iterate through all the debuffs on the target and check for the chance to cure it
					for(int i = 0; i < 15; i++)
					{
						if(buffs[i].spell && buffs[i].diseasecounters)
						{
							buffs[i].diseasecounters = buffs[i].diseasecounters + amount;
							if(buffs[i].diseasecounters <= 0)
								BuffFadeBySlot(i, true);
							break;
						}
					}
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a disease counter spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_PoisonCounter:
			{
				//Yeahlight: Spell is a cure poison spell
				if(amount < 0)
				{
					//Yeahlight: Iterate through all the debuffs on the target and check for the chance to cure it
					for(int i = 0; i < 15; i++)
					{
						if(buffs[i].spell && buffs[i].poisoncounters)
						{
							buffs[i].poisoncounters = buffs[i].poisoncounters + amount;
							if(buffs[i].poisoncounters <= 0)
								BuffFadeBySlot(i, true);
							break;
						}
					}
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a poison counter spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_Calm:
			{
				//Yeahlight: Only add/remove hate from NPCs
				if(this->IsNPC())
				{
					this->CastToNPC()->AddToHateList(caster, 0, amount);
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): You casted a calm hate spell, amount: %i.", spell->GetSpellName(), amount);
				break;
			}
			case SE_WeaponProc:
			{
				Spell* spell = spells_handler.GetSpellPtr(base);
				//Yeahlight: Legit spell proc bonus found
				if(spell)
					SetBonusProcSpell(spell);
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell name = %s): Weapon proc bonus of spell ID %i.", spell->GetSpellName(), base);
				break;
			}
			case SE_StopRain:
			{
				zone->zone_weather = 0;
				zone->weatherSend();
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::ApplySpellsBonuses(spell name = %s): You casted a stop rain spell, amount: %i.", spell->GetSpellName(), base);
				break;
			}
			case SE_CallOfHero:
			{
				//Yeahlight: Call of the Hero may only be used on PCs
				int32 zoneid = 0;
				if(this->IsClient())
					this->CastToClient()->MovePC(zoneid, caster->GetX(), caster->GetY(), caster->GetZ(), false, true);
				else
					caster->Message(RED, "This spell may only be cast on players.");
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::ApplySpellsBonuses(spell name = %s): You casted a call of the hero spell, amount: %i.", spell->GetSpellName(), base);
				break;
			}
			case SE_CallPet:
			{
				//Yeahlight: This spell line may only be used on NPC pets
				if(GetPet() && GetPet()->IsNPC())
				{
					GetPet()->CastToNPC()->GMMove(GetX(), GetY(), GetZ(), GetHeading());
					GetPet()->pStandingPetOrder = SPO_Follow;
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::ApplySpellsBonuses(spell name = %s): You casted a call pet spell, amount: %i.", spell->GetSpellName(), base);
				break;
			}
			case SE_DeathSave:
			{
				//Yeahlight: Only apply divine intervention to players
				if(this->IsClient())
				{
					sint16 successChance = 0;
					float baseChance = 0.00f;
					switch(base)
					{
						//Yeahlight: Death Pact (CLR: 51)
						case 1:
						{
							baseChance = 0.10f;
							break;
						}
						//Yeahlight: Divine Intervention (CLR: 60)
						case 2:
						{
							baseChance = 0.30f;
							break;
						}
						default:
						{
							baseChance = 0.10f;
						}
					}
					//Yeahlight: The target's CHA is calculated into the bonus save chance
					successChance = (((float)CastToClient()->GetCHA() * 0.0005f) + baseChance) * 100;
					//Yeahlight: The worst possible save chance is the spell's base chance
					if(successChance < baseChance)
						successChance = baseChance;
					else if(successChance > 100)
						successChance = 100;
					this->CastToClient()->SetDeathSave(successChance);
				}
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::ApplySpellsBonuses(spell name = %s): You casted a death save spell, amount: %i.", spell->GetSpellName(), base);
				break;
			}
			case SE_Succor:
			{
				//Yeahlight: There should be nothing to do here
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::ApplySpellsBonuses(spell name = %s): You casted a succor spell, amount: %i.", spell->GetSpellName(), base);
				break;
			}
			case 0xFE:
			case 0xFF:
			case SE_Harmony:
			case SE_ChangeFrenzyRad:
			case SE_Lull:
			case SE_TotalHP:
			case SE_ArmorClass:
			case SE_MagnifyVision:
			case SE_ATK:
			case SE_STR:
			case SE_DEX:
			case SE_AGI:
			case SE_STA:
			case SE_INT:
			case SE_WIS:
			case SE_CHA:
			case SE_ResistFire:
			case SE_ResistCold:
			case SE_ResistPoison:
			case SE_ResistDisease:
			case SE_ResistMagic:
			{
				// Buffs are handeled elsewhere
				break;
			}
			default:
			{
				CAST_CLIENT_DEBUG_PTR(caster)->Log(CP_SPELL, "Mob::SpellEffect(spell_name = %s): unknown effect (%i) for amount: %i.", spell->GetSpellName(), effect_id, amount);
				break;
			}
		}
	}
	if(this->IsClient())
		this->CastToClient()->Save();
}