Search in sources :

Example 11 with UnitCategory

use of games.strategy.triplea.util.UnitCategory in project triplea by triplea-game.

the class BattleDisplay method updateKilledUnits.

/**
 * updates the panel content according to killed units for the player.
 *
 * @param killedUnits
 *        list of units killed
 * @param playerId
 *        player kills belongs to
 */
private Collection<Unit> updateKilledUnits(final Collection<Unit> killedUnits, final PlayerID playerId) {
    final JPanel casualtyPanel;
    if (playerId.equals(defender)) {
        casualtyPanel = casualtiesInstantPanelDefender;
    } else {
        casualtyPanel = casualtiesInstantPanelAttacker;
    }
    Map<Unit, Collection<Unit>> dependentsMap;
    gameData.acquireReadLock();
    try {
        dependentsMap = BattleCalculator.getDependents(killedUnits);
    } finally {
        gameData.releaseReadLock();
    }
    final Collection<Unit> dependentUnitsReturned = new ArrayList<>();
    for (Collection<Unit> dependentCollection : dependentsMap.values()) {
        dependentUnitsReturned.addAll(dependentCollection);
    }
    for (final UnitCategory category : UnitSeperator.categorize(killedUnits, dependentsMap, false, false)) {
        final JPanel panel = new JPanel();
        JLabel unit = uiContext.createUnitImageJLabel(category.getType(), category.getOwner());
        panel.add(unit);
        panel.add(new JLabel("x " + category.getUnits().size()));
        for (final UnitOwner owner : category.getDependents()) {
            unit = uiContext.createUnitImageJLabel(owner.getType(), owner.getOwner());
            panel.add(unit);
            // TODO this size is of the transport collection size, not the transportED collection size.
            panel.add(new JLabel("x " + category.getUnits().size()));
        }
        casualtyPanel.add(panel);
    }
    return dependentUnitsReturned;
}
Also used : JPanel(javax.swing.JPanel) UnitOwner(games.strategy.triplea.util.UnitOwner) ArrayList(java.util.ArrayList) Collection(java.util.Collection) JLabel(javax.swing.JLabel) Unit(games.strategy.engine.data.Unit) UnitCategory(games.strategy.triplea.util.UnitCategory)

Example 12 with UnitCategory

use of games.strategy.triplea.util.UnitCategory in project triplea by triplea-game.

the class MovePanel method getUnitsToUnload.

/**
 * Return the units that are to be unloaded for this route.
 * If needed will ask the user what transports to unload.
 * This is needed because the user needs to be able to select what transports to unload
 * in the case where some transports have different movement, different
 * units etc
 */
