Вот что меня заинтересовало в сборке Тринити.
02194 WeaponAttackType attType = BASE_ATTACK;
02195
02196 // Check damage class instead of attack type to correctly handle judgements
02197 // - they are meele, but can't be dodged/parried/deflected because of ranged dmg class
02198 if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)
02199 attType = RANGED_ATTACK;
- - - Updated - - -
Короче, вот, если кому будет интересно.
http://docs.trinitycore.info/df/dd9/...fa4d5f017f5304
Код:
SpellMissInfo Unit::MeleeSpellHitResult ( Unit * victim,
SpellInfo const * spellInfo
)
02188 {
02189 // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will additionally fully ignore
02190 // resist and deflect chances
02191 if (spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT))
02192 return SPELL_MISS_NONE;
02193
02194 WeaponAttackType attType = BASE_ATTACK;
02195
02196 // Check damage class instead of attack type to correctly handle judgements
02197 // - they are meele, but can't be dodged/parried/deflected because of ranged dmg class
02198 if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)
02199 attType = RANGED_ATTACK;
02200
02201 uint32 roll = urand(0, 10000);
02202
02203 uint32 missChance = uint32(MeleeSpellMissChance(victim, attType, spellInfo->Id) * 100.0f);
02204
02205 // Roll miss
02206 uint32 tmp = missChance;
02207 if (roll < tmp)
02208 return SPELL_MISS_MISS;
02209
02210 // Chance resist mechanic (select max value from every mechanic spell effect)
02211 int32 resist_mech = 0;
02212 // Get effects mechanic and chance
02213 for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff)
02214 {
02215 int32 effect_mech = spellInfo->GetEffectMechanic(eff, GetMap()->GetDifficultyID());
02216 if (effect_mech)
02217 {
02218 int32 temp = victim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effect_mech);
02219 if (resist_mech < temp * 100)
02220 resist_mech = temp * 100;
02221 }
02222 }
02223 // Roll chance
02224 tmp += resist_mech;
02225 if (roll < tmp)
02226 return SPELL_MISS_RESIST;
02227
02228 bool canDodge = true;
02229 bool canParry = true;
02230 bool canBlock = spellInfo->HasAttribute(SPELL_ATTR3_BLOCKABLE_SPELL);
02231
02232 // Same spells cannot be parry/dodge
02233 if (spellInfo->HasAttribute(SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK))
02234 return SPELL_MISS_NONE;
02235
02236 // Chance resist mechanic
02237 int32 resist_chance = victim->GetMechanicResistChance(spellInfo) * 100;
02238 tmp += resist_chance;
02239 if (roll < tmp)
02240 return SPELL_MISS_RESIST;
02241
02242 // Ranged attacks can only miss, resist and deflect
02243 if (attType == RANGED_ATTACK)
02244 {
02245 canParry = false;
02246 canDodge = false;
02247
02248 // only if in front
02249 if (victim->HasInArc(float(M_PI), this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION))
02250 {
02251 int32 deflect_chance = victim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS) * 100;
02252 tmp += deflect_chance;
02253 if (roll < tmp)
02254 return SPELL_MISS_DEFLECT;
02255 }
02256 return SPELL_MISS_NONE;
02257 }
02258
02259 // Check for attack from behind
02260 if (!victim->HasInArc(float(M_PI), this))
02261 {
02262 if (!victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION))
02263 {
02264 // Can`t dodge from behind in PvP (but its possible in PvE)
02265 if (victim->GetTypeId() == TYPEID_PLAYER)
02266 canDodge = false;
02267 // Can`t parry or block
02268 canParry = false;
02269 canBlock = false;
02270 }
02271 else // Only deterrence as of 3.3.5
02272 {
02273 if (spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET))
02274 canParry = false;
02275 }
02276 }
02277 // Check creatures flags_extra for disable parry
02278 if (victim->GetTypeId() == TYPEID_UNIT)
02279 {
02280 uint32 flagEx = victim->ToCreature()->GetCreatureTemplate()->flags_extra;
02281 if (flagEx & CREATURE_FLAG_EXTRA_NO_PARRY)
02282 canParry = false;
02283 // Check creatures flags_extra for disable block
02284 if (flagEx & CREATURE_FLAG_EXTRA_NO_BLOCK)
02285 canBlock = false;
02286 }
02287 // Ignore combat result aura
02288 AuraEffectList const& ignore = GetAuraEffectsByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
02289 for (AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
02290 {
02291 if (!(*i)->IsAffectingSpell(spellInfo))
02292 continue;
02293 switch ((*i)->GetMiscValue())
02294 {
02295 case MELEE_HIT_DODGE:
02296 canDodge = false;
02297 break;
02298 case MELEE_HIT_BLOCK:
02299 canBlock = false;
02300 break;
02301 case MELEE_HIT_PARRY:
02302 canParry = false;
02303 break;
02304 default:
02305 TC_LOG_DEBUG("entities.unit", "Spell %u SPELL_AURA_IGNORE_COMBAT_RESULT has unhandled state %d", (*i)->GetId(), (*i)->GetMiscValue());
02306 break;
02307 }
02308 }
02309
02310 if (canDodge)
02311 {
02312 // Roll dodge
02313 int32 dodgeChance = int32(victim->GetUnitDodgeChance() * 100.0f);
02314 // Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
02315 dodgeChance += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE) * 100;
02316 dodgeChance = int32(float(dodgeChance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
02317 // Reduce dodge chance by attacker expertise rating
02318 if (GetTypeId() == TYPEID_PLAYER)
02319 dodgeChance -= int32(ToPlayer()->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
02320 else
02321 dodgeChance -= GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE) * 25;
02322 if (dodgeChance < 0)
02323 dodgeChance = 0;
02324
02325 if (roll < (tmp += dodgeChance))
02326 return SPELL_MISS_DODGE;
02327 }
02328
02329 if (canParry)
02330 {
02331 // Roll parry
02332 int32 parryChance = int32(victim->GetUnitParryChance() * 100.0f);
02333 // Reduce parry chance by attacker expertise rating
02334 if (GetTypeId() == TYPEID_PLAYER)
02335 parryChance -= int32(ToPlayer()->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
02336 else
02337 parryChance -= GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE) * 25;
02338 if (parryChance < 0)
02339 parryChance = 0;
02340
02341 tmp += parryChance;
02342 if (roll < tmp)
02343 return SPELL_MISS_PARRY;
02344 }
02345
02346 if (canBlock)
02347 {
02348 int32 blockChance = int32(victim->GetUnitBlockChance() * 100.0f);
02349 if (blockChance < 0)
02350 blockChance = 0;
02351 tmp += blockChance;
02352
02353 if (roll < tmp)
02354 return SPELL_MISS_BLOCK;
02355 }
02356
02357 return SPELL_MISS_NONE;
02358 }
Хочу отметить, что встречаемый в коде SPELL_AURA_IGNORE_HIT_DIRECTION является одним из эффектов Сдерживания.