Search in sources :

Example 51 with Resource

use of games.strategy.engine.data.Resource in project triplea by triplea-game.

the class BattleTracker method takeOver.

public void takeOver(final Territory territory, final PlayerID id, final IDelegateBridge bridge, final UndoableMove changeTracker, final Collection<Unit> arrivingUnits) {
    // This could be NULL if unowned water
    final TerritoryAttachment ta = TerritoryAttachment.get(territory);
    if (ta == null) {
        // TODO: allow capture/destroy of infrastructure on unowned water
        return;
    }
    final GameData data = bridge.getData();
    final Collection<Unit> arrivedUnits = (arrivingUnits == null ? null : new ArrayList<>(arrivingUnits));
    final RelationshipTracker relationshipTracker = data.getRelationshipTracker();
    final boolean isTerritoryOwnerAnEnemy = relationshipTracker.canTakeOverOwnedTerritory(id, territory.getOwner());
    // check to make sure attackers have more than just transports. If they don't, exit here.
    if (territory.isWater() && arrivedUnits != null) {
        // Total Attacking Sea units = all units - land units - air units - submerged subs
        // Also subtract transports & subs (if they can't control sea zones)
        int totalMatches = arrivedUnits.size() - CollectionUtils.countMatches(arrivedUnits, Matches.unitIsLand()) - CollectionUtils.countMatches(arrivedUnits, Matches.unitIsAir()) - CollectionUtils.countMatches(arrivedUnits, Matches.unitIsSubmerged());
        // If transports are restricted from controlling sea zones, subtract them
        final Predicate<Unit> transportsCanNotControl = Matches.unitIsTransportAndNotDestroyer().and(Matches.unitIsTransportButNotCombatTransport());
        if (!Properties.getTransportControlSeaZone(data)) {
            totalMatches -= CollectionUtils.countMatches(arrivedUnits, transportsCanNotControl);
        }
        // If subs are restricted from controlling sea zones, subtract them
        if (Properties.getSubControlSeaZoneRestricted(data)) {
            totalMatches -= CollectionUtils.countMatches(arrivedUnits, Matches.unitIsSub());
        }
        if (totalMatches == 0) {
            return;
        }
    }
    // If it was a Convoy Route- check ownership of the associated neighboring territory and set message
    if (ta.getConvoyRoute()) {
        // we could be part of a convoy route for another territory
        final Collection<Territory> attachedConvoyTo = TerritoryAttachment.getWhatTerritoriesThisIsUsedInConvoysFor(territory, data);
        for (final Territory convoy : attachedConvoyTo) {
            final TerritoryAttachment cta = TerritoryAttachment.get(convoy);
            if (!cta.getConvoyRoute()) {
                continue;
            }
            final PlayerID convoyOwner = convoy.getOwner();
            if (relationshipTracker.isAllied(id, convoyOwner)) {
                if (CollectionUtils.getMatches(cta.getConvoyAttached(), Matches.isTerritoryAllied(convoyOwner, data)).size() <= 0) {
                    bridge.getHistoryWriter().addChildToEvent(convoyOwner.getName() + " gains " + cta.getProduction() + " production in " + convoy.getName() + " for the liberation the convoy route in " + territory.getName());
                }
            } else if (relationshipTracker.isAtWar(id, convoyOwner)) {
                if (CollectionUtils.getMatches(cta.getConvoyAttached(), Matches.isTerritoryAllied(convoyOwner, data)).size() == 1) {
                    bridge.getHistoryWriter().addChildToEvent(convoyOwner.getName() + " loses " + cta.getProduction() + " production in " + convoy.getName() + " due to the capture of the convoy route in " + territory.getName());
                }
            }
        }
    }
    // if neutral, we may charge money to enter
    if (territory.getOwner().isNull() && !territory.isWater() && Properties.getNeutralCharge(data) >= 0) {
        final Resource pus = data.getResourceList().getResource(Constants.PUS);
        final int puChargeIdeal = -Properties.getNeutralCharge(data);
        final int puChargeReal = Math.min(0, Math.max(puChargeIdeal, -id.getResources().getQuantity(pus)));
        final Change neutralFee = ChangeFactory.changeResourcesChange(id, pus, puChargeReal);
        bridge.addChange(neutralFee);
        if (changeTracker != null) {
            changeTracker.addChange(neutralFee);
        }
        if (puChargeIdeal == puChargeReal) {
            bridge.getHistoryWriter().addChildToEvent(id.getName() + " loses " + -puChargeReal + " " + MyFormatter.pluralize("PU", -puChargeReal) + " for violating " + territory.getName() + "s neutrality.");
        } else {
            System.out.println("Player, " + id.getName() + " attacks a Neutral territory, and should have had to pay " + puChargeIdeal + ", but did not have enough PUs to pay! This is a bug.");
            bridge.getHistoryWriter().addChildToEvent(id.getName() + " loses " + -puChargeReal + " " + MyFormatter.pluralize("PU", -puChargeReal) + " for violating " + territory.getName() + "s neutrality.  Correct amount to charge is: " + puChargeIdeal + ".  Player should not have been able to make this attack!");
        }
    }
    // instead it is relying on the fact that the capital should be owned by the person it is attached to
    if (isTerritoryOwnerAnEnemy && ta.getCapital() != null) {
        // if the capital is owned by the capitols player take the money
        final PlayerID whoseCapital = data.getPlayerList().getPlayerId(ta.getCapital());
        final PlayerAttachment pa = PlayerAttachment.get(id);
        final PlayerAttachment paWhoseCapital = PlayerAttachment.get(whoseCapital);
        final List<Territory> capitalsList = new ArrayList<>(TerritoryAttachment.getAllCurrentlyOwnedCapitals(whoseCapital, data));
        // we are losing one right now, so it is < not <=
        if (paWhoseCapital != null && paWhoseCapital.getRetainCapitalNumber() < capitalsList.size()) {
            // do nothing, we keep our money since we still control enough capitals
            bridge.getHistoryWriter().addChildToEvent(id.getName() + " captures one of " + whoseCapital.getName() + " capitals");
        } else if (whoseCapital.equals(territory.getOwner())) {
            final Resource pus = data.getResourceList().getResource(Constants.PUS);
            final int capturedPuCount = whoseCapital.getResources().getQuantity(pus);
            if (pa != null) {
                if (isPacificTheater(data)) {
                    final Change changeVp = ChangeFactory.attachmentPropertyChange(pa, (capturedPuCount + pa.getCaptureVps()), "captureVps");
                    bridge.addChange(changeVp);
                    if (changeTracker != null) {
                        changeTracker.addChange(changeVp);
                    }
                }
            }
            final Change remove = ChangeFactory.changeResourcesChange(whoseCapital, pus, -capturedPuCount);
            bridge.addChange(remove);
            if (paWhoseCapital != null && paWhoseCapital.getDestroysPUs()) {
                bridge.getHistoryWriter().addChildToEvent(id.getName() + " destroys " + capturedPuCount + MyFormatter.pluralize("PU", capturedPuCount) + " while taking " + whoseCapital.getName() + " capital");
                if (changeTracker != null) {
                    changeTracker.addChange(remove);
                }
            } else {
                bridge.getHistoryWriter().addChildToEvent(id.getName() + " captures " + capturedPuCount + MyFormatter.pluralize("PU", capturedPuCount) + " while taking " + whoseCapital.getName() + " capital");
                if (changeTracker != null) {
                    changeTracker.addChange(remove);
                }
                final Change add = ChangeFactory.changeResourcesChange(id, pus, capturedPuCount);
                bridge.addChange(add);
                if (changeTracker != null) {
                    changeTracker.addChange(add);
                }
            }
            // remove all the tokens of the captured player
            final Resource tokens = data.getResourceList().getResource(Constants.TECH_TOKENS);
            if (tokens != null) {
                final int currTokens = whoseCapital.getResources().getQuantity(Constants.TECH_TOKENS);
                final Change removeTokens = ChangeFactory.changeResourcesChange(whoseCapital, tokens, -currTokens);
                bridge.addChange(removeTokens);
                if (changeTracker != null) {
                    changeTracker.addChange(removeTokens);
                }
            }
        }
    }
    // is this an allied territory, revert to original owner if it is, unless they dont own there captital
    final PlayerID terrOrigOwner = OriginalOwnerTracker.getOriginalOwner(territory);
    PlayerID newOwner = id;
    // then we do not worry about this.
    if (isTerritoryOwnerAnEnemy && terrOrigOwner != null && relationshipTracker.isAllied(terrOrigOwner, id) && !terrOrigOwner.equals(territory.getOwner())) {
        final List<Territory> capitalsListOwned = new ArrayList<>(TerritoryAttachment.getAllCurrentlyOwnedCapitals(terrOrigOwner, data));
        if (!capitalsListOwned.isEmpty()) {
            newOwner = terrOrigOwner;
        } else {
            newOwner = id;
            final List<Territory> capitalsListOriginal = new ArrayList<>(TerritoryAttachment.getAllCapitals(terrOrigOwner, data));
            for (final Territory current : capitalsListOriginal) {
                if (territory.equals(current) || current.getOwner().equals(PlayerID.NULL_PLAYERID)) {
                    // if a neutral controls our capital, our territories get liberated (ie: china in ww2v3)
                    newOwner = terrOrigOwner;
                }
            }
        }
    }
    // then we set that here (except we don't set it if we are liberating allied owned territory)
    if (isTerritoryOwnerAnEnemy && newOwner.equals(id) && Matches.territoryHasWhenCapturedByGoesTo().test(territory)) {
        for (final String value : ta.getWhenCapturedByGoesTo()) {
            final String[] s = value.split(":");
            final PlayerID capturingPlayer = data.getPlayerList().getPlayerId(s[0]);
            final PlayerID goesToPlayer = data.getPlayerList().getPlayerId(s[1]);
            if (capturingPlayer.equals(goesToPlayer)) {
                continue;
            }
            if (capturingPlayer.equals(id)) {
                newOwner = goesToPlayer;
                break;
            }
        }
    }
    if (isTerritoryOwnerAnEnemy) {
        final Change takeOver = ChangeFactory.changeOwner(territory, newOwner);
        bridge.getHistoryWriter().addChildToEvent(takeOver.toString());
        bridge.addChange(takeOver);
        if (changeTracker != null) {
            changeTracker.addChange(takeOver);
            changeTracker.addToConquered(territory);
        }
        // play a sound
        if (territory.isWater()) {
            // should probably see if there is something actually happening for water
            bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_TERRITORY_CAPTURE_SEA, id);
        } else if (ta.getCapital() != null) {
            bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_TERRITORY_CAPTURE_CAPITAL, id);
        } else if (m_blitzed.contains(territory) && arrivedUnits.stream().anyMatch(Matches.unitCanBlitz())) {
            bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_TERRITORY_CAPTURE_BLITZ, id);
        } else {
            bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_TERRITORY_CAPTURE_LAND, id);
        }
    }
    // TODO: see if necessary
    if (territory.getUnits().anyMatch(Matches.unitIsEnemyOf(data, id).and(Matches.unitCanBeDamaged()))) {
        final IBattle bombingBattle = getPendingBattle(territory, true, null);
        if (bombingBattle != null) {
            final BattleResults results = new BattleResults(bombingBattle, WhoWon.DRAW, data);
            getBattleRecords().addResultToBattle(id, bombingBattle.getBattleId(), null, 0, 0, BattleRecord.BattleResultDescription.NO_BATTLE, results);
            bombingBattle.cancelBattle(bridge);
            removeBattle(bombingBattle);
            throw new IllegalStateException("Bombing Raids should be dealt with first! Be sure the battle has dependencies set correctly!");
        }
    }
    captureOrDestroyUnits(territory, id, newOwner, bridge, changeTracker);
    // Also check to make sure playerAttachment even HAS a capital to fix abend
    if (isTerritoryOwnerAnEnemy && terrOrigOwner != null && ta.getCapital() != null && TerritoryAttachment.getAllCapitals(terrOrigOwner, data).contains(territory) && relationshipTracker.isAllied(terrOrigOwner, id)) {
        // if it is give it back to the original owner
        final Collection<Territory> originallyOwned = OriginalOwnerTracker.getOriginallyOwned(data, terrOrigOwner);
        final List<Territory> friendlyTerritories = CollectionUtils.getMatches(originallyOwned, Matches.isTerritoryAllied(terrOrigOwner, data));
        // give back the factories as well.
        for (final Territory item : friendlyTerritories) {
            if (item.getOwner() == terrOrigOwner) {
                continue;
            }
            final Change takeOverFriendlyTerritories = ChangeFactory.changeOwner(item, terrOrigOwner);
            bridge.addChange(takeOverFriendlyTerritories);
            bridge.getHistoryWriter().addChildToEvent(takeOverFriendlyTerritories.toString());
            if (changeTracker != null) {
                changeTracker.addChange(takeOverFriendlyTerritories);
            }
            final Collection<Unit> units = CollectionUtils.getMatches(item.getUnits().getUnits(), Matches.unitIsInfrastructure());
            if (!units.isEmpty()) {
                final Change takeOverNonComUnits = ChangeFactory.changeOwner(units, terrOrigOwner, territory);
                bridge.addChange(takeOverNonComUnits);
                if (changeTracker != null) {
                    changeTracker.addChange(takeOverNonComUnits);
                }
            }
        }
    }
    // (they may want to unload from the transport and attack)
    if (Matches.territoryIsWater().test(territory) && arrivedUnits != null) {
        arrivedUnits.removeAll(CollectionUtils.getMatches(arrivedUnits, Matches.unitIsLand()));
    }
    markWasInCombat(arrivedUnits, bridge, changeTracker);
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) Territory(games.strategy.engine.data.Territory) GameData(games.strategy.engine.data.GameData) TerritoryAttachment(games.strategy.triplea.attachments.TerritoryAttachment) BattleResults(games.strategy.triplea.oddsCalculator.ta.BattleResults) ArrayList(java.util.ArrayList) Resource(games.strategy.engine.data.Resource) CompositeChange(games.strategy.engine.data.CompositeChange) Change(games.strategy.engine.data.Change) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) PlayerAttachment(games.strategy.triplea.attachments.PlayerAttachment) RelationshipTracker(games.strategy.engine.data.RelationshipTracker)

Example 52 with Resource

use of games.strategy.engine.data.Resource in project triplea by triplea-game.

the class TerritoryAttachment method setResources.

private void setResources(final String value) throws GameParseException {
    if (value == null) {
        m_resources = null;
        return;
    }
    if (m_resources == null) {
        m_resources = new ResourceCollection(getData());
    }
    final String[] s = value.split(":");
    final int amount = getInt(s[0]);
    if (s[1].equals(Constants.PUS)) {
        throw new GameParseException("Please set PUs using production, not resource" + thisErrorMsg());
    }
    final Resource resource = getData().getResourceList().getResource(s[1]);
    if (resource == null) {
        throw new GameParseException("No resource named: " + s[1] + thisErrorMsg());
    }
    m_resources.putResource(resource, amount);
}
Also used : Resource(games.strategy.engine.data.Resource) GameParseException(games.strategy.engine.data.GameParseException) ResourceCollection(games.strategy.engine.data.ResourceCollection)

Example 53 with Resource

use of games.strategy.engine.data.Resource in project triplea by triplea-game.

the class TriggerAttachment method triggerResourceChange.

private static IntegerMap<Resource> triggerResourceChange(final Set<TriggerAttachment> satisfiedTriggers, final IDelegateBridge bridge, final String beforeOrAfter, final String stepName, final boolean useUses, final boolean testUses, final boolean testChance, final boolean testWhen, final StringBuilder endOfTurnReport) {
    final GameData data = bridge.getData();
    Collection<TriggerAttachment> trigs = CollectionUtils.getMatches(satisfiedTriggers, resourceMatch());
    if (testWhen) {
        trigs = CollectionUtils.getMatches(trigs, whenOrDefaultMatch(beforeOrAfter, stepName));
    }
    if (testUses) {
        trigs = CollectionUtils.getMatches(trigs, availableUses);
    }
    final IntegerMap<Resource> resources = new IntegerMap<>();
    for (final TriggerAttachment t : trigs) {
        if (testChance && !t.testChance(bridge)) {
            continue;
        }
        if (useUses) {
            t.use(bridge);
        }
        final int eachMultiple = getEachMultiple(t);
        for (final PlayerID player : t.getPlayers()) {
            for (int i = 0; i < eachMultiple; ++i) {
                int toAdd = t.getResourceCount();
                if (t.getResource().equals(Constants.PUS)) {
                    toAdd *= Properties.getPuMultiplier(data);
                }
                resources.add(data.getResourceList().getResource(t.getResource()), toAdd);
                int total = player.getResources().getQuantity(t.getResource()) + toAdd;
                if (total < 0) {
                    toAdd -= total;
                    total = 0;
                }
                bridge.addChange(ChangeFactory.changeResourcesChange(player, data.getResourceList().getResource(t.getResource()), toAdd));
                final String puMessage = MyFormatter.attachmentNameToText(t.getName()) + ": " + player.getName() + " met a national objective for an additional " + t.getResourceCount() + " " + t.getResource() + "; end with " + total + " " + t.getResource();
                bridge.getHistoryWriter().startEvent(puMessage);
                endOfTurnReport.append(puMessage).append(" <br />");
            }
        }
    }
    return resources;
}
Also used : IntegerMap(games.strategy.util.IntegerMap) PlayerID(games.strategy.engine.data.PlayerID) GameData(games.strategy.engine.data.GameData) Resource(games.strategy.engine.data.Resource)

Example 54 with Resource

use of games.strategy.engine.data.Resource in project triplea by triplea-game.

the class TriggerAttachment method setResource.

private void setResource(final String s) throws GameParseException {
    if (s == null) {
        m_resource = null;
        return;
    }
    final Resource r = getData().getResourceList().getResource(s);
    if (r == null) {
        throw new GameParseException("Invalid resource: " + s + thisErrorMsg());
    }
    m_resource = s;
}
Also used : Resource(games.strategy.engine.data.Resource) GameParseException(games.strategy.engine.data.GameParseException)

Example 55 with Resource

use of games.strategy.engine.data.Resource in project triplea by triplea-game.

the class UnitAttachment method setFuelCost.

private void setFuelCost(final String value) throws GameParseException {
    final String[] s = value.split(":");
    if (s.length != 2) {
        throw new GameParseException("fuelCost must have two fields" + thisErrorMsg());
    }
    final String resourceToProduce = s[1];
    // validate that this resource exists in the xml
    final Resource r = getData().getResourceList().getResource(resourceToProduce);
    if (r == null) {
        throw new GameParseException("fuelCost: No resource called:" + resourceToProduce + thisErrorMsg());
    }
    final int n = getInt(s[0]);
    if (n < 0) {
        throw new GameParseException("fuelCost must have positive values" + thisErrorMsg());
    }
    m_fuelCost.put(r, n);
}
Also used : Resource(games.strategy.engine.data.Resource) GameParseException(games.strategy.engine.data.GameParseException)

Aggregations

Resource (games.strategy.engine.data.Resource)71 PlayerID (games.strategy.engine.data.PlayerID)22 IntegerMap (games.strategy.util.IntegerMap)16 GameData (games.strategy.engine.data.GameData)15 Unit (games.strategy.engine.data.Unit)15 ArrayList (java.util.ArrayList)15 Territory (games.strategy.engine.data.Territory)14 UnitType (games.strategy.engine.data.UnitType)13 Change (games.strategy.engine.data.Change)11 CompositeChange (games.strategy.engine.data.CompositeChange)11 ProductionRule (games.strategy.engine.data.ProductionRule)10 TripleAUnit (games.strategy.triplea.TripleAUnit)10 NamedAttachable (games.strategy.engine.data.NamedAttachable)9 ResourceCollection (games.strategy.engine.data.ResourceCollection)8 PlayerAttachment (games.strategy.triplea.attachments.PlayerAttachment)7 GameParseException (games.strategy.engine.data.GameParseException)6 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)6 HashMap (java.util.HashMap)6 HashSet (java.util.HashSet)6 Test (org.junit.jupiter.api.Test)5