Skip to content

Commit cc3c220

Browse files
authored
Merge pull request #6562 from IllianiCBT/immersiveUpdate
Fixed Campaign Portrait Fallback; Updated Immersive Dialog Visuals
2 parents e0228d6 + e0ebe3a commit cc3c220

File tree

4 files changed

+56
-31
lines changed

4 files changed

+56
-31
lines changed

MekHQ/src/mekhq/campaign/Campaign.java

+25-21
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,6 @@
161161
import mekhq.campaign.personnel.Person;
162162
import mekhq.campaign.personnel.PersonnelOptions;
163163
import mekhq.campaign.personnel.RandomDependents;
164-
import mekhq.campaign.personnel.skills.Skill;
165-
import mekhq.campaign.personnel.skills.SkillType;
166164
import mekhq.campaign.personnel.SpecialAbility;
167165
import mekhq.campaign.personnel.autoAwards.AutoAwardsController;
168166
import mekhq.campaign.personnel.death.RandomDeath;
@@ -1930,8 +1928,8 @@ public Person newPerson(final PersonnelRole primaryRole, final String factionCod
19301928
* @return A new {@link Person}.
19311929
*/
19321930
public Person newPerson(final PersonnelRole primaryRole, final PersonnelRole secondaryRole,
1933-
final AbstractFactionSelector factionSelector, final AbstractPlanetSelector planetSelector,
1934-
final Gender gender) {
1931+
final AbstractFactionSelector factionSelector, final AbstractPlanetSelector planetSelector,
1932+
final Gender gender) {
19351933
return newPerson(primaryRole, secondaryRole, getPersonnelGenerator(factionSelector, planetSelector), gender);
19361934
}
19371935

@@ -1958,7 +1956,7 @@ public Person newPerson(final PersonnelRole primaryRole, final AbstractPersonnel
19581956
* @return A new {@link Person} configured using {@code personnelGenerator}.
19591957
*/
19601958
public Person newPerson(final PersonnelRole primaryRole, final PersonnelRole secondaryRole,
1961-
final AbstractPersonnelGenerator personnelGenerator, final Gender gender) {
1959+
final AbstractPersonnelGenerator personnelGenerator, final Gender gender) {
19621960
final Person person = personnelGenerator.generate(this, primaryRole, secondaryRole, gender);
19631961

19641962
// Assign a random portrait after we generate a new person
@@ -2320,17 +2318,20 @@ public void checkBloodnameAdd(Person person, boolean ignoreDice) {
23202318
switch (person.getPrimaryRole()) {
23212319
case GROUND_VEHICLE_DRIVER:
23222320
bloodnameTarget += person.hasSkill(SkillType.S_PILOT_GVEE) ?
2323-
person.getSkill(SkillType.S_PILOT_GVEE).getFinalSkillValue(options) :
2321+
person.getSkill(SkillType.S_PILOT_GVEE)
2322+
.getFinalSkillValue(options) :
23242323
TargetRoll.AUTOMATIC_FAIL;
23252324
break;
23262325
case NAVAL_VEHICLE_DRIVER:
23272326
bloodnameTarget += person.hasSkill(SkillType.S_PILOT_NVEE) ?
2328-
person.getSkill(SkillType.S_PILOT_NVEE).getFinalSkillValue(options) :
2327+
person.getSkill(SkillType.S_PILOT_NVEE)
2328+
.getFinalSkillValue(options) :
23292329
TargetRoll.AUTOMATIC_FAIL;
23302330
break;
23312331
case VTOL_PILOT:
23322332
bloodnameTarget += person.hasSkill(SkillType.S_PILOT_VTOL) ?
2333-
person.getSkill(SkillType.S_PILOT_VTOL).getFinalSkillValue(options) :
2333+
person.getSkill(SkillType.S_PILOT_VTOL)
2334+
.getFinalSkillValue(options) :
23342335
TargetRoll.AUTOMATIC_FAIL;
23352336
break;
23362337
default:
@@ -2371,7 +2372,8 @@ public void checkBloodnameAdd(Person person, boolean ignoreDice) {
23712372
case VESSEL_NAVIGATOR:
23722373
bloodnameTarget += 2 *
23732374
(person.hasSkill(SkillType.S_NAV) ?
2374-
person.getSkill(SkillType.S_NAV).getFinalSkillValue(options) :
2375+
person.getSkill(SkillType.S_NAV)
2376+
.getFinalSkillValue(options) :
23752377
TargetRoll.AUTOMATIC_FAIL);
23762378
break;
23772379
default:
@@ -2654,7 +2656,7 @@ public AbstractPlanetSelector getPlanetSelector(final RandomOriginOptions option
26542656
* @return An {@link AbstractPersonnelGenerator} to use when creating new personnel.
26552657
*/
26562658
public AbstractPersonnelGenerator getPersonnelGenerator(final AbstractFactionSelector factionSelector,
2657-
final AbstractPlanetSelector planetSelector) {
2659+
final AbstractPlanetSelector planetSelector) {
26582660
final DefaultPersonnelGenerator generator = new DefaultPersonnelGenerator(factionSelector, planetSelector);
26592661
generator.setNameGenerator(RandomNameGenerator.getInstance());
26602662
generator.setSkillPreferences(getRandomSkillPreferences());
@@ -2829,7 +2831,7 @@ private int getDefaultStockPercent(Part part) {
28292831
* @param ignoreSparesUnderQuality spares with a quality lower than this threshold are excluded from counting.
28302832
*/
28312833
private void updatePartInUseData(PartInUse partInUse, Part incomingPart, boolean ignoreMothballedUnits,
2832-
PartQuality ignoreSparesUnderQuality) {
2834+
PartQuality ignoreSparesUnderQuality) {
28332835
Unit unit = incomingPart.getUnit();
28342836
if (unit != null) {
28352837
// Ignore conventional infantry
@@ -2875,7 +2877,7 @@ private void updatePartInUseData(PartInUse partInUse, Part incomingPart, boolean
28752877
* @param ignoreSparesUnderQuality don't count spare parts lower than this quality
28762878
*/
28772879
public void updatePartInUse(PartInUse partInUse, boolean ignoreMothballedUnits,
2878-
PartQuality ignoreSparesUnderQuality) {
2880+
PartQuality ignoreSparesUnderQuality) {
28792881
partInUse.setUseCount(0);
28802882
partInUse.setStoreCount(0);
28812883
partInUse.setTransferCount(0);
@@ -2932,7 +2934,7 @@ public void updatePartInUse(PartInUse partInUse, boolean ignoreMothballedUnits,
29322934
*/
29332935

29342936
public Set<PartInUse> getPartsInUse(boolean ignoreMothballedUnits, boolean isResupply,
2935-
PartQuality ignoreSparesUnderQuality) {
2937+
PartQuality ignoreSparesUnderQuality) {
29362938
// java.util.Set doesn't supply a get(Object) method, so we have to use a
29372939
// java.util.Map
29382940
Map<PartInUse, PartInUse> inUse = new HashMap<>();
@@ -3290,7 +3292,8 @@ public TargetRoll getTargetFor(Person medWork, Person doctor) {
32903292
if (getPatientsFor(doctor) > 25) {
32913293
return new TargetRoll(TargetRoll.IMPOSSIBLE, doctor.getFullName() + " already has 25 patients.");
32923294
}
3293-
TargetRoll target = new TargetRoll(skill.getFinalSkillValue(doctor.getOptions()), skill.getSkillLevel().toString());
3295+
TargetRoll target = new TargetRoll(skill.getFinalSkillValue(doctor.getOptions()),
3296+
skill.getSkillLevel().toString());
32943297
if (target.getValue() == TargetRoll.IMPOSSIBLE) {
32953298
return target;
32963299
}
@@ -3789,7 +3792,7 @@ public boolean canPayFor(IAcquisitionWork acquisition) {
37893792
* @return The result of the rolls.
37903793
*/
37913794
public PartAcquisitionResult findContactForAcquisition(IAcquisitionWork acquisition, Person person,
3792-
PlanetarySystem system) {
3795+
PlanetarySystem system) {
37933796
TargetRoll target = getTargetForAcquisition(acquisition, person);
37943797

37953798
String impossibleSentencePrefix = person == null ?
@@ -3900,7 +3903,7 @@ public boolean acquireEquipment(IAcquisitionWork acquisition, Person person) {
39003903
* successful.
39013904
*/
39023905
private boolean acquireEquipment(IAcquisitionWork acquisition, Person person, PlanetarySystem system,
3903-
int transitDays) {
3906+
int transitDays) {
39043907
boolean found = false;
39053908
String report = "";
39063909

@@ -6322,7 +6325,7 @@ public void removeFunds(final TransactionType type, final Money quantity, @Nulla
63226325
* @param individualPayouts Map of Person to the Money they're owed
63236326
*/
63246327
public void payPersonnel(TransactionType type, Money quantity, String description,
6325-
Map<Person, Money> individualPayouts) {
6328+
Map<Person, Money> individualPayouts) {
63266329
getFinances().debit(type,
63276330
getLocalDate(),
63286331
quantity,
@@ -7456,7 +7459,7 @@ public TargetRoll getTargetForAcquisition(final IAcquisitionWork acquisition, fi
74567459
* an impossible/automatic result under specific circumstances.
74577460
*/
74587461
public TargetRoll getTargetForAcquisition(final IAcquisitionWork acquisition, final @Nullable Person person,
7459-
final boolean checkDaysToWait) {
7462+
final boolean checkDaysToWait) {
74607463
if (getCampaignOptions().getAcquisitionSkill().equals(S_AUTO)) {
74617464
return new TargetRoll(TargetRoll.AUTOMATIC_SUCCESS, "Automatic Success");
74627465
}
@@ -7489,7 +7492,8 @@ public TargetRoll getTargetForAcquisition(final IAcquisitionWork acquisition, fi
74897492
return new TargetRoll(TargetRoll.IMPOSSIBLE, "It is extinct!");
74907493
}
74917494

7492-
TargetRoll target = new TargetRoll(skill.getFinalSkillValue(person.getOptions()), skill.getSkillLevel().toString());
7495+
TargetRoll target = new TargetRoll(skill.getFinalSkillValue(person.getOptions()),
7496+
skill.getSkillLevel().toString());
74937497
target.append(acquisition.getAllAcquisitionMods());
74947498

74957499
if (getCampaignOptions().isUseAtB() && getCampaignOptions().isRestrictPartsByMission()) {
@@ -8712,7 +8716,7 @@ public Set<Unit> getTransportsByType(CampaignTransportType campaignTransportType
87128716
* @return units that have that transport type
87138717
*/
87148718
public Set<Unit> getTransportsByType(CampaignTransportType campaignTransportType, TransporterType transporterType,
8715-
double unitSize) {
8719+
double unitSize) {
87168720
return Objects.requireNonNull(getCampaignTransporterMap(campaignTransportType))
87178721
.getTransportsByType(transporterType, unitSize);
87188722
}
@@ -9540,7 +9544,7 @@ public ImageIcon getCampaignFactionIcon() {
95409544
if (campaignIcon.getFilename() == null) {
95419545
icon = getFactionLogo(this, getFaction().getShortName(), true);
95429546
} else {
9543-
icon = new ImageIcon(campaignIcon.getFilename());
9547+
icon = campaignIcon.getImageIcon();
95449548
}
95459549
return icon;
95469550
}

MekHQ/src/mekhq/gui/baseComponents/immersiveDialogs/ImmersiveDialogCore.java

+25-3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import static megamek.client.ui.WrapLayout.wordWrap;
3434
import static megamek.client.ui.swing.util.FlatLafStyleBuilder.setFontScaling;
3535
import static megamek.client.ui.swing.util.UIUtil.scaleForGUI;
36+
import static megamek.common.icons.Portrait.DEFAULT_PORTRAIT_FILENAME;
3637
import static mekhq.campaign.force.Force.FORCE_NONE;
3738
import static mekhq.utilities.ImageUtilities.scaleImageIcon;
3839
import static mekhq.utilities.MHQInternationalization.getFormattedTextAt;
@@ -42,17 +43,21 @@
4243
import java.awt.Dimension;
4344
import java.awt.GridBagConstraints;
4445
import java.awt.GridBagLayout;
46+
import java.awt.Image;
4547
import java.awt.Insets;
4648
import java.awt.Point;
4749
import java.awt.Toolkit;
50+
import java.awt.image.ImageObserver;
4851
import java.util.ArrayList;
4952
import java.util.List;
53+
import java.util.Objects;
5054
import java.util.UUID;
5155
import javax.swing.*;
5256
import javax.swing.event.HyperlinkEvent;
5357
import javax.swing.event.HyperlinkEvent.EventType;
5458

5559
import megamek.common.annotations.Nullable;
60+
import megamek.common.icons.Portrait;
5661
import megamek.logging.MMLogger;
5762
import mekhq.campaign.Campaign;
5863
import mekhq.campaign.force.Force;
@@ -82,7 +87,7 @@ public class ImmersiveDialogCore extends JDialog {
8287
private int CENTER_WIDTH = scaleForGUI(400);
8388

8489
private final int PADDING = scaleForGUI(5);
85-
protected final int IMAGE_WIDTH = 250; // This is scaled to GUI by 'scaleImageIconToWidth'
90+
protected static final int IMAGE_WIDTH = scaleForGUI(200);
8691

8792
private JPanel northPanel;
8893
private JPanel southPanel;
@@ -600,7 +605,7 @@ protected JPanel buildSpeakerPanel(@Nullable Person speaker, Campaign campaign)
600605
JPanel speakerBox = new JPanel();
601606
speakerBox.setLayout(new BoxLayout(speakerBox, BoxLayout.Y_AXIS));
602607
speakerBox.setAlignmentX(Component.CENTER_ALIGNMENT);
603-
speakerBox.setMaximumSize(scaleForGUI(IMAGE_WIDTH, MAX_VALUE));
608+
speakerBox.setMaximumSize(new Dimension(IMAGE_WIDTH, scaleForGUI(MAX_VALUE)));
604609

605610
// Get speaker details
606611
String speakerName = campaign.getName();
@@ -704,7 +709,24 @@ public static StringBuilder getSpeakerDescription(Campaign campaign, Person spea
704709
return campaign.getCampaignFactionIcon();
705710
}
706711

707-
return speaker.getPortrait().getImageIcon();
712+
Portrait portrait = speaker.getPortrait();
713+
714+
if (portrait == null || Objects.equals(portrait.getFilename(), DEFAULT_PORTRAIT_FILENAME)) {
715+
return campaign.getCampaignFactionIcon();
716+
}
717+
718+
// The following sorcery is due to the compressed manner in which personnel portraits are stored.
719+
// We need to manipulate the original base image, otherwise it looks grainy and terrible.
720+
ImageObserver observer = (img, infoFlags, x, y, width, height) -> true;
721+
722+
Image baseImage = portrait.getBaseImage();
723+
int baseImageHeight = baseImage.getHeight(observer);
724+
int baseImageWidth = baseImage.getWidth(observer);
725+
int targetWidth = Math.max(1, IMAGE_WIDTH);
726+
727+
int height = (int) Math.ceil((double) targetWidth * baseImageHeight / baseImageWidth);
728+
729+
return new ImageIcon(baseImage.getScaledInstance(targetWidth, height, Image.SCALE_SMOOTH));
708730
}
709731

710732
/**

MekHQ/src/mekhq/gui/baseComponents/immersiveDialogs/ImmersiveDialogNag.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public static DialogChoice fromIndex(int choiceIndex) {
113113
* messages from the resource bundle.
114114
*/
115115
public ImmersiveDialogNag(final Campaign campaign, final @Nullable AdministratorSpecialization specialization,
116-
final String nagConstant, final String messageKey) {
116+
final String nagConstant, final String messageKey) {
117117
ImmersiveDialogCore dialog = constructDialog(campaign, specialization, messageKey);
118118
processDialogChoice(dialog.getDialogChoice(), nagConstant);
119119
}
@@ -135,7 +135,7 @@ public ImmersiveDialogNag(final Campaign campaign, final @Nullable Administrator
135135
* button labels.
136136
*/
137137
protected ImmersiveDialogCore constructDialog(Campaign campaign, AdministratorSpecialization specialization,
138-
String messageKey) {
138+
String messageKey) {
139139
return new ImmersiveDialogCore(campaign,
140140
getSpeaker(campaign, specialization),
141141
null,
@@ -145,7 +145,7 @@ protected ImmersiveDialogCore constructDialog(Campaign campaign, AdministratorSp
145145
null,
146146
true,
147147
null,
148-
campaign.getCampaignFactionIcon(),
148+
null,
149149
true);
150150
}
151151

MekHQ/src/mekhq/gui/baseComponents/immersiveDialogs/ImmersiveDialogSimple.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,8 @@ public class ImmersiveDialogSimple extends ImmersiveDialogCore {
8080
* buttons are stacked vertically; otherwise, they are arranged side-by-side.
8181
*/
8282
public ImmersiveDialogSimple(Campaign campaign, @Nullable Person leftSpeaker, @Nullable Person rightSpeaker,
83-
String centerMessage, @Nullable List<String> buttonLabels,
84-
@Nullable String outOfCharacterMessage, @Nullable ImageIcon imageIcon,
85-
boolean useVerticalLayout) {
83+
String centerMessage, @Nullable List<String> buttonLabels, @Nullable String outOfCharacterMessage,
84+
@Nullable ImageIcon imageIcon, boolean useVerticalLayout) {
8685
super(campaign,
8786
leftSpeaker,
8887
rightSpeaker,
@@ -92,7 +91,7 @@ public ImmersiveDialogSimple(Campaign campaign, @Nullable Person leftSpeaker, @N
9291
null,
9392
useVerticalLayout,
9493
null,
95-
imageIcon == null ? campaign.getCampaignFactionIcon() : imageIcon,
94+
imageIcon,
9695
true);
9796
}
9897

0 commit comments

Comments
 (0)