/// 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; } }