2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
6
* This program is distributed in the hope that it will be useful,
7
* but WITHOUT ANY WARRANTY; without even the implied warranty of
8
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9
* GNU General Public License for more details.
10
* You should have received a copy of the GNU General Public License
11
* along with this program; if not, write to the Free Software
12
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
* NonFightingBattle.java
18
* Created on November 23, 2001, 11:53 AM
21
package games.strategy.triplea.delegate;
23
import games.strategy.engine.data.*;
24
import games.strategy.engine.delegate.IDelegateBridge;
25
import games.strategy.triplea.formatter.MyFormatter;
26
import games.strategy.util.*;
31
* Battle in which no fighting occurs. <b>
32
* Example is a naval invasion into an empty country,
33
* but the battle cannot be fought until a naval battle
36
* @author Sean Bridges
39
public class NonFightingBattle implements Battle
42
private Territory m_battleSite;
43
private PlayerID m_attacker;
44
private BattleTracker m_battleTracker;
45
private GameData m_data;
46
private boolean m_isOver = false;
49
//maps unit -> Collection of units
50
//if unit is lost in a battle we are dependent on
51
//then we lose the corresponding collection of units
52
private Map<Unit, Collection<Unit>> m_dependentUnits = new HashMap<Unit, Collection<Unit>>();
54
public NonFightingBattle(Territory battleSite, PlayerID attacker, BattleTracker battleTracker, boolean neutral, GameData data)
56
m_battleTracker = battleTracker;
57
m_attacker = attacker;
58
m_battleSite = battleSite;
62
public void fight(IDelegateBridge bridge)
64
if(!m_battleTracker.getDependentOn(this).isEmpty())
65
throw new IllegalStateException("Must fight battles that this battle depends on first");
67
//if any attacking non air units then win
68
boolean someAttacking = hasAttackingUnits();
71
m_battleTracker.takeOver(m_battleSite, m_attacker, bridge, m_data, null, null);
72
m_battleTracker.addToConquered(m_battleSite);
79
m_battleTracker.removeBattle(this);
83
public boolean isOver()
88
private boolean hasAttackingUnits()
90
CompositeMatch<Unit> attackingLand = new CompositeMatchAnd<Unit>();
91
attackingLand.add(Matches.alliedUnit(m_attacker, m_data));
92
attackingLand.add(Matches.UnitIsLand);
93
boolean someAttacking = m_battleSite.getUnits().someMatch(attackingLand);
97
public boolean isBombingRun()
102
public void removeAttack(Route route, Collection<Unit> units)
104
Iterator<Unit> dependents = m_dependentUnits.keySet().iterator();
105
while(dependents.hasNext())
107
Unit dependence = dependents.next();
108
Collection<Unit> dependent = m_dependentUnits.get(dependence);
109
dependent.removeAll(units);
113
public boolean isEmpty()
115
return !hasAttackingUnits();
118
public Change addAttackChange(Route route, Collection<Unit> units)
120
Map<Unit, Collection<Unit>> addedTransporting = new TransportTracker().transporting(units);
121
Iterator<Unit> iter = addedTransporting.keySet().iterator();
122
while(iter.hasNext())
124
Unit unit = iter.next();
125
if(m_dependentUnits.get(unit) != null)
126
m_dependentUnits.get(unit).addAll( addedTransporting.get(unit));
128
m_dependentUnits.put(unit, addedTransporting.get(unit));
130
return ChangeFactory.EMPTY_CHANGE;
133
public Change addCombatChange(Route route, Collection<Unit> units, PlayerID player)
135
Map<Unit, Collection<Unit>> addedTransporting = new TransportTracker().transporting(units);
136
Iterator<Unit> iter = addedTransporting.keySet().iterator();
137
while(iter.hasNext())
139
Unit unit = iter.next();
140
if(m_dependentUnits.get(unit) != null)
141
m_dependentUnits.get(unit).addAll( addedTransporting.get(unit));
143
m_dependentUnits.put(unit, addedTransporting.get(unit));
145
return ChangeFactory.EMPTY_CHANGE;
148
public Territory getTerritory()
153
public void unitsLostInPrecedingBattle(Battle battle, Collection<Unit> units, IDelegateBridge bridge)
155
Collection<Unit> lost = getDependentUnits(units);
156
lost = Match.getMatches(lost, Matches.unitIsInTerritory(m_battleSite));
159
Change change = ChangeFactory.removeUnits(m_battleSite, lost);
160
bridge.addChange(change);
162
String transcriptText = MyFormatter.unitsToText(lost) + " lost in " + m_battleSite.getName();
163
bridge.getHistoryWriter().startEvent(transcriptText);
167
public Collection<Unit> getDependentUnits(Collection units)
169
Collection<Unit> rVal = new ArrayList<Unit>();
171
Iterator iter = units.iterator();
172
while(iter.hasNext())
174
Unit unit = (Unit) iter.next();
175
Collection<Unit> dependent = m_dependentUnits.get(unit);
176
if(dependent != null)
177
rVal.addAll(dependent);
182
public int hashCode()
184
return m_battleSite.hashCode();
187
public boolean equals(Object o)
189
//2 battles are equal if they are both the same type (boming or not)
190
//and occur on the same territory
191
//equals in the sense that they should never occupy the same Set
192
//if these conditions are met
193
if (o == null || ! (o instanceof Battle))
196
Battle other = (Battle) o;
197
return other.getTerritory().equals(this.m_battleSite) &&
198
other.isBombingRun() == this.isBombingRun();
202
* Add bombarding unit. Doesn't make sense here so just do
205
public void addBombardingUnit(Unit unit) {
210
* Return whether battle is amphibious.
212
public boolean isAmphibious() {
216
public Collection<Unit> getAmphibiousLandAttackers()
218
return new ArrayList<Unit>();
221
public Collection<Unit> getBombardingUnits()
223
return new ArrayList<Unit>();
226
public int getBattleRound()