Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the Automatic Tracking of Award Eligibility and Additional Award Enhancements #4008

Merged
merged 75 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
0c5b682
Completed Award Controller framework and hooked it into the end of Mi…
IllianiCBT Apr 11, 2024
06895b9
Added better filtering out of Prisoners and Dependents; improved docu…
IllianiCBT Apr 11, 2024
5d448a2
Added requested additional functionality to Skill Awards
IllianiCBT Apr 12, 2024
d1ef51f
Further improvements to Skill Awards, added InjuryAwards.java
IllianiCBT Apr 12, 2024
a7946f0
Refactored Skill Awards
IllianiCBT Apr 15, 2024
7064188
Fixed missing break in switch case
IllianiCBT Apr 15, 2024
5508d53
Removed MissionAccomplishedAwards.java and moved functionality to Mis…
IllianiCBT Apr 15, 2024
379939d
Refactoring and adding support for Rank Awards
IllianiCBT Apr 15, 2024
bbabdd2
Refactoring and adding support for Time in Service Awards
IllianiCBT Apr 15, 2024
a30a011
Refactoring and added support for Contract Awards
IllianiCBT Apr 16, 2024
a9e3ff8
Refactoring and added support for Theatre of War awards
IllianiCBT Apr 16, 2024
dab7e57
Fixed typo
IllianiCBT Apr 16, 2024
09b90a1
Refactoring, improved functionality for Theatre of War Awards
IllianiCBT Apr 16, 2024
e110ffa
Refactoring
IllianiCBT Apr 16, 2024
eaabd8e
Refactoring & added support for Faction Hunter Awards
IllianiCBT Apr 16, 2024
7adc92a
Refactoring
IllianiCBT Apr 16, 2024
8ac45af
Refactoring and remaining award work
IllianiCBT Apr 17, 2024
f7f67b2
Merge branch 'MegaMek:master' into AutoMedals
IllianiCBT Apr 17, 2024
7b8e6ce
Added missing checks mandated by Github
IllianiCBT Apr 17, 2024
998b4d2
Merge remote-tracking branch 'origin/AutoMedals' into AutoMedals
IllianiCBT Apr 17, 2024
233438c
Merge branch 'MegaMek:master' into AutoMedals
IllianiCBT Apr 18, 2024
90819fe
Refactoring and added support for Scenario Kill Awards
IllianiCBT Apr 18, 2024
4fe542a
Refactoring and added support for Injury Awards
IllianiCBT Apr 18, 2024
434848a
Removed InjuryAwards.java
IllianiCBT Apr 18, 2024
ad9bea8
Adjustments following GitHub feedback
IllianiCBT Apr 18, 2024
a7dd9b3
Refactoring & initial phase two functionality
IllianiCBT Apr 19, 2024
a540afc
Typos caught by Github
IllianiCBT Apr 19, 2024
487fc8d
Refactoring and added support for 'Only issue the best award' Campaig…
IllianiCBT Apr 19, 2024
2401ef8
Refactoring and remaining Phase Two functionality
IllianiCBT Apr 19, 2024
cd65770
Bug fixes
IllianiCBT Apr 20, 2024
2536bd6
More bug fixes
IllianiCBT Apr 20, 2024
f0a8b70
Final refactoring in prep for Phase 3 development
IllianiCBT Apr 20, 2024
edae73b
Added initial GUI support
IllianiCBT Apr 21, 2024
647bb9b
Refactoring and GUI support for Kill Awards(General)
IllianiCBT Apr 22, 2024
9354067
Fixed infinite loop in TOE reading tech
IllianiCBT Apr 22, 2024
e390a7c
Mass rollout of GUI support
IllianiCBT Apr 22, 2024
10ce719
Fixed really nasty bug
IllianiCBT Apr 23, 2024
43e9f46
Split Kill campaign option into individual and formation
IllianiCBT Apr 23, 2024
79c0908
Final GUI functionality, & added the ability to ignore the standard set
IllianiCBT Apr 23, 2024
e767635
Added Toggle All buttons to Award Ceremony
IllianiCBT Apr 23, 2024
709d9c7
Added the ability to assign multiple award image tiers to Awards
IllianiCBT Apr 23, 2024
4f1e328
Added support for wide and square award images
IllianiCBT Apr 23, 2024
7376998
Bug fixes & refactoring
IllianiCBT Apr 23, 2024
89af65f
Rolled back faulty multiple award image functionality
IllianiCBT Apr 24, 2024
f36e2ad
Restored previously faulty code
IllianiCBT Apr 24, 2024
b525d16
Added ability to run autoAwards manually
IllianiCBT Apr 24, 2024
bb8025e
Reorganized the Standard Set
IllianiCBT Apr 24, 2024
ed6437a
Remaining Phase Three functionality
IllianiCBT Apr 24, 2024
14d2f2b
Removed unused tag precedence from the Standard Set
IllianiCBT Apr 24, 2024
c3fc84f
Final update
IllianiCBT Apr 24, 2024
d12e207
Merge remote-tracking branch 'origin/AutoMedals' into AutoMedals
IllianiCBT Apr 24, 2024
1772ba1
Fixing bad merge
IllianiCBT Apr 24, 2024
4f05df5
Merge branch 'MegaMek:master' into AutoMedals
IllianiCBT Apr 24, 2024
038e269
Merge remote-tracking branch 'origin/AutoMedals' into AutoMedals
IllianiCBT Apr 24, 2024
5441b10
Removed errant TODOs
IllianiCBT Apr 24, 2024
27fdba3
Delete .gitignore
IllianiCBT Apr 24, 2024
ed8271d
Remove unnecessary award attributes in XML. Fixed bug with Ignore Sta…
IllianiCBT Apr 24, 2024
f616aba
Merge remote-tracking branch 'origin/AutoMedals' into AutoMedals
IllianiCBT Apr 24, 2024
cf49c23
Revert "Delete .gitignore"
IllianiCBT Apr 24, 2024
d7a4a94
Turns out I shouldn't have deleted .gitignore from within GitHub. Thi…
IllianiCBT Apr 24, 2024
69dc2df
Removed remaining size and range from Awards with the Ignore tag
IllianiCBT Apr 24, 2024
e2bb805
Merge branch 'master' into AutoMedals
IllianiCBT May 15, 2024
8ebeadb
Refactored auto award files and remove redundant comments
IllianiCBT May 15, 2024
dd906fd
Rolled back awards image picker in PersonViewPanel
IllianiCBT May 15, 2024
b0579cb
Restored Award Guides moving them to Archive Docs
IllianiCBT May 15, 2024
41e1cd5
Added 'group' field to Award class and implemented in UI
IllianiCBT May 15, 2024
b3bbe64
Update Award constructor and cleanup PersonnelTableMouseAdapter
IllianiCBT May 15, 2024
f377f91
Updated group award names and refactored handling of "group" awards
IllianiCBT May 15, 2024
0862b6d
Add compatibility handler for "Standard" award set
IllianiCBT May 15, 2024
df81fd7
Updated award group labels and implement standard set ignore option
IllianiCBT May 15, 2024
96c837a
Added additional Misc Award handling
IllianiCBT May 15, 2024
475d829
Updated documentation
IllianiCBT May 15, 2024
7c3d731
Add exception handling to MedalOfHonor method
IllianiCBT May 15, 2024
28934c9
Merge branch 'master' into AutoMedals
IllianiCBT May 16, 2024
843c8c4
Merge branch 'master' into AutoMedals
IllianiCBT May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
168 changes: 84 additions & 84 deletions MekHQ/data/universe/awards/standard.xml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions MekHQ/resources/mekhq/resources/AutoAwards.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
EligibleForAwardReport.format=is eligible for the {0} award from the [{1}] set.
EligibleForAwardReportAll.format=All active personnel are eligible for the {0} award from the [{1}] set.
14 changes: 14 additions & 0 deletions MekHQ/src/mekhq/campaign/ResolveScenarioTracker.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import mekhq.campaign.parts.Armor;
import mekhq.campaign.parts.Part;
import mekhq.campaign.personnel.Person;
import mekhq.campaign.personnel.autoAwards.AutoAwardsPostScenarioController;
import mekhq.campaign.personnel.enums.PersonnelStatus;
import mekhq.campaign.personnel.enums.PrisonerStatus;
import mekhq.campaign.unit.TestUnit;
Expand Down Expand Up @@ -1413,6 +1414,7 @@ public void resolveScenario(ScenarioStatus resolution, String report) {
for (Kill k : status.getKills()) {
getCampaign().addKill(k);
}

if (status.isMissing()) {
person.changeStatus(getCampaign(), getCampaign().getLocalDate(), PersonnelStatus.MIA);
} else if (status.isDead()) {
Expand All @@ -1430,6 +1432,18 @@ public void resolveScenario(ScenarioStatus resolution, String report) {
if (status.toRemove()) {
getCampaign().removePerson(person, false);
}

// TODO add Posthumous Awards to Campaign Options
boolean fakeCampaignOptionPosthumousAwardsIsEnabled = false;
if (!person.getStatus().isDead() || fakeCampaignOptionPosthumousAwardsIsEnabled) {
int injuryCount = 0;

if (status.getHits() > person.getHits()) {
injuryCount = status.getHits() - person.getHits();
}

new AutoAwardsPostScenarioController(campaign, scenario.getId(), person, injuryCount);
}
}

//region Prisoners
Expand Down
86 changes: 70 additions & 16 deletions MekHQ/src/mekhq/campaign/force/Force.java
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ public Vector<UUID> getAllUnits(boolean combatForcesOnly) {
/**
* Add a unit id to the units vector. In general, this
* should not be called directly to add unid because they will
* not be assigned a force id. Use {@link Campaign#addUnitToForce(mekhq.campaign.unit.Unit, int)}
* not be assigned a force id. Use {@link Campaign#addUnitToForce(Unit, int)}
* instead
* @param uid
*/
Expand All @@ -311,12 +311,12 @@ public void addUnit(Campaign campaign, UUID uid, boolean useTransfers, Force old
}
}
}

updateCommander(campaign);
}

/**
* This should not be directly called except by {@link Campaign#removeUnitFromForce(mekhq.campaign.unit.Unit)}
* This should not be directly called except by {@link Campaign#removeUnitFromForce(Unit)}
* instead
* @param id
*/
Expand All @@ -341,7 +341,7 @@ public void removeUnit(Campaign campaign, UUID id, boolean log) {
}
}
}

updateCommander(campaign);
}
}
Expand Down Expand Up @@ -384,27 +384,27 @@ public int getId() {
public void setId(int i) {
this.id = i;
}

public UUID getForceCommanderID() {
return forceCommanderID;
}

public void setForceCommanderID(UUID commanderID) {
forceCommanderID = commanderID;
}

public List<UUID> getEligibleCommanders(Campaign c) {
List<UUID> people = new ArrayList<>();
Person highestRankPerson = c.getPerson(getForceCommanderID());
// safety check: if the person is no longer assigned to a unit or the force,

// safety check: if the person is no longer assigned to a unit or the force,
// then they're not really the highest ranked person in the force.
if ((highestRankPerson != null) &&
if ((highestRankPerson != null) &&
((highestRankPerson.getUnit() == null) ||
(!getUnits().contains(highestRankPerson.getUnit().getId())))) {
highestRankPerson = null;
}

for (UUID uid : getUnits()) {
Unit u = c.getUnit(uid);
if (null != u) {
Expand All @@ -425,23 +425,23 @@ public List<UUID> getEligibleCommanders(Campaign c) {
}
}
}

return people;
}

/**
* Automatically update the force's commander
*/
public void updateCommander(Campaign c) {
List<UUID> eligibleCommanders = getEligibleCommanders(c);

// logic: if we found someone eligible who is a higher rank, the first one of those becomes the new commander
// otherwise, the existing commander remains the commander
if (!eligibleCommanders.contains(getForceCommanderID()) && (eligibleCommanders.size() > 0)) {
forceCommanderID = eligibleCommanders.get(0);
}
}

public void removeSubForce(int id) {
int idx = 0;
boolean found = false;
Expand Down Expand Up @@ -605,7 +605,7 @@ public void writeToXML(PrintWriter pw1, int indent) {
} else if (version.isLowerThan("0.49.7")) {
retVal.setForceIcon(ForceIconMigrator.migrateForceIcon0496To0497(retVal.getForceIcon()));
}

retVal.updateCommander(c);

return retVal;
Expand Down Expand Up @@ -713,4 +713,58 @@ public int getPrimaryUnitType(Campaign c) {

return biggestBucketID;
}


/**
* Finds the distance (depth) from the origin force
* @param force the force to get depth for
*/
public static int getDepth(Force force) {
int depth = 0;

Force parent = force.getParentForce();

if (parent != null) {
depth++;

while (parent != null) {
parent = force.getParentForce();

if (parent != null) {
depth++;
}
}
}

return depth;
}

/**
* Uses a recursive search to find the maximum distance (depth) from the origin force
* @param force the current force. Should always equal campaign.getForce(0), if called remotely
* @param depth the current recursive depth. Can be left null, if called remotely
*/
public static int getMaximumDepth(Force force, @Nullable Integer depth) {
Vector<Force> subforces = force.getSubForces();

if (depth == null) {
depth = 0;
}

int maximumDepth;
int nextDepth;

if (subforces.isEmpty()) {
return depth;
} else {
maximumDepth = depth;
for (Force subforce: subforces) {
nextDepth = getMaximumDepth(subforce, depth + 1);
if (nextDepth > maximumDepth) {
maximumDepth = nextDepth;
}
}
}
return maximumDepth;
}
}
42 changes: 39 additions & 3 deletions MekHQ/src/mekhq/campaign/personnel/Award.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ public class Award implements Comparable<Award> {
@XmlElement(name = "edge")
private int edge = 0;

@XmlElement(name = "qty")
private int qty;

@XmlElement(name = "item")
private String item;

@XmlElement(name = "size")
private String size;

@XmlElement(name = "range")
private String range;

@XmlElement(name = "stackable")
private boolean stackable = false;

Expand All @@ -72,7 +84,7 @@ public Award() {
}

public Award(String name, String set, String description, List<String> medals, List<String> ribbons,
List<String> miscs, int xp, int edge, boolean stackable, int id) {
List<String> miscs, int xp, int edge, boolean stackable, int qty, String item, String size, String range, int id) {
this.name = name;
this.set = set;
this.description = description;
Expand All @@ -81,6 +93,10 @@ public Award(String name, String set, String description, List<String> medals,
this.miscs = miscs;
this.xp = xp;
this.edge = edge;
this.qty = qty;
this.item = item;
this.size = size;
this.range = range;
this.stackable = stackable;
dates = new ArrayList<>();
this.id = id;
Expand Down Expand Up @@ -125,6 +141,26 @@ public String getDescription() {
return description;
}

/**
* Returns the xml element 'qty'
* Use getQuantity() if looking for the number of times an award has been issued to an individual
*/
public int getQty() {
return qty;
}

public String getItem() {
return item;
}

public String getSize() {
return size;
}

public String getRange() {
return range;
}

/**
* Gets the file name of an award given i times.
* @param i times given the award
Expand Down Expand Up @@ -189,7 +225,7 @@ public int getEdgeReward() {
*/
public Award createCopy() {
return new Award(this.name, this.set, this.description, this.medals, this.ribbons, this.miscs,
this.xp, this.edge, this.stackable, this.id);
this.xp, this.edge, this.stackable, this.qty, this.item, this.size, this.range, this.id);
}

/**
Expand Down Expand Up @@ -284,7 +320,7 @@ public boolean hasDates() {
}

/**
* @return the number of times this award has been awarded to the person.
* @return the number of times this award has been awarded.
*/
public int getQuantity() {
return dates.size();
Expand Down