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

Adding Clan Personnel Tracking to MegaMek #5166

Merged
merged 10 commits into from
Feb 21, 2024
1 change: 1 addition & 0 deletions megamek/i18n/megamek/client/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,7 @@ CustomMechDialog.OffboardDistance=Offboard units need to be at least one mapshee
CustomMechDialog.RandomSkill=Random Skill
CustomMechDialog.RandomName=Random Name
CustomMechDialog.RandomCallsign=Random Callsign
CustomMechDialog.chkClanPilot=Clan Pilot
CustomMechDialog.setCompanyMaster=Set as company-level master ({0}M / {1}S free)
CustomMechDialog.setCompanyMaster1=Set as company-level master ({0}M free)
CustomMechDialog.setIndependentMaster=Set as independent master ({0} free)
Expand Down
1 change: 1 addition & 0 deletions megamek/i18n/megamek/client/messages_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ CustomMechDialog.labOffBoard=Ausserhalb der Karte aufstellen?
CustomMechDialog.labOffBoardDirection=Richtung ausserhalb der Karte:
CustomMechDialog.labOffBoardDistance=Entfernung ausserhalb der Karte (Hexfelder):
CustomMechDialog.labPiloting=Pilotenwert:
CustomMechDialog.chkClanPilot=Clan-Pilot
CustomMechDialog.labUnitNum=Einheit tauschen mit:
CustomMechDialog.None=Keine
CustomMechDialog.North=Norden
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ protected RankedPath rankPath(MovePath path, Game game, int maxRange, double fal
// If I cannot kick because I am a clan unit and "No physical attacks for the clans"
// is enabled, set maximum physical damage for this path to zero.
if (game.getOptions().booleanOption(OptionsConstants.ALLOWED_NO_CLAN_PHYSICAL)
&& path.getEntity().isClan()) {
&& path.getEntity().getCrew().isClanPilot()) {
damageEstimate.physicalDamage = 0;
}

Expand Down
56 changes: 19 additions & 37 deletions megamek/src/megamek/client/generator/RandomNameGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,54 +141,40 @@ public RandomNameGenerator() {
/**
* This is used to generate a name for MegaMek only that uses the chosen faction
* @param gender the gender to generate the name for
* @param clanPilot if the name is for a clanPilot
* @return a string containing the randomly generated name
*/
public String generate(Gender gender) {
return generate(gender, getChosenFaction());
}

/**
* Generate a name for MegaMek only, using the clan name hack
*
* This is a hack used for MegaMek, where we assume any chosen faction with a name containing the
* String "clan" is a clan faction.
* @param gender the gender to generate the name for
* @param faction the faction code to use, which is the generator's name where possible
* @return a string containing the randomly generated name
*/
public String generate(Gender gender, String faction) {
// this is a total hack, but for now lets assume that if the faction name contains
// the word "clan" we should only spit out first names
return generate(gender, faction.toLowerCase().contains("clan"), faction);
public String generate(Gender gender, boolean clanPilot) {
return generate(gender, clanPilot, getChosenFaction());
}

/**
* Generate a single random name for MegaMek only
*
* @param gender the gender to generate the name for
* @param isClan true if the name should be for a clanner, otherwise false
* @param clanPilot if the name is for a clanPilot
* @param faction a string containing the faction key with which to generate the name from.
* If the faction is not a key for the <code>factionSurnames</code> Map,
* it will instead generate based on the General list
* @return a string containing the randomly generated name
*/
public String generate(Gender gender, boolean isClan, String faction) {
public String generate(Gender gender, boolean clanPilot, String faction) {
String name = UNNAMED_FULL_NAME;
if (initialized) {
// This checks to see if we've got a name map for the faction. If we do not, then we
// go to check if the person is a clanner. If they are, then they default to the default
// go to check if the person is a clanPilot. If they are, then they default to the default
// clan key provided that exists.
// If the key isn't set by either case above, then the name is generated based on the
// default faction key
faction = factionEthnicCodes.containsKey(faction) ? faction
: ((isClan && (factionEthnicCodes.containsKey(KEY_DEFAULT_CLAN)))
: ((clanPilot && (factionEthnicCodes.containsKey(KEY_DEFAULT_CLAN)))
? KEY_DEFAULT_CLAN : KEY_DEFAULT_FACTION);
final int ethnicCode = factionEthnicCodes.get(faction).randomItem();
final int givenNameEthnicCode = factionGivenNames.get(faction).get(ethnicCode).randomItem();

name = (gender.isFemale() ? femaleGivenNames : maleGivenNames).get(givenNameEthnicCode).randomItem();

if (!isClan) {
if (!clanPilot) {
name += " " + surnames.get(ethnicCode).randomItem();
}
}
Expand All @@ -197,20 +183,16 @@ public String generate(Gender gender, boolean isClan, String faction) {

/**
* @param gender the gender to generate the name for
* @param faction the specified faction code
* @param clanPilot if the person is a clanPilot
* @param ethnicCode the specified ethnic code
* @return a string containing the randomly generated name
*/
public String generateWithEthnicCode(Gender gender, String faction, int ethnicCode) {
public String generateWithEthnicCode(Gender gender, boolean clanPilot, int ethnicCode) {
String name = UNNAMED_FULL_NAME;
if (initialized) {
// this is a total hack, but for now lets assume that if the faction name contains
// the word "clan" we should only spit out first names
boolean isClan = faction.toLowerCase().equals("clan");

name = (gender.isFemale() ? femaleGivenNames : maleGivenNames).get(ethnicCode).randomItem();

if (!isClan) {
if (!clanPilot) {
name += " " + surnames.get(ethnicCode).randomItem();
}
}
Expand All @@ -221,48 +203,48 @@ public String generateWithEthnicCode(Gender gender, String faction, int ethnicCo
* Generate a single random name split between a given name and surname
*
* @param gender the gender to generate the name for
* @param isClan true if the name should be for a clanner, otherwise false
* @param clanPilot if the person is a clanPilot
* @param faction a string containing the faction key with which to generate the name from.
* If the faction is not a key for the <code>factionSurnames</code> Map,
* it will instead generate based on the General list
* @return - a String[] containing the name,
* with the given name at String[0]
* and the surname at String[1]
*/
public String[] generateGivenNameSurnameSplit(Gender gender, boolean isClan, String faction) {
public String[] generateGivenNameSurnameSplit(Gender gender, boolean clanPilot, String faction) {
String[] name = { UNNAMED, UNNAMED_SURNAME };
if (initialized) {
// This checks to see if we've got a name map for the faction. If we do not, then we
// go to check if the person is a clanner. If they are, then they default to the default
// go to check if the person is a clanPilot. If they are, then they default to the default
// clan key provided that exists.
// If the key isn't set by either case above, then the name is generated based on the
// default faction key
faction = factionEthnicCodes.containsKey(faction) ? faction
: ((isClan && (factionEthnicCodes.containsKey(KEY_DEFAULT_CLAN)))
: ((clanPilot && (factionEthnicCodes.containsKey(KEY_DEFAULT_CLAN)))
? KEY_DEFAULT_CLAN : KEY_DEFAULT_FACTION);
final int ethnicCode = factionEthnicCodes.get(faction).randomItem();
final int givenNameEthnicCode = factionGivenNames.get(faction).get(ethnicCode).randomItem();

name[0] = (gender.isFemale() ? femaleGivenNames : maleGivenNames).get(givenNameEthnicCode).randomItem();

name[1] = isClan ? "" : surnames.get(ethnicCode).randomItem();
name[1] = clanPilot ? "" : surnames.get(ethnicCode).randomItem();
}
return name;
}

/**
* @param gender the gender to generate the name for
* @param isClan true if the name should be for a clanner, otherwise false
* @param clanPilot if the person is a clanPilot
* @param ethnicCode the specified ethnic code
* @return - a String[] containing the name,
* with the given name at String[0]
* and the surname at String[1]
*/
public String[] generateGivenNameSurnameSplitWithEthnicCode(Gender gender, boolean isClan, int ethnicCode) {
public String[] generateGivenNameSurnameSplitWithEthnicCode(Gender gender, boolean clanPilot, int ethnicCode) {
String[] name = { UNNAMED, UNNAMED_SURNAME };
if (initialized) {
name[0] = (gender.isFemale() ? femaleGivenNames : maleGivenNames).get(ethnicCode).randomItem();
name[1] = isClan ? "" : surnames.get(ethnicCode).randomItem();
name[1] = clanPilot ? "" : surnames.get(ethnicCode).randomItem();
}
return name;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,8 @@
import megamek.common.LAMPilot;
import megamek.common.enums.SkillLevel;

import java.io.Serializable;

public abstract class AbstractSkillGenerator implements Serializable {
public abstract class AbstractSkillGenerator {
//region Variable Declarations
private static final long serialVersionUID = 8475341940660043659L;

private final SkillGeneratorMethod method;
private SkillLevel level;
private SkillGeneratorType type;
Expand Down Expand Up @@ -89,7 +85,7 @@ public void setRandomSkills(final Entity entity) {
* Generates random skills based on an entity crewmember by crewmember, and then assigns the
* values to the crew before sorting them.
* @param entity the Entity whose skills are to be randomly set
* @param forceClan forces the type to be clan if the entity is a clan unit
* @param forceClan forces the type to be clan if the crew are led by a clan pilot
*/
public void setRandomSkills(final Entity entity, final boolean forceClan) {
for (int i = 0; i < entity.getCrew().getSlotCount(); i++) {
Expand All @@ -109,7 +105,7 @@ public void setRandomSkills(final Entity entity, final boolean forceClan) {
}

/**
* Generates random skills for an entity based on the current settings of the random skills
* Generates random skills for an entity based on the current settings of the random skill
* generator, but does not assign those new skills to that entity
* @param entity the Entity to generate a random skill array for
* @return an integer array containing the (Gunnery, Piloting) skill values, or an alternative
Expand All @@ -120,15 +116,30 @@ public int[] generateRandomSkills(final Entity entity) {
}

/**
* Generates random skills for an entity based on the current settings of the random skills
* Generates random skills for an entity based on the current settings of the random skill
* generator, but does not assign those new skills to that entity. The return value MUST be
* cleaned with cleanReturn for this setup to work properly.
* @param entity the Entity to generate a random skill array for
* @param forceClan forces the type to be clan if the entity is a clan unit
* @return an integer array containing the (Gunnery, Piloting) skill values, or an alternative
* pairing if applicable [(Gunnery, Anti-'Mech) for infantry]
*/
public abstract int[] generateRandomSkills(final Entity entity, final boolean forceClan);
public int[] generateRandomSkills(final Entity entity, final boolean forceClan) {
return generateRandomSkills(entity, entity.getCrew().isClanPilot(), forceClan);
}

/**
* Generates random skills for an entity based on the current settings of the random skill
* generator, but does not assign those new skills to that entity. The return value MUST be
* cleaned with cleanReturn for this setup to work properly.
* @param entity the Entity to generate a random skill array for
* @param clanPilot if the crew to generate a random skills array for are a clan crew
* @param forceClan forces the type to be clan if the crew are a clan crew
* @return an integer array containing the (Gunnery, Piloting) skill values, or an alternative
* pairing if applicable [(Gunnery, Anti-'Mech) for infantry]
*/
public abstract int[] generateRandomSkills(final Entity entity, final boolean clanPilot,
final boolean forceClan);

/**
* This cleans up the return value before the final return, and by doing so to handling two
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
import megamek.common.Entity;

public class ConstantSkillGenerator extends AbstractSkillGenerator {
//region Variable Declarations
private static final long serialVersionUID = -7927373286417045956L;
//endregion Variable Declarations

//region Constructors
public ConstantSkillGenerator() {
this(SkillGeneratorMethod.CONSTANT);
Expand All @@ -36,16 +32,9 @@ protected ConstantSkillGenerator(final SkillGeneratorMethod method) {
}
//endregion Constructors

/**
* This returns the unmodified default random skill value, which is a set of constants
*
* @param entity the Entity to generate a random skill array for
* @param forceClan forces the type to be clan if the entity is a clan unit
* @return an integer array containing the (Gunnery, Piloting) skill values, or an alternative
* pairing if applicable [(Gunnery, Anti-'Mech) for infantry]
*/
@Override
public int[] generateRandomSkills(final Entity entity, final boolean forceClan) {
public int[] generateRandomSkills(final Entity entity, final boolean clanPilot,
final boolean forceClan) {
return cleanReturn(entity, getLevel().getDefaultSkillValues());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,21 @@
import megamek.common.enums.SkillLevel;

public class ModifiedConstantSkillGenerator extends ConstantSkillGenerator {
//region Variable Declarations
private static final long serialVersionUID = -3276792082665884815L;
//endregion Variable Declarations

//region Constructors
public ModifiedConstantSkillGenerator() {
super(SkillGeneratorMethod.MODIFIED_CONSTANT);
}
//endregion Constructors

@Override
public int[] generateRandomSkills(final Entity entity, final boolean forceClan) {
public int[] generateRandomSkills(final Entity entity, final boolean clanPilot,
final boolean forceClan) {
if (getType().isManeiDomini()) {
// JHS72 pg. 121, they are always considered elite
return SkillLevel.ELITE.getDefaultSkillValues();
}

final int[] skills = super.generateRandomSkills(entity, forceClan);
final int[] skills = super.generateRandomSkills(entity, clanPilot, forceClan);

// Now we need to make all kinds of adjustments based on the table on pg. 40 of TW
// Infantry Anti-'Mech skill should be one higher unless foot
Expand All @@ -53,8 +50,8 @@ public int[] generateRandomSkills(final Entity entity, final boolean forceClan)
skills[0]++;
}

// Now lets handle clanners
if (getType().isClan() || (forceClan && entity.isClan())) {
// Now lets handle clan pilots
if (getType().isClan() || (forceClan && clanPilot)) {
// 'Mechs and Battle Armour are better (but not ProtoMechs),
// Tanks are worse, while Gunnery is worse for Infantry, Conventional Fighters
// and Small Craft
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,16 @@
import megamek.common.*;

public class ModifiedTotalWarfareSkillGenerator extends TotalWarfareSkillGenerator {
//region Variable Declarations
private static final long serialVersionUID = -4805975255577570411L;
//endregion Variable Declarations

//region Constructors
public ModifiedTotalWarfareSkillGenerator() {
super(SkillGeneratorMethod.MODIFIED_TOTAL_WARFARE);
}
//endregion Constructors

@Override
protected int determineBonus(final Entity entity, final boolean forceClan) {
final SkillGeneratorType type = (forceClan && entity.isClan()) ? SkillGeneratorType.CLAN : getType();
protected int determineBonus(final Entity entity, final boolean clanPilot,
final boolean forceClan) {
final SkillGeneratorType type = (forceClan && clanPilot) ? SkillGeneratorType.CLAN : getType();

int bonus = 0;
if (type.isClan()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@
import megamek.common.enums.SkillLevel;

public class TaharqaSkillGenerator extends TotalWarfareSkillGenerator {
//region Variable Declarations
private static final long serialVersionUID = -7334417837623003013L;
//endregion Variable Declarations

//region Constructors
public TaharqaSkillGenerator() {
super(SkillGeneratorMethod.TAHARQA);
Expand All @@ -38,12 +34,14 @@ public TaharqaSkillGenerator() {
/**
* The base skill level for each entity is determined separately in Taharqa's Method
* @param entity the Entity to generate a random skill array for
* @param forceClan forces the type to be clan if the entity is a clan unit
* @param clanPilot if the crew to generate a random skills array for are a clan crew
* @param forceClan forces the type to be clan if the crew are a clan crew
* @return an integer array containing the (Gunnery, Piloting) skill values, or an alternative
* pairing if applicable [(Gunnery, Anti-'Mech) for infantry]
*/
@Override
public int[] generateRandomSkills(final Entity entity, final boolean forceClan) {
public int[] generateRandomSkills(final Entity entity, final boolean clanPilot,
final boolean forceClan) {
int bonus;
switch (getLevel()) {
case ULTRA_GREEN:
Expand Down Expand Up @@ -94,6 +92,6 @@ public int[] generateRandomSkills(final Entity entity, final boolean forceClan)
level = SkillLevel.LEGENDARY;
}

return generateRandomSkills(level, entity, forceClan);
return generateRandomSkills(level, entity, clanPilot, forceClan);
}
}
Loading
Loading