Add region discover check to all native settlement interactions, BR#3174.

This commit is contained in:
Mike Pope 2020-01-20 10:31:36 +10:30
parent 3aedda3682
commit ee62792591
11 changed files with 104 additions and 79 deletions

View File

@ -31,6 +31,7 @@ import net.sf.freecol.common.model.Unit;
import net.sf.freecol.common.model.Unit.MoveType;
import net.sf.freecol.server.FreeColServer;
import net.sf.freecol.server.model.ServerPlayer;
import net.sf.freecol.server.model.ServerUnit;
/**
@ -93,9 +94,9 @@ public class AskSkillMessage extends AttributeMessage {
final String unitId = getStringAttribute(UNIT_TAG);
final String directionString = getStringAttribute(DIRECTION_TAG);
Unit unit;
ServerUnit unit;
try {
unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class);
unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class);
} catch (Exception e) {
return serverPlayer.clientError(e.getMessage());
}

View File

@ -30,6 +30,7 @@ import net.sf.freecol.common.model.Player;
import net.sf.freecol.common.model.Unit;
import net.sf.freecol.server.FreeColServer;
import net.sf.freecol.server.model.ServerPlayer;
import net.sf.freecol.server.model.ServerUnit;
/**
@ -170,6 +171,6 @@ public class DeliverGiftMessage extends ObjectMessage {
// Proceed to deliver.
return igc(freeColServer)
.deliverGiftToSettlement(serverPlayer, unit, is, goods);
.deliverGiftToSettlement(serverPlayer, (ServerUnit)unit, is, goods);
}
}

View File

@ -32,6 +32,7 @@ import net.sf.freecol.common.model.Unit;
import net.sf.freecol.common.model.Unit.MoveType;
import net.sf.freecol.server.FreeColServer;
import net.sf.freecol.server.model.ServerPlayer;
import net.sf.freecol.server.model.ServerUnit;
/**
@ -130,6 +131,6 @@ public class DemandTributeMessage extends AttributeMessage {
// Do the demand
return igc(freeColServer)
.demandTribute(serverPlayer, unit, is);
.demandTribute(serverPlayer, (ServerUnit)unit, is);
}
}

View File

@ -30,6 +30,7 @@ import net.sf.freecol.common.model.Unit;
import net.sf.freecol.common.model.Unit.MoveType;
import net.sf.freecol.server.FreeColServer;
import net.sf.freecol.server.model.ServerPlayer;
import net.sf.freecol.server.model.ServerUnit;
/**
@ -113,7 +114,7 @@ public class InciteMessage extends AttributeMessage {
ServerPlayer serverPlayer) {
final Game game = freeColServer.getGame();
Unit unit;
ServerUnit unit;
try {
unit = getUnit(serverPlayer);
} catch (Exception e) {
@ -152,8 +153,8 @@ public class InciteMessage extends AttributeMessage {
// Public interface
public Unit getUnit(Player player) {
return player.getOurFreeColGameObject(getStringAttribute(UNIT_TAG), Unit.class);
public ServerUnit getUnit(Player player) {
return player.getOurFreeColGameObject(getStringAttribute(UNIT_TAG), ServerUnit.class);
}
public IndianSettlement getSettlement(Unit unit) {

View File

@ -31,6 +31,7 @@ import net.sf.freecol.common.model.Unit;
import net.sf.freecol.common.model.Unit.MoveType;
import net.sf.freecol.server.FreeColServer;
import net.sf.freecol.server.model.ServerPlayer;
import net.sf.freecol.server.model.ServerUnit;
/**
@ -93,9 +94,9 @@ public class LearnSkillMessage extends AttributeMessage {
final String unitId = getStringAttribute(UNIT_TAG);
final String directionString = getStringAttribute(DIRECTION_TAG);
Unit unit;
ServerUnit unit;
try {
unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class);
unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class);
} catch (Exception e) {
return serverPlayer.clientError(e.getMessage());
}

View File

@ -32,6 +32,7 @@ import net.sf.freecol.common.model.Unit;
import net.sf.freecol.common.model.Unit.MoveType;
import net.sf.freecol.server.FreeColServer;
import net.sf.freecol.server.model.ServerPlayer;
import net.sf.freecol.server.model.ServerUnit;
/**
@ -98,9 +99,9 @@ public class MissionaryMessage extends AttributeMessage {
final String unitId = getStringAttribute(UNIT_TAG);
final String directionString = getStringAttribute(DIRECTION_TAG);
Unit unit;
ServerUnit unit;
try {
unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class);
unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class);
} catch (Exception e) {
return serverPlayer.clientError(e.getMessage());
}

View File

@ -32,6 +32,7 @@ import net.sf.freecol.common.model.Unit;
import net.sf.freecol.common.model.Unit.MoveType;
import net.sf.freecol.server.FreeColServer;
import net.sf.freecol.server.model.ServerPlayer;
import net.sf.freecol.server.model.ServerUnit;
/**
@ -94,9 +95,9 @@ public class ScoutIndianSettlementMessage extends AttributeMessage {
final String unitId = getStringAttribute(UNIT_TAG);
final String directionString = getStringAttribute(DIRECTION_TAG);
Unit unit;
ServerUnit unit;
try {
unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class);
unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class);
} catch (Exception e) {
return serverPlayer.clientError(e.getMessage());
}

View File

@ -32,6 +32,7 @@ import net.sf.freecol.common.model.Unit.MoveType;
import net.sf.freecol.server.FreeColServer;
import net.sf.freecol.server.ai.AIPlayer;
import net.sf.freecol.server.model.ServerPlayer;
import net.sf.freecol.server.model.ServerUnit;
/**
@ -121,9 +122,9 @@ public class ScoutSpeakToChiefMessage extends AttributeMessage {
final String unitId = getStringAttribute(UNIT_TAG);
final String settlementId = getStringAttribute(SETTLEMENT_TAG);
Unit unit;
ServerUnit unit;
try {
unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class);
unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class);
} catch (Exception e) {
return serverPlayer.clientError(e.getMessage());
}

View File

@ -401,14 +401,14 @@ public final class InGameController extends Controller {
* @param sis The {@code ServerIndianSettlement} to give to.
* @param cs A {@code ChangeSet} to update.
*/
private void csBuy(Unit unit, Goods goods, int price,
private void csBuy(ServerUnit unit, Goods goods, int price,
ServerIndianSettlement sis, ChangeSet cs) {
final Specification spec = getGame().getSpecification();
final int alarmBonus = -Math.round(price * 0.001f
* spec.getPercentage(GameOptions.ALARM_BONUS_BUY));
final Player owner = unit.getOwner();
csVisit((ServerPlayer)owner, sis, 0, cs);
unit.csVisit((ServerPlayer)owner, sis, 0, cs);
GoodsLocation.moveGoods(sis, goods.getType(), goods.getAmount(), unit);
cs.add(See.perhaps(), unit);
sis.getOwner().modifyGold(price);
@ -433,14 +433,14 @@ public final class InGameController extends Controller {
* @param sis The {@code ServerIndianSettlement} to sell to.
* @param cs A {@code ChangeSet} to update.
*/
private void csSell(Unit unit, Goods goods, int price,
private void csSell(ServerUnit unit, Goods goods, int price,
ServerIndianSettlement sis, ChangeSet cs) {
final Specification spec = getGame().getSpecification();
final Player owner = unit.getOwner();
final int alarmBonus = -Math.round(price * 0.001f
* spec.getPercentage(GameOptions.ALARM_BONUS_SELL));
csVisit((ServerPlayer)owner, sis, 0, cs);
unit.csVisit((ServerPlayer)owner, sis, 0, cs);
GoodsLocation.moveGoods(unit, goods.getType(), goods.getAmount(), sis);
cs.add(See.perhaps(), unit);
sis.getOwner().modifyGold(-price);
@ -467,14 +467,14 @@ public final class InGameController extends Controller {
* @param sis The {@code ServerIndianSettlement} to give to.
* @param cs A {@code ChangeSet} to update.
*/
private void csGift(Unit unit, Goods goods, int price,
private void csGift(ServerUnit unit, Goods goods, int price,
ServerIndianSettlement sis, ChangeSet cs) {
final Specification spec = getGame().getSpecification();
final Player owner = unit.getOwner();
final int alarmBonus = -Math.round(price * 0.001f
* spec.getPercentage(GameOptions.ALARM_BONUS_GIFT));
csVisit((ServerPlayer)owner, sis, 0, cs);
unit.csVisit((ServerPlayer)owner, sis, 0, cs);
GoodsLocation.moveGoods(unit, goods.getType(), goods.getAmount(), sis);
cs.add(See.perhaps(), unit);
sis.csModifyAlarm(owner, alarmBonus, true, cs);
@ -486,39 +486,6 @@ public final class InGameController extends Controller {
+ " at " + sis.getName() + " worth " + price);
}
/**
* Visits a native settlement, possibly scouting it full if it is
* as a result of a scout actually asking to speak to the chief,
* or for other settlement-contacting events such as missionary
* actions, demanding tribute, learning skills and trading if the
* settlementActionsContactChief game option is enabled. It is
* still unclear what Col1 did here.
*
* @param serverPlayer The {@code ServerPlayer} that is contacting
* the settlement.
* @param is The {@code IndianSettlement} to contact.
* @param scout Positive if this contact is due to a scout asking to
* speak to the chief, zero if it is another unit, negative if
* this is from the greeting dialog generation.
* @param cs A {@code ChangeSet} to update.
*/
private void csVisit(ServerPlayer serverPlayer, IndianSettlement is,
int scout, ChangeSet cs) {
final Player owner = is.getOwner();
if (serverPlayer.csContact(owner, cs)) {
serverPlayer.csNativeFirstContact(owner, null, cs);
}
is.setVisited(serverPlayer);
if (scout > 0 || (scout == 0 && getGame().getSpecification()
.getBoolean(GameOptions.SETTLEMENT_ACTIONS_CONTACT_CHIEF))) {
is.setScouted(serverPlayer);
}
// Force the settlement tile to become uncached. Should not
// be necessary but this might mitigate BR#3128.
is.getTile().seeTile(serverPlayer);
}
/**
* Launch the REF.
*
@ -872,11 +839,11 @@ public final class InGameController extends Controller {
* @param is The {@code IndianSettlement} to learn from.
* @return A {@code ChangeSet} encapsulating this action.
*/
public ChangeSet askLearnSkill(ServerPlayer serverPlayer, Unit unit,
public ChangeSet askLearnSkill(ServerPlayer serverPlayer, ServerUnit unit,
IndianSettlement is) {
ChangeSet cs = new ChangeSet();
csVisit(serverPlayer, is, 0, cs);
unit.csVisit(serverPlayer, is, 0, cs);
Tile tile = is.getTile();
tile.updateIndianSettlement(serverPlayer);
cs.add(See.only(serverPlayer), tile);
@ -1679,7 +1646,8 @@ public final class InGameController extends Controller {
* @return A {@code ChangeSet} encapsulating this action.
*/
public ChangeSet deliverGiftToSettlement(ServerPlayer serverPlayer,
Unit unit, Settlement settlement,
ServerUnit unit,
Settlement settlement,
Goods goods) {
NativeTradeSession session
= Session.lookup(NativeTradeSession.class, unit, settlement);
@ -1701,7 +1669,7 @@ public final class InGameController extends Controller {
* 0.001f * getGame().getSpecification()
.getPercentage(GameOptions.ALARM_BONUS_GIFT));
csVisit(serverPlayer, sis, 0, cs);
unit.csVisit(serverPlayer, sis, 0, cs);
sis.csModifyAlarm(serverPlayer, alarmBonus, true, cs);
sis.updateWantedGoods();
tile.updateIndianSettlement(serverPlayer);
@ -1743,12 +1711,12 @@ public final class InGameController extends Controller {
* @param is The {@code IndianSettlement} demanded of.
* @return A {@code ChangeSet} encapsulating this action.
*/
public ChangeSet demandTribute(ServerPlayer serverPlayer, Unit unit,
public ChangeSet demandTribute(ServerPlayer serverPlayer, ServerUnit unit,
IndianSettlement is) {
ChangeSet cs = new ChangeSet();
final int TURNS_PER_TRIBUTE = 5;
csVisit(serverPlayer, is, 0, cs);
unit.csVisit(serverPlayer, is, 0, cs);
Player indianPlayer = is.getOwner();
int gold = 0;
@ -1815,10 +1783,11 @@ public final class InGameController extends Controller {
* to denounce.
* @return A {@code ChangeSet} encapsulating this action.
*/
public ChangeSet denounceMission(ServerPlayer serverPlayer, Unit unit,
public ChangeSet denounceMission(ServerPlayer serverPlayer,
ServerUnit unit,
IndianSettlement is) {
ChangeSet cs = new ChangeSet();
csVisit(serverPlayer, is, 0, cs);
unit.csVisit(serverPlayer, is, 0, cs);
// Determine result
Unit missionary = is.getMissionary();
@ -2351,10 +2320,11 @@ public final class InGameController extends Controller {
* @param is The {@code IndianSettlement} to establish at.
* @return A {@code ChangeSet} encapsulating this action.
*/
public ChangeSet establishMission(ServerPlayer serverPlayer, Unit unit,
public ChangeSet establishMission(ServerPlayer serverPlayer,
ServerUnit unit,
IndianSettlement is) {
ChangeSet cs = new ChangeSet();
csVisit(serverPlayer, is, 0, cs);
unit.csVisit(serverPlayer, is, 0, cs);
// Result depends on tension wrt this settlement.
// Establish if at least not angry.
@ -2475,12 +2445,12 @@ public final class InGameController extends Controller {
* @param gold The amount of gold in the bribe.
* @return A {@code ChangeSet} encapsulating this action.
*/
public ChangeSet incite(ServerPlayer serverPlayer, Unit unit,
public ChangeSet incite(ServerPlayer serverPlayer, ServerUnit unit,
IndianSettlement is, Player enemy, int gold) {
ChangeSet cs = new ChangeSet();
Tile tile = is.getTile();
csVisit(serverPlayer, is, 0, cs);
unit.csVisit(serverPlayer, is, 0, cs);
tile.updateIndianSettlement(serverPlayer);
cs.add(See.only(serverPlayer), tile);
@ -2630,7 +2600,8 @@ public final class InGameController extends Controller {
* @return A {@code ChangeSet} encapsulating this action.
*/
public ChangeSet learnFromIndianSettlement(ServerPlayer serverPlayer,
Unit unit, IndianSettlement is) {
ServerUnit unit,
IndianSettlement is) {
// Sanity checks.
final Specification spec = getGame().getSpecification();
final UnitType skill = is.getLearnableSkill();
@ -2646,7 +2617,7 @@ public final class InGameController extends Controller {
// Try to learn
ChangeSet cs = new ChangeSet();
unit.setMovesLeft(0);
csVisit(serverPlayer, is, 0, cs);
unit.csVisit(serverPlayer, is, 0, cs);
Location loc = unit.getLocation();
switch (is.getAlarm(serverPlayer).getLevel()) {
case HATEFUL: // Killed, might be visible to other players.
@ -3068,7 +3039,7 @@ public final class InGameController extends Controller {
@SuppressFBWarnings(value="SF_SWITCH_FALLTHROUGH")
public ChangeSet nativeTrade(ServerPlayer serverPlayer,
NativeTradeAction action, NativeTrade nt) {
final Unit unit = nt.getUnit();
final ServerUnit unit = (ServerUnit)nt.getUnit();
final IndianSettlement is = nt.getIndianSettlement();
final Player otherPlayer = (serverPlayer.owns(unit))
? is.getOwner() : unit.getOwner();
@ -3481,12 +3452,13 @@ public final class InGameController extends Controller {
* @return A {@code ChangeSet} encapsulating this action.
*/
public ChangeSet scoutIndianSettlement(ServerPlayer serverPlayer,
Unit unit, IndianSettlement is) {
ServerUnit unit,
IndianSettlement is) {
final Player owner = is.getOwner();
ChangeSet cs = new ChangeSet();
Tile tile = is.getTile();
csVisit(serverPlayer, is, -1, cs);
unit.csVisit(serverPlayer, is, -1, cs);
tile.updateIndianSettlement(serverPlayer);
cs.add(See.only(serverPlayer), tile);
cs.add(See.only(serverPlayer), new NationSummaryMessage(owner,
@ -3506,7 +3478,7 @@ public final class InGameController extends Controller {
* @return A {@code ChangeSet} encapsulating this action.
*/
public ChangeSet scoutSpeakToChief(ServerPlayer serverPlayer,
Unit unit, IndianSettlement is) {
ServerUnit unit, IndianSettlement is) {
ChangeSet cs = new ChangeSet();
Tile tile = is.getTile();
boolean tileDirty = is.setVisited(serverPlayer);
@ -3561,7 +3533,7 @@ public final class InGameController extends Controller {
}
// Have now spoken to the chief.
csVisit(serverPlayer, is, 1, cs);
unit.csVisit(serverPlayer, is, 1, cs);
tileDirty = true;
// Update settlement tile with new information, and any

View File

@ -880,15 +880,60 @@ public class ServerUnit extends Unit implements TurnTaker {
.addStringTemplate("%enemyNation%", enemy));
}
// Check for region discovery
Region region = newTile.getDiscoverableRegion();
if (region != null && region.checkDiscover(this)
&& owner.isEuropean()) {
csCheckDiscoverRegion(newTile, cs);
}
/**
* Check for a new region.
*
* @param tile The {@code Tile} to chack at.
* @param cs A {@code ChangeSet} to update.
*/
public void csCheckDiscoverRegion(Tile tile, ChangeSet cs) {
final Region region = tile.getDiscoverableRegion();
if (region == null || !region.checkDiscover(this)) return;
final Player owner = this.getOwner();
if (owner.isEuropean()) {
cs.add(See.only(owner),
new NewRegionNameMessage(region, newTile, this,
new NewRegionNameMessage(region, tile, this,
owner.getNameForRegion(region)));
}
}
/**
* Visits a native settlement, possibly scouting it fully if
* as a result of a scout actually asking to speak to the chief,
* or for other settlement-contacting events such as missionary
* actions, demanding tribute, learning skills and trading if the
* settlementActionsContactChief game option is enabled. It is
* still unclear what Col1 did here.
*
* @param serverPlayer The {@code ServerPlayer} that is contacting
* the settlement.
* @param is The {@code IndianSettlement} to contact.
* @param scout Positive if this contact is due to a scout asking to
* speak to the chief, zero if it is another unit, negative if
* this is from the greeting dialog generation.
* @param cs A {@code ChangeSet} to update.
*/
public void csVisit(ServerPlayer serverPlayer, IndianSettlement is,
int scout, ChangeSet cs) {
final Player owner = is.getOwner();
if (serverPlayer.csContact(owner, cs)) {
serverPlayer.csNativeFirstContact(owner, null, cs);
}
is.setVisited(serverPlayer);
if (scout > 0 || (scout == 0 && getGame().getSpecification()
.getBoolean(GameOptions.SETTLEMENT_ACTIONS_CONTACT_CHIEF))) {
is.setScouted(serverPlayer);
}
// Force the settlement tile to become uncached. Should not
// be necessary but this might mitigate BR#3128.
final Tile tile = is.getTile();
tile.seeTile(serverPlayer);
csCheckDiscoverRegion(tile, cs);
}
/**
* Remove this unit from the game.

View File

@ -280,7 +280,7 @@ public class InGameControllerTest extends FreeColTestCase {
Tile tile = camp.getTile().getNeighbourOrNull(Direction.N);
ServerUnit dutchJesuit = new ServerUnit(game, tile, dutch, missionaryType);
dutch.exploreForUnit(dutchJesuit);
Unit frenchJesuit = new ServerUnit(game, tile, french, missionaryType);
ServerUnit frenchJesuit = new ServerUnit(game, tile, french, missionaryType);
french.exploreForUnit(frenchJesuit);
// Set Dutch tension to HATEFUL