mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
CombatLki - part 1.
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -14477,6 +14477,7 @@ src/main/java/forge/game/ai/ComputerUtilCost.java -text
|
|||||||
src/main/java/forge/game/ai/ComputerUtilMana.java -text
|
src/main/java/forge/game/ai/ComputerUtilMana.java -text
|
||||||
src/main/java/forge/game/combat/AttackingBand.java -text
|
src/main/java/forge/game/combat/AttackingBand.java -text
|
||||||
src/main/java/forge/game/combat/Combat.java svneol=native#text/plain
|
src/main/java/forge/game/combat/Combat.java svneol=native#text/plain
|
||||||
|
src/main/java/forge/game/combat/CombatLki.java -text
|
||||||
src/main/java/forge/game/combat/CombatUtil.java svneol=native#text/plain
|
src/main/java/forge/game/combat/CombatUtil.java svneol=native#text/plain
|
||||||
src/main/java/forge/game/event/GameEvent.java -text
|
src/main/java/forge/game/event/GameEvent.java -text
|
||||||
src/main/java/forge/game/event/GameEventAnteCardsSelected.java -text
|
src/main/java/forge/game/event/GameEventAnteCardsSelected.java -text
|
||||||
|
|||||||
@@ -224,7 +224,10 @@ public class GameAction {
|
|||||||
|
|
||||||
if (zoneFrom != null) {
|
if (zoneFrom != null) {
|
||||||
if (zoneFrom.is(ZoneType.Battlefield) && c.isCreature() && game.getCombat() != null) {
|
if (zoneFrom.is(ZoneType.Battlefield) && c.isCreature() && game.getCombat() != null) {
|
||||||
|
if ( !zoneTo.is(ZoneType.Battlefield) )
|
||||||
|
game.getCombat().saveLKI(lastKnownInfo);
|
||||||
game.getCombat().removeFromCombat(c);
|
game.getCombat().removeFromCombat(c);
|
||||||
|
|
||||||
}
|
}
|
||||||
zoneFrom.remove(c);
|
zoneFrom.remove(c);
|
||||||
}
|
}
|
||||||
@@ -233,11 +236,7 @@ public class GameAction {
|
|||||||
|
|
||||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||||
runParams.put("Card", lastKnownInfo);
|
runParams.put("Card", lastKnownInfo);
|
||||||
if (zoneFrom != null) {
|
runParams.put("Origin", zoneFrom != null ? zoneFrom.getZoneType().name() : null);
|
||||||
runParams.put("Origin", zoneFrom.getZoneType().name());
|
|
||||||
} else {
|
|
||||||
runParams.put("Origin", null);
|
|
||||||
}
|
|
||||||
runParams.put("Destination", zoneTo.getZoneType().name());
|
runParams.put("Destination", zoneTo.getZoneType().name());
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams, false);
|
game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams, false);
|
||||||
// AllZone.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
// AllZone.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
||||||
@@ -1350,9 +1349,6 @@ public class GameAction {
|
|||||||
final boolean persist = (c.hasKeyword("Persist") && (c.getCounters(CounterType.M1M1) == 0)) && !c.isToken();
|
final boolean persist = (c.hasKeyword("Persist") && (c.getCounters(CounterType.M1M1) == 0)) && !c.isToken();
|
||||||
final boolean undying = (c.hasKeyword("Undying") && (c.getCounters(CounterType.P1P1) == 0)) && !c.isToken();
|
final boolean undying = (c.hasKeyword("Undying") && (c.getCounters(CounterType.P1P1) == 0)) && !c.isToken();
|
||||||
|
|
||||||
if (game.getPhaseHandler().inCombat())
|
|
||||||
game.getPhaseHandler().getCombat().removeFromCombat(c);
|
|
||||||
|
|
||||||
final Card newCard = this.moveToGraveyard(c);
|
final Card newCard = this.moveToGraveyard(c);
|
||||||
|
|
||||||
// Destroy needs to be called with Last Known Information
|
// Destroy needs to be called with Last Known Information
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
@@ -59,6 +57,7 @@ public class Combat {
|
|||||||
|
|
||||||
private Map<Card, List<Card>> attackersOrderedForDamageAssignment = new HashMap<Card, List<Card>>();
|
private Map<Card, List<Card>> attackersOrderedForDamageAssignment = new HashMap<Card, List<Card>>();
|
||||||
private Map<Card, List<Card>> blockersOrderedForDamageAssignment = new HashMap<Card, List<Card>>();
|
private Map<Card, List<Card>> blockersOrderedForDamageAssignment = new HashMap<Card, List<Card>>();
|
||||||
|
private Map<GameEntity, CombatLki> lkiCache = new HashMap<GameEntity, CombatLki>();
|
||||||
|
|
||||||
|
|
||||||
public Combat(Player attacker) {
|
public Combat(Player attacker) {
|
||||||
@@ -104,7 +103,6 @@ public class Combat {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final void addAttacker(final Card c, GameEntity defender) {
|
public final void addAttacker(final Card c, GameEntity defender) {
|
||||||
addAttacker(c, defender, null);
|
addAttacker(c, defender, null);
|
||||||
}
|
}
|
||||||
@@ -125,13 +123,7 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final GameEntity getDefenderByAttacker(final Card c) {
|
public final GameEntity getDefenderByAttacker(final Card c) {
|
||||||
for(Entry<GameEntity, Collection<AttackingBand>> e : attackedEntities.entrySet()) {
|
return getDefenderByAttacker(getBandOfAttacker(c));
|
||||||
for(AttackingBand ab : e.getValue()) {
|
|
||||||
if ( ab.contains(c) )
|
|
||||||
return e.getKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final GameEntity getDefenderByAttacker(final AttackingBand c) {
|
public final GameEntity getDefenderByAttacker(final AttackingBand c) {
|
||||||
@@ -160,6 +152,10 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final AttackingBand getBandOfAttacker(final Card c) {
|
public final AttackingBand getBandOfAttacker(final Card c) {
|
||||||
|
if ( !c.isInPlay() ) {
|
||||||
|
CombatLki lki = lkiCache.get(c);
|
||||||
|
return lki == null ? null : lki.getFirstBand();
|
||||||
|
}
|
||||||
for(Collection<AttackingBand> abs : attackedEntities.values()) {
|
for(Collection<AttackingBand> abs : attackedEntities.values()) {
|
||||||
for(AttackingBand ab : abs) {
|
for(AttackingBand ab : abs) {
|
||||||
if ( ab.contains(c) )
|
if ( ab.contains(c) )
|
||||||
@@ -182,10 +178,11 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAttacking(Card card, GameEntity defender) {
|
public boolean isAttacking(Card card, GameEntity defender) {
|
||||||
|
AttackingBand ab = getBandOfAttacker(card);
|
||||||
|
|
||||||
for(Entry<GameEntity, Collection<AttackingBand>> ee : attackedEntities.entrySet())
|
for(Entry<GameEntity, Collection<AttackingBand>> ee : attackedEntities.entrySet())
|
||||||
for(AttackingBand ab : ee.getValue())
|
if ( ee.getValue().contains(ab) )
|
||||||
if (ab.contains(card))
|
return ee.getKey() == defender;
|
||||||
return ee.getKey() == defender;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,6 +255,15 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
return blocked;
|
return blocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final List<AttackingBand> getAttackingBandsBlockedBy(Card blocker) {
|
||||||
|
List<AttackingBand> bands = Lists.newArrayList();
|
||||||
|
for( Entry<AttackingBand, Collection<Card>> kv : blockedBands.entrySet()) {
|
||||||
|
if (kv.getValue().contains(blocker))
|
||||||
|
bands.add(kv.getKey());
|
||||||
|
}
|
||||||
|
return bands;
|
||||||
|
}
|
||||||
|
|
||||||
public Player getDefendingPlayerRelatedTo(final Card source) {
|
public Player getDefendingPlayerRelatedTo(final Card source) {
|
||||||
Card attacker = source;
|
Card attacker = source;
|
||||||
@@ -333,24 +339,13 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeAttackerFromBand(AttackingBand ab, Card c) {
|
|
||||||
ab.removeAttacker(c);
|
|
||||||
|
|
||||||
// removed
|
|
||||||
if (ab.isEmpty()) {
|
|
||||||
blockedBands.remove(ab);
|
|
||||||
for(Collection<AttackingBand> abs: attackedEntities.values())
|
|
||||||
abs.remove(ab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove a combatant whose side is unknown
|
// remove a combatant whose side is unknown
|
||||||
public final void removeFromCombat(final Card c) {
|
public final void removeFromCombat(final Card c) {
|
||||||
AttackingBand ab = getBandOfAttacker(c);
|
AttackingBand ab = getBandOfAttacker(c);
|
||||||
if (ab != null) {
|
if (ab != null) {
|
||||||
unregisterAttacker(c, ab);
|
unregisterAttacker(c, ab);
|
||||||
removeAttackerFromBand(ab, c);
|
ab.removeAttacker(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not found in attackers, look for this card in blockers
|
// if not found in attackers, look for this card in blockers
|
||||||
@@ -365,7 +360,6 @@ public class Combat {
|
|||||||
|
|
||||||
public final void removeAbsentCombatants() {
|
public final void removeAbsentCombatants() {
|
||||||
// iterate all attackers and remove them
|
// iterate all attackers and remove them
|
||||||
List<Pair<AttackingBand, Card>> toRemoveAtk = new ArrayList<>();
|
|
||||||
for(Entry<GameEntity, Collection<AttackingBand>> ee : attackedEntities.entrySet()) {
|
for(Entry<GameEntity, Collection<AttackingBand>> ee : attackedEntities.entrySet()) {
|
||||||
for(AttackingBand ab : ee.getValue()) {
|
for(AttackingBand ab : ee.getValue()) {
|
||||||
List<Card> atk = ab.getAttackers();
|
List<Card> atk = ab.getAttackers();
|
||||||
@@ -373,15 +367,10 @@ public class Combat {
|
|||||||
Card c = atk.get(i);
|
Card c = atk.get(i);
|
||||||
if ( !c.isInPlay() ) {
|
if ( !c.isInPlay() ) {
|
||||||
unregisterAttacker(c, ab);
|
unregisterAttacker(c, ab);
|
||||||
toRemoveAtk.add(Pair.of(ab, c));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// remove as a separate step to avoid modifications with iterator open in for-loop
|
|
||||||
for(Pair<AttackingBand, Card> pair : toRemoveAtk) {
|
|
||||||
removeAttackerFromBand(pair.getKey(), pair.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
Collection<Card> toRemove = Lists.newArrayList();
|
Collection<Card> toRemove = Lists.newArrayList();
|
||||||
for(Entry<AttackingBand, Collection<Card>> be : blockedBands.entrySet()) {
|
for(Entry<AttackingBand, Collection<Card>> be : blockedBands.entrySet()) {
|
||||||
@@ -389,7 +378,6 @@ public class Combat {
|
|||||||
for( Card b : be.getValue()) {
|
for( Card b : be.getValue()) {
|
||||||
if ( !b.isInPlay() ) {
|
if ( !b.isInPlay() ) {
|
||||||
unregisterDefender(b, be.getKey());
|
unregisterDefender(b, be.getKey());
|
||||||
toRemove.add(b);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
be.getValue().removeAll(toRemove);
|
be.getValue().removeAll(toRemove);
|
||||||
@@ -665,4 +653,21 @@ public class Combat {
|
|||||||
return blockers != null && blockers.contains(blocker);
|
return blockers != null && blockers.contains(blocker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
* @param lastKnownInfo
|
||||||
|
*/
|
||||||
|
public void saveLKI(Card lastKnownInfo) {
|
||||||
|
List<AttackingBand> attackersBlocked = null;
|
||||||
|
AttackingBand attackingBand = getBandOfAttacker(lastKnownInfo);
|
||||||
|
boolean isAttacker = attackingBand != null;
|
||||||
|
if ( !isAttacker ) {
|
||||||
|
attackersBlocked= getAttackingBandsBlockedBy(lastKnownInfo);
|
||||||
|
if ( attackersBlocked.isEmpty() )
|
||||||
|
return; // card was not even in combat
|
||||||
|
}
|
||||||
|
List<AttackingBand> relatedBands = isAttacker ? Lists.newArrayList(attackingBand) : attackersBlocked;
|
||||||
|
lkiCache.put(lastKnownInfo, new CombatLki(isAttacker, relatedBands));
|
||||||
|
}
|
||||||
|
|
||||||
} // Class Combat
|
} // Class Combat
|
||||||
|
|||||||
25
src/main/java/forge/game/combat/CombatLki.java
Normal file
25
src/main/java/forge/game/combat/CombatLki.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package forge.game.combat;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this type.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CombatLki {
|
||||||
|
|
||||||
|
public final List<AttackingBand> relatedBands;
|
||||||
|
public final boolean isAttacker;
|
||||||
|
|
||||||
|
|
||||||
|
public CombatLki(boolean isAttacker, List<AttackingBand> relatedBands) {
|
||||||
|
this.isAttacker = isAttacker;
|
||||||
|
this.relatedBands = Collections.unmodifiableList(relatedBands);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttackingBand getFirstBand() {
|
||||||
|
return relatedBands.isEmpty() ? null : relatedBands.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user