private Collection<Unit> getUnitsToUnload(final Route route, final Collection<Unit> unitsToUnload) {
    final Collection<Unit> allUnits = getFirstSelectedTerritory().getUnits().getUnits();
    final List<Unit> candidateUnits = CollectionUtils.getMatches(allUnits, getUnloadableMatch(route, unitsToUnload));
    if (unitsToUnload.size() == candidateUnits.size()) {
        return unitsToUnload;
    }
    final List<Unit> candidateTransports = CollectionUtils.getMatches(allUnits, Matches.unitIsTransportingSomeCategories(candidateUnits));
    // Remove all incapable transports
    final Collection<Unit> incapableTransports = CollectionUtils.getMatches(candidateTransports, Matches.transportCannotUnload(route.getEnd()));
    candidateTransports.removeAll(incapableTransports);
    if (candidateTransports.size() == 0) {
        return Collections.emptyList();
    }
    // Just one transport, don't bother to ask
    if (candidateTransports.size() == 1) {
        return unitsToUnload;
    }
    // Are the transports all of the same type and if they are, then don't ask
    final Collection<UnitCategory> categories = UnitSeperator.categorize(candidateTransports, mustMoveWithDetails.getMustMoveWith(), true, false);
    if (categories.size() == 1) {
        return unitsToUnload;
    }
    sortTransportsToUnload(candidateTransports, route);
    // unitsToUnload are actually dependents, but need to select transports
    final Set<Unit> defaultSelections = TransportUtils.findMinTransportsToUnload(unitsToUnload, candidateTransports);
    // Match criteria to ensure that chosen transports will match selected units
    final Predicate<Collection<Unit>> transportsToUnloadMatch = units -> {
        final List<Unit> sortedTransports = CollectionUtils.getMatches(units, Matches.unitIsTransport());
        final Collection<Unit> availableUnits = new ArrayList<>(unitsToUnload);
        // track the changing capacities of the transports as we assign units
        final IntegerMap<Unit> capacityMap = new IntegerMap<>();
        for (final Unit transport : sortedTransports) {
            final Collection<Unit> transporting = TripleAUnit.get(transport).getTransporting();
            capacityMap.add(transport, TransportUtils.getTransportCost(transporting));
        }
        boolean hasChanged = false;
        final Comparator<Unit> increasingCapacityComparator = UnitComparator.getIncreasingCapacityComparator(sortedTransports);
        // the selected units amongst the current selection of chosen transports.
        do {
            hasChanged = false;
            // Sort transports by increasing capacity
            sortedTransports.sort(increasingCapacityComparator);
            // Try to remove one unit from each transport, in succession
            final Iterator<Unit> transportIter = sortedTransports.iterator();
            while (transportIter.hasNext()) {
                final Unit transport = transportIter.next();
                final Collection<Unit> transporting = TripleAUnit.get(transport).getTransporting();
                if (transporting == null) {
                    continue;
                }
                final Collection<UnitCategory> transCategories = UnitSeperator.categorize(transporting);
                final Iterator<Unit> unitIter = availableUnits.iterator();
                while (unitIter.hasNext()) {
                    final Unit unit = unitIter.next();
                    final Collection<UnitCategory> unitCategory = UnitSeperator.categorize(Collections.singleton(unit));
                    // Is one of the transported units of the same type we want to unload?
                    if (CollectionUtils.someIntersect(transCategories, unitCategory)) {
                        // Unload the unit, remove the transport from our list, and continue
                        hasChanged = true;
                        unitIter.remove();
                        transportIter.remove();
                        break;
                    }
                }
            }
        // Repeat until there are no units left or no changes occur
        } while (availableUnits.size() > 0 && hasChanged);
        // If we haven't seen all of the transports (and removed them) then there are extra transports that don't fit
        return (sortedTransports.size() == 0);
    };
    // Choosing what transports to unload
    final UnitChooser chooser = new UnitChooser(candidateTransports, defaultSelections, mustMoveWithDetails.getMustMoveWith(), /* categorizeMovement */
    true, /* categorizeTransportCost */
    false, /* allowTwoHit */
    false, getMap().getUiContext(), transportsToUnloadMatch);
    chooser.setTitle("What transports do you want to unload");
    final int option = JOptionPane.showOptionDialog(getTopLevelAncestor(), chooser, "What transports do you want to unload", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null);
    if (option != JOptionPane.OK_OPTION) {
        return Collections.emptyList();
    }
    final Collection<Unit> chosenTransports = CollectionUtils.getMatches(chooser.getSelected(), Matches.unitIsTransport());
    final List<Unit> allUnitsInSelectedTransports = new ArrayList<>();
    for (final Unit transport : chosenTransports) {
        final Collection<Unit> transporting = TripleAUnit.get(transport).getTransporting();
        if (transporting != null) {
            allUnitsInSelectedTransports.addAll(transporting);
        }
    }
    allUnitsInSelectedTransports.retainAll(candidateUnits);
    sortUnitsToMove(allUnitsInSelectedTransports, route);
    final List<Unit> selectedUnitsToUnload = new ArrayList<>();
    final List<Unit> sortedTransports = new ArrayList<>(chosenTransports);
    sortedTransports.sort(UnitComparator.getIncreasingCapacityComparator(sortedTransports));
    final Collection<Unit> selectedUnits = new ArrayList<>(unitsToUnload);
    // First pass: choose one unit from each selected transport
    for (final Unit transport : sortedTransports) {
        boolean hasChanged = false;
        final Iterator<Unit> selectedIter = selectedUnits.iterator();
        while (selectedIter.hasNext()) {
            final Unit selected = selectedIter.next();
            final Collection<Unit> transporting = TripleAUnit.get(transport).getTransporting();
            for (final Unit candidate : transporting) {
                if (selected.getType().equals(candidate.getType()) && selected.getOwner().equals(candidate.getOwner()) && selected.getHits() == candidate.getHits()) {
                    hasChanged = true;
                    selectedUnitsToUnload.add(candidate);
                    allUnitsInSelectedTransports.remove(candidate);
                    selectedIter.remove();
                    break;
                }
            }
            if (hasChanged) {
                break;
            }
        }
    }
    // Now fill remaining slots in preferred unit order
    for (final Unit selected : selectedUnits) {
        final Iterator<Unit> candidateIter = allUnitsInSelectedTransports.iterator();
        while (candidateIter.hasNext()) {
            final Unit candidate = candidateIter.next();
            if (selected.getType().equals(candidate.getType()) && selected.getOwner().equals(candidate.getOwner()) && selected.getHits() == candidate.getHits()) {
                selectedUnitsToUnload.add(candidate);
                candidateIter.remove();
                break;
            }
        }
    }
    return selectedUnitsToUnload;
}
Also used : BaseEditDelegate(games.strategy.triplea.delegate.BaseEditDelegate) KeyListener(java.awt.event.KeyListener) GameStepPropertiesHelper(games.strategy.triplea.delegate.GameStepPropertiesHelper) UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) Point(java.awt.Point) HashMap(java.util.HashMap) TechAttachment(games.strategy.triplea.attachments.TechAttachment) PredicateBuilder(games.strategy.util.PredicateBuilder) Properties(games.strategy.triplea.Properties) UnitSeperator(games.strategy.triplea.util.UnitSeperator) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Route(games.strategy.engine.data.Route) TransportTracker(games.strategy.triplea.delegate.TransportTracker) UnitCategory(games.strategy.triplea.util.UnitCategory) MoveValidator(games.strategy.triplea.delegate.MoveValidator) Map(java.util.Map) MoveType(games.strategy.triplea.delegate.AbstractMoveDelegate.MoveType) UnitType(games.strategy.engine.data.UnitType) TripleAUnit(games.strategy.triplea.TripleAUnit) LinkedHashSet(java.util.LinkedHashSet) CollectionUtils(games.strategy.util.CollectionUtils) IntegerMap(games.strategy.util.IntegerMap) Unit(games.strategy.engine.data.Unit) Iterator(java.util.Iterator) Image(java.awt.Image) Predicate(java.util.function.Predicate) Collection(java.util.Collection) UnitComparator(games.strategy.triplea.delegate.UnitComparator) Set(java.util.Set) Territory(games.strategy.engine.data.Territory) KeyEvent(java.awt.event.KeyEvent) JOptionPane(javax.swing.JOptionPane) MouseEvent(java.awt.event.MouseEvent) ClientLogger(games.strategy.debug.ClientLogger) GameData(games.strategy.engine.data.GameData) MoveDescription(games.strategy.triplea.delegate.dataObjects.MoveDescription) List(java.util.List) PlayerID(games.strategy.engine.data.PlayerID) Matches(games.strategy.triplea.delegate.Matches) MoveValidationResult(games.strategy.triplea.delegate.dataObjects.MoveValidationResult) AbstractMoveDelegate(games.strategy.triplea.delegate.AbstractMoveDelegate) Comparator(java.util.Comparator) Collections(java.util.Collections) MustMoveWithDetails(games.strategy.triplea.delegate.dataObjects.MustMoveWithDetails) TransportUtils(games.strategy.triplea.util.TransportUtils) IntegerMap(games.strategy.util.IntegerMap) ArrayList(java.util.ArrayList) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) Point(java.awt.Point) UnitComparator(games.strategy.triplea.delegate.UnitComparator) Comparator(java.util.Comparator) Iterator(java.util.Iterator) Collection(java.util.Collection) ArrayList(java.util.ArrayList) List(java.util.List) UnitCategory(games.strategy.triplea.util.UnitCategory)

