Search in sources :

Example 36 with BattleFieldObject

use of eidolons.entity.obj.BattleFieldObject in project Eidolons by IDemiurge.

the class DC_StateManager method checkCellBuffs.

private void checkCellBuffs() {
    for (BattleFieldObject unit : getGame().getBfObjects()) {
        if (unit.isDead()) {
            continue;
        }
        Obj cell = game.getCellByCoordinate(unit.getCoordinates());
        if (cell == null) {
            continue;
        }
        if (cell.getBuffs() == null) {
            continue;
        }
        for (BuffObj buff : game.getCellByCoordinate(unit.getCoordinates()).getBuffs()) {
            if (unit.hasBuff(buff.getName())) {
                continue;
            }
            if (buff.isAppliedThrough()) {
                Condition retainCondition = new PositionCondition(KEYS.SOURCE.toString(), cell);
                getGame().getManager().copyBuff(buff, unit, retainCondition);
            }
        }
    }
}
Also used : PositionCondition(main.elements.conditions.standard.PositionCondition) Condition(main.elements.conditions.Condition) BattleFieldObject(eidolons.entity.obj.BattleFieldObject) BuffObj(main.entity.obj.BuffObj) DC_SpellObj(eidolons.entity.active.DC_SpellObj) DC_Obj(eidolons.entity.obj.DC_Obj) DC_ActiveObj(eidolons.entity.active.DC_ActiveObj) Obj(main.entity.obj.Obj) BuffObj(main.entity.obj.BuffObj) PositionCondition(main.elements.conditions.standard.PositionCondition)

Example 37 with BattleFieldObject

use of eidolons.entity.obj.BattleFieldObject in project Eidolons by IDemiurge.

the class SpectrumEffect method applyThis.

public boolean applyThis() {
    if (range == null)
        range = new Formula(rangeFormula).getInt(ref);
    Integer backwardRange = 0;
    Integer sidePenalty = 0;
    if (vision) {
        range = new Formula(StringMaster.getValueRef(KEYS.SOURCE, PARAMS.SIGHT_RANGE)).getInt(ref);
        // TODO
        backwardRange = null;
        // will be taken from unit
        sidePenalty = null;
    }
    if (ref.getObj(source) instanceof BattleFieldObject)
        bfObj = ((BattleFieldObject) ref.getObj(source));
    else {
    // TODO
    }
    FACING_DIRECTION facing = bfObj.getFacing();
    if (circular) {
        backwardRange = range;
        facing = FACING_DIRECTION.NORTH;
    } else {
        sidePenalty = 1;
    }
    List<Coordinates> coordinates = new ArrayList<>(getGame().getVisionMaster().getSightMaster().getSpectrumCoordinates(range, sidePenalty, backwardRange, bfObj, vision, facing));
    // boolean x-ray ++ tall/short/etc
    if (effects == null) {
        initEffects();
    }
    for (Coordinates c : coordinates) {
        // TODO WHAT IF IT'S ON A DIFFERENT Z-LEVEL?
        // applyThrough = true; // ?
        // if (!applyThrough)
        // if (!(getGame().getObjectByCoordinate(c, true) instanceof
        // DC_Cell))
        // continue;
        DequeImpl<? extends Obj> objects = new DequeImpl<>(getGame().getObjectsOnCoordinate(getGame().getDungeon().getZ(), c, null, true, applyThrough));
        if (applyThrough) {
            objects.addCast(getGame().getCellByCoordinate(c));
        }
        for (Obj o : objects) {
            ref.setMatch(o.getId());
            if (filterConditions != null) {
                if (!filterConditions.preCheck(ref)) {
                    continue;
                }
            }
            Integer target = o.getId();
            // target = getGame().getCellByCoordinate(c).getId();
            if (getGame().getObjectById(target) == null) {
                continue;
            }
            for (Effect effect : effects.getEffects()) {
                Ref REF = Ref.getCopy(ref);
                REF.setTarget(target);
                if (reductionForDistance != null) {
                    // for the first time
                    effect.resetOriginalFormula();
                    // to set original
                    effect.resetOriginalFormula();
                    String reduction = reductionForDistance;
                    if (reductionForDistanceModifier != null)
                        reduction += (reductionForDistanceModifier);
                    Formula effectFormula = effect.getFormula();
                    reduction = reduction.replace(X, effectFormula.toString());
                    int distance = PositionMaster.getDistance(REF.getSourceObj(), REF.getTargetObj());
                    reduction = reduction.replace("distance", distance + "");
                    effectFormula.append(reduction);
                    // TODO
                    Integer amount = effectFormula.getInt(ref);
                    if (amount < 0) {
                        effect.setAmount(amount);
                    }
                    effect.setAmount(amount);
                }
                effect.apply(REF);
            }
        }
    }
    return true;
}
Also used : Coordinates(main.game.bf.Coordinates) ArrayList(java.util.ArrayList) Formula(main.system.math.Formula) FACING_DIRECTION(main.game.bf.Coordinates.FACING_DIRECTION) Ref(main.entity.Ref) BattleFieldObject(eidolons.entity.obj.BattleFieldObject) Obj(main.entity.obj.Obj) DC_Effect(eidolons.ability.effects.DC_Effect) Effect(main.ability.effects.Effect) DequeImpl(main.system.datatypes.DequeImpl)

