Skip to content

Commit

Permalink
Merge pull request #5436 from kuronekochomusuke/lightningStorm
Browse files Browse the repository at this point in the history
lightning storm updates
  • Loading branch information
HammerGS authored Oct 29, 2024
2 parents 2e39701 + 3bd584f commit 785fc3b
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 22 deletions.
2 changes: 2 additions & 0 deletions megamek/i18n/megamek/common/options/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ GameOptionsInfo.option.hidden_units.displayableName=Hidden Units
GameOptionsInfo.option.hidden_units.description=If checked, players may deploy units hidden.
GameOptionsInfo.option.black_ice.displayableName=Black Ice
GameOptionsInfo.option.black_ice.description=If checked, Black Ice may form on pavement if temperatures are below -30C. TO:AR p38\nDoes not affect Black Ice forming due to Ice Storms. TO:AR p58
GameOptionsInfo.option.lightning_storm_targets_units.displayableName=Lightning Storm targets units
GameOptionsInfo.option.lightning_storm_targets_units.description=If unchecked, targets random hex on the board
GameOptionsInfo.option.double_blind.displayableName=TacOps Double blind
GameOptionsInfo.option.double_blind.description=If checked, enemy units will only be visible if they are in line of sight of one or more of your units, or within sensor range. \nUnchecked by default.
GameOptionsInfo.option.single_blind_bots.displayableName=(Unofficial) Default bots to single blind, when using TacOps Double blind
Expand Down
3 changes: 3 additions & 0 deletions megamek/i18n/megamek/common/report-messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,9 @@
5606=player must choose <data> bombs to be destroyed.
5607=bot loses <data> bombs.
5608=<data> (<data>) Internal Bomb Bay + Cargo critical: Damage exceeds remaining bombs; all bombs destroyed.
5620=<newline>Damage from lightning storm<newline>-------------------
5621=lightning strike in hex <data>
5622= and adjacent hex <data>

#6000's -- Damage Related
6005=\ no effect.
Expand Down
7 changes: 5 additions & 2 deletions megamek/src/megamek/common/Sensor.java
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,15 @@ public int adjustRange(int range, Game game, LosEffects los) {
return 0;
}

