Skip to content

Commit

Permalink
Merge pull request MegaMek#5213 from SJuliez/icon64
Browse files Browse the repository at this point in the history
Part of icon chooser (MML)
  • Loading branch information
SJuliez authored Mar 9, 2024
2 parents 07b212b + 79b62ed commit 953e0df
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 3 deletions.
5 changes: 5 additions & 0 deletions megamek/src/megamek/client/ui/swing/tileset/MechTileset.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ public Image imageFor(Entity entity) {
}

public Image imageFor(Entity entity, int secondaryPos) {
// Return the embedded icon, if the unit has one and this is the one-hex icon
if ((secondaryPos == -1) && entity.hasEmbeddedIcon()) {
return entity.getIcon();
}

MechEntry entry = entryFor(entity, secondaryPos);

if (entry == null) {
Expand Down
16 changes: 16 additions & 0 deletions megamek/src/megamek/common/BTObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -417,4 +417,20 @@ default boolean isSingleUnit() {
default @Nullable Image getFluffImage() {
return null;
}

/**
* Returns an icon for this unit or object for the game board. Note that this is the 84 x 72 standard
* size icon; icons for landed large craft are not handled by this method.
* Important: This method returns only an icon that is stored in the object itself, e.g. if it
* was part of the unit's file or is created by the unit itself. It does not search for the icon
* through the mechset.
*
* @implNote The default implementation returns null. For canon units, this will return null, as they
* do not store icon images in the unit files.
*
* @return An icon for this object/unit if it contains one as part of the object/unit
*/
default @Nullable Image getIcon() {
return null;
}
}
29 changes: 29 additions & 0 deletions megamek/src/megamek/common/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import megamek.MMConstants;
import megamek.client.bot.princess.FireControl;
import megamek.client.ui.Base64Image;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.calculationReport.CalculationReport;
import megamek.client.ui.swing.calculationReport.DummyCalculationReport;
Expand Down Expand Up @@ -829,6 +830,9 @@ public abstract class Entity extends TurnOrdered implements Transporter, Targeta
*/
protected ArrayList<WeaponAttackAction> incomingGuidedAttacks;

/** The icon for this unit; This is empty unless the unit file has an embedded icon. */
protected Base64Image icon = new Base64Image();

/**
* Generates a new, blank, entity.
*/
Expand Down Expand Up @@ -15820,6 +15824,31 @@ public String specificName() {
return getModel();
}

@Override
public Image getIcon() {
return icon.getImage();
}

/** Sets the embedded icon for this unit to the given base64 string. */
public void setIcon(String icon64) {
icon = new Base64Image(icon64);
}

/**
* Returns true when this unit has an embedded icon, i.e. an icon stored in the unit file rather than
* found by the mechset. Currently returns false when a mode-specific icon is needed (LAMs/QVs)
*
* @return True when this unit has an embedded icon
*/
public boolean hasEmbeddedIcon() {
return !icon.isEmpty() && getTilesetModeString().isBlank();
}

/** @return The embedded icon of this unit in the full Base64Image form. */
public Base64Image getBase64Icon() {
return icon;
}

@Override
public boolean countForStrengthSum() {
return !isDestroyed() && !isTrapped() && !isPartOfFighterSquadron();
Expand Down
7 changes: 7 additions & 0 deletions megamek/src/megamek/common/Mech.java
Original file line number Diff line number Diff line change
Expand Up @@ -4463,6 +4463,13 @@ public String getMtf() {
sb.append(newLine);
}

if (!icon.isEmpty()) {
sb.append(newLine);
sb.append(MtfFile.ICON);
sb.append(icon.getBase64String());
sb.append(newLine);
}

if (getFluff().hasEmbeddedFluffImage()) {
sb.append(newLine);
sb.append(MtfFile.FLUFF_IMAGE);
Expand Down
10 changes: 10 additions & 0 deletions megamek/src/megamek/common/icons/Camouflage.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ public Camouflage() {
public Camouflage(final @Nullable String category, final @Nullable String filename) {
super(category, filename);
}

/**
* Returns a new camo of the given PlayerColour.
*
* @param color A PlayerColour
* @return A camo of the given PlayerColour color
*/
public static Camouflage of(PlayerColour color) {
return new Camouflage(COLOUR_CAMOUFLAGE, color.name());
}
//endregion Constructors

//region Boolean Methods
Expand Down
8 changes: 8 additions & 0 deletions megamek/src/megamek/common/loaders/BLKFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ protected void setBasicEntityData(Entity entity) throws EntityLoadingException {
entity.getFluff().setFluffImage(dataFile.getDataAsString("fluffimage")[0]);
}

if (dataFile.exists("icon")) {
entity.setIcon(dataFile.getDataAsString("icon")[0]);
}

setTechLevel(entity);
setFluff(entity);
checkManualBV(entity);
Expand Down Expand Up @@ -1166,6 +1170,10 @@ public static BuildingBlock getBlock(Entity t) {
blk.writeBlockData("escape_pod", js.getEscapePods());
}

if (t.hasEmbeddedIcon()) {
blk.writeBlockData("icon", t.getBase64Icon().getBase64String());
}

if (t.getFluff().hasEmbeddedFluffImage()) {
blk.writeBlockData("fluffimage", t.getFluff().getBase64FluffImage().getBase64String());
}
Expand Down
9 changes: 8 additions & 1 deletion megamek/src/megamek/common/loaders/MtfFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ public class MtfFile implements IMechLoader {
private final Map<EntityFluff.System, String> systemManufacturers = new EnumMap<>(EntityFluff.System.class);
private final Map<EntityFluff.System, String> systemModels = new EnumMap<>(EntityFluff.System.class);
private String notes = "";
private String imagePath = "";

private String fluffImageEncoded = "";
private String iconEncoded = "";

private int bv = 0;
private String role;
Expand Down Expand Up @@ -146,6 +146,7 @@ public class MtfFile implements IMechLoader {
public static final String WEAPON_QUIRK = "weaponquirk:";
public static final String ROLE = "role:";
public static final String FLUFF_IMAGE = "fluffimage:";
public static final String ICON = "icon:";

public MtfFile(InputStream is) throws EntityLoadingException {
try (InputStreamReader isr = new InputStreamReader(is);
Expand Down Expand Up @@ -463,6 +464,7 @@ public Entity getEntity() throws Exception {
mech.getFluff().setPrimaryFactory(primaryFactory);
mech.getFluff().setNotes(notes);
mech.getFluff().setFluffImage(fluffImageEncoded);
mech.setIcon(iconEncoded);
systemManufacturers.forEach((k, v) -> mech.getFluff().setSystemManufacturer(k, v));
systemModels.forEach((k, v) -> mech.getFluff().setSystemModel(k, v));

Expand Down Expand Up @@ -1262,6 +1264,11 @@ private boolean isProcessedComponent(String line) {
return true;
}

if (lineLower.startsWith(ICON)) {
iconEncoded = line.substring(ICON.length());
return true;
}

if (lineLower.startsWith(QUIRK) || lineLower.startsWith(WEAPON_QUIRK)) {
quirkLines.add(line);
return true;
Expand Down
8 changes: 6 additions & 2 deletions megamek/src/megamek/common/util/ImageUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,13 @@ public boolean isAnimated() {
}

/**
* takes an image and converts it to text in the Base64 encoding.
* takes an image and converts it to text in the Base64 encoding. When the given image is null, an
* empty String is returned.
*/
public static String base64TextEncodeImage(Image image) {
public static String base64TextEncodeImage(@Nullable Image image) {
if (image == null) {
return "";
}
BufferedImage bufferedImage = convertToBufferedImage(image);
String base64Text;

Expand Down

0 comments on commit 953e0df

Please sign in to comment.