use of games.strategy.engine.data.Resource in project triplea by triplea-game.
the class TechnologyDelegate method checkEnoughMoney.
boolean checkEnoughMoney(final int rolls, final IntegerMap<PlayerID> whoPaysHowMuch) {
final Resource pus = getData().getResourceList().getResource(Constants.PUS);
final int cost = rolls * getTechCost();
if (whoPaysHowMuch == null || whoPaysHowMuch.isEmpty()) {
final int has = bridge.getPlayerId().getResources().getQuantity(pus);
return has >= cost;
}
int runningTotal = 0;
for (final Entry<PlayerID, Integer> entry : whoPaysHowMuch.entrySet()) {
final int has = entry.getKey().getResources().getQuantity(pus);
final int paying = entry.getValue();
if (paying > has) {
return false;
}
runningTotal += paying;
}
return runningTotal >= cost;
}
use of games.strategy.engine.data.Resource 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.Resource in project triplea by triplea-game.
the class EndTurnDelegate method addUnitCreatedResources.
private String addUnitCreatedResources(final IDelegateBridge bridge) {
// Find total unit generated resources for all owned units
final GameData data = getData();
final PlayerID player = data.getSequence().getStep().getPlayerId();
final IntegerMap<Resource> resourceTotalsMap = findUnitCreatedResources(player, data);
// Add resource changes and create end turn report string
final StringBuilder endTurnReport = new StringBuilder();
final CompositeChange change = new CompositeChange();
for (final Resource resource : resourceTotalsMap.keySet()) {
int toAdd = resourceTotalsMap.getInt(resource);
if (toAdd == 0) {
continue;
}
int total = player.getResources().getQuantity(resource) + toAdd;
if (total < 0) {
toAdd -= total;
total = 0;
}
final String transcriptText = "Units generate " + toAdd + " " + resource.getName() + "; " + player.getName() + " end with " + total + " " + resource.getName();
bridge.getHistoryWriter().startEvent(transcriptText);
endTurnReport.append(transcriptText).append("<br />");
final Change resources = ChangeFactory.changeResourcesChange(player, resource, toAdd);
change.add(resources);
}
if (!change.isEmpty()) {
bridge.addChange(change);
}
return endTurnReport.toString();
}
use of games.strategy.engine.data.Resource in project triplea by triplea-game.
the class InitializationDelegate method initDeleteAssetsOfDisabledPlayers.
private static void initDeleteAssetsOfDisabledPlayers(final IDelegateBridge bridge) {
final GameData data = bridge.getData();
if (!Properties.getDisabledPlayersAssetsDeleted(data)) {
return;
}
for (final PlayerID player : data.getPlayerList().getPlayers()) {
if (player.isNull() || !player.getIsDisabled()) {
continue;
}
// delete all the stuff they have
final CompositeChange change = new CompositeChange();
for (final Resource r : player.getResources().getResourcesCopy().keySet()) {
final int deleted = player.getResources().getQuantity(r);
if (deleted != 0) {
change.add(ChangeFactory.changeResourcesChange(player, r, -deleted));
}
}
final Collection<Unit> heldUnits = player.getUnits().getUnits();
if (!heldUnits.isEmpty()) {
change.add(ChangeFactory.removeUnits(player, heldUnits));
}
final Predicate<Unit> owned = Matches.unitIsOwnedBy(player);
for (final Territory t : data.getMap().getTerritories()) {
final Collection<Unit> terrUnits = t.getUnits().getMatches(owned);
if (!terrUnits.isEmpty()) {
change.add(ChangeFactory.removeUnits(t, terrUnits));
}
}
if (!change.isEmpty()) {
bridge.getHistoryWriter().startEvent("Remove all resources and units from: " + player.getName());
bridge.addChange(change);
}
}
}
use of games.strategy.engine.data.Resource in project triplea by triplea-game.
the class BattleDelegate method fireKamikazeSuicideAttacks.
/**
* This rolls the dice and validates them to see if units died or not.
* It will use LowLuck or normal dice.
* If any units die, we remove them from the game, and if units take damage but live, we also do that here.
*/
private void fireKamikazeSuicideAttacks(final Unit unitUnderFire, final IntegerMap<Resource> numberOfAttacks, final IntegerMap<Resource> resourcesAndAttackValues, final PlayerID firingEnemy, final Territory location) {
// TODO: find a way to autosave after each dice roll.
final GameData data = getData();
final int diceSides = data.getDiceSides();
final CompositeChange change = new CompositeChange();
int hits = 0;
int[] rolls = null;
if (Properties.getLowLuck(data)) {
int power = 0;
for (final Entry<Resource, Integer> entry : numberOfAttacks.entrySet()) {
final Resource r = entry.getKey();
final int num = entry.getValue();
change.add(ChangeFactory.changeResourcesChange(firingEnemy, r, -num));
power += num * resourcesAndAttackValues.getInt(r);
}
if (power > 0) {
hits = power / diceSides;
final int remainder = power % diceSides;
if (remainder > 0) {
rolls = bridge.getRandom(diceSides, 1, firingEnemy, DiceType.COMBAT, "Rolling for remainder in Kamikaze Suicide Attack on unit: " + unitUnderFire.getType().getName());
if (remainder > rolls[0]) {
hits++;
}
}
}
} else {
// avoid multiple calls of getRandom, so just do it once at the beginning
final int numTokens = numberOfAttacks.totalValues();
rolls = bridge.getRandom(diceSides, numTokens, firingEnemy, DiceType.COMBAT, "Rolling for Kamikaze Suicide Attack on unit: " + unitUnderFire.getType().getName());
final int[] powerOfTokens = new int[numTokens];
int j = 0;
for (final Entry<Resource, Integer> entry : numberOfAttacks.entrySet()) {
final Resource r = entry.getKey();
int num = entry.getValue();
change.add(ChangeFactory.changeResourcesChange(firingEnemy, r, -num));
final int power = resourcesAndAttackValues.getInt(r);
while (num > 0) {
powerOfTokens[j] = power;
j++;
num--;
}
}
for (int i = 0; i < rolls.length; i++) {
if (powerOfTokens[i] > rolls[i]) {
hits++;
}
}
}
final String title = "Kamikaze Suicide Attack attacks " + MyFormatter.unitsToText(Collections.singleton(unitUnderFire));
final String dice = " scoring " + hits + " hits. Rolls: " + MyFormatter.asDice(rolls);
bridge.getHistoryWriter().startEvent(title + dice, unitUnderFire);
if (hits > 0) {
final UnitAttachment ua = UnitAttachment.get(unitUnderFire.getType());
final int currentHits = unitUnderFire.getHits();
if (ua.getHitPoints() <= currentHits + hits) {
// TODO: kill dependents
change.add(ChangeFactory.removeUnits(location, Collections.singleton(unitUnderFire)));
} else {
final IntegerMap<Unit> hitMap = new IntegerMap<>();
hitMap.put(unitUnderFire, hits);
change.add(createDamageChange(hitMap, bridge));
}
}
if (!change.isEmpty()) {
bridge.addChange(change);
}
// kamikaze suicide attacks, even if unsuccessful, deny the ability to bombard from this sea zone
battleTracker.addNoBombardAllowedFromHere(location);
// TODO: display this as actual dice for both players
final Collection<PlayerID> playersInvolved = new ArrayList<>();
playersInvolved.add(player);
playersInvolved.add(firingEnemy);
this.getDisplay().reportMessageToPlayers(playersInvolved, null, title + dice, title);
}
Aggregations