Example 13 with UnitCategory

use of games.strategy.triplea.util.UnitCategory in project triplea by triplea-game.

the class MovePanel method allowSpecificUnitSelection.

/**
 * Allow the user to select specific units, if for example some units
 * have different movement
 * Units are sorted in preferred order, so units represents the default selections.
 */
private boolean allowSpecificUnitSelection(final Collection<Unit> units, final Route route, boolean mustQueryUser, final Predicate<Collection<Unit>> matchCriteria) {
    final List<Unit> candidateUnits = getFirstSelectedTerritory().getUnits().getMatches(getMovableMatch(route, units));
    if (!mustQueryUser) {
        final Set<UnitCategory> categories = UnitSeperator.categorize(candidateUnits, mustMoveWithDetails.getMustMoveWith(), true, false);
        for (final UnitCategory category1 : categories) {
            // we cant move these, dont bother to check
            if (category1.getMovement() == 0) {
                continue;
            }
            for (final UnitCategory category2 : categories) {
                // we cant move these, dont bother to check
                if (category2.getMovement() == 0) {
                    continue;
                }
                // then the user has to refine his selection
                if (category1 != category2 && category1.getType() == category2.getType() && !category1.equals(category2)) {
                    // if we are moving all the units from both categories, then nothing to choose
                    if (units.containsAll(category1.getUnits()) && units.containsAll(category2.getUnits())) {
                        continue;
                    }
                    // if we are moving some of the units from either category, then we need to stop
                    if (!CollectionUtils.intersection(category1.getUnits(), units).isEmpty() || !CollectionUtils.intersection(category2.getUnits(), units).isEmpty()) {
                        mustQueryUser = true;
                    }
                }
            }
        }
    }
    if (mustQueryUser) {
        final List<Unit> defaultSelections = new ArrayList<>(units.size());
        if (route.isLoad()) {
            final Collection<Unit> transportsToLoad = new ArrayList<>(getTransportsToLoad(route, units, false));
            defaultSelections.addAll(TransportUtils.mapTransports(route, units, transportsToLoad).keySet());
        } else {
            defaultSelections.addAll(units);
        }
        // sort candidateUnits in preferred order
        sortUnitsToMove(candidateUnits, route);
        final UnitChooser chooser = new UnitChooser(candidateUnits, defaultSelections, mustMoveWithDetails.getMustMoveWith(), true, false, false, getMap().getUiContext(), matchCriteria);
        final String text = "Select units to move from " + getFirstSelectedTerritory() + ".";
        final int option = JOptionPane.showOptionDialog(getTopLevelAncestor(), chooser, text, JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null);
        if (option != JOptionPane.OK_OPTION) {
            units.clear();
            return false;
        }
        units.clear();
        units.addAll(chooser.getSelected(false));
    }
    // add the dependent units
    final List<Unit> unitsCopy = new ArrayList<>(units);
    for (final Unit unit : unitsCopy) {
        final Collection<Unit> forced = mustMoveWithDetails.getMustMoveWith().get(unit);
        if (forced != null) {
            // add dependent if necessary
            for (final Unit dependent : forced) {
                if (unitsCopy.indexOf(dependent) == -1) {
                    units.add(dependent);
                }
            }
        }
    }
    return true;
}
Also used : ArrayList(java.util.ArrayList) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) UnitCategory(games.strategy.triplea.util.UnitCategory) Point(java.awt.Point)

