Skip to content

Commit e67abf1

Browse files
authored
Merge pull request #6552 from IllianiCBT/atowAttributes
Added ATOW Attribute Tracking and Utility Methods
2 parents 920533a + 13f9ada commit e67abf1

File tree

6 files changed

+1082
-29
lines changed

6 files changed

+1082
-29
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# suppress inspection "UnusedProperty" for whole file
2+
NONE.label=None
3+
NONE.shortName=None
4+
NONE.description=THIS SHOULDN''T BE VISIBLE
5+
STRENGTH.label=Strength
6+
STRENGTH.shortName=STR
7+
STRENGTH.description=Represents the character''s physical strength or power.
8+
BODY.label=Body
9+
BODY.shortName=BOD
10+
BODY.description=Represents the character''s overall physical condition and health.
11+
REFLEXES.label=Reflexes
12+
REFLEXES.shortName=RFL
13+
REFLEXES.description=Represents the character''s reflexes or reaction time.
14+
DEXTERITY.label=Dexterity
15+
DEXTERITY.shortName=DEX
16+
DEXTERITY.description=Represents the character''s coordination and fine motor skills.
17+
INTELLIGENCE.label=Intelligence
18+
INTELLIGENCE.shortName=INT
19+
INTELLIGENCE.description=Represents the character''s cognitive ability and problem-solving skills.
20+
WILLPOWER.label=Willpower
21+
WILLPOWER.shortName=WIL
22+
WILLPOWER.description=Represents the character''s mental willpower and determination.
23+
CHARISMA.label=Charisma
24+
CHARISMA.shortName=CHA
25+
CHARISMA.description=Represents the character''s social skills and personal magnetism.

MekHQ/src/mekhq/campaign/personnel/Person.java

+129-26
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,11 @@
9090
import mekhq.campaign.personnel.ranks.RankSystem;
9191
import mekhq.campaign.personnel.ranks.RankValidator;
9292
import mekhq.campaign.personnel.ranks.Ranks;
93+
import mekhq.campaign.personnel.skills.Attributes;
9394
import mekhq.campaign.personnel.skills.Skill;
9495
import mekhq.campaign.personnel.skills.SkillType;
9596
import mekhq.campaign.personnel.skills.Skills;
97+
import mekhq.campaign.personnel.skills.enums.SkillAttribute;
9698
import mekhq.campaign.randomEvents.personalities.enums.Aggression;
9799
import mekhq.campaign.randomEvents.personalities.enums.Ambition;
98100
import mekhq.campaign.randomEvents.personalities.enums.Greed;
@@ -199,6 +201,7 @@ public class Person {
199201
private int wealth;
200202
private int reputation;
201203
private int unlucky;
204+
private Attributes atowAttributes;
202205

203206
private PersonnelStatus status;
204207
private int xp;
@@ -427,6 +430,7 @@ public Person(final String preNominal, final String givenName, final String surn
427430
wealth = 0;
428431
reputation = 0;
429432
unlucky = 0;
433+
atowAttributes = new Attributes();
430434
dateOfDeath = null;
431435
recruitment = null;
432436
joinedCampaign = null;
@@ -2339,6 +2343,10 @@ public void writeToXML(final PrintWriter pw, int indent, final Campaign campaign
23392343
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "unlucky", unlucky);
23402344
}
23412345

2346+
MHQXMLUtility.writeSimpleXMLOpenTag(pw, indent++, "atowAttributes");
2347+
atowAttributes.writeAttributesToXML(pw, indent);
2348+
MHQXMLUtility.writeSimpleXMLCloseTag(pw, --indent, "atowAttributes");
2349+
23422350
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "minutesLeft", minutesLeft);
23432351

23442352
if (overtimeLeft > 0) {
@@ -2748,6 +2756,8 @@ public static Person generateInstanceFromXML(Node wn, Campaign campaign, Version
27482756
person.reputation = MathUtility.parseInt(wn2.getTextContent());
27492757
} else if (wn2.getNodeName().equalsIgnoreCase("unlucky")) {
27502758
person.unlucky = MathUtility.parseInt(wn2.getTextContent());
2759+
} else if (wn2.getNodeName().equalsIgnoreCase("atowAttributes")) {
2760+
person.atowAttributes = new Attributes().generateAttributesFromXML(wn2);
27512761
} else if (wn2.getNodeName().equalsIgnoreCase("pilotHits")) {
27522762
person.hits = MathUtility.parseInt(wn2.getTextContent());
27532763
} else if (wn2.getNodeName().equalsIgnoreCase("skill")) {
@@ -3493,18 +3503,18 @@ public int getExperienceLevel(final Campaign campaign, final boolean secondary)
34933503
SkillType.EXP_NONE;
34943504
case MECHANIC:
34953505
if (isTechsHaveAdministration) {
3496-
if (hasSkill(SkillType.S_TECH_MECHANIC) && hasSkill(SkillType.S_ADMIN)) {
3506+
if (hasSkill(SkillType.S_TECH_MECHANIC) && hasSkill(S_ADMIN)) {
34973507
if (isAlternativeQualityAveraging) {
34983508
int rawScore = (int) Math.floor((getSkill(SkillType.S_TECH_MECHANIC).getLevel() +
3499-
getSkill(SkillType.S_ADMIN).getLevel()) / 2.0);
3509+
getSkill(S_ADMIN).getLevel()) / 2.0);
35003510
if (getSkill(SkillType.S_TECH_MECHANIC).getType().getExperienceLevel(rawScore) ==
3501-
getSkill(SkillType.S_ADMIN).getType().getExperienceLevel(rawScore)) {
3511+
getSkill(S_ADMIN).getType().getExperienceLevel(rawScore)) {
35023512
return getSkill(SkillType.S_TECH_MECHANIC).getType().getExperienceLevel(rawScore);
35033513
}
35043514
}
35053515

35063516
return (int) Math.floor((getSkill(SkillType.S_TECH_MECHANIC).getExperienceLevel() +
3507-
getSkill(SkillType.S_ADMIN).getExperienceLevel()) / 2.0);
3517+
getSkill(S_ADMIN).getExperienceLevel()) / 2.0);
35083518
} else {
35093519
return SkillType.EXP_NONE;
35103520
}
@@ -3579,18 +3589,18 @@ public int getExperienceLevel(final Campaign campaign, final boolean secondary)
35793589
SkillType.EXP_NONE;
35803590
case VESSEL_CREW:
35813591
if (isTechsHaveAdministration) {
3582-
if (hasSkill(SkillType.S_TECH_VESSEL) && hasSkill(SkillType.S_ADMIN)) {
3592+
if (hasSkill(SkillType.S_TECH_VESSEL) && hasSkill(S_ADMIN)) {
35833593
if (isAlternativeQualityAveraging) {
35843594
int rawScore = (int) Math.floor((getSkill(SkillType.S_TECH_VESSEL).getLevel() +
3585-
getSkill(SkillType.S_ADMIN).getLevel()) / 2.0);
3595+
getSkill(S_ADMIN).getLevel()) / 2.0);
35863596
if (getSkill(SkillType.S_TECH_VESSEL).getType().getExperienceLevel(rawScore) ==
3587-
getSkill(SkillType.S_ADMIN).getType().getExperienceLevel(rawScore)) {
3597+
getSkill(S_ADMIN).getType().getExperienceLevel(rawScore)) {
35883598
return getSkill(SkillType.S_TECH_VESSEL).getType().getExperienceLevel(rawScore);
35893599
}
35903600
}
35913601

35923602
return (int) Math.floor((getSkill(SkillType.S_TECH_VESSEL).getExperienceLevel() +
3593-
getSkill(SkillType.S_ADMIN).getExperienceLevel()) / 2.0);
3603+
getSkill(S_ADMIN).getExperienceLevel()) / 2.0);
35943604
} else {
35953605
return SkillType.EXP_NONE;
35963606
}
@@ -3603,18 +3613,18 @@ public int getExperienceLevel(final Campaign campaign, final boolean secondary)
36033613
return hasSkill(SkillType.S_NAV) ? getSkill(SkillType.S_NAV).getExperienceLevel() : SkillType.EXP_NONE;
36043614
case MEK_TECH:
36053615
if (isTechsHaveAdministration) {
3606-
if (hasSkill(SkillType.S_TECH_MEK) && hasSkill(SkillType.S_ADMIN)) {
3616+
if (hasSkill(SkillType.S_TECH_MEK) && hasSkill(S_ADMIN)) {
36073617
if (isAlternativeQualityAveraging) {
36083618
int rawScore = (int) Math.floor((getSkill(SkillType.S_TECH_MEK).getLevel() +
3609-
getSkill(SkillType.S_ADMIN).getLevel()) / 2.0);
3619+
getSkill(S_ADMIN).getLevel()) / 2.0);
36103620
if (getSkill(SkillType.S_TECH_MEK).getType().getExperienceLevel(rawScore) ==
3611-
getSkill(SkillType.S_ADMIN).getType().getExperienceLevel(rawScore)) {
3621+
getSkill(S_ADMIN).getType().getExperienceLevel(rawScore)) {
36123622
return getSkill(SkillType.S_TECH_MEK).getType().getExperienceLevel(rawScore);
36133623
}
36143624
}
36153625

36163626
return (int) Math.floor((getSkill(SkillType.S_TECH_MEK).getExperienceLevel() +
3617-
getSkill(SkillType.S_ADMIN).getExperienceLevel()) / 2.0);
3627+
getSkill(S_ADMIN).getExperienceLevel()) / 2.0);
36183628
} else {
36193629
return SkillType.EXP_NONE;
36203630
}
@@ -3625,18 +3635,18 @@ public int getExperienceLevel(final Campaign campaign, final boolean secondary)
36253635
}
36263636
case AERO_TEK:
36273637
if (isTechsHaveAdministration) {
3628-
if (hasSkill(SkillType.S_TECH_AERO) && hasSkill(SkillType.S_ADMIN)) {
3638+
if (hasSkill(SkillType.S_TECH_AERO) && hasSkill(S_ADMIN)) {
36293639
if (isAlternativeQualityAveraging) {
36303640
int rawScore = (int) Math.floor((getSkill(SkillType.S_TECH_AERO).getLevel() +
3631-
getSkill(SkillType.S_ADMIN).getLevel()) / 2.0);
3641+
getSkill(S_ADMIN).getLevel()) / 2.0);
36323642
if (getSkill(SkillType.S_TECH_AERO).getType().getExperienceLevel(rawScore) ==
3633-
getSkill(SkillType.S_ADMIN).getType().getExperienceLevel(rawScore)) {
3643+
getSkill(S_ADMIN).getType().getExperienceLevel(rawScore)) {
36343644
return getSkill(SkillType.S_TECH_AERO).getType().getExperienceLevel(rawScore);
36353645
}
36363646
}
36373647

36383648
return (int) Math.floor((getSkill(SkillType.S_TECH_AERO).getExperienceLevel() +
3639-
getSkill(SkillType.S_ADMIN).getExperienceLevel()) / 2.0);
3649+
getSkill(S_ADMIN).getExperienceLevel()) / 2.0);
36403650
} else {
36413651
return SkillType.EXP_NONE;
36423652
}
@@ -3647,18 +3657,18 @@ public int getExperienceLevel(final Campaign campaign, final boolean secondary)
36473657
}
36483658
case BA_TECH:
36493659
if (isTechsHaveAdministration) {
3650-
if (hasSkill(SkillType.S_TECH_BA) && hasSkill(SkillType.S_ADMIN)) {
3660+
if (hasSkill(SkillType.S_TECH_BA) && hasSkill(S_ADMIN)) {
36513661
if (isAlternativeQualityAveraging) {
36523662
int rawScore = (int) Math.floor((getSkill(SkillType.S_TECH_BA).getLevel() +
3653-
getSkill(SkillType.S_ADMIN).getLevel()) / 2.0);
3663+
getSkill(S_ADMIN).getLevel()) / 2.0);
36543664
if (getSkill(SkillType.S_TECH_BA).getType().getExperienceLevel(rawScore) ==
3655-
getSkill(SkillType.S_ADMIN).getType().getExperienceLevel(rawScore)) {
3665+
getSkill(S_ADMIN).getType().getExperienceLevel(rawScore)) {
36563666
return getSkill(SkillType.S_TECH_BA).getType().getExperienceLevel(rawScore);
36573667
}
36583668
}
36593669

36603670
return (int) Math.floor((getSkill(SkillType.S_TECH_BA).getExperienceLevel() +
3661-
getSkill(SkillType.S_ADMIN).getExperienceLevel()) / 2.0);
3671+
getSkill(S_ADMIN).getExperienceLevel()) / 2.0);
36623672
} else {
36633673
return SkillType.EXP_NONE;
36643674
}
@@ -3673,18 +3683,18 @@ public int getExperienceLevel(final Campaign campaign, final boolean secondary)
36733683
SkillType.EXP_NONE;
36743684
case DOCTOR:
36753685
if (isDoctorsHaveAdministration) {
3676-
if (hasSkill(SkillType.S_DOCTOR) && hasSkill(SkillType.S_ADMIN)) {
3686+
if (hasSkill(SkillType.S_DOCTOR) && hasSkill(S_ADMIN)) {
36773687
if (isAlternativeQualityAveraging) {
36783688
int rawScore = (int) Math.floor((getSkill(SkillType.S_DOCTOR).getLevel() +
3679-
getSkill(SkillType.S_ADMIN).getLevel()) / 2.0);
3689+
getSkill(S_ADMIN).getLevel()) / 2.0);
36803690
if (getSkill(SkillType.S_DOCTOR).getType().getExperienceLevel(rawScore) ==
3681-
getSkill(SkillType.S_ADMIN).getType().getExperienceLevel(rawScore)) {
3691+
getSkill(S_ADMIN).getType().getExperienceLevel(rawScore)) {
36823692
return getSkill(SkillType.S_DOCTOR).getType().getExperienceLevel(rawScore);
36833693
}
36843694
}
36853695

36863696
return (int) Math.floor((getSkill(SkillType.S_DOCTOR).getExperienceLevel() +
3687-
getSkill(SkillType.S_ADMIN).getExperienceLevel()) / 2.0);
3697+
getSkill(S_ADMIN).getExperienceLevel()) / 2.0);
36883698
} else {
36893699
return SkillType.EXP_NONE;
36903700
}
@@ -4619,7 +4629,7 @@ public double calculateTechTimeMultiplier(boolean isTechsUseAdministration) {
46194629

46204630
double administrationMultiplier = 1.0 - (TECH_ADMINISTRATION_MULTIPLIER * REGULAR_EXPERIENCE_LEVEL);
46214631

4622-
Skill administration = skills.getSkill(SkillType.S_ADMIN);
4632+
Skill administration = skills.getSkill(S_ADMIN);
46234633
int experienceLevel = SkillLevel.NONE.getExperienceLevel();
46244634

46254635
if (administration != null) {
@@ -4667,7 +4677,7 @@ public int getDoctorMedicalCapacity(final boolean doctorsUseAdministration, fina
46674677

46684678
double administrationMultiplier = 1.0 - (DOCTOR_ADMINISTRATION_MULTIPLIER * REGULAR_EXPERIENCE_LEVEL);
46694679

4670-
Skill administration = skills.getSkill(SkillType.S_ADMIN);
4680+
Skill administration = skills.getSkill(S_ADMIN);
46714681
int experienceLevel = SkillLevel.NONE.getExperienceLevel();
46724682

46734683
if (administration != null) {
@@ -4901,6 +4911,99 @@ public void setUnlucky(final int unlucky) {
49014911
this.unlucky = unlucky;
49024912
}
49034913

4914+
/**
4915+
* Retrieves the character's {@link Attributes} object containing the character's attribute scores.
4916+
*
4917+
* <p><b>Usage:</b> In most cases you'll want to use {@link #getAttributeScore(SkillAttribute)} instead, as that
4918+
* will allow you to jump straight to the exact score you need.</p>
4919+
*
4920+
* @return the character's {@link Attributes} object.
4921+
*
4922+
* @since 0.50.5
4923+
*/
4924+
public Attributes getATOWAttributes() {
4925+
return atowAttributes;
4926+
}
4927+
4928+
/**
4929+
* Retrieves the score of a specified attribute.
4930+
*
4931+
* <p>The method maps the provided {@link SkillAttribute} to its corresponding attribute in
4932+
* the {@link Attributes} object and returns its value. If the {@link SkillAttribute} is {@code NONE}, the method
4933+
* returns a score of 0. If the {@code attribute} is {@code null}, an error is logged, and the method returns a
4934+
* score of 0.</p>
4935+
*
4936+
* @param attribute the {@link SkillAttribute} to retrieve the score for.
4937+
*
4938+
* @return the score of the specified attribute, or 0 if the attribute is {@code NONE} or {@code null}.
4939+
*
4940+
* @since 0.50.5
4941+
*/
4942+
public int getAttributeScore(final SkillAttribute attribute) {
4943+
if (attribute == null) {
4944+
logger.error("(getAttributeScore) SkillAttribute is null.");
4945+
return 0;
4946+
}
4947+
4948+
return switch (attribute) {
4949+
case NONE -> 0;
4950+
case STRENGTH -> atowAttributes.getStrength();
4951+
case BODY -> atowAttributes.getBody();
4952+
case REFLEXES -> atowAttributes.getReflexes();
4953+
case DEXTERITY -> atowAttributes.getDexterity();
4954+
case INTELLIGENCE -> atowAttributes.getIntelligence();
4955+
case WILLPOWER -> atowAttributes.getWillpower();
4956+
case CHARISMA -> atowAttributes.getCharisma();
4957+
};
4958+
}
4959+
4960+
/**
4961+
* Sets the character's {@link Attributes} object which contains their ATOW Attribute scores.
4962+
*
4963+
* <p><b>Usage:</b> This completely wipes the character's attribute scores and is likely not the method you're
4964+
* looking for. Consider{@link #changeAttributeScore(SkillAttribute, int)} if you just want to increment or
4965+
* decrement a specific attribute by a certain value.</p>
4966+
*
4967+
* @param atowAttributes the {@link Attributes} object to set.
4968+
*
4969+
* @since 0.50.5
4970+
*/
4971+
public void setATOWAttributes(final Attributes atowAttributes) {
4972+
this.atowAttributes = atowAttributes;
4973+
}
4974+
4975+
/**
4976+
* Modifies the score of a specified attribute by applying a delta value.
4977+
*
4978+
* <p>This method maps the provided {@link SkillAttribute} to its corresponding attribute in the
4979+
* {@link Attributes} object and adjusts its value by the specified delta. If the {@code attribute} is {@code NONE},
4980+
* the method does nothing. If {@code attribute} is {@code null}, an error is logged, and the method returns without
4981+
* performing any operation.</p>
4982+
*
4983+
* @param attribute the {@link SkillAttribute} to modify the score for.
4984+
* @param delta the value to add to (or subtract from) the current score of the specified attribute.
4985+
*
4986+
* @since 0.50.5
4987+
*/
4988+
public void changeAttributeScore(final SkillAttribute attribute, final int delta) {
4989+
if (attribute == null) {
4990+
logger.error("(changeAttributeScore) SkillAttribute is null.");
4991+
return;
4992+
}
4993+
4994+
switch (attribute) {
4995+
case NONE -> {
4996+
}
4997+
case STRENGTH -> atowAttributes.changeStrength(delta);
4998+
case BODY -> atowAttributes.changeBody(delta);
4999+
case REFLEXES -> atowAttributes.changeReflexes(delta);
5000+
case DEXTERITY -> atowAttributes.changeDexterity(delta);
5001+
case INTELLIGENCE -> atowAttributes.changeIntelligence(delta);
5002+
case WILLPOWER -> atowAttributes.changeWillpower(delta);
5003+
case CHARISMA -> atowAttributes.changeCharisma(delta);
5004+
}
5005+
}
5006+
49045007
public void resetSkillTypes() {
49055008
skills.getSkills().forEach(Skill::updateType);
49065009
}

0 commit comments

Comments
 (0)