package com.cardshifter.modapi.actions.attack; import com.cardshifter.modapi.actions.ActionAllowedCheckEvent; import com.cardshifter.modapi.actions.ActionPerformEvent; import com.cardshifter.modapi.actions.SpecificActionSystem; import com.cardshifter.modapi.base.ECSGame; import com.cardshifter.modapi.base.Entity; import com.cardshifter.modapi.base.PlayerComponent; import com.cardshifter.modapi.events.IEvent; import com.cardshifter.modapi.resources.ECSResource; import com.cardshifter.modapi.resources.ResourceRetriever; import java.util.function.BiPredicate; public class AttackDamageYGO extends SpecificActionSystem { private final ResourceRetriever attack; private final ResourceRetriever health; private final BiPredicate<Entity, Entity> allowCounterAttack; public AttackDamageYGO(ECSResource attack, ECSResource health, BiPredicate<Entity, Entity> allowCounterAttack) { super("Attack"); this.attack = ResourceRetriever.forResource(attack); this.health = ResourceRetriever.forResource(health); this.allowCounterAttack = allowCounterAttack; } @Override protected void isAllowed(ActionAllowedCheckEvent event) { if (attack.getFor(event.getEntity()) <= 0) { event.setAllowed(false); } } @Override protected void onPerform(ActionPerformEvent event) { Entity source = event.getEntity(); Entity target = event.getAction().getTargetSets().get(0).getChosenTargets().get(0); ECSGame game = event.getEntity().getGame(); int attackDamage = attack.getFor(source); int defenseDamage = attack.getFor(target); if (target.hasComponent(PlayerComponent.class)) { damage(event, attackDamage, target, source, game); } else { DamageEvent damageEvent = new DamageEvent(event, target, source, attackDamage); game.getEvents().executeEvent(damageEvent, e -> { }); destroyOrNothing(damageEvent.getDamage(), target); } if (allowCounterAttack.test(source, target)) { destroyOrNothing(defenseDamage, source); } } private void damage(IEvent cause, int damage, Entity target, Entity damagedBy, ECSGame game) { if (damage <= 0) { return; } game.getEvents().executeEvent(new DamageEvent(cause, target, damagedBy, damage), e -> health.resFor(target).change(-e.getDamage())); } private int destroyOrNothing(int damage, Entity target) { int overflowDamage = damage - health.getFor(target); if (overflowDamage >= 0) { target.destroy(); } return overflowDamage; } }