use of main.system.graphics.AnimPhase in project Eidolons by IDemiurge.
the class DC_AttackMaster method attackNow.
/**
* @return null if attack has been delayed by target's first strike; false if target is killed; true otherwise
*/
private Boolean attackNow(Attack attack, Ref ref, boolean free, boolean canCounter, Effect onHit, Effect onKill, boolean offhand, boolean isCounter) {
if (!(ref.getTargetObj() instanceof BattleFieldObject)) {
return true;
}
// PhaseAnimation animation =
// game.getAnimationManager().getAnimation(attack.getAction().getAnimationKey());
DC_ActiveObj action = (DC_ActiveObj) ref.getObj(KEYS.ACTIVE);
if (action.checkProperty(G_PROPS.ACTION_TAGS, "" + ActionEnums.ACTION_TAGS.OFF_HAND)) {
offhand = true;
}
if (!offhand) {
if (action.isRanged()) {
if (!action.isThrow()) {
if (getAttackWeapon(ref, true).isRanged()) {
offhand = true;
}
}
}
}
BattleFieldObject attacked = (BattleFieldObject) ref.getTargetObj();
Unit attacker = (Unit) ref.getSourceObj();
if (attack.isSneak()) {
if (attacked.checkPassive(UnitEnums.STANDARD_PASSIVES.SNEAK_IMMUNE)) {
attack.setSneak(false);
log(StringMaster.MESSAGE_PREFIX_INFO + attacked.getName() + " is immune to Sneak Attacks!");
} else {
log(StringMaster.MESSAGE_PREFIX_ALERT + attacker.getNameIfKnown() + " makes a Sneak Attack against " + attacked.getName());
}
}
if (canCounter) {
if (!attacked.canCounter(action, attack.isSneak())) {
canCounter = false;
}
}
LogMaster.log(LogMaster.ATTACKING_DEBUG, attacker.getNameIfKnown() + " attacks " + attacked.getName());
// } ====> Need a common messaging interface for actions/costs
String damage_mods = "";
// if (sneak)
// damage_mods+=DAMAGE_MODIFIER.SNEAK;
ref.setValue(KEYS.DAMAGE_MODS, damage_mods);
boolean countered = false;
if (canCounter) {
if (attacked.hasFirstStrike() && !attacker.hasFirstStrike()) {
if (!attacker.hasNoRetaliation()) {
// countered = tryCounter(attack);
return null;
}
}
}
if (attacker.isDead()) {
attack.getAnimation().addPhase(new AnimPhase(PHASE_TYPE.INTERRUPTED, ref));
return false;
}
// TODO revamp
DC_SoundMaster.playEffectSound(SOUNDS.ATTACK, attacker);
if (action.isRanged()) {
DC_SoundMaster.playRangedAttack(getAttackWeapon(ref, offhand));
}
int amount = attacker.getIntParam(PARAMS.BASE_DAMAGE);
ref.setAmount(amount);
Event event = new Event(STANDARD_EVENT_TYPE.UNIT_IS_BEING_ATTACKED, ref);
if (!event.fire()) {
attack.getAnimation().addPhase(new AnimPhase(PHASE_TYPE.INTERRUPTED, ref));
return false;
}
// initializeFullModifiers(attack.isSneak(), offhand, action, ref);
Boolean dodged = false;
if (ref.getEffect().isInterrupted()) {
event.getRef().getEffect().setInterrupted(false);
dodged = true;
}
if (!attacked.isDead())
if (!dodged) {
boolean parried = parryRule.tryParry(attack);
if (parried) {
attack.setParried(true);
// if (
// EventMaster.fireStandard(STANDARD_EVENT_TYPE.ATTACK_DODGED, ref)) {
attacked.applySpecialEffects(SPECIAL_EFFECTS_CASE.ON_PARRY, attacker, ref);
attacker.applySpecialEffects(SPECIAL_EFFECTS_CASE.ON_PARRY_SELF, attacked, ref);
// }
return true;
}
dodged = DefenseVsAttackRule.checkDodgedOrCrit(attack);
}
// BEFORE_HIT
if (!attacked.isDead())
if (dodged == null) {
if (!new Event(STANDARD_EVENT_TYPE.UNIT_HAS_BEEN_HIT, ref).fire()) {
return false;
}
if (attacker.isDead()) {
return true;
}
// if (attacked.isDead()) { // now in unit.kill()
// if (onKill != null) {
// onKill.apply(ref);
// }
// attacked.applySpecialEffects(SPECIAL_EFFECTS_CASE.ON_DEATH, attacker, ref);
// return true;
// }
} else {
if (dodged) {
attack.setDodged(true);
log(attacked.getName() + " has dodged an attack from " + attacker.getNameIfKnown());
DC_SoundMaster.playMissedSound(attacker, getAttackWeapon(ref, offhand));
StackingRule.actionMissed(action);
// ++ animation? *MISS* //TODO ++ true strike
action.setFailedLast(true);
if (checkEffectsInterrupt(attacked, attacker, SPECIAL_EFFECTS_CASE.ON_DODGE, ref, offhand)) {
return true;
}
if (canCounter) {
if ((!countered) || attacked.hasDoubleCounter()) {
// tryCounter(attack); TODO ?
return true;
}
}
} else {
if (attacked.checkPassive(UnitEnums.STANDARD_PASSIVES.CRITICAL_IMMUNE)) {
log(StringMaster.MESSAGE_PREFIX_INFO + attacked.getName() + " is immune to Critical Hits!");
} else {
log(StringMaster.MESSAGE_PREFIX_ALERT + attacker.getNameIfKnown() + " scores a critical hit on " + attacked.getName());
attack.setCritical(true);
}
}
}
attacked.applySpecialEffects(SPECIAL_EFFECTS_CASE.BEFORE_HIT, attacker, ref);
attacker.applySpecialEffects(SPECIAL_EFFECTS_CASE.BEFORE_ATTACK, attacked, ref);
Integer final_amount = attack.getDamage();
// TODO REAL CALC How to calc damage w/o crit (for parry)?
if (final_amount == Attack.DAMAGE_NOT_SET) {
AttackCalculator calculator = new AttackCalculator(attack, false);
final_amount = calculator.calculateFinalDamage();
}
// TODO different for multiDamageType
if (CoreEngine.isPhaseAnimsOn())
PhaseAnimator.getInstance().initAttackAnimRawDamage(attack);
ref.setAmount(final_amount);
if (final_amount < 0) {
return true;
}
ref.setAmount(final_amount);
DAMAGE_TYPE dmg_type = ref.getDamageType();
if (attack.isCritical()) {
if (attacker.checkPassive(UnitEnums.STANDARD_PASSIVES.CLEAVING_CRITICALS)) {
// TODO add default cleave?
CleaveRule.addCriticalCleave(attacker);
dmg_type = GenericEnums.DAMAGE_TYPE.SLASHING;
}
}
if (dmg_type == null) {
dmg_type = action.getDamageType();
}
if (dmg_type == null) {
if (!checkWeapon(ref)) {
dmg_type = attacker.getDamageType();
} else {
dmg_type = getAttackWeapon(ref, offhand).getDamageType();
}
}
attack.setDamageType(dmg_type);
if (attack.getDamage() == Attack.DAMAGE_NOT_SET) {
attack.setDamage(final_amount);
}
if (!new Event(STANDARD_EVENT_TYPE.UNIT_HAS_BEEN_ATTACKED, ref).fire()) {
return false;
}
if (!new Event(STANDARD_EVENT_TYPE.UNIT_HAS_BEEN_HIT, ref).fire()) {
return false;
}
Unit attackedUnit = null;
if (attacked instanceof Unit) {
attackedUnit = (Unit) attacked;
}
if (!attacked.isDead())
if (attackedUnit != null)
if (attackedUnit.getOffhandWeapon() != null) {
if (attackedUnit.getOffhandWeapon().isShield()) {
if (!attack.isSneak()) {
// && !isCounter) {
int blocked = game.getArmorMaster().getShieldDamageBlocked(final_amount, attackedUnit, attacker, action, getAttackWeapon(ref, attack.isOffhand()), attack.getDamageType());
final_amount -= blocked;
if (blocked > 0) {
Ref REF = ref.getCopy();
REF.setAmount(blocked);
if (checkEffectsInterrupt(attackedUnit, attacker, SPECIAL_EFFECTS_CASE.ON_SHIELD_BLOCK, REF, offhand)) {
return true;
}
if (checkEffectsInterrupt(attacker, attackedUnit, SPECIAL_EFFECTS_CASE.ON_SHIELD_BLOCK_SELF, REF, offhand)) {
return true;
}
}
}
}
}
// armor penetration?
attack.setDamage(final_amount);
if (checkAttackEventsInterrupt(attack, ref)) {
return true;
}
// ForceRule.addForceEffects(action); now in executor.resolve() for all actions
Damage damageObj = DamageFactory.getDamageForAttack(dmg_type, ref, final_amount);
int damageDealt = DamageDealer.dealDamage(damageObj);
attack.damageDealt(damageDealt);
attack.reset();
if (attacked.isDead()) {
if (!attack.isTriggered()) {
game.getRules().getCleaveRule().apply(ref, attack);
}
}
if (onHit != null) {
onHit.apply(ref);
}
if (!action.isRanged()) {
// e.g.
attacked.applySpecialEffects(SPECIAL_EFFECTS_CASE.ON_HIT, attacker, ref);
}
if (attackedUnit != null)
// e.g.
attacker.applySpecialEffects(SPECIAL_EFFECTS_CASE.ON_ATTACK, attackedUnit, ref, offhand);
try {
// map=
CoatingRule.unitIsHit(attacked, attacker, offhand, action, attack, attack.getWeapon());
} catch (Exception e) {
main.system.ExceptionMaster.printStackTrace(e);
}
if (attackedUnit != null) {
InjuryRule.applyInjuryRule(action);
if (attack.isCritical()) {
checkEffectsInterrupt(attackedUnit, attacker, SPECIAL_EFFECTS_CASE.ON_CRIT_SELF, ref, offhand);
checkEffectsInterrupt(attacker, attackedUnit, SPECIAL_EFFECTS_CASE.ON_CRIT, ref, offhand);
}
}
return true;
}
use of main.system.graphics.AnimPhase in project Eidolons by IDemiurge.
the class DefenseVsAttackRule method checkDodgedOrCrit.
public static Boolean checkDodgedOrCrit(Unit attacker, BattleFieldObject attacked, DC_ActiveObj action, Ref ref, boolean offhand, PhaseAnimation animation, boolean logged) {
if (attacked.checkPassive(UnitEnums.STANDARD_PASSIVES.IMMATERIAL)) {
if (!attacker.checkPassive(UnitEnums.STANDARD_PASSIVES.IMMATERIAL)) {
if (!RollMaster.roll(GenericEnums.ROLL_TYPES.IMMATERIAL, ref)) {
// TODO ANIM
return true;
}
}
}
boolean crit = false;
int attack = getAttackValue(offhand, attacker, attacked, action);
int defense = getDefenseValue(attacker, attacked, action);
float diff = defense - attack;
if (diff < 0) {
crit = true;
}
int chance = getChance(action, attacker, attacked, attack, defense, crit);
if (logged) {
main.system.auxiliary.log.LogMaster.log(1, "" + (crit ? "...chance for critical strike: " : "..." + attacked.getName() + "'s chance to dodge: ") + String.valueOf(chance) + "%");
}
boolean result = RandomWizard.chance(chance);
if (isCRIT_TEST()) {
result = true;
crit = true;
}
if (result) {
if (crit) {
if (animation != null) {
animation.addPhase(new AnimPhase(PHASE_TYPE.ATTACK_CRITICAL, chance));
}
return false;
} else {
if (animation != null) {
animation.addPhase(new AnimPhase(PHASE_TYPE.ATTACK_DODGED, chance));
}
return true;
}
}
chance = action.getIntParam(PARAMS.AUTO_CRIT_CHANCE);
if (chance > 0) {
if (!RandomWizard.chance(chance)) {
return null;
}
animation.addPhase(new AnimPhase(PHASE_TYPE.ATTACK_CRITICAL, chance, true));
return false;
}
return null;
}
use of main.system.graphics.AnimPhase in project Eidolons by IDemiurge.
the class AttackCalculator method addMainPhase.
public void addMainPhase() {
if (anim == null) {
anim = attack.getAnimation();
}
anim.addSubPhase(new AnimPhase(PHASE_TYPE.DAMAGE_FORMULA, attack, modMap, bonusMap));
anim.addSubPhase(new AnimPhase(PHASE_TYPE.DAMAGE_FORMULA_MODS, attack, modMap));
}
use of main.system.graphics.AnimPhase in project Eidolons by IDemiurge.
the class AttackCalculator method getCriticalDamageBonus.
private Integer getCriticalDamageBonus(Attack attack, Integer amount, Unit attacker, BattleFieldObject attacked, DC_ActiveObj action, boolean offhand) {
if (attacked.checkPassive(UnitEnums.STANDARD_PASSIVES.CRITICAL_IMMUNE)) {
return 0;
}
int mod = CriticalAttackRule.getCriticalDamagePercentage(action, attacked);
int bonus = MathMaster.applyMod(amount, mod);
if (!precalc) {
if (attack.getAnimation() != null) {
attack.getAnimation().addPhase(new AnimPhase(PHASE_TYPE.ATTACK_CRITICAL, mod, bonus));
}
}
bonusMap.put(MOD_IDENTIFIER.CRIT, bonus);
return bonus;
}
use of main.system.graphics.AnimPhase in project Eidolons by IDemiurge.
the class RollMaster method rollLogged.
/**
* @param logString to be appended to the logged string; for success by default,
* for failure if contains @
* @param rollSource special descriptor for logging, e.g. if rolling vs Ensnare
* @returns false if target has resisted ('wins roll')
*/
public static boolean rollLogged(ROLL_TYPES roll_type, String success, String fail, Ref ref, String logString, String rollSource) {
boolean result = roll(roll_type, success, fail, ref, logString, rollSource, false);
if (!checkRollLogged(roll_type, result)) {
return result;
}
Object[] args = { roll_type.getName(), ref.getSourceObj().getName(), ref.getTargetObj().getName() };
if (roll_type.isLogToTop()) {
args = new Object[] { main.system.text.LogManager.WRITE_TO_TOP, roll_type.getName(), ref.getSourceObj().getName(), ref.getTargetObj().getName() };
}
LogEntryNode entry = ref.getGame().getLogManager().newLogEntryNode(result ? ENTRY_TYPE.ROLL_LOST : ENTRY_TYPE.ROLL_WON, args);
ref.getGame().getLogManager().log(RollMaster.logString);
ref.getGame().getLogManager().doneLogEntryNode();
if (CoreEngine.isPhaseAnimsOn())
if (ref.getActive() != null) {
ANIM anim = new EffectAnimation((DC_ActiveObj) ref.getActive());
anim.addPhase(new AnimPhase(PHASE_TYPE.ROLL, roll));
entry.setLinkedAnimation(anim);
}
// PHASE_TYPE.ROLL));
if (ref.getGame().isDummyMode()) {
return true;
}
return result;
}
Aggregations