Example 38 with BattleFieldObject

use of eidolons.entity.obj.BattleFieldObject in project Eidolons by IDemiurge.

the class SelfMoveEffect method applyThis.

@Override
public boolean applyThis() {
    BattleFieldObject obj = (BattleFieldObject) ref.getSourceObj();
    origin = new Coordinates(obj.getCoordinates().getX(), obj.getCoordinates().getY());
    destination = getCoordinates();
    if (// if selective?
    destination == null) {
        return false;
    }
    game.getMovementManager().move(obj, destination, free, mod, ref);
    return true;
}
Also used : BattleFieldObject(eidolons.entity.obj.BattleFieldObject) Coordinates(main.game.bf.Coordinates)

Example 39 with BattleFieldObject

use of eidolons.entity.obj.BattleFieldObject in project Eidolons by IDemiurge.

the class DamageCalculator method precalculateDamage.

/**
 * Calculates damage for AI's FutureBuilder (AttackEffect)
 *
 * @param attack
 * @return
 */
public static int precalculateDamage(Attack attack, Boolean min_max_normal) {
    BattleFieldObject attacked = attack.getAttacked();
    Unit attacker = attack.getAttacker();
    if (!attacked.checkPassive(UnitEnums.STANDARD_PASSIVES.SNEAK_IMMUNE)) {
        attack.setSneak(SneakRule.checkSneak(attack.getRef()));
    }
    // TODO ref.setFuture(true) -> average dice, auto-reset action etc
    AttackCalculator calculator = new AttackCalculator(attack, true);
    if (min_max_normal != null)
        if (min_max_normal) {
            calculator.setMin(true);
        } else {
            calculator.setMax(true);
        }
    int amount = calculator.calculateFinalDamage();
    DAMAGE_TYPE dmg_type = attack.getDamageType();
    if (dmg_type == DAMAGE_TYPE.PURE || dmg_type == DAMAGE_TYPE.POISON) {
        return amount;
    }
    if (!(attacked instanceof Unit)) {
        return amount;
    }
    int blocked = attacked.getGame().getArmorSimulator().getShieldDamageBlocked(amount, (Unit) attacked, attacker, attack.getAction(), attack.getWeapon(), attack.getDamageType());
    blocked += attacked.getGame().getArmorSimulator().getArmorBlockDamage(amount, (Unit) attacked, attacker, attack.getAction());
    amount = calculateDamage(true, attacked, attacker, amount, null, blocked, attack.getDamageType());
    if (attack.getAction().isAttackGeneric()) {
        return amount;
    }
    return amount;
}
Also used : AttackCalculator(eidolons.game.battlecraft.rules.combat.attack.AttackCalculator) BattleFieldObject(eidolons.entity.obj.BattleFieldObject) DAMAGE_TYPE(main.content.enums.GenericEnums.DAMAGE_TYPE) Unit(eidolons.entity.obj.unit.Unit)

Example 40 with BattleFieldObject

use of eidolons.entity.obj.BattleFieldObject 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;
}
Also used : AnimPhase(main.system.graphics.AnimPhase) DAMAGE_TYPE(main.content.enums.GenericEnums.DAMAGE_TYPE) Unit(eidolons.entity.obj.unit.Unit) Ref(main.entity.Ref) BattleFieldObject(eidolons.entity.obj.BattleFieldObject) Event(main.game.logic.event.Event) DC_ActiveObj(eidolons.entity.active.DC_ActiveObj) Damage(eidolons.game.battlecraft.rules.combat.damage.Damage)

Aggregations

BattleFieldObject (eidolons.entity.obj.BattleFieldObject)52 Unit (eidolons.entity.obj.unit.Unit)24 Coordinates (main.game.bf.Coordinates)22 DC_Obj (eidolons.entity.obj.DC_Obj)12 Ref (main.entity.Ref)12 DC_ActiveObj (eidolons.entity.active.DC_ActiveObj)10 Obj (main.entity.obj.Obj)9 DequeImpl (main.system.datatypes.DequeImpl)8 Event (main.game.logic.event.Event)7 ArrayList (java.util.ArrayList)6 List (java.util.List)6 DIRECTION (main.game.bf.Coordinates.DIRECTION)5 TextureRegion (com.badlogic.gdx.graphics.g2d.TextureRegion)4 Vector2 (com.badlogic.gdx.math.Vector2)4 Align (com.badlogic.gdx.utils.Align)4 Eidolons (eidolons.game.core.Eidolons)4 Gdx (com.badlogic.gdx.Gdx)3 Keys (com.badlogic.gdx.Input.Keys)3 Batch (com.badlogic.gdx.graphics.g2d.Batch)3 Group (com.badlogic.gdx.scenes.scene2d.Group)3