/// Returns true if the spell was resisted
bool CMagicActionBasicDamage::computeMagicResistance(
	CEntityBase* const target,
	CTargetInfos& targetInfos,
	uint32 const casterSkillvalue,
	DMGTYPE::EDamageType const _DmgType,
	sint32 _DmgHp,
	CEntityBase const* const actor,
	float rangeFactor,
	float powerFactor)
{
	// test resistance
	float resistFactor = 1.0f;
	//if entity invincible, it aways resists the effect
	const CSEffectPtr effect = target->lookForActiveEffect(EFFECT_FAMILIES::Invincibility);
	if ( effect )
	{
		targetInfos.Immune = true;
		resistFactor = 0.0f;
	}
	else
	{
		if (!EntitiesNoResist)
		{
			uint32 resistValue = target->getMagicResistance(_DmgType);
			
			if (resistValue == CCreatureResists::ImmuneScore )
			{
				targetInfos.Immune = true;
				resistFactor = 0.0f;
			}
			else
			{
				uint32 localCasterSkillValue = casterSkillvalue;

				if ( actor->getId().getType() == RYZOMID::player )
				{
					// boost magic skill for low level chars
					uint32 sb = (uint32)MagicSkillStartValue.get();
					localCasterSkillValue = max( sb, localCasterSkillValue );

					// add magic boost from consumable
					CCharacter * pC = (CCharacter *)actor;
					localCasterSkillValue += pC->magicSuccessModifier();
				}

				// get the chances
				const uint8 roll = (uint8)RandomGenerator.rand( 99 );
				resistFactor = CStaticSuccessTable::getSuccessFactor(SUCCESS_TABLE_TYPE::MagicResistDirect, localCasterSkillValue - resistValue, roll);
				
				// increase resists modifier for next resists test
				if (resistFactor > 0.0f)
					target->incResistModifier(_DmgType, resistFactor);
				
				if ( resistFactor <= 0.0f )
				{
					// Xp gain log
					if (PlayerManager.logXPGain(actor->getEntityRowId()))
					{
						const uint8 chances = CStaticSuccessTable::getSuccessChance( SUCCESS_TABLE_TYPE::MagicResistDirect, localCasterSkillValue - resistValue ); 
						nlinfo("[XPLOG] Magic attack Actor %s on %s, delta = %d, target has Resisted (chances %u, tirage %u)", actor->getId().toString().c_str(), target->getId().toString().c_str(),
							targetInfos.ReportAction.DeltaLvl, chances, roll);
					}
				}
			}
		}
		else
		{
			resistFactor = 1.0f;
		}
	}
	if ( resistFactor > 0.0f )
	{
		if ( resistFactor > 1.0f )
			resistFactor = 1.0f;
		
		float dmgFactor = resistFactor * rangeFactor * (1.0f + powerFactor);
		
		// if PVP, apply PVP magic damage factor
		if( actor != target && actor->getId().getType() == RYZOMID::player && target->getId().getType() == RYZOMID::player)
		{
			dmgFactor *= PVPMagicDamageFactor.get();
		}

		// add spire effect ( magic offense )
		if ( actor->getId().getType() == RYZOMID::player )
		{
			CCharacter* charac = (CCharacter*)actor;
			const CSEffect* pEffect = charac->lookForActiveEffect( EFFECT_FAMILIES::TotemCombatMagOff );
			if ( pEffect != NULL )
			{
				dmgFactor *= ( 1.0f + pEffect->getParamValue() / 100.0f );
			}
		}
		
		sint32 realDmgHp =  sint32 ( _DmgHp * dmgFactor );
		
		// update target infos
		targetInfos.DmgHp			= realDmgHp;
		targetInfos.ResistFactor	= resistFactor;
		targetInfos.DmgFactor		= dmgFactor;
		
		return false;
	}
	else
	{
		return true;
	}
}
bool CMagicActionBasicDamage::launchOnEntity(
	CMagicPhrase*		phrase,
	CEntityBase*		actor,
	CEntityBase*		target,
	bool				mainTarget,
	uint32				casterSkillvalue,
	uint32				casterSkillBaseValue,
	MBEHAV::CBehaviour&	behav,
	bool				isMad,
	float				rangeFactor,
	CTargetInfos&		targetInfos)
{
	// for main target only, check reflect damage effects
	if (mainTarget)
	{
		const CSEffectPtr effect = target->lookForActiveEffect(EFFECT_FAMILIES::ReflectDamage);
		if ( effect )
		{
			target = actor;
			isMad = true;
		}
	}

	// change caster skill according to target race (for special items that gives a skill bonus against Kitins for exemple)
	casterSkillvalue += actor->getSkillModifierForRace(target->getRace());

	// init target infos
	targetInfos.RowId			= target->getEntityRowId();
	targetInfos.MainTarget		= mainTarget;
	targetInfos.DmgHp			= 0;
	targetInfos.ResistFactor	= 1.0f;
	targetInfos.DmgFactor		= 1.0f;
	targetInfos.Immune			= false;

	targetInfos.ReportAction.TargetRowId = target->getEntityRowId();

	if( target->getId().getType() != RYZOMID::player )
	{
		const CStaticCreatures * creatureSheet = target->getForm();
		if( creatureSheet != 0 )
		{
			targetInfos.ReportAction.DeltaLvl = casterSkillBaseValue - creatureSheet->getXPLevel();
		}
	}

	
	// test resistance
	float resistFactor = 1.0f;
	//if entity invincible, it aways resists the effect
	const CSEffectPtr effect = target->lookForActiveEffect(EFFECT_FAMILIES::Invincibility);
	if ( effect )
	{
		targetInfos.Immune = true;
		resistFactor = 0.0f;
	}
	else
	{
		if (!EntitiesNoResist)
		{
			uint32 resistValue = target->getMagicResistance(_DmgType);

			if (resistValue == CCreatureResists::ImmuneScore )
			{
				targetInfos.Immune = true;
				resistFactor = 0.0f;
			}
			else
			{
				if ( actor->getId().getType() == RYZOMID::player )
				{
					// boost magic skill for low level chars
					uint32 sb = MagicSkillStartValue.get();
					casterSkillvalue = max( sb, casterSkillvalue );

					// add magic boost from consumable
					CCharacter * pC = dynamic_cast<CCharacter *>(actor);
					if(pC)
						casterSkillvalue += pC->magicSuccessModifier();
				}

				// get the chances
				const uint8 roll = (uint8)RandomGenerator.rand( 99 );
				resistFactor = CStaticSuccessTable::getSuccessFactor(SUCCESS_TABLE_TYPE::MagicResistDirect, casterSkillvalue - resistValue, roll);

				// increase resists modifier for next resists test
				if (resistFactor > 0.0f)
					target->incResistModifier(_DmgType, resistFactor);

				if ( resistFactor <= 0.0f )
				{
					// Xp gain log
					if (PlayerManager.logXPGain(actor->getEntityRowId()))
					{
						const uint8 chances = CStaticSuccessTable::getSuccessChance( SUCCESS_TABLE_TYPE::MagicResistDirect, casterSkillvalue - resistValue ); 
						nlinfo("[XPLOG] Magic attack Actor %s on %s, delta = %d, target has Resisted (chances %u, tirage %u)", actor->getId().toString().c_str(), target->getId().toString().c_str(),
							targetInfos.ReportAction.DeltaLvl, chances, roll);
					}
				}
			}
		}
		else
		{
			resistFactor = 1.0f;
		}
	}
	if ( resistFactor > 0.0f )
	{
		if ( resistFactor > 1.0f )
			resistFactor = 1.0f;
		
		float dmgFactor = resistFactor * rangeFactor * (1.0f + phrase->getUsedItemStats().getPowerFactor(_Skill, phrase->getBrickMaxSabrinaCost()));
		
		// if PVP, apply PVP magic damage factor
		if( actor != target && actor->getId().getType() == RYZOMID::player && target->getId().getType() == RYZOMID::player)
		{
			dmgFactor *= PVPMagicDamageFactor.get();
		}

		// add spire effect ( magic offense )
		if ( actor->getId().getType() == RYZOMID::player )
		{
			CCharacter* charac = (CCharacter*)actor;
			const CSEffect* pEffect = charac->lookForActiveEffect( EFFECT_FAMILIES::TotemCombatMagOff );
			if ( pEffect != NULL )
			{
				dmgFactor *= ( 1.0f + pEffect->getParamValue() / 100.0f );
			}
		}
		
		sint32 maxDmgHp =  sint32 ( _DmgHp * dmgFactor );
		sint32 realDmgHp = target->applyDamageOnArmor( _DmgType, maxDmgHp );
		
		// update behaviour for lost Hp
		CCreature * npc = dynamic_cast<CCreature*>(target);
		CCharacter * c = dynamic_cast<CCharacter*>(actor);
		if(npc && c)
		{
			if(PHRASE_UTILITIES::testRange(*actor, *target, (uint32)npc->getMaxHitRangeForPC()*1000))
			{
				behav.DeltaHP -= (sint16)realDmgHp;
			}
			else
			{
				behav.DeltaHP = 0;
			}
		}
		
		// update target infos
		targetInfos.DmgHp			= maxDmgHp;
		targetInfos.ResistFactor	= resistFactor;
		targetInfos.DmgFactor		= dmgFactor;
		
		return false;
	}
	else
	{
		// don't tell the player now, but wait to send message when the missile hit the player (at apply() time)
		targetInfos.ResistFactor	= 0.f;
		
		CAiEventReport report;
		report.Originator = phrase->getActor();
		report.Target = target->getEntityRowId();
		report.Type = ACTNATURE::OFFENSIVE_MAGIC;
		//////////////////////////////////////////////////////////////////////////
		// TEMPORARY : set a small value for resist aggro
		//////////////////////////////////////////////////////////////////////////					
		report.AggroAdd = -0.02f;
		CCreature * npc = dynamic_cast<CCreature*>(target);
		CCharacter * c = dynamic_cast<CCharacter*>(actor);
		if(npc && c && PHRASE_UTILITIES::testRange(*actor, *target, (uint32)npc->getMaxHitRangeForPC()*1000) )
			CPhraseManager::getInstance().addAiEventReport(report);
		return true;
	}
}