//TO:AR 6th ed. p 190
if ((type != TYPE_MEK_SEISMIC) && (type != TYPE_VEE_SEISMIC)) {
PlanetaryConditions conditions = game.getPlanetaryConditions();
if (conditions.getEMI().isEMI()) {
if (conditions.isEMI()) {
range -= 4;
}
// TODO: add lightning
if (conditions.getWeather().isLightningStorm()) {
range -= 1;
}
}

if ((type == TYPE_MEK_RADAR) || (type == TYPE_VEE_RADAR)
Expand Down
2 changes: 1 addition & 1 deletion megamek/src/megamek/common/actions/WeaponAttackAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -5560,7 +5560,7 @@ public static ToHitData processAttackerSPAs(ToHitData toHit, Entity ae, Targetab
toHit.addModifier(-1, Messages.getString("WeaponAttackAction.RainSpec"));
}

if (conditions.getWeather().isModerateRainOrHeavyRainOrGustingRainOrDownpour()) {
if (conditions.getWeather().isModerateRainOrHeavyRainOrGustingRainOrDownpourOrLightningStorm()) {
toHit.addModifier(-1, Messages.getString("WeaponAttackAction.RainSpec"));
}
}
Expand Down
1 change: 1 addition & 0 deletions megamek/src/megamek/common/options/GameOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public synchronized void initialize() {
addOption(advancedRules, OptionsConstants.ADVANCED_MINEFIELDS, false);
addOption(advancedRules, OptionsConstants.ADVANCED_HIDDEN_UNITS, true);
addOption(advancedRules, OptionsConstants.ADVANCED_BLACK_ICE, false);
addOption(advancedRules, OptionsConstants.ADVANCED_LIGHTNING_STORM_TARGETS_UNITS, false);
addOption(advancedRules, OptionsConstants.ADVANCED_DOUBLE_BLIND, false);
addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_SENSORS, false);
addOption(advancedRules, OptionsConstants.ADVANCED_SUPRESS_ALL_DB_MESSAGES, false);
Expand Down
1 change: 1 addition & 0 deletions megamek/src/megamek/common/options/OptionsConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ public class OptionsConstants {
public static final String ADVANCED_MINEFIELDS = "minefields";
public static final String ADVANCED_HIDDEN_UNITS = "hidden_units";
public static final String ADVANCED_BLACK_ICE= "black_ice";
public static final String ADVANCED_LIGHTNING_STORM_TARGETS_UNITS= "lightning_storm_targets_units";
public static final String ADVANCED_DOUBLE_BLIND = "double_blind";
public static final String ADVANCED_SINGLE_BLIND_BOTS = "single_blind_bots";
public static final String ADVANCED_TACOPS_SENSORS = "tacops_sensors";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ public int getWeatherHitPenalty(Entity en) {
if (getWeather().isLightRainOrLightSnow()
&& en.isConventionalInfantry()) {
return 1;
} else if (getWeather().isModerateRainOrHeavyRainOrGustingRainOrModerateSnowOrSnowFlurriesOrHeavySnowOrSleet()) {
} else if (getWeather().isModerateRainOrHeavyRainOrGustingRainOrModerateSnowOrSnowFlurriesOrHeavySnowOrSleetOrLightningStorm()) {
return 1;
} else if(getWeather().isDownpour()) {
return 2;
Expand Down Expand Up @@ -403,7 +403,7 @@ && getWind().isStrongerThan(Wind.STORM)) {
public int getIgniteModifiers() {
int mod = 0;

if (getWeather().isLightRainOrModerateRain() ) {
if (getWeather().isLightRainOrModerateRainOrLightningStorm() ) {
mod += 1;
}

Expand Down Expand Up @@ -449,6 +449,7 @@ public boolean putOutFire() {
case MOD_RAIN:
case MOD_SNOW:
case SNOW_FLURRIES:
case LIGHTNING_STORM:
roll = roll + 2;
break;
case HEAVY_RAIN:
Expand Down Expand Up @@ -752,7 +753,7 @@ && getWind().isStrongerThan(Wind.LIGHT_GALE)) {
} else {
otherRange = 8;
}
} else if (getWeather().isModerateRainOrModerateSnow()) {
} else if (getWeather().isModerateRainOrModerateSnowOrLightningStorm()) {
if (isMekOrVee || isLowAltitudeAero) {
otherRange = 20;
} else if (isAero) {
Expand Down Expand Up @@ -885,6 +886,7 @@ public static Wind setWindFromWeather(Weather weather, Wind wind) {
switch (weather) {
case ICE_STORM:
case SNOW_FLURRIES:
case LIGHTNING_STORM:
return Wind.MOD_GALE;
case GUSTING_RAIN:
return Wind.STRONG_GALE;
Expand Down
30 changes: 20 additions & 10 deletions megamek/src/megamek/common/planetaryconditions/Weather.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,25 +143,33 @@ public boolean isHeavyRainOrGustingRain() {
}


public boolean isLightRainOrModerateRain() {
public boolean isLightRainOrModerateRainOrLightningStorm() {
return isLightRain()
|| isModerateRain();
|| isModerateRain()
|| isLightningStorm();
}

public boolean isModerateSnowOrSnowFlurries() {
return isModerateSnow()
|| isSnowFlurries();
}

public boolean isModerateRainOrModerateSnow() {
public boolean isModerateRainOrLightningStorm() {
return isModerateRain()
|| isLightningStorm();
}

public boolean isModerateRainOrModerateSnowOrLightningStorm() {
return isModerateRain()
|| isModerateSnow();
|| isModerateSnow()
|| isLightningStorm();
}

public boolean isDownpourOrHeavySnowOrIceStorm() {
public boolean isDownpourOrHeavySnowOrIceStormOrLightningStorm() {
return isDownpour()
|| isHeavySnow()
|| isIceStorm();
|| isIceStorm()
|| isLightningStorm();
}

public boolean isSnowFlurriesOrSleetOrIceStorm() {
Expand Down Expand Up @@ -220,11 +228,12 @@ public boolean isModerateSnowOrHeavySnowOrSnowFlurriesOrSleet() {
|| isSleet();
}

public boolean isModerateRainOrHeavyRainOrGustingRainOrDownpour() {
public boolean isModerateRainOrHeavyRainOrGustingRainOrDownpourOrLightningStorm() {
return isModerateRain()
|| isHeavyRain()
|| isGustingRain()
|| isDownpour();
|| isDownpour()
|| isLightningStorm();
}

public boolean isGustingRainOrSnowFlurriesOrIceStormOrLightningStorm() {
Expand Down Expand Up @@ -260,14 +269,15 @@ public boolean isHeavyRainOrGustingRainOrDownpourOrLightSnowOrModerateSnowOrSnow
|| isSnowFlurries();
}

public boolean isModerateRainOrHeavyRainOrGustingRainOrModerateSnowOrSnowFlurriesOrHeavySnowOrSleet() {
public boolean isModerateRainOrHeavyRainOrGustingRainOrModerateSnowOrSnowFlurriesOrHeavySnowOrSleetOrLightningStorm() {
return isModerateRain()
|| isHeavyRain()
|| isGustingRain()
|| isModerateSnow()
|| isSnowFlurries()
|| isHeavySnow()
|| isSleet();
|| isSleet()
|| isLightningStorm();
}

public boolean isAnyRain() {
Expand Down
2 changes: 1 addition & 1 deletion megamek/src/megamek/common/util/BoardUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,7 @@ public static void addWeatherConditions(Board board, Weather weatherCond, Wind w
Hex hex = board.getHex(c);

//moderate rain - mud in clear hexes, depth 0 water, and dirt roads (not implemented yet)
if (weatherCond.isModerateRain()) {
if (weatherCond.isModerateRainOrLightningStorm()) {
if ((hex.terrainsPresent() == 0) || (hex.containsTerrain(Terrains.WATER) && (hex.depth() == 0))) {
hex.addTerrain(new Terrain(Terrains.MUD, 1));
if (hex.containsTerrain(Terrains.WATER)) {
Expand Down
113 changes: 112 additions & 1 deletion megamek/src/megamek/server/totalwarfare/TWGameManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -14948,6 +14948,16 @@ private PilotingRollData getKickPushPSR(Entity psrEntity, Entity attacker,
return psr;
}

void resolveWeather() {
PlanetaryConditions conditions = game.getPlanetaryConditions();
if (conditions.isBlowingSandActive()) {
addReport(resolveBlowingSandDamage());
}
if (conditions.getWeather().isLightningStorm()) {
addReport(resolveLightningStormDamage());
}
}

/**
* Each mek sinks the amount of heat appropriate to its current heat
* capacity.
Expand Down Expand Up @@ -29704,6 +29714,7 @@ public static PilotingRollData getEjectModifiers(Game game, Entity entity, int c
}
Hex targetHex = game.getBoard().getHex(targetCoords);
// Terrain modifiers should only apply if the unit is on the ground...
// TO:AR 6th ed p165
if (!entity.isSpaceborne() && !entity.isAirborne()) {
if (targetHex != null) {
if ((targetHex.terrainLevel(Terrains.WATER) > 0)
Expand Down Expand Up @@ -29741,6 +29752,7 @@ public static PilotingRollData getEjectModifiers(Game game, Entity entity, int c
// battle, but it shouldn't
// That's a fix for another day, probably when I get around to space terrain and
// 'weather'
// TO:AR 6th ed p165
if (conditions.getGravity() == 0) {
rollTarget.addModifier(3, "Zero-G");
} else if (conditions.getGravity() < 0.8) {
Expand All @@ -29752,6 +29764,7 @@ public static PilotingRollData getEjectModifiers(Game game, Entity entity, int c
// Vacuum shouldn't apply to ASF ejection since they're designed for it, but the
// rules don't specify
// High and low pressures make more sense to apply to all
// TO:AR 6th ed p165
if (conditions.getAtmosphere().isVacuum()) {
rollTarget.addModifier(3, "Vacuum");
} else if (conditions.getAtmosphere().isVeryHigh()) {
Expand All @@ -29761,11 +29774,13 @@ public static PilotingRollData getEjectModifiers(Game game, Entity entity, int c
}
}

if (conditions.getWeather().isDownpourOrHeavySnowOrIceStorm()
// TO:AR 6th ed p165
if (conditions.getWeather().isDownpourOrHeavySnowOrIceStormOrLightningStorm()
|| conditions.getWind().isStrongGale()) {
rollTarget.addModifier(2, "Bad Weather");
}

// TO:AR 6th ed p165
if (conditions.getWind().isStrongerThan(Wind.STRONG_GALE)
|| (conditions.getWeather().isHeavySnow() && conditions.getWind().isStrongGale())) {
rollTarget.addModifier(3, "Really Bad Weather");
Expand Down Expand Up @@ -31253,6 +31268,102 @@ public List<SmokeCloud> getSmokeCloudList() {
return game.getSmokeCloudList();
}

/**
* Check to see if Lightning Storm caused damage
* TO:AR 6th ed. p. 57
* */
private Vector<Report> resolveLightningStormDamage() {
Vector<Report> vFullReport = new Vector<>();
Roll rollStrike = Compute.rollD6(1);

if (rollStrike.getIntValue() > 4) {
Report.addNewline(vFullReport);
vFullReport.add(new Report(5620, Report.PUBLIC));

Roll rollNumber = Compute.rollD6(1);
int numberOfStrikes = Math.max(1, rollNumber.getIntValue() / 2);

for (int i = 0; i < numberOfStrikes; i++) {
Roll rollType = Compute.rollD6(1);
int damage;
switch (rollType.getIntValue()) {
case 1:
case 2:
case 3:
damage = 5;
break;
case 4:
case 5:
damage = 10;
break;
default:
damage = 15;
}

Coords coords;

if (game.getOptions().booleanOption(OptionsConstants.ADVANCED_LIGHTNING_STORM_TARGETS_UNITS)) {
List<Entity> entities = game.getEntitiesVector().stream()
.filter(e -> e.getPosition() != null)
.toList();
int index = Compute.randomInt(entities.size());
coords = entities.get(index).getPosition();
} else {
int x = Compute.randomInt(game.getBoard().getWidth());
int y = Compute.randomInt(game.getBoard().getHeight());
coords = new Coords(x, y);
}

Report r;
r = new Report(5621);
r.add(coords.getBoardNum());
vFullReport.add(r);

vFullReport.addAll(lightningStormDamage(coords, damage));

if (rollType.getIntValue() == 6) {
for (Coords locationAdjacent : coords.allAdjacent()) {
r = new Report(5622);
r.add(locationAdjacent.getBoardNum());
vFullReport.add(r);

vFullReport.addAll(lightningStormDamage(locationAdjacent, 5));
}
}
}
}

return vFullReport;
}

private Vector<Report> lightningStormDamage(Coords coords, int damage) {
Vector<Report> vFullReport = new Vector<>();
Vector<Report> newReports = tryClearHex(coords, damage, Entity.NONE);
vFullReport.addAll(newReports);

Building bldg = game.getBoard().getBuildingAt(coords);

if (bldg != null) {
Vector<Report> buildingReport = damageBuilding(bldg, damage, coords);
vFullReport.addAll(buildingReport);
}

List<Entity> hitEntities = game.getEntitiesVector().stream()
.filter(e -> coords.equals(e.getPosition())
&& !(e instanceof GunEmplacement))
.toList();

for (Entity entity : hitEntities) {
ToHitData toHit = new ToHitData();
toHit.setSideTable(ToHitData.SIDE_RANDOM);
HitData hit = entity.rollHitLocation(ToHitData.HIT_NORMAL, toHit.getSideTable());
Vector<Report> entityReport = damageEntity(entity, hit, damage);
vFullReport.addAll(entityReport);
}

return vFullReport;
}

/**
* Check to see if blowing sand caused damage to airborne VTOL/WIGEs
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,7 @@ void managePhase() {
gameManager.resetEntityPhase(phase);
gameManager.clearReports();
gameManager.resolveHeat();
PlanetaryConditions conditions = gameManager.getGame().getPlanetaryConditions();
if (conditions.isBlowingSandActive()) {
gameManager.addReport(gameManager.resolveBlowingSandDamage());
}
gameManager.resolveWeather();
gameManager.addReport(gameManager.resolveControlRolls());
gameManager.addReport(gameManager.checkForTraitors());
// write End Phase header
Expand Down

0 comments on commit 785fc3b

Please sign in to comment.