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

3498: Adding Clanner Tracking to MegaMek #3500

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions megamek/i18n/megamek/client/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,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.chkClanner=Clanner
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
11 changes: 5 additions & 6 deletions megamek/src/megamek/client/bot/MoveOption.java
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,14 @@ public boolean changeToPhysical() {
return false;
}
}
boolean isClan = getEntity().isClan();

if ((last == null)
|| (last.getMovementType(true) == EntityMovementType.MOVE_ILLEGAL)) {
return false;
}
if ((last.getType() != MoveStepType.FORWARDS)
|| (isClan
&& getGame().getOptions().booleanOption(OptionsConstants.ALLOWED_NO_CLAN_PHYSICAL) && (getEntity()
.getSwarmAttackerId() == Entity.NONE))) {
} else if ((last.getType() != MoveStepType.FORWARDS)
|| (getEntity().getCrew().isClanner()
&& getGame().getOptions().booleanOption(OptionsConstants.ALLOWED_NO_CLAN_PHYSICAL)
&& (getEntity().getSwarmAttackerId() == Entity.NONE))) {
return false;
}
// TODO: this just takes the first target
Expand Down
5 changes: 2 additions & 3 deletions megamek/src/megamek/client/bot/princess/BasicPathRanker.java
Original file line number Diff line number Diff line change
Expand Up @@ -579,9 +579,8 @@ protected RankedPath rankPath(MovePath path, Game game, int maxRange,
// 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()) {
if (game.getOptions().booleanOption(OptionsConstants.ALLOWED_NO_CLAN_PHYSICAL)
&& path.getEntity().getCrew().isClanner()) {
damageEstimate.physicalDamage = 0;
}

Expand Down
52 changes: 17 additions & 35 deletions megamek/src/megamek/client/generator/RandomNameGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,38 +141,24 @@ 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 clanner if the name is for a clanner
* @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 clanner) {
return generate(gender, clanner, 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 clanner if the name is for a clanner
* @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 clanner, 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
Expand All @@ -181,14 +167,14 @@ public String generate(Gender gender, boolean isClan, String faction) {
// 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)))
: ((clanner && (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 (!clanner) {
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 clanner if the person is a clanner
* @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 clanner, 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 (!clanner) {
name += " " + surnames.get(ethnicCode).randomItem();
}
}
Expand All @@ -221,15 +203,15 @@ 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 clanner if the person is a clanner
* @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 clanner, 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
Expand All @@ -238,31 +220,31 @@ public String[] generateGivenNameSurnameSplit(Gender gender, boolean isClan, Str
// 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)))
: ((clanner && (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] = clanner ? "" : 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 clanner if the person is a clanner
* @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 clanner, 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] = clanner ? "" : surnames.get(ethnicCode).randomItem();
}
return name;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@

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 +87,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 clanner
*/
public void setRandomSkills(final Entity entity, final boolean forceClan) {
for (int i = 0; i < entity.getCrew().getSlotCount(); i++) {
Expand All @@ -109,7 +107,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 +118,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().isClanner(), 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 clanner if the crew to generate a random skills array for are clanners
* @param forceClan forces the type to be clan if the crew are clanners
* @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 clanner,
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 clanner,
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 clanner,
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, clanner, 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 @@ -54,7 +51,7 @@ public int[] generateRandomSkills(final Entity entity, final boolean forceClan)
}

// Now lets handle clanners
if (getType().isClan() || (forceClan && entity.isClan())) {
if (getType().isClan() || (forceClan && clanner)) {
// '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 clanner,
final boolean forceClan) {
final SkillGeneratorType type = (forceClan && clanner) ? 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 clanner if the crew to generate a random skills array for are clanners
* @param forceClan forces the type to be clan if the crew are clanners
* @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 clanner,
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, clanner, forceClan);
}
}
Loading