Example 14 with UnitCategory

use of games.strategy.triplea.util.UnitCategory in project triplea by triplea-game.

the class MapPanel method setMouseShadowUnits.

void setMouseShadowUnits(final Collection<Unit> units) {
    if (units == null || units.isEmpty()) {
        movementLeftForCurrentUnits = "";
        mouseShadowImage = null;
        SwingUtilities.invokeLater(this::repaint);
        return;
    }
    final Tuple<Integer, Integer> movementLeft = TripleAUnit.getMinAndMaxMovementLeft(CollectionUtils.getMatches(units, Matches.unitIsBeingTransported().negate()));
    movementLeftForCurrentUnits = movementLeft.getFirst() + (movementLeft.getSecond() > movementLeft.getFirst() ? "+" : "");
    gameData.acquireReadLock();
    try {
        movementFuelCost = Route.getMovementFuelCostCharge(units, routeDescription.getRoute(), units.iterator().next().getOwner(), gameData);
    } finally {
        gameData.releaseReadLock();
    }
    final Set<UnitCategory> categories = UnitSeperator.categorize(units);
    final int iconWidth = uiContext.getUnitImageFactory().getUnitImageWidth();
    final int horizontalSpace = 5;
    final BufferedImage img = Util.createImage(categories.size() * (horizontalSpace + iconWidth), uiContext.getUnitImageFactory().getUnitImageHeight(), true);
    final Graphics2D g = img.createGraphics();
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f));
    g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    final Rectangle bounds = new Rectangle(0, 0, 0, 0);
    getData().acquireReadLock();
    try {
        int i = 0;
        for (final UnitCategory category : categories) {
            final Point place = new Point(i * (iconWidth + horizontalSpace), 0);
            final UnitsDrawer drawer = new UnitsDrawer(category.getUnits().size(), category.getType().getName(), category.getOwner().getName(), place, category.getDamaged(), category.getBombingDamage(), category.getDisabled(), false, "", uiContext);
            drawer.draw(bounds, gameData, g, uiContext.getMapData(), null, null);
            i++;
        }
    } finally {
        getData().releaseReadLock();
    }
    mouseShadowImage = img;
    SwingUtilities.invokeLater(this::repaint);
    g.dispose();
}
Also used : UnitsDrawer(games.strategy.triplea.ui.screen.UnitsDrawer) Rectangle(java.awt.Rectangle) Point(java.awt.Point) UnitCategory(games.strategy.triplea.util.UnitCategory) Point(java.awt.Point) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D)

Example 15 with UnitCategory

use of games.strategy.triplea.util.UnitCategory in project triplea by triplea-game.

the class AbstractUndoableMovesPanel method createComponentForMove.

private JComponent createComponentForMove(final AbstractUndoableMove move) {
    final Box unitsBox = new Box(BoxLayout.X_AXIS);
    unitsBox.add(new JLabel((move.getIndex() + 1) + ") "));
    final Collection<UnitCategory> unitCategories = UnitSeperator.categorize(move.getUnits());
    final Dimension buttonSize = new Dimension(80, 22);
    for (final UnitCategory category : unitCategories) {
        final Optional<ImageIcon> icon = movePanel.getMap().getUiContext().getUnitImageFactory().getIcon(category.getType(), category.getOwner(), category.hasDamageOrBombingUnitDamage(), category.getDisabled());
        if (icon.isPresent()) {
            final JLabel label = new JLabel("x" + category.getUnits().size() + " ", icon.get(), SwingConstants.LEFT);
            unitsBox.add(label);
        }
    }
    unitsBox.add(Box.createHorizontalGlue());
    final JLabel text = new JLabel(move.getMoveLabel());
    final Box textBox = new Box(BoxLayout.X_AXIS);
    textBox.add(text);
    textBox.add(Box.createHorizontalGlue());
    final JButton cancelButton = new JButton(new UndoMoveActionListener(move.getIndex()));
    setSize(buttonSize, cancelButton);
    final JButton viewbutton = new JButton(new ViewAction(move));
    setSize(buttonSize, viewbutton);
    final Box buttonsBox = new Box(BoxLayout.X_AXIS);
    buttonsBox.add(viewbutton);
    buttonsBox.add(cancelButton);
    buttonsBox.add(Box.createHorizontalGlue());
    final Box containerBox = new Box(BoxLayout.Y_AXIS);
    containerBox.add(unitsBox);
    containerBox.add(textBox);
    containerBox.add(buttonsBox);
    containerBox.add(new JLabel(" "));
    return containerBox;
}
Also used : ImageIcon(javax.swing.ImageIcon) JButton(javax.swing.JButton) JLabel(javax.swing.JLabel) Box(javax.swing.Box) Dimension(java.awt.Dimension) UnitCategory(games.strategy.triplea.util.UnitCategory)

Aggregations

UnitCategory (games.strategy.triplea.util.UnitCategory)17 Unit (games.strategy.engine.data.Unit)8 ArrayList (java.util.ArrayList)7 Territory (games.strategy.engine.data.Territory)5 Point (java.awt.Point)5 GameData (games.strategy.engine.data.GameData)4 PlayerID (games.strategy.engine.data.PlayerID)4 UnitType (games.strategy.engine.data.UnitType)4 TripleAUnit (games.strategy.triplea.TripleAUnit)4 JPanel (javax.swing.JPanel)4 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)3 Image (java.awt.Image)3 Collection (java.util.Collection)3 LinkedHashSet (java.util.LinkedHashSet)3 List (java.util.List)3 BoxLayout (javax.swing.BoxLayout)3 ImageIcon (javax.swing.ImageIcon)3 JLabel (javax.swing.JLabel)3 Matches (games.strategy.triplea.delegate.Matches)2 UnitSeperator (games.strategy.triplea.util.UnitSeperator)2