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);
}
}
}
}
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;
}
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;
}
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;
}
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;
}
Aggregations