Various bug fixes.

This commit is contained in:
Stian Grenborgen 2004-05-07 17:23:40 +00:00
parent 54609e1440
commit edb9f32623
13 changed files with 177 additions and 100 deletions

View File

@ -171,7 +171,8 @@ public final class InGameController {
Element reply = client.ask(moveElement);
freeColClient.getInGameInputHandler().handle(client.getConnection(), reply);
}
/**
* Performs an attack in a specified direction. Note that the server
* handles the attack calculations here.
@ -181,17 +182,39 @@ public final class InGameController {
*/
private void attack(Unit unit, int direction) {
Client client = freeColClient.getClient();
Game game = freeColClient.getGame();
Map map = game.getMap();
// Inform the server:
Element attackElement = Message.createNewRootElement("attack");
attackElement.setAttribute("unit", unit.getID());
attackElement.setAttribute("direction", Integer.toString(direction));
//client.send(moveElement);
Element reply = client.ask(attackElement);
freeColClient.getInGameInputHandler().handle(client.getConnection(), reply);
// Get the result of the attack from the server:
Element attackResultElement = client.ask(attackElement);
int result = Integer.parseInt(attackResultElement.getAttribute("result"));
Element updateElement = (Element) attackResultElement.getElementsByTagName("update").item(0);
if (updateElement != null) {
freeColClient.getInGameInputHandler().handle(client.getConnection(), updateElement);
}
Unit defender = map.getNeighbourOrNull(direction, unit.getTile()).getDefendingUnit(unit);
if (result == Unit.ATTACKER_LOSS) {
unit.loseAttack();
} else {
unit.winAttack(defender);
}
if (unit.getMovesLeft() <= 0) {
nextActiveUnit(unit.getTile());
}
freeColClient.getCanvas().refresh();
}
/**
* Disembarks the specified unit in a specified direction.
*
@ -686,7 +709,10 @@ public final class InGameController {
Unit unit = gui.getActiveUnit();
unit.skip();
if (unit != null) {
unit.skip();
}
nextActiveUnit();
}

View File

@ -74,8 +74,6 @@ public final class InGameInputHandler implements MessageHandler {
reply = opponentMove(element);
} else if (type.equals("opponentAttack")) {
reply = opponentAttack(element);
} else if (type.equals("attackResult")) {
reply = attackResult(element);
} else if (type.equals("setCurrentPlayer")) {
reply = setCurrentPlayer(element);
} else if (type.equals("emigrateUnitInEuropeConfirmed")) {
@ -163,8 +161,13 @@ public final class InGameInputHandler implements MessageHandler {
if (!opponentMoveElement.hasAttribute("tile")) {
Unit unit = (Unit) game.getFreeColGameObject(opponentMoveElement.getAttribute("unit"));
//Player player = unit.getOwner();
// This originally said player.___, which made no sense. -sjm
if (unit == null) {
//throw new NullPointerException();
logger.warning("Could not find the 'unit' in 'opponentMove'.");
return null;
}
if ((unit.getTile() != null) && (currentPlayer.canSee(map.getNeighbourOrNull(direction, unit.getTile())))) {
unit.move(direction);
} else {
@ -181,6 +184,7 @@ public final class InGameInputHandler implements MessageHandler {
return null;
}
/**
* Handles an "opponentAttack"-message.
*
@ -209,36 +213,6 @@ public final class InGameInputHandler implements MessageHandler {
return null;
}
/**
* Handles an "attackResult"-message.
*
* @param attackResultElement The element (root element in a DOM-parsed XML tree) that
* holds all the information.
*/
private Element attackResult(Element attackResultElement) {
Game game = freeColClient.getGame();
Map map = game.getMap();
int direction = Integer.parseInt(attackResultElement.getAttribute("direction"));
int result = Integer.parseInt(attackResultElement.getAttribute("result"));
Unit unit = (Unit) game.getFreeColGameObject(attackResultElement.getAttribute("unit"));
Unit defender = map.getNeighbourOrNull(direction, unit.getTile()).getDefendingUnit(unit);
if (result == Unit.ATTACKER_LOSS) {
unit.loseAttack();
} else {
unit.winAttack(defender);
}
if (attackResultElement.hasAttribute("update")) {
this.update((Element) attackResultElement.getElementsByTagName("update").item(0));
}
freeColClient.getCanvas().refresh();
return null;
}
/**
* Handles a "setCurrentPlayer"-message.

View File

@ -504,6 +504,15 @@ public final class Building extends FreeColGameObject implements WorkLocation {
colony.addGoods(goodsOutputType, goodsOutput);
}
public void dispose() {
for (int i=0; i<units.size(); i++) {
((Unit) units.get(i)).dispose();
}
super.dispose();
}
/**
* Makes a XML-representation of this object.

View File

@ -355,6 +355,8 @@ public final class Colony extends Settlement implements Location {
public Iterator getUnitIterator() {
ArrayList units = new ArrayList();
throw new UnsupportedOperationException();
}
@ -370,7 +372,7 @@ public final class Colony extends Settlement implements Location {
public boolean canAdd(Locatable locatable) {
throw new UnsupportedOperationException();
}
/**
* Gets the <code>Unit</code> that is currently defending this <code>Colony</code>.
* @param attacker The target that would be attacking this colony.
@ -378,23 +380,27 @@ public final class Colony extends Settlement implements Location {
*/
public Unit getDefendingUnit(Unit attacker) {
Iterator i = getWorkLocationIterator();
ArrayList units = new ArrayList();
//ArrayList units = new ArrayList();
while (i.hasNext()) {
WorkLocation w = (WorkLocation) i.next();
if (w instanceof Building) {
Iterator unitIterator = w.getUnitIterator();
while (unitIterator.hasNext()) {
Unit unit = (Unit)unitIterator.next();
units.add(unit);
//units.add(unit);
return unit;
}
} else if (w instanceof ColonyTile) {
Unit unit = ((ColonyTile)w).getUnit();
if (unit != null) units.add(unit);
//if (unit != null) units.add(unit);
return unit;
}
}
return null;
/* This is not neccessary: soldiers are outside colony (on the tile):
Iterator unitIterator = units.iterator();
Unit defender = null;
if (unitIterator.hasNext()) {
defender = (Unit) unitIterator.next();
@ -409,10 +415,11 @@ public final class Colony extends Settlement implements Location {
defender = nextUnit;
}
}
return defender;
*/
}
/**
* Adds to the hammer count of the colony.
* @param amount The number of hammers to add.
@ -560,6 +567,18 @@ public final class Colony extends Settlement implements Location {
}
public void dispose() {
Iterator i = getWorkLocationIterator();
while (i.hasNext()) {
WorkLocation w = (WorkLocation) i.next();
((FreeColGameObject) w).dispose();
}
getTile().setSettlement(null);
super.dispose();
}
/**
* Make a XML-representation of this object.

View File

@ -251,6 +251,15 @@ public class ColonyTile extends FreeColGameObject implements WorkLocation {
}
public void dispose() {
if (unit != null) {
unit.dispose();
}
super.dispose();
}
/**
* Makes an XML-representation of this object.
*

View File

@ -168,7 +168,7 @@ public class Game extends FreeColGameObject {
if (id == null || id.equals("")) {
throw new NullPointerException();
}
return (FreeColGameObject) freeColGameObjects.get(id);
}

View File

@ -150,15 +150,6 @@ public class IndianSettlement extends Settlement {
}
/**
* Returns <i>null</i>.
* @return <i>null</i>.
*/
public Tile getTile() {
return super.getTile();
}
/**
* Adds a <code>Locatable</code> to this Location.
*
@ -213,6 +204,35 @@ public class IndianSettlement extends Settlement {
}
/**
* Gets the <code>Unit</code> that is currently defending this <code>IndianSettlement</code>.
* @param attacker The target that would be attacking this <code>IndianSettlement</code>.
* @return The <code>Unit</code> that has been choosen to defend this <code>IndianSettlement</code>.
*/
public Unit getDefendingUnit(Unit attacker) {
Iterator unitIterator = getUnitIterator();
Unit defender = null;
if (unitIterator.hasNext()) {
defender = (Unit) unitIterator.next();
} else {
return null;
}
while (unitIterator.hasNext()) {
Unit nextUnit = (Unit) unitIterator.next();
if (nextUnit.getDefensePower(attacker) > defender.getDefensePower(attacker)) {
defender = nextUnit;
}
}
return defender;
}
public boolean contains(Locatable locatable) {
if (locatable instanceof Unit) {
return unitContainer.contains((Unit) locatable);
@ -230,8 +250,15 @@ public class IndianSettlement extends Settlement {
public void newTurn() {
}
public void dispose() {
unitContainer.dispose();
getTile().setSettlement(null);
super.dispose();
}
/**
* Make a XML-representation of this object.
*
@ -242,6 +269,7 @@ public class IndianSettlement extends Settlement {
Element indianSettlementElement = document.createElement(getXMLElementTagName());
indianSettlementElement.setAttribute("ID", getID());
indianSettlementElement.setAttribute("tile", tile.getID());
indianSettlementElement.setAttribute("owner", owner.getID());
indianSettlementElement.setAttribute("tribe", Integer.toString(tribe));
indianSettlementElement.setAttribute("kind", Integer.toString(kind));
@ -261,6 +289,7 @@ public class IndianSettlement extends Settlement {
public void readFromXMLElement(Element indianSettlementElement) {
setID(indianSettlementElement.getAttribute("ID"));
tile = (Tile) getGame().getFreeColGameObject(indianSettlementElement.getAttribute("tile"));
owner = (Player)getGame().getFreeColGameObject(indianSettlementElement.getAttribute("owner"));
tribe = Integer.parseInt(indianSettlementElement.getAttribute("tribe"));
kind = Integer.parseInt(indianSettlementElement.getAttribute("kind"));
@ -277,8 +306,7 @@ public class IndianSettlement extends Settlement {
/**
* Returns the tag name of the root element representing this object.
*
* @return the tag name.
* @return "indianSettlement".
*/
public static String getXMLElementTagName() {
return "indianSettlement";

View File

@ -49,8 +49,14 @@ abstract public class Settlement extends FreeColGameObject implements Location {
/**
* Gets the <code>Unit</code> that is currently defending this <code>Settlement</code>.
* @param attacker The target that would be attacking this <code>Settlement</code>.
* @return The <code>Unit</code> that has been choosen to defend this <code>Settlement</code>.
*/
abstract public Unit getDefendingUnit(Unit attacker);
/**
* Gets the <code>Tile</code> where this <code>Settlement</code> is located.
* @return The <code>Tile</code> where this <code>Settlement</code> is located.

View File

@ -177,17 +177,15 @@ public final class Tile extends FreeColGameObject implements Location {
}
}
if (settlement != null) {
Unit settlementDefender = null;
if (settlement instanceof Colony) {
settlementDefender = ((Colony)settlement).getDefendingUnit(attacker);
}
if ((settlementDefender != null) && ((defender == null) || (settlementDefender.getDefensePower(attacker) > defender.getDefensePower(attacker)))) {
defender = settlementDefender;
}
if (defender != null) {
return defender;
}
if (settlement != null) {
return settlement.getDefendingUnit(attacker);
} else {
return null;
}
return defender;
}

View File

@ -427,7 +427,7 @@ public class Unit extends FreeColGameObject implements Location, Locatable {
int type = getMoveType(direction);
if (type != MOVE && type != DISEMBARK && type != MOVE_HIGH_SEAS) {
throw new IllegalStateException("Illegal move requested!");
throw new IllegalStateException("Illegal move requested: " + type);
}
setState(ACTIVE);
@ -2049,10 +2049,6 @@ public class Unit extends FreeColGameObject implements Location, Locatable {
Tile newTile = defender.getTile();
if (newTile == null) {
throw new NullPointerException();
}
movesLeft = 0;
if (defender.getType() == BRAVE) {
defender.dispose();
@ -2060,7 +2056,7 @@ public class Unit extends FreeColGameObject implements Location, Locatable {
if (newTile.getSettlement().getUnitCount() <= 0) {
//TODO: Burn the camp. Get treasure.
newTile.getSettlement().dispose();
setLocation(newTile);
//setLocation(newTile);
}
} else {
Iterator unitIterator = newTile.getUnitIterator();
@ -2104,6 +2100,7 @@ public class Unit extends FreeColGameObject implements Location, Locatable {
defender.setArmed(false, true);
if (getType() == BRAVE) {
//TODO: don't always do this. Have some random chance.
// ATTACKER_LOSS_MUSKETS.
setArmed(true, true);
}
}
@ -2129,13 +2126,10 @@ public class Unit extends FreeColGameObject implements Location, Locatable {
setType(DAMAGED_ARTILLERY);
} else if ((getType() == KINGS_REGULAR) || (getType() == DAMAGED_ARTILLERY)) {
dispose();
return; // Do NOT try to go any further!
} else {
setArmed(false, true);
}
}
return;
}
@ -2391,8 +2385,16 @@ public class Unit extends FreeColGameObject implements Location, Locatable {
if (unitElement.hasAttribute("location")) {
location = (Location) getGame().getFreeColGameObject(unitElement.getAttribute("location"));
/*
In this case, 'location == null' can only occur if the location specified in the
XML-Element does not exists:
*/
if (location == null) {
throw new NullPointerException();
}
}
if (isCarrier()) {
Element unitContainerElement = (Element) unitElement.getElementsByTagName(UnitContainer.getXMLElementTagName()).item(0);
if (unitContainer != null) {

View File

@ -70,6 +70,9 @@ public final class AIInGameInputHandler implements MessageHandler {
// Therefore most of these messages are useless.
if (type.equals("update")) {
} else if (type.equals("remove")) {
} else if (type.equals("startGame")) {
} else if (type.equals("updateGame")) {
} else if (type.equals("addPlayer")) {
} else if (type.equals("opponentMove")) {
} else if (type.equals("opponentAttack")) {
} else if (type.equals("attackResult")) {

View File

@ -153,14 +153,15 @@ public final class InGameInputHandler implements MessageHandler {
continue;
}
Element opponentMoveElement = Message.createNewRootElement("opponentMove");
opponentMoveElement.setAttribute("direction", Integer.toString(direction));
try {
if (enemyPlayer.canSee(oldTile)) {
Element opponentMoveElement = Message.createNewRootElement("opponentMove");
opponentMoveElement.setAttribute("direction", Integer.toString(direction));
opponentMoveElement.setAttribute("unit", unit.getID());
enemyPlayer.getConnection().send(opponentMoveElement);
} else if (enemyPlayer.canSee(newTile)) {
Element opponentMoveElement = Message.createNewRootElement("opponentMove");
opponentMoveElement.setAttribute("direction", Integer.toString(direction));
opponentMoveElement.setAttribute("tile", unit.getTile().getID());
opponentMoveElement.appendChild(unit.toXMLElement(enemyPlayer, opponentMoveElement.getOwnerDocument()));
enemyPlayer.getConnection().send(opponentMoveElement);
@ -194,13 +195,10 @@ public final class InGameInputHandler implements MessageHandler {
*/
private Element attack(Connection connection, Element attackElement) {
Game game = freeColServer.getGame();
ServerPlayer player = freeColServer.getPlayer(connection);
Unit unit = (Unit) game.getFreeColGameObject(attackElement.getAttribute("unit"));
int direction = Integer.parseInt(attackElement.getAttribute("direction"));
Unit defender = null;
if (unit == null) {
throw new IllegalArgumentException("Could not find 'Unit' with specified ID: " + attackElement.getAttribute("unit"));
@ -208,23 +206,26 @@ public final class InGameInputHandler implements MessageHandler {
Tile oldTile = unit.getTile();
Tile newTile = game.getMap().getNeighbourOrNull(direction, unit.getTile());
if (newTile == null) {
throw new IllegalArgumentException("Could not find tile in direction " + direction + " from unit with ID " + attackElement.getAttribute("unit"));
}
defender = newTile.getDefendingUnit(unit);
Unit defender = newTile.getDefendingUnit(unit);
if (defender == null) {
throw new IllegalStateException("Nothing to attack in direction " + direction + " from unit with ID " + attackElement.getAttribute("unit"));
}
// Calculate the result:
int attack_power = unit.getOffensePower(defender);
int total_probability = attack_power + defender.getDefensePower(unit);
int result = Unit.ATTACKER_LOSS; // Assume this until otherwise calculated.
if ((attackCalculator.nextInt(total_probability)) <= attack_power) {
// Win.
result = Unit.ATTACKER_WIN;
unit.winAttack(defender);
} // Loss code is later, when unit is no longer needed.
if ((attackCalculator.nextInt(total_probability)) <= attack_power) {
result = Unit.ATTACKER_WIN;
}
// Inform the other players (other then the player attacking) about the attack:
Iterator enemyPlayerIterator = game.getPlayerIterator();
while (enemyPlayerIterator.hasNext()) {
ServerPlayer enemyPlayer = (ServerPlayer) enemyPlayerIterator.next();
@ -245,10 +246,10 @@ public final class InGameInputHandler implements MessageHandler {
}
}
// Create the reply:
Element reply = Message.createNewRootElement("attackResult");
reply.setAttribute("direction", Integer.toString(direction));
reply.setAttribute("result", Integer.toString(result));
reply.setAttribute("unit", unit.getID());
if (unit.getTile().equals(newTile)) { // In other words, we moved...
Element update = reply.getOwnerDocument().createElement("update");
Vector surroundingTiles = game.getMap().getSurroundingTiles(unit.getTile(), unit.getLineOfSight());
@ -258,13 +259,14 @@ public final class InGameInputHandler implements MessageHandler {
player.setExplored(t);
update.appendChild(t.toXMLElement(player, update.getOwnerDocument()));
}
reply.appendChild(update);
}
// This is down here do it doesn't interfere with other unit code.
if (result == Unit.ATTACKER_LOSS) {
unit.loseAttack();
} else {
unit.winAttack(defender);
}
return reply;
}

View File

@ -416,7 +416,8 @@ public class MapGenerator {
if (landMap[i][j]) {
t = new Tile(game, getRandomTileType(((Math.min(j, height - j) * 100) / height)), i, j);
if ((t.getType() != t.ARCTIC) && (tileType.nextInt(3) > 0)) {
//if ((t.getType() != t.ARCTIC) && (tileType.nextInt(3) > 0)) {
if ((t.getType() != t.ARCTIC) && (tileType.nextInt(3) > 1)) {
t.setForested(true);
} else if ((t.getType() != t.ARCTIC) && (t.getType() != t.TUNDRA)) {
int k = tileType.nextInt(8);