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/combat/AttackingBand.java -text
|
||||
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/event/GameEvent.java -text
|
||||
src/main/java/forge/game/event/GameEventAnteCardsSelected.java -text
|
||||
|
||||
@@ -224,7 +224,10 @@ public class GameAction {
|
||||
|
||||
if (zoneFrom != null) {
|
||||
if (zoneFrom.is(ZoneType.Battlefield) && c.isCreature() && game.getCombat() != null) {
|
||||
if ( !zoneTo.is(ZoneType.Battlefield) )
|
||||
game.getCombat().saveLKI(lastKnownInfo);
|
||||
game.getCombat().removeFromCombat(c);
|
||||
|
||||
}
|
||||
zoneFrom.remove(c);
|
||||
}
|
||||
@@ -233,11 +236,7 @@ public class GameAction {
|
||||
|
||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||
runParams.put("Card", lastKnownInfo);
|
||||
if (zoneFrom != null) {
|
||||
runParams.put("Origin", zoneFrom.getZoneType().name());
|
||||
} else {
|
||||
runParams.put("Origin", null);
|
||||
}
|
||||
runParams.put("Origin", zoneFrom != null ? zoneFrom.getZoneType().name() : null);
|
||||
runParams.put("Destination", zoneTo.getZoneType().name());
|
||||
game.getTriggerHandler().runTrigger(TriggerType.ChangesZone, runParams, false);
|
||||
// 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 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);
|
||||
|
||||
// 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.Entry;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
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>> blockersOrderedForDamageAssignment = new HashMap<Card, List<Card>>();
|
||||
private Map<GameEntity, CombatLki> lkiCache = new HashMap<GameEntity, CombatLki>();
|
||||
|
||||
|
||||
public Combat(Player attacker) {
|
||||
@@ -104,7 +103,6 @@ public class Combat {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public final void addAttacker(final Card c, GameEntity defender) {
|
||||
addAttacker(c, defender, null);
|
||||
}
|
||||
@@ -125,13 +123,7 @@ public class Combat {
|
||||
}
|
||||
|
||||
public final GameEntity getDefenderByAttacker(final Card c) {
|
||||
for(Entry<GameEntity, Collection<AttackingBand>> e : attackedEntities.entrySet()) {
|
||||
for(AttackingBand ab : e.getValue()) {
|
||||
if ( ab.contains(c) )
|
||||
return e.getKey();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return getDefenderByAttacker(getBandOfAttacker(c));
|
||||
}
|
||||
|
||||
public final GameEntity getDefenderByAttacker(final AttackingBand c) {
|
||||
@@ -160,6 +152,10 @@ public class Combat {
|
||||
}
|
||||
|
||||
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(AttackingBand ab : abs) {
|
||||
if ( ab.contains(c) )
|
||||
@@ -182,9 +178,10 @@ public class Combat {
|
||||
}
|
||||
|
||||
public boolean isAttacking(Card card, GameEntity defender) {
|
||||
AttackingBand ab = getBandOfAttacker(card);
|
||||
|
||||
for(Entry<GameEntity, Collection<AttackingBand>> ee : attackedEntities.entrySet())
|
||||
for(AttackingBand ab : ee.getValue())
|
||||
if (ab.contains(card))
|
||||
if ( ee.getValue().contains(ab) )
|
||||
return ee.getKey() == defender;
|
||||
return false;
|
||||
}
|
||||
@@ -259,6 +256,15 @@ public class Combat {
|
||||
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) {
|
||||
Card attacker = source;
|
||||
if (source.isAura()) {
|
||||
@@ -334,23 +340,12 @@ 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
|
||||
public final void removeFromCombat(final Card c) {
|
||||
AttackingBand ab = getBandOfAttacker(c);
|
||||
if (ab != null) {
|
||||
unregisterAttacker(c, ab);
|
||||
removeAttackerFromBand(ab, c);
|
||||
ab.removeAttacker(c);
|
||||
}
|
||||
|
||||
// if not found in attackers, look for this card in blockers
|
||||
@@ -365,7 +360,6 @@ public class Combat {
|
||||
|
||||
public final void removeAbsentCombatants() {
|
||||
// iterate all attackers and remove them
|
||||
List<Pair<AttackingBand, Card>> toRemoveAtk = new ArrayList<>();
|
||||
for(Entry<GameEntity, Collection<AttackingBand>> ee : attackedEntities.entrySet()) {
|
||||
for(AttackingBand ab : ee.getValue()) {
|
||||
List<Card> atk = ab.getAttackers();
|
||||
@@ -373,15 +367,10 @@ public class Combat {
|
||||
Card c = atk.get(i);
|
||||
if ( !c.isInPlay() ) {
|
||||
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();
|
||||
for(Entry<AttackingBand, Collection<Card>> be : blockedBands.entrySet()) {
|
||||
@@ -389,7 +378,6 @@ public class Combat {
|
||||
for( Card b : be.getValue()) {
|
||||
if ( !b.isInPlay() ) {
|
||||
unregisterDefender(b, be.getKey());
|
||||
toRemove.add(b);
|
||||
}
|
||||
}
|
||||
be.getValue().removeAll(toRemove);
|
||||
@@ -665,4 +653,21 @@ public class Combat {
|
||||
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
|
||||
|
||||
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