Search in sources :

Example 26 with Resource

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

the class SimpleUnitPanel method addUnits.

private void addUnits(final PlayerID player, final int quantity, final NamedAttachable unit, final boolean damaged, final boolean disabled) {
    final JLabel label = new JLabel();
    label.setText(" x " + quantity);
    if (unit instanceof UnitType) {
        final Optional<ImageIcon> icon = uiContext.getUnitImageFactory().getIcon((UnitType) unit, player, damaged, disabled);
        icon.ifPresent(label::setIcon);
    } else if (unit instanceof Resource) {
        label.setIcon(uiContext.getResourceImageFactory().getIcon(unit, true));
    }
    add(label);
}
Also used : ImageIcon(javax.swing.ImageIcon) UnitType(games.strategy.engine.data.UnitType) Resource(games.strategy.engine.data.Resource) JLabel(javax.swing.JLabel)

Example 27 with Resource

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

the class MapRouteDrawer method createMovementLeftImage.

/**
 * This draws current moves, max moves, and fuel cost.
 */
private static BufferedImage createMovementLeftImage(final String curMovement, final String maxMovement, final ResourceCollection movementFuelCost, final ResourceImageFactory resourceImageFactory) {
    // Create and configure image
    final String unitMovementLeft = (maxMovement == null || maxMovement.trim().length() == 0) ? "" : "/" + maxMovement;
    final int imageWidth = findMovementLeftImageWidth(curMovement, unitMovementLeft, movementFuelCost);
    final BufferedImage image = new BufferedImage(imageWidth, MESSAGE_HEIGHT, BufferedImage.TYPE_INT_ARGB);
    final Graphics2D graphics = image.createGraphics();
    graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    graphics.setFont(MESSAGE_FONT);
    final FontMetrics fontMetrics = graphics.getFontMetrics();
    // Draw background
    graphics.setColor(new Color(220, 220, 220));
    final int rectHeight = MESSAGE_HEIGHT - 2;
    graphics.fillRoundRect(0, 0, imageWidth - 2, rectHeight, rectHeight, rectHeight);
    graphics.setColor(Color.BLACK);
    graphics.drawRoundRect(0, 0, imageWidth - 2, rectHeight, rectHeight, rectHeight);
    // Draw current movement
    graphics.setColor(new Color(0, 0, 200));
    final boolean hasEnoughMovement = !unitMovementLeft.isEmpty();
    final int textWidthOffset = fontMetrics.stringWidth(curMovement) / 2;
    graphics.drawString(curMovement, !hasEnoughMovement ? (image.getWidth() / 2 - textWidthOffset) : MESSAGE_PADDING, MESSAGE_TEXT_Y);
    // If has enough movement, draw remaining movement and fuel costs
    if (hasEnoughMovement) {
        int x = MESSAGE_PADDING + fontMetrics.stringWidth(curMovement);
        graphics.setColor(new Color(0, 0, 200));
        graphics.drawString(unitMovementLeft, x, MESSAGE_TEXT_Y);
        x += fontMetrics.stringWidth(unitMovementLeft) + MESSAGE_TEXT_SPACING;
        graphics.setColor(new Color(200, 0, 0));
        for (final Resource resource : movementFuelCost.getResourcesCopy().keySet()) {
            try {
                resourceImageFactory.getIcon(resource, false).paintIcon(null, graphics, x, 2);
            } catch (final IllegalStateException e) {
                graphics.drawString(resource.getName().substring(0, 1), x, MESSAGE_TEXT_Y);
            }
            x += ResourceImageFactory.IMAGE_SIZE;
            final String quantity = "-" + movementFuelCost.getQuantity(resource);
            graphics.drawString(quantity, x, MESSAGE_TEXT_Y);
            x += fontMetrics.stringWidth(quantity) + MESSAGE_TEXT_SPACING;
        }
    }
    graphics.dispose();
    return image;
}
Also used : FontMetrics(java.awt.FontMetrics) Color(java.awt.Color) Resource(games.strategy.engine.data.Resource) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D)

Example 28 with Resource

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

the class PurchaseDelegate method getRepairCosts.

private IntegerMap<Resource> getRepairCosts(final Map<Unit, IntegerMap<RepairRule>> repairRules, final PlayerID player) {
    final IntegerMap<Resource> costs = new IntegerMap<>();
    for (final IntegerMap<RepairRule> map : repairRules.values()) {
        for (final RepairRule rule : map.keySet()) {
            costs.addMultiple(rule.getCosts(), map.getInt(rule));
        }
    }
    final double discount = TechAbilityAttachment.getRepairDiscount(player, getData());
    if (discount != 1.0D) {
        costs.multiplyAllValuesBy(discount, 3);
    }
    return costs;
}
Also used : IntegerMap(games.strategy.util.IntegerMap) Resource(games.strategy.engine.data.Resource) RepairRule(games.strategy.engine.data.RepairRule)

Example 29 with Resource

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

the class RocketsFireHelper method fireRocket.

private static void fireRocket(final PlayerID player, final Territory attackedTerritory, final IDelegateBridge bridge, final Territory attackFrom) {
    final GameData data = bridge.getData();
    final PlayerID attacked = attackedTerritory.getOwner();
    final Resource pus = data.getResourceList().getResource(Constants.PUS);
    final boolean damageFromBombingDoneToUnits = isDamageFromBombingDoneToUnitsInsteadOfTerritories(data);
    // unit damage vs territory damage
    final Collection<Unit> enemyUnits = attackedTerritory.getUnits().getMatches(Matches.enemyUnit(player, data).and(Matches.unitIsBeingTransported().negate()));
    final Collection<Unit> enemyTargetsTotal = CollectionUtils.getMatches(enemyUnits, Matches.unitIsAtMaxDamageOrNotCanBeDamaged(attackedTerritory).negate());
    final Collection<Unit> rockets;
    // attackFrom could be null if WW2V1
    if (attackFrom == null) {
        rockets = null;
    } else {
        rockets = new ArrayList<>(CollectionUtils.getMatches(attackFrom.getUnits().getUnits(), rocketMatch(player)));
    }
    final int numberOfAttacks = (rockets == null ? 1 : Math.min(TechAbilityAttachment.getRocketNumberPerTerritory(player, data), TechAbilityAttachment.getRocketDiceNumber(rockets, data)));
    if (numberOfAttacks <= 0) {
        return;
    }
    final Collection<Unit> targets = new ArrayList<>();
    if (damageFromBombingDoneToUnits) {
        // TODO: rockets needs to be completely redone to allow for multiple rockets to fire at different targets, etc
        // etc.
        final HashSet<UnitType> legalTargetsForTheseRockets = new HashSet<>();
        if (rockets == null) {
            legalTargetsForTheseRockets.addAll(data.getUnitTypeList().getAllUnitTypes());
        } else {
            // a hack for now, we let the rockets fire at anyone who could be targetted by any rocket
            for (final Unit r : rockets) {
                legalTargetsForTheseRockets.addAll(UnitAttachment.get(r.getType()).getBombingTargets(data));
            }
        }
        final Collection<Unit> enemyTargets = CollectionUtils.getMatches(enemyTargetsTotal, Matches.unitIsOfTypes(legalTargetsForTheseRockets));
        if (enemyTargets.isEmpty()) {
            // TODO: this sucks
            return;
        }
        Unit target = null;
        if (enemyTargets.size() == 1) {
            target = enemyTargets.iterator().next();
        } else {
            while (target == null) {
                final ITripleAPlayer iplayer = (ITripleAPlayer) bridge.getRemotePlayer(player);
                target = iplayer.whatShouldBomberBomb(attackedTerritory, enemyTargets, rockets);
            }
        }
        if (target == null) {
            throw new IllegalStateException("No Targets in " + attackedTerritory.getName());
        }
        targets.add(target);
    }
    final boolean doNotUseBombingBonus = !Properties.getUseBombingMaxDiceSidesAndBonus(data) || rockets == null;
    int cost = 0;
    final String transcript;
    if (!Properties.getLowLuckDamageOnly(data)) {
        if (doNotUseBombingBonus || rockets == null) {
            // no low luck, and no bonus, so just roll based on the map's dice sides
            final int[] rolls = bridge.getRandom(data.getDiceSides(), numberOfAttacks, player, DiceType.BOMBING, "Rocket fired by " + player.getName() + " at " + attacked.getName());
            for (final int r : rolls) {
                // we are zero based
                cost += r + 1;
            }
            transcript = "Rockets " + (attackFrom == null ? "" : "in " + attackFrom.getName()) + " roll: " + MyFormatter.asDice(rolls);
        } else {
            // we must use bombing bonus
            int highestMaxDice = 0;
            int highestBonus = 0;
            final int diceSides = data.getDiceSides();
            for (final Unit u : rockets) {
                final UnitAttachment ua = UnitAttachment.get(u.getType());
                int maxDice = ua.getBombingMaxDieSides();
                final int bonus = ua.getBombingBonus();
                // map, and zero for the bonus.
                if (maxDice < 0) {
                    maxDice = diceSides;
                }
                // we only roll once for rockets, so if there are other rockets here we just roll for the best rocket
                if ((bonus + ((maxDice + 1) / 2)) > (highestBonus + ((highestMaxDice + 1) / 2))) {
                    highestMaxDice = maxDice;
                    highestBonus = bonus;
                }
            }
            // now we roll, or don't if there is nothing to roll.
            if (highestMaxDice > 0) {
                final int[] rolls = bridge.getRandom(highestMaxDice, numberOfAttacks, player, DiceType.BOMBING, "Rocket fired by " + player.getName() + " at " + attacked.getName());
                for (int i = 0; i < rolls.length; i++) {
                    final int r = Math.max(-1, rolls[i] + highestBonus);
                    rolls[i] = r;
                    // we are zero based
                    cost += r + 1;
                }
                transcript = "Rockets " + (attackFrom == null ? "" : "in " + attackFrom.getName()) + " roll: " + MyFormatter.asDice(rolls);
            } else {
                cost = highestBonus * numberOfAttacks;
                transcript = "Rockets " + (attackFrom == null ? "" : "in " + attackFrom.getName()) + " do " + highestBonus + " damage for each rocket";
            }
        }
    } else {
        if (doNotUseBombingBonus || rockets == null) {
            // no bonus, so just roll based on the map's dice sides, but modify for LL
            final int maxDice = (data.getDiceSides() + 1) / 3;
            final int bonus = (data.getDiceSides() + 1) / 3;
            final int[] rolls = bridge.getRandom(maxDice, numberOfAttacks, player, DiceType.BOMBING, "Rocket fired by " + player.getName() + " at " + attacked.getName());
            for (int i = 0; i < rolls.length; i++) {
                final int r = rolls[i] + bonus;
                rolls[i] = r;
                // we are zero based
                cost += r + 1;
            }
            transcript = "Rockets " + (attackFrom == null ? "" : "in " + attackFrom.getName()) + " roll: " + MyFormatter.asDice(rolls);
        } else {
            int highestMaxDice = 0;
            int highestBonus = 0;
            final int diceSides = data.getDiceSides();
            for (final Unit u : rockets) {
                final UnitAttachment ua = UnitAttachment.get(u.getType());
                int maxDice = ua.getBombingMaxDieSides();
                int bonus = ua.getBombingBonus();
                // map, and zero for the bonus.
                if (maxDice < 0 || doNotUseBombingBonus) {
                    maxDice = diceSides;
                }
                if (doNotUseBombingBonus) {
                    bonus = 0;
                }
                // luck by 2/3.
                if (maxDice >= 5) {
                    bonus += (maxDice + 1) / 3;
                    maxDice = (maxDice + 1) / 3;
                }
                // we only roll once for rockets, so if there are other rockets here we just roll for the best rocket
                if ((bonus + ((maxDice + 1) / 2)) > (highestBonus + ((highestMaxDice + 1) / 2))) {
                    highestMaxDice = maxDice;
                    highestBonus = bonus;
                }
            }
            // now we roll, or don't if there is nothing to roll.
            if (highestMaxDice > 0) {
                final int[] rolls = bridge.getRandom(highestMaxDice, numberOfAttacks, player, DiceType.BOMBING, "Rocket fired by " + player.getName() + " at " + attacked.getName());
                for (int i = 0; i < rolls.length; i++) {
                    final int r = Math.max(-1, rolls[i] + highestBonus);
                    rolls[i] = r;
                    // we are zero based
                    cost += r + 1;
                }
                transcript = "Rockets " + (attackFrom == null ? "" : "in " + attackFrom.getName()) + " roll: " + MyFormatter.asDice(rolls);
            } else {
                cost = highestBonus * numberOfAttacks;
                transcript = "Rockets " + (attackFrom == null ? "" : "in " + attackFrom.getName()) + " do " + highestBonus + " damage for each rocket";
            }
        }
    }
    int territoryProduction = TerritoryAttachment.getProduction(attackedTerritory);
    if (damageFromBombingDoneToUnits && !targets.isEmpty()) {
        // we are doing damage to 'target', not to the territory
        final Unit target = targets.iterator().next();
        // UnitAttachment ua = UnitAttachment.get(target.getType());
        final TripleAUnit taUnit = (TripleAUnit) target;
        final int damageLimit = taUnit.getHowMuchMoreDamageCanThisUnitTake(target, attackedTerritory);
        cost = Math.max(0, Math.min(cost, damageLimit));
        final int totalDamage = taUnit.getUnitDamage() + cost;
        // Record production lost
        // DelegateFinder.moveDelegate(data).PUsLost(attackedTerritory, cost);
        // apply the hits to the targets
        final IntegerMap<Unit> damageMap = new IntegerMap<>();
        damageMap.put(target, totalDamage);
        bridge.addChange(ChangeFactory.bombingUnitDamage(damageMap));
    // attackedTerritory.notifyChanged();
    // in WW2V2, limit rocket attack cost to production value of factory.
    } else if (isWW2V2(data) || isLimitRocketDamageToProduction(data)) {
        // If we are limiting total PUs lost then take that into account
        if (isPuCap(data) || isLimitRocketDamagePerTurn(data)) {
            final int alreadyLost = DelegateFinder.moveDelegate(data).pusAlreadyLost(attackedTerritory);
            territoryProduction -= alreadyLost;
            territoryProduction = Math.max(0, territoryProduction);
        }
        if (cost > territoryProduction) {
            cost = territoryProduction;
        }
    }
    // Record the PUs lost
    DelegateFinder.moveDelegate(data).pusLost(attackedTerritory, cost);
    if (damageFromBombingDoneToUnits && !targets.isEmpty()) {
        getRemote(bridge).reportMessage("Rocket attack in " + attackedTerritory.getName() + " does " + cost + " damage to " + targets.iterator().next(), "Rocket attack in " + attackedTerritory.getName() + " does " + cost + " damage to " + targets.iterator().next());
        bridge.getHistoryWriter().startEvent("Rocket attack in " + attackedTerritory.getName() + " does " + cost + " damage to " + targets.iterator().next());
    } else {
        cost *= Properties.getPuMultiplier(data);
        getRemote(bridge).reportMessage("Rocket attack in " + attackedTerritory.getName() + " costs:" + cost, "Rocket attack in " + attackedTerritory.getName() + " costs:" + cost);
        // Trying to remove more PUs than the victim has is A Bad Thing[tm]
        final int availForRemoval = attacked.getResources().getQuantity(pus);
        if (cost > availForRemoval) {
            cost = availForRemoval;
        }
        final String transcriptText = attacked.getName() + " lost " + cost + " PUs to rocket attack by " + player.getName();
        bridge.getHistoryWriter().startEvent(transcriptText);
        final Change rocketCharge = ChangeFactory.changeResourcesChange(attacked, pus, -cost);
        bridge.addChange(rocketCharge);
    }
    bridge.getHistoryWriter().addChildToEvent(transcript, rockets == null ? null : new ArrayList<>(rockets));
    // this is null in WW2V1
    if (attackFrom != null) {
        if (rockets != null && !rockets.isEmpty()) {
            // TODO: only a certain number fired...
            final Change change = ChangeFactory.markNoMovementChange(Collections.singleton(rockets.iterator().next()));
            bridge.addChange(change);
        } else {
            throw new IllegalStateException("No rockets?" + attackFrom.getUnits().getUnits());
        }
    }
    // kill any units that can die if they have reached max damage (veqryn)
    if (targets.stream().anyMatch(Matches.unitCanDieFromReachingMaxDamage())) {
        final List<Unit> unitsCanDie = CollectionUtils.getMatches(targets, Matches.unitCanDieFromReachingMaxDamage());
        unitsCanDie.retainAll(CollectionUtils.getMatches(unitsCanDie, Matches.unitIsAtMaxDamageOrNotCanBeDamaged(attackedTerritory)));
        if (!unitsCanDie.isEmpty()) {
            final Change removeDead = ChangeFactory.removeUnits(attackedTerritory, unitsCanDie);
            final String transcriptText = MyFormatter.unitsToText(unitsCanDie) + " lost in " + attackedTerritory.getName();
            bridge.getHistoryWriter().addChildToEvent(transcriptText, unitsCanDie);
            bridge.addChange(removeDead);
        }
    }
    // play a sound
    if (cost > 0) {
        bridge.getSoundChannelBroadcaster().playSoundForAll(SoundPath.CLIP_BOMBING_ROCKET, player);
    }
}
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) ArrayList(java.util.ArrayList) Change(games.strategy.engine.data.Change) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) TripleAUnit(games.strategy.triplea.TripleAUnit) ITripleAPlayer(games.strategy.triplea.player.ITripleAPlayer) UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) UnitType(games.strategy.engine.data.UnitType) HashSet(java.util.HashSet)

Example 30 with Resource

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

the class ResourceImageFactory method getResourcesPanel.

private JPanel getResourcesPanel(final ResourceCollection resources, final boolean showEmpty, final PlayerID player, final GameData data) {
    final JPanel resourcePanel = new JPanel();
    List<Resource> resourcesInOrder = new ArrayList<>();
    data.acquireReadLock();
    try {
        resourcesInOrder = data.getResourceList().getResources();
    } finally {
        data.releaseReadLock();
    }
    int count = 0;
    for (final Resource resource : resourcesInOrder) {
        if ((player != null && !resource.isDisplayedFor(player)) || (!showEmpty && resources.getQuantity(resource) == 0)) {
            continue;
        }
        final JLabel resourceLabel = getLabel(resource, resources.getResourcesCopy());
        resourceLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));
        resourcePanel.add(resourceLabel, new GridBagConstraints(count++, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
    }
    return resourcePanel;
}
Also used : JPanel(javax.swing.JPanel) GridBagConstraints(java.awt.GridBagConstraints) Insets(java.awt.Insets) Resource(games.strategy.engine.data.Resource) ArrayList(java.util.ArrayList) JLabel(javax.swing.JLabel)

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