/** * Why would this mission be invalid with the given unit? * * @param aiUnit The <code>AIUnit</code> to test. * @return A reason why the mission would be invalid with the unit, or null if none found. */ private static String invalidMissionReason(AIUnit aiUnit) { String reason = invalidAIUnitReason(aiUnit); IndianSettlement home; return (reason != null) ? reason : ((home = getHome(aiUnit)) == null || home.isDisposed()) ? "home-destroyed" : null; }
/** * When searching for threats to a settlement, the indian player should ignore naval threats, as * he does not have naval power */ public void testSecureIndianSettlementMissionIgnoreNavalThreat() { Game game = ServerTestHelper.startServerGame(getCoastTestMap(plainsType)); Map map = game.getMap(); AIMain aiMain = ServerTestHelper.getServer().getAIMain(); InGameController igc = ServerTestHelper.getInGameController(); // Create player and unit ServerPlayer inca = (ServerPlayer) game.getPlayerByNationId("model.nation.inca"); NativeAIPlayer aiInca = (NativeAIPlayer) aiMain.getAIPlayer(inca); ServerPlayer dutch = (ServerPlayer) game.getPlayerByNationId("model.nation.dutch"); Tile settlementTile = map.getTile(9, 9); Tile seaTile = map.getTile(10, 9); assertTrue("Settlement tile should be land", settlementTile.isLand()); assertFalse("Galleon tile should be ocean", seaTile.isLand()); FreeColTestCase.IndianSettlementBuilder builder = new FreeColTestCase.IndianSettlementBuilder(game); IndianSettlement camp = builder.player(inca).settlementTile(settlementTile).initialBravesInCamp(10).build(); ServerUnit galleon = new ServerUnit(game, seaTile, dutch, galleonType); int unitsInGalleon = 6; for (int i = 0; i < unitsInGalleon; i++) { ServerUnit artillery = new ServerUnit(game, settlementTile, dutch, artilleryType); igc.embarkUnit(dutch, artillery, galleon); } assertEquals("Wrong number of units onboard galleon", unitsInGalleon, galleon.getUnitCount()); assertEquals("Galleon should be full", 0, galleon.getSpaceLeft()); for (Unit brave : camp.getUnitList()) { AIUnit aiUnit = aiMain.getAIUnit(brave); assertNotNull(aiUnit); new UnitWanderHostileMission(aiMain, aiUnit); assertTrue("No enemy units present", aiUnit.hasMission(UnitWanderHostileMission.class)); } inca.setStance(dutch, Stance.WAR); inca.setTension(dutch, new Tension(Tension.Level.HATEFUL.getLimit())); assertTrue("Indian player should be at war with dutch", inca.getStance(dutch) == Stance.WAR); assertEquals( "Wrong Indian player tension towards dutch", Tension.Level.HATEFUL.getLimit(), inca.getTension(dutch).getValue()); aiInca.abortInvalidMissions(); aiInca.secureIndianSettlement(camp, lb); boolean seeking = false; for (Unit brave : inca.getUnits()) { AIUnit aiUnit = aiMain.getAIUnit(brave); assertNotNull(aiUnit); if (aiUnit.hasMission(UnitSeekAndDestroyMission.class)) { seeking = true; break; } } assertFalse("Braves should not pursue naval units", seeking); }
/** * Allows spread of horses and arms between settlements * * <p>FIXME: the hardwired goods/equipment types are a wart. * * @param settlement The other <code>IndianSettlement</code> to trade with. */ public void tradeGoodsWithSettlement(IndianSettlement settlement) { GoodsType armsType = getSpecification().getGoodsType("model.goods.muskets"); GoodsType horsesType = getSpecification().getGoodsType("model.goods.horses"); List<GoodsType> goodsToTrade = new ArrayList<>(); goodsToTrade.add(armsType); goodsToTrade.add(horsesType); for (GoodsType goods : goodsToTrade) { int goodsInStock = getGoodsCount(goods); if (goodsInStock <= 50) { continue; } int goodsTraded = goodsInStock / 2; settlement.addGoods(goods, goodsTraded); removeGoods(goods, goodsTraded); } }
/** {@inheritDoc} */ @Override public Mission doMission(LogBuilder lb) { lb.add(tag); String reason = invalidReason(); if (reason != null) return lbFail(lb, false, reason); final AIUnit aiUnit = getAIUnit(); final Unit unit = getUnit(); final IndianSettlement is = unit.getHomeIndianSettlement(); Direction d; while (!this.demanded) { Unit.MoveType mt = travelToTarget(getTarget(), null, lb); switch (mt) { case MOVE_HIGH_SEAS: case MOVE_NO_MOVES: case MOVE_ILLEGAL: return lbWait(lb); case MOVE_NO_REPAIR: return lbFail(lb, false, AIUNITDIED); case MOVE_NO_TILE: return this; case ATTACK_SETTLEMENT: // Arrived? d = unit.getTile().getDirection(getTarget().getTile()); if (d != null) break; // Yes, arrived at target // Fall through case ATTACK_UNIT: // Something is blocking our path Location blocker = resolveBlockage(aiUnit, getTarget()); if (blocker == null) { moveRandomly(tag, null); continue; } d = unit.getTile().getDirection(blocker.getTile()); if (AIMessage.askAttack(aiUnit, d)) { return lbAttack(lb, blocker); } continue; default: return lbMove(lb, mt); } // Load the goods. lbAt(lb); Colony colony = (Colony) getTarget(); Player enemy = colony.getOwner(); Goods goods = selectGoods(colony); GoodsType type = (goods == null) ? null : goods.getType(); int amount = (goods == null) ? 0 : goods.getAmount(); if (goods == null) { if (!enemy.checkGold(1)) { return lbDone(lb, false, "empty handed"); } amount = enemy.getGold() / 20; if (amount == 0) amount = enemy.getGold(); } this.demanded = AIMessage.askIndianDemand(aiUnit, colony, type, amount); if (this.demanded && (goods == null || hasTribute())) { if (goods == null) { return lbDone(lb, false, "accepted tribute ", amount, " gold"); } lb.add(", accepted tribute ", goods); return lbRetarget(lb); } // Consider attacking if not content. int unitTension = (is == null) ? 0 : is.getAlarm(enemy).getValue(); int tension = Math.max(unitTension, unit.getOwner().getTension(enemy).getValue()); d = unit.getTile().getDirection(colony.getTile()); if (tension >= Tension.Level.CONTENT.getLimit() && d != null) { if (AIMessage.askAttack(aiUnit, d)) lbAttack(lb, colony); } return lbDone(lb, false, "refused at ", colony); } // Take the goods home for (; ; ) { Unit.MoveType mt = travelToTarget(getTarget(), CostDeciders.avoidSettlementsAndBlockingUnits(), lb); switch (mt) { case MOVE: // Arrived break; case MOVE_HIGH_SEAS: case MOVE_NO_MOVES: case MOVE_ILLEGAL: return lbWait(lb); case MOVE_NO_REPAIR: return lbFail(lb, false, AIUNITDIED); case MOVE_NO_TILE: return this; default: return lbMove(lb, mt); } // Unload the goods lbAt(lb); GoodsContainer container = unit.getGoodsContainer(); for (Goods goods : container.getCompactGoods()) { Goods tribute = container.removeGoods(goods.getType()); is.addGoods(tribute); } return lbDone(lb, false, "unloaded tribute"); } }
public void testSecureIndianSettlementMission() { Game game = ServerTestHelper.startServerGame(getTestMap()); Map map = game.getMap(); AIMain aiMain = ServerTestHelper.getServer().getAIMain(); // Create player and unit ServerPlayer inca = (ServerPlayer) game.getPlayerByNationId("model.nation.inca"); NativeAIPlayer aiInca = (NativeAIPlayer) aiMain.getAIPlayer(inca); ServerPlayer dutch = (ServerPlayer) game.getPlayerByNationId("model.nation.dutch"); Tile settlementTile = map.getTile(9, 9); Tile adjacentTile = settlementTile.getNeighbourOrNull(Direction.N); assertTrue("Settlement tile should be land", settlementTile.isLand()); assertTrue("Adjacent tile should be land", adjacentTile != null && adjacentTile.isLand()); FreeColTestCase.IndianSettlementBuilder builder = new FreeColTestCase.IndianSettlementBuilder(game); IndianSettlement camp = builder.player(inca).settlementTile(settlementTile).initialBravesInCamp(8).build(); assertEquals("One camp", 1, inca.getNumberOfSettlements()); // Put one brave outside the camp, but in the settlement tile, // so that he may defend the settlement Unit braveOutside = new ServerUnit(game, settlementTile, inca, braveType); braveOutside.setHomeIndianSettlement(camp); // Setup enemy units int enemyUnits = camp.getUnitCount() + 1; for (int i = 0; i < enemyUnits; i++) { new ServerUnit(game, adjacentTile, dutch, veteranType); } Iterator<Unit> campUnitIter = camp.getOwnedUnitsIterator(); while (campUnitIter.hasNext()) { Unit brave = campUnitIter.next(); assertNotNull("Got null while getting the camps units", brave); AIUnit aiUnit = aiMain.getAIUnit(brave); assertNotNull("Couldnt get the ai object for the brave", aiUnit); new UnitWanderHostileMission(aiMain, aiUnit); assertTrue( "Should be UnitWanderHostileMission", aiUnit.hasMission(UnitWanderHostileMission.class)); assertEquals( "Unit should be candidate for seek+destroy", null, UnitSeekAndDestroyMission.invalidReason(aiUnit)); assertEquals( "Unit should be candidate for defend", null, DefendSettlementMission.invalidReason(aiUnit)); } inca.setStance(dutch, Stance.WAR); inca.setTension(dutch, new Tension(Tension.Level.HATEFUL.getLimit())); camp.setAlarm(dutch, inca.getTension(dutch)); assertTrue("Indian player should be at war with dutch", inca.getStance(dutch) == Stance.WAR); assertEquals( "Wrong Indian player tension towards dutch", Tension.Level.HATEFUL.getLimit(), inca.getTension(dutch).getValue()); aiInca.secureIndianSettlement(camp, lb); // Verify if a unit was assigned a UnitSeekAndDestroyMission boolean isSeekAndDestroyMission = false; for (Unit brave : inca.getUnits()) { AIUnit aiUnit = aiMain.getAIUnit(brave); assertNotNull("Couldnt get aiUnit for players brave", aiUnit); assertNotNull("Unit missing mission", aiUnit.getMission()); isSeekAndDestroyMission = aiUnit.hasMission(UnitSeekAndDestroyMission.class); if (isSeekAndDestroyMission) break; } assertTrue("A brave should have a UnitSeekAndDestroyMission", isSeekAndDestroyMission); }