use of games.strategy.engine.data.Change in project triplea by triplea-game.
the class PurchaseDelegate method purchase.
@Override
public String purchase(final IntegerMap<ProductionRule> productionRules) {
final IntegerMap<Resource> costs = getCosts(productionRules);
final IntegerMap<NamedAttachable> results = getResults(productionRules);
if (!(canAfford(costs, player))) {
return NOT_ENOUGH_RESOURCES;
}
// check to see if player has too many of any building with a building limit
for (final NamedAttachable next : results.keySet()) {
if (!(next instanceof Resource)) {
final UnitType type = (UnitType) next;
final int quantity = results.getInt(type);
final UnitAttachment ua = UnitAttachment.get(type);
final int maxBuilt = ua.getMaxBuiltPerPlayer();
if (maxBuilt == 0) {
return "May not build any of this unit right now: " + type.getName();
} else if (maxBuilt > 0) {
// count how many units are yet to be placed or are in the field
int currentlyBuilt = player.getUnits().countMatches(Matches.unitIsOfType(type));
final Predicate<Unit> unitTypeOwnedBy = Matches.unitIsOfType(type).and(Matches.unitIsOwnedBy(player));
final Collection<Territory> allTerrs = getData().getMap().getTerritories();
for (final Territory t : allTerrs) {
currentlyBuilt += t.getUnits().countMatches(unitTypeOwnedBy);
}
final int allowedBuild = maxBuilt - currentlyBuilt;
if (allowedBuild - quantity < 0) {
return "May only build " + allowedBuild + " of " + type.getName() + " this turn, may only build " + maxBuilt + " total";
}
}
}
}
// remove first, since add logs PUs remaining
final Collection<Unit> totalUnits = new ArrayList<>();
final Collection<UnitType> totalUnitTypes = new ArrayList<>();
final Collection<Resource> totalResources = new ArrayList<>();
final CompositeChange changes = new CompositeChange();
// and find all added units
for (final NamedAttachable next : results.keySet()) {
if (next instanceof Resource) {
final Resource resource = (Resource) next;
final int quantity = results.getInt(resource);
final Change change = ChangeFactory.changeResourcesChange(player, resource, quantity);
changes.add(change);
for (int i = 0; i < quantity; i++) {
totalResources.add(resource);
}
} else {
final UnitType type = (UnitType) next;
final int quantity = results.getInt(type);
final Collection<Unit> units = type.create(quantity, player);
totalUnits.addAll(units);
for (int i = 0; i < quantity; i++) {
totalUnitTypes.add(type);
}
}
}
final Collection<NamedAttachable> totalAll = new ArrayList<>();
totalAll.addAll(totalUnitTypes);
totalAll.addAll(totalResources);
// add changes for added units
if (!totalUnits.isEmpty()) {
final Change change = ChangeFactory.addUnits(player, totalUnits);
changes.add(change);
}
// add changes for spent resources
final String remaining = removeFromPlayer(costs, changes);
// add history event
final String transcriptText;
if (!totalUnits.isEmpty()) {
transcriptText = player.getName() + " buy " + MyFormatter.defaultNamedToTextList(totalAll, ", ", true) + "; " + remaining;
} else {
transcriptText = player.getName() + " buy nothing; " + remaining;
}
bridge.getHistoryWriter().startEvent(transcriptText, totalUnits);
// commit changes
bridge.addChange(changes);
return null;
}
use of games.strategy.engine.data.Change in project triplea by triplea-game.
the class PurchaseDelegate method removeFromPlayer.
protected String removeFromPlayer(final IntegerMap<Resource> costs, final CompositeChange changes) {
final StringBuilder returnString = new StringBuilder("Remaining resources: ");
final IntegerMap<Resource> left = player.getResources().getResourcesCopy();
left.subtract(costs);
for (final Entry<Resource, Integer> entry : left.entrySet()) {
returnString.append(entry.getValue()).append(" ").append(entry.getKey().getName()).append("; ");
}
for (final Resource resource : costs.keySet()) {
final float quantity = costs.getInt(resource);
final int cost = (int) quantity;
final Change change = ChangeFactory.changeResourcesChange(player, resource, -cost);
changes.add(change);
}
return returnString.toString();
}
use of games.strategy.engine.data.Change in project triplea by triplea-game.
the class TechTracker method removeAdvance.
static void removeAdvance(final PlayerID player, final IDelegateBridge bridge, final TechAdvance advance) {
final Change attachmentChange;
if (advance instanceof GenericTechAdvance) {
if (((GenericTechAdvance) advance).getAdvance() == null) {
attachmentChange = ChangeFactory.genericTechChange(TechAttachment.get(player), false, advance.getProperty());
} else {
attachmentChange = ChangeFactory.attachmentPropertyChange(TechAttachment.get(player), "false", advance.getProperty());
}
} else {
attachmentChange = ChangeFactory.attachmentPropertyChange(TechAttachment.get(player), "false", advance.getProperty());
}
bridge.addChange(attachmentChange);
}
use of games.strategy.engine.data.Change in project triplea by triplea-game.
the class TechnologyDelegate method rollTech.
@Override
public TechResults rollTech(final int techRolls, final TechnologyFrontier techToRollFor, final int newTokens, final IntegerMap<PlayerID> whoPaysHowMuch) {
int rollCount = techRolls;
if (isWW2V3TechModel()) {
rollCount = newTokens;
}
final boolean canPay = checkEnoughMoney(rollCount, whoPaysHowMuch);
if (!canPay) {
return new TechResults("Not enough money to pay for that many tech rolls.");
}
chargeForTechRolls(rollCount, whoPaysHowMuch);
int currTokens = 0;
if (isWW2V3TechModel()) {
currTokens = player.getResources().getQuantity(Constants.TECH_TOKENS);
}
final GameData data = getData();
if (getAvailableTechs(player, data).isEmpty()) {
if (isWW2V3TechModel()) {
final Resource techTokens = data.getResourceList().getResource(Constants.TECH_TOKENS);
final String transcriptText = player.getName() + " No more available tech advances.";
bridge.getHistoryWriter().startEvent(transcriptText);
final Change removeTokens = ChangeFactory.changeResourcesChange(bridge.getPlayerId(), techTokens, -currTokens);
bridge.addChange(removeTokens);
}
return new TechResults("No more available tech advances.");
}
final String annotation = player.getName() + " rolling for tech.";
final int[] random;
int techHits;
int remainder = 0;
final int diceSides = data.getDiceSides();
if (BaseEditDelegate.getEditMode(data)) {
final ITripleAPlayer tripleaPlayer = getRemotePlayer();
random = tripleaPlayer.selectFixedDice(techRolls, diceSides, true, annotation, diceSides);
techHits = getTechHits(random);
} else if (isLowLuckTechOnly()) {
techHits = techRolls / diceSides;
remainder = techRolls % diceSides;
if (remainder > 0) {
random = bridge.getRandom(diceSides, 1, player, DiceType.TECH, annotation);
if (random[0] + 1 <= remainder) {
techHits++;
}
} else {
random = bridge.getRandom(diceSides, 1, player, DiceType.TECH, annotation);
remainder = diceSides;
}
} else {
random = bridge.getRandom(diceSides, techRolls, player, DiceType.TECH, annotation);
techHits = getTechHits(random);
}
final boolean isRevisedModel = isWW2V2() || (isSelectableTechRoll() && !isWW2V3TechModel());
final String directedTechInfo = isRevisedModel ? " for " + techToRollFor.getTechs().get(0) : "";
final DiceRoll renderDice = (isLowLuckTechOnly() ? new DiceRoll(random, techHits, remainder, false) : new DiceRoll(random, techHits, diceSides - 1, true));
bridge.getHistoryWriter().startEvent(player.getName() + (random.length > 1 ? " roll " : " rolls : ") + MyFormatter.asDice(random) + directedTechInfo + " and gets " + techHits + " " + MyFormatter.pluralize("hit", techHits), renderDice);
if (isWW2V3TechModel() && (techHits > 0 || Properties.getRemoveAllTechTokensAtEndOfTurn(data))) {
techCategory = techToRollFor;
// remove all the tokens
final Resource techTokens = data.getResourceList().getResource(Constants.TECH_TOKENS);
final String transcriptText = player.getName() + " removing all Technology Tokens after " + (techHits > 0 ? "successful" : "unsuccessful") + " research.";
bridge.getHistoryWriter().startEvent(transcriptText);
final Change removeTokens = ChangeFactory.changeResourcesChange(bridge.getPlayerId(), techTokens, -currTokens);
bridge.addChange(removeTokens);
}
final Collection<TechAdvance> advances;
if (isRevisedModel) {
if (techHits > 0) {
advances = Collections.singletonList(techToRollFor.getTechs().get(0));
} else {
advances = Collections.emptyList();
}
} else {
advances = getTechAdvances(techHits);
}
// Put in techs so they can be activated later.
techs.put(player, advances);
final List<String> advancesAsString = new ArrayList<>();
int count = advances.size();
final StringBuilder text = new StringBuilder();
for (final TechAdvance advance : advances) {
text.append(advance.getName());
count--;
advancesAsString.add(advance.getName());
if (count > 1) {
text.append(", ");
}
if (count == 1) {
text.append(" and ");
}
}
final String transcriptText = player.getName() + " discover " + text;
if (advances.size() > 0) {
bridge.getHistoryWriter().startEvent(transcriptText);
// play a sound
getSoundChannel().playSoundForAll(SoundPath.CLIP_TECHNOLOGY_SUCCESSFUL, player);
} else {
getSoundChannel().playSoundForAll(SoundPath.CLIP_TECHNOLOGY_FAILURE, player);
}
return new TechResults(random, remainder, techHits, advancesAsString, player);
}
use of games.strategy.engine.data.Change in project triplea by triplea-game.
the class UndoableMove method undoSpecific.
@Override
protected void undoSpecific(final IDelegateBridge bridge) {
final GameData data = bridge.getData();
final BattleTracker battleTracker = DelegateFinder.battleDelegate(data).getBattleTracker();
battleTracker.undoBattle(m_route, m_units, bridge.getPlayerId(), bridge);
// clean up dependencies
for (final UndoableMove other : m_iDependOn) {
other.m_dependOnMe.remove(this);
}
// this can happen for air units moving out of a battle zone
for (final IBattle battle : battleTracker.getPendingBattles(m_route.getStart(), null)) {
if (battle == null || battle.isOver()) {
continue;
}
for (final Unit unit : m_units) {
final Route routeUnitUsedToMove = DelegateFinder.moveDelegate(data).getRouteUsedToMoveInto(unit, m_route.getStart());
if (!battle.getBattleType().isBombingRun()) {
// into the battle zone will be null
if (routeUnitUsedToMove != null) {
final Change change = battle.addAttackChange(routeUnitUsedToMove, Collections.singleton(unit), null);
bridge.addChange(change);
}
} else {
HashMap<Unit, HashSet<Unit>> targets = null;
Unit target = null;
if (routeUnitUsedToMove != null && routeUnitUsedToMove.getEnd() != null) {
final Territory end = routeUnitUsedToMove.getEnd();
final Collection<Unit> enemyTargetsTotal = end.getUnits().getMatches(Matches.enemyUnit(bridge.getPlayerId(), data).and(Matches.unitCanBeDamaged()).and(Matches.unitIsBeingTransported().negate()));
final Collection<Unit> enemyTargets = CollectionUtils.getMatches(enemyTargetsTotal, Matches.unitIsOfTypes(UnitAttachment.getAllowedBombingTargetsIntersection(CollectionUtils.getMatches(Collections.singleton(unit), Matches.unitIsStrategicBomber()), data)));
if (enemyTargets.size() > 1 && Properties.getDamageFromBombingDoneToUnitsInsteadOfTerritories(data) && !Properties.getRaidsMayBePreceededByAirBattles(data)) {
while (target == null) {
target = ((ITripleAPlayer) bridge.getRemotePlayer(bridge.getPlayerId())).whatShouldBomberBomb(end, enemyTargets, Collections.singletonList(unit));
}
} else if (!enemyTargets.isEmpty()) {
target = enemyTargets.iterator().next();
}
if (target != null) {
targets = new HashMap<>();
targets.put(target, new HashSet<>(Collections.singleton(unit)));
}
}
final Change change = battle.addAttackChange(routeUnitUsedToMove, Collections.singleton(unit), targets);
bridge.addChange(change);
}
}
}
// Clear any temporary dependents
MovePanel.clearDependents(m_units);
}
Aggregations