From a3652eb55c8530f6c03413e1a386782b3634b8fc Mon Sep 17 00:00:00 2001 From: repligator Date: Wed, 24 Jul 2024 19:49:12 -0400 Subject: [PATCH 01/22] Added whitespace Added whitespace for 3 items in the menu that appears when rightclicking a mech during a game. This changes ViewWarhammer IIC into View Warhammer IIC. --- megamek/i18n/megamek/client/messages.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/megamek/i18n/megamek/client/messages.properties b/megamek/i18n/megamek/client/messages.properties index 9bf341958c5..b3ae327c19b 100644 --- a/megamek/i18n/megamek/client/messages.properties +++ b/megamek/i18n/megamek/client/messages.properties @@ -898,7 +898,7 @@ ClientGUI.openUnitListFileDialog.title=Open Unit List File ClientGUI.saveUnitListFileDialog.title=Save Unit List As ClientGUI.SaveUnitsDialog.message=Do you want to save a record of all units\n(including salvage) to a file? ClientGUI.SaveUnitsDialog.title=Save Units? -ClientGUI.selectMenuItem=Select +ClientGUI.selectMenuItem=Select\u0020 ClientGUI.skinningHelpPath=docs/help/en/skinning/skinningHowTo.html ClientGUI.skinningHelpPath.title=How To: Skinning ClientGUI.StartingScenario=Starting scenario... @@ -906,8 +906,8 @@ ClientGUI.Show=Show ClientGUI.targetMenuItem=Target ClientGUI.title=MegaMek Client ClientGUI.TransmittingData=Receiving game data... -ClientGUI.viewMenuItem=View -ClientGUI.viewReadoutMenuItem=View Readout +ClientGUI.viewMenuItem=View\u0020 +ClientGUI.viewReadoutMenuItem=View Readout\u0020 ClientGUI.doneMenuItem=Done ClientGUI.waitingOnTheServer=Waiting for the server... ClientGUI.PointBlankShot.Message={0} has moved adjacent to the hidden {1}. Take pointblank shot? From 39e5e795e2043ed9ac81642e566b757aa9a0b08a Mon Sep 17 00:00:00 2001 From: sleet01 Date: Wed, 24 Jul 2024 23:23:19 -0700 Subject: [PATCH 02/22] Fix Reflective armor not appearing in MML dropdown --- megamek/src/megamek/common/equipment/ArmorType.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/megamek/src/megamek/common/equipment/ArmorType.java b/megamek/src/megamek/common/equipment/ArmorType.java index dd341c3c9a9..1d4e9bb4a85 100644 --- a/megamek/src/megamek/common/equipment/ArmorType.java +++ b/megamek/src/megamek/common/equipment/ArmorType.java @@ -780,7 +780,7 @@ private static ArmorType createISReflective() { armor.patchworkSlotsMechSV = 2; armor.patchworkSlotsCVFtr = 1; armor.flags = armor.flags.or(F_REFLECTIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT) - .or(F_SUPPORT_TANK_EQUIPMENT); + .or(F_SUPPORT_TANK_EQUIPMENT).or(F_FIGHTER_EQUIPMENT); armor.rulesRefs = "93, TO: AU&E"; //Tech Progression tweaked to combine IntOps with TRO Prototypes/3145 NTNU RS armor.techAdvancement.setTechBase(TECH_BASE_IS).setTechRating(RATING_E) @@ -809,7 +809,7 @@ private static ArmorType createClanReflective() { armor.patchworkSlotsMechSV = 1; armor.patchworkSlotsCVFtr = 1; armor.flags = armor.flags.or(F_REFLECTIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT) - .or(F_SUPPORT_TANK_EQUIPMENT); + .or(F_SUPPORT_TANK_EQUIPMENT).or(F_FIGHTER_EQUIPMENT); armor.rulesRefs = "93, TO: AU&E"; //Tech Progression tweaked to combine IntOps with TRO Prototypes/3145 NTNU RS armor.techAdvancement.setTechBase(TECH_BASE_CLAN).setTechRating(RATING_F) From bdf78ddcdea499679f4b0c53c0af5f1c96a6456f Mon Sep 17 00:00:00 2001 From: repligator Date: Fri, 26 Jul 2024 09:47:14 -0400 Subject: [PATCH 03/22] Adds needed whitespace to right-click target --- megamek/i18n/megamek/client/messages.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/megamek/i18n/megamek/client/messages.properties b/megamek/i18n/megamek/client/messages.properties index b3ae327c19b..ad7d8938d41 100644 --- a/megamek/i18n/megamek/client/messages.properties +++ b/megamek/i18n/megamek/client/messages.properties @@ -903,7 +903,7 @@ ClientGUI.skinningHelpPath=docs/help/en/skinning/skinningHowTo.html ClientGUI.skinningHelpPath.title=How To: Skinning ClientGUI.StartingScenario=Starting scenario... ClientGUI.Show=Show -ClientGUI.targetMenuItem=Target +ClientGUI.targetMenuItem=Target\u0020 ClientGUI.title=MegaMek Client ClientGUI.TransmittingData=Receiving game data... ClientGUI.viewMenuItem=View\u0020 From 515ab6cffd7ff020f2fd80e166b3ce34fef4a04f Mon Sep 17 00:00:00 2001 From: repligator Date: Fri, 26 Jul 2024 12:50:56 -0400 Subject: [PATCH 04/22] Removes the 50 hex minimum for bearings-only launches. --- megamek/src/megamek/common/RangeType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/megamek/src/megamek/common/RangeType.java b/megamek/src/megamek/common/RangeType.java index 35c54946c5a..f4925ca1497 100644 --- a/megamek/src/megamek/common/RangeType.java +++ b/megamek/src/megamek/common/RangeType.java @@ -23,7 +23,7 @@ public class RangeType { public static final int RANGE_EXTREME = 4; public static final int RANGE_LOS = 5; public static final int RANGE_OUT = Integer.MAX_VALUE; - public static final int RANGE_BEARINGS_ONLY_MINIMUM = 51; + public static final int RANGE_BEARINGS_ONLY_MINIMUM = 1; public static final int RANGE_BEARINGS_ONLY_OUT = 5000; public int r_min; From f6ec9ea30553e7380054fdd03855985fbcfad665 Mon Sep 17 00:00:00 2001 From: SJuliez Date: Fri, 26 Jul 2024 22:48:47 +0200 Subject: [PATCH 05/22] Update history.txt --- megamek/docs/history.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/megamek/docs/history.txt b/megamek/docs/history.txt index 27496371fcc..b828da8434b 100644 --- a/megamek/docs/history.txt +++ b/megamek/docs/history.txt @@ -52,6 +52,7 @@ MEGAMEK VERSION HISTORY: + PR #5783: Update Ammunition Autoconfig doc for 0.50.0 + Fix #5794: Fixes Sprite-Swap + PR #5792: Update princess Stealth handling ++ PR #5800: Bearings-only launches are no longer being prevented at ranges below 51 hexes 0.49.20 (2024-06-28 2100 UTC) (THIS IS THE LAST VERSION TO SUPPORT JAVA 11) + PR #5281, #5327, #5308, #5336, #5318, #5383, #5369, #5384, #5455, #5505, #5541: Code internals: preparatory work for supporting game types such as SBF, code cleanup for string drawing, superclass change for BoardView, From 67b80658d06e99d090f62bc072985b3dd9fef107 Mon Sep 17 00:00:00 2001 From: SJuliez Date: Fri, 26 Jul 2024 22:50:12 +0200 Subject: [PATCH 06/22] Update history.txt --- megamek/docs/history.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/megamek/docs/history.txt b/megamek/docs/history.txt index b828da8434b..55dafbc48de 100644 --- a/megamek/docs/history.txt +++ b/megamek/docs/history.txt @@ -53,6 +53,7 @@ MEGAMEK VERSION HISTORY: + Fix #5794: Fixes Sprite-Swap + PR #5792: Update princess Stealth handling + PR #5800: Bearings-only launches are no longer being prevented at ranges below 51 hexes ++ PR #5791: Added much-needed whitespace to some menu items of the board right click menu 0.49.20 (2024-06-28 2100 UTC) (THIS IS THE LAST VERSION TO SUPPORT JAVA 11) + PR #5281, #5327, #5308, #5336, #5318, #5383, #5369, #5384, #5455, #5505, #5541: Code internals: preparatory work for supporting game types such as SBF, code cleanup for string drawing, superclass change for BoardView, From 5b0b3617b1ebb15052da81bb18e0aa3cbb39a959 Mon Sep 17 00:00:00 2001 From: repligator Date: Fri, 26 Jul 2024 17:31:45 -0400 Subject: [PATCH 07/22] Removes a number of duplicated infantry weapons All MM and MML tests passed or ignored. --- megamek/src/megamek/common/WeaponType.java | 28 ---------------------- 1 file changed, 28 deletions(-) diff --git a/megamek/src/megamek/common/WeaponType.java b/megamek/src/megamek/common/WeaponType.java index ff2ab596f99..fdf09b0d7c0 100644 --- a/megamek/src/megamek/common/WeaponType.java +++ b/megamek/src/megamek/common/WeaponType.java @@ -1571,21 +1571,6 @@ public static void initializeTypes() { EquipmentType.addType(new InfantryPulseLaserPistolNWW12()); EquipmentType.addType(new InfantryPulseLaserPistolRDISunSwarmPulsar()); - EquipmentType.addType(new InfantryLaserPistolAA75L()); - EquipmentType.addType(new InfantryLaserPistolAWAWilibyMk4LaserPistol()); - EquipmentType.addType(new InfantryLaserPistolBR25()); - EquipmentType.addType(new InfantryLaserPistolBrightStarL12()); - EquipmentType.addType(new InfantryLaserPistolBrightStarL15()); - EquipmentType.addType(new InfantryLaserPistolBrightStarL7()); - EquipmentType.addType(new InfantryLaserPistolDarklightIVLaserPistol()); - EquipmentType.addType(new InfantryLaserPistolKelvin000Lancer3MM()); - EquipmentType.addType(new InfantryLaserPistolXingShan()); - EquipmentType.addType(new InfantryLaserPistolXingShanER()); - EquipmentType.addType(new InfantryPulseLaserPistolMedusaIII()); - EquipmentType.addType(new InfantryPulseLaserPistolMedusaIV()); - EquipmentType.addType(new InfantryPulseLaserPistolNWW12()); - EquipmentType.addType(new InfantryPulseLaserPistolRDISunSwarmPulsar()); - // Clan Pistols - Commented out can be considered Obsolete EquipmentType.addType(new InfantryPistolClanERLaserPistolWeapon()); EquipmentType.addType(new InfantryPistolClanGaussPistolWeapon()); @@ -1730,19 +1715,6 @@ public static void initializeTypes() { EquipmentType.addType(new InfantryPulseLaserRifleGaul()); EquipmentType.addType(new InfantryPulseLaserRifleTirbuni()); - // Shrapnel Laser Rifles - EquipmentType.addType(new InfantryLaserCarbineBrightstarL15()); - EquipmentType.addType(new InfantryLaserRifleDarkLightCLLight()); - EquipmentType.addType(new InfantryLaserRifleDWSL5S()); - EquipmentType.addType(new InfantryLaserRifleScorcherVIBlazerRifle()); - EquipmentType.addType(new InfantryLaserRifleSyrtisFirebolt12Repaired()); - EquipmentType.addType(new InfantryLaserRifleSyrtisFirebolt12Unrepaired()); - EquipmentType.addType(new InfantryLaserRifleWolfBaronSunraker()); - EquipmentType.addType(new InfantryLaserRifleYangLie()); - EquipmentType.addType(new InfantryPulseLaserRifleDWSL5C()); - EquipmentType.addType(new InfantryPulseLaserRifleGaul()); - EquipmentType.addType(new InfantryPulseLaserRifleTirbuni()); - // Shrapnel Sniper Files EquipmentType.addType(new InfantrySniperRifleBartonAMRAntiArmor()); EquipmentType.addType(new InfantrySniperRifleBartonAMRStandard()); From 30e099a061b993c63dd16d630f9660ceca2c4ba1 Mon Sep 17 00:00:00 2001 From: sleet01 Date: Fri, 26 Jul 2024 15:25:58 -0700 Subject: [PATCH 08/22] Update history.txt --- megamek/docs/history.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/megamek/docs/history.txt b/megamek/docs/history.txt index 55dafbc48de..355396a624c 100644 --- a/megamek/docs/history.txt +++ b/megamek/docs/history.txt @@ -54,6 +54,7 @@ MEGAMEK VERSION HISTORY: + PR #5792: Update princess Stealth handling + PR #5800: Bearings-only launches are no longer being prevented at ranges below 51 hexes + PR #5791: Added much-needed whitespace to some menu items of the board right click menu ++ PR #5798: Fix Reflective armor not appearing in MML dropdown 0.49.20 (2024-06-28 2100 UTC) (THIS IS THE LAST VERSION TO SUPPORT JAVA 11) + PR #5281, #5327, #5308, #5336, #5318, #5383, #5369, #5384, #5455, #5505, #5541: Code internals: preparatory work for supporting game types such as SBF, code cleanup for string drawing, superclass change for BoardView, From f6d866a46b5e7cd24babf8d6d7df98983cdb24d9 Mon Sep 17 00:00:00 2001 From: HammerGS Date: Fri, 26 Jul 2024 19:11:58 -0600 Subject: [PATCH 09/22] Data: Updating Unit files and RAT Generator update --- megamek/data/forcegenerator/2571.xml | 26 ++-- megamek/data/forcegenerator/2650.xml | 30 ++--- megamek/data/forcegenerator/2700.xml | 35 +++--- megamek/data/forcegenerator/2765.xml | 35 +++--- megamek/data/forcegenerator/2780.xml | 40 +++--- megamek/data/forcegenerator/2807.xml | 35 +++--- megamek/data/forcegenerator/2815.xml | 40 +++--- megamek/data/forcegenerator/2823.xml | 40 +++--- megamek/data/forcegenerator/2830.xml | 40 +++--- megamek/data/forcegenerator/2835.xml | 40 +++--- megamek/data/forcegenerator/2855.xml | 40 +++--- megamek/data/forcegenerator/2860.xml | 40 +++--- megamek/data/forcegenerator/2865.xml | 40 +++--- megamek/data/forcegenerator/2870.xml | 40 +++--- megamek/data/forcegenerator/2900.xml | 40 +++--- megamek/data/forcegenerator/2950.xml | 40 +++--- megamek/data/forcegenerator/3019.xml | 40 +++--- megamek/data/forcegenerator/3028.xml | 40 +++--- megamek/data/forcegenerator/3039.xml | 40 +++--- megamek/data/forcegenerator/3049.xml | 40 +++--- megamek/data/forcegenerator/3055.xml | 40 +++--- megamek/data/forcegenerator/3058.xml | 40 +++--- megamek/data/forcegenerator/3060.xml | 54 +++++---- megamek/data/forcegenerator/3067.xml | 76 ++++++------ megamek/data/forcegenerator/3075.xml | 76 ++++++------ megamek/data/forcegenerator/3078.xml | 76 ++++++------ megamek/data/forcegenerator/3082.xml | 88 +++++++------- megamek/data/forcegenerator/3085.xml | 94 +++++++-------- megamek/data/forcegenerator/3100.xml | 114 +++++++++--------- megamek/data/forcegenerator/3131.xml | 114 +++++++++--------- megamek/data/forcegenerator/3145.xml | 114 +++++++++--------- megamek/data/forcegenerator/3150.xml | 114 +++++++++--------- megamek/data/forcegenerator/3160.xml | 114 +++++++++--------- .../Gray Death Strike Suit (HarJel)(Sqd5).blk | 2 +- .../Gray Death Strike Suit (HarJel)(Sqd6).blk | 2 +- megamek/data/mechfiles/name_changes.txt | 1 + megamek/docs/history.txt | 1 + 37 files changed, 1000 insertions(+), 881 deletions(-) diff --git a/megamek/data/forcegenerator/2571.xml b/megamek/data/forcegenerator/2571.xml index 3d938aa515a..6343e385868 100644 --- a/megamek/data/forcegenerator/2571.xml +++ b/megamek/data/forcegenerator/2571.xml @@ -486,6 +486,19 @@ General:8 + + SL:8 + + General:8,SL.R:8 + + + + SL:6,IS:4,MERC:4,Periphery:4 + + cargo,civilian + General:8 + + CC:2,LA:4,SL:2,FWL:2,RWR:2,FS:2,MERC:2,DC:2 @@ -501,19 +514,6 @@ General:2 - - SL:8 - - General:8,SL.R:8 - - - - SL:6,IS:4,MERC:4,Periphery:4 - - cargo,civilian - General:8 - - General:1 diff --git a/megamek/data/forcegenerator/2650.xml b/megamek/data/forcegenerator/2650.xml index 5f9182526be..423264d05d8 100644 --- a/megamek/data/forcegenerator/2650.xml +++ b/megamek/data/forcegenerator/2650.xml @@ -504,21 +504,6 @@ General:8 - - CC:2,LA:4,SL:2,FWL:2,RWR:2,FS:2,MERC:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,IS:7,Periphery.Deep:7,RWR:9,FS:6,MERC:7,TC:8,Periphery:7,LA:8,FWL:8,SL.R:0,TH.HM:6,DC:9 @@ -538,6 +523,21 @@ General:8 + + CC:2,LA:4,SL:2,FWL:2,RWR:2,FS:2,MERC:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + SL:1 diff --git a/megamek/data/forcegenerator/2700.xml b/megamek/data/forcegenerator/2700.xml index 20ed393d6ad..d4111b0ed09 100644 --- a/megamek/data/forcegenerator/2700.xml +++ b/megamek/data/forcegenerator/2700.xml @@ -589,21 +589,6 @@ General:8 - - CC:2,LA:4,SL:2,FWL:2,RWR:2,FS:2,MERC:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,IS:7,Periphery.Deep:7,RWR:9,FS:6,MERC:7,TC:8,Periphery:7,LA:8,FWL:8,SL.R:0,TH.HM:6,DC:9 @@ -623,6 +608,21 @@ General:8 + + CC:2,LA:4,SL:2,FWL:2,RWR:2,FS:2,MERC:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + SL:2 @@ -2727,7 +2727,10 @@ DC:2+ - + + SL.R:5 + + recon SL.R:5 diff --git a/megamek/data/forcegenerator/2765.xml b/megamek/data/forcegenerator/2765.xml index 6e9cb1998ab..0b71a5e1381 100644 --- a/megamek/data/forcegenerator/2765.xml +++ b/megamek/data/forcegenerator/2765.xml @@ -624,21 +624,6 @@ General:8 - - CC:2,LA:4,SL:2,FWL:2,RWR:2,FS:2,MERC:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,IS:7,Periphery.Deep:7,RWR:9,FS:6,MERC:7,TC:8,Periphery:7,LA:8,FWL:8,SL.R:0,TH.HM:6,DC:9 @@ -665,6 +650,21 @@ General:8 + + CC:2,LA:4,SL:2,FWL:2,RWR:2,FS:2,MERC:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + SL:2 @@ -2874,7 +2874,10 @@ DC:3+ - + + SL.R:6 + + recon SL.R:6 diff --git a/megamek/data/forcegenerator/2780.xml b/megamek/data/forcegenerator/2780.xml index 0fd32f4aa33..c468e7cfe79 100644 --- a/megamek/data/forcegenerator/2780.xml +++ b/megamek/data/forcegenerator/2780.xml @@ -623,21 +623,6 @@ General:8 - - CC:2,LA:4,SL:2,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,LA:8,IS:7,Periphery.Deep:7,FWL:8,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,DC:9 @@ -663,6 +648,21 @@ General:8 + + CC:2,LA:4,SL:2,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + SL:2,NIOPS:1 @@ -2883,11 +2883,17 @@ DC:3+ - + + SL.R:7 + + recon SL.R:7 - + + SL.R:4 + + recon SL.R:4 diff --git a/megamek/data/forcegenerator/2807.xml b/megamek/data/forcegenerator/2807.xml index f5dad9224e4..58e73105c96 100644 --- a/megamek/data/forcegenerator/2807.xml +++ b/megamek/data/forcegenerator/2807.xml @@ -614,21 +614,6 @@ General:8 - - CC:2,LA:4,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,LA:8,IS:7,FWL:8,Periphery.Deep:7,FS:6,CIR:7,MERC:7,TC:8,Periphery:7,DC:9 @@ -660,6 +645,21 @@ PP:4 + + CC:2,LA:4,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + PP:2,CS:1,NIOPS:1 @@ -2956,7 +2956,10 @@ DC:3+ - + + PP:3 + + recon PP:3 diff --git a/megamek/data/forcegenerator/2815.xml b/megamek/data/forcegenerator/2815.xml index 1b465349cd2..8246e31ca50 100644 --- a/megamek/data/forcegenerator/2815.xml +++ b/megamek/data/forcegenerator/2815.xml @@ -806,21 +806,6 @@ General:8 - - CC:2,LA:4,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,LA:8,IS:7,FWL:8,Periphery.Deep:7,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,DC:9 @@ -852,6 +837,21 @@ PP:5 + + CC:2,LA:4,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + PP:2,CHH:1,CCC:1,CSR:2,CSV:1,CLAN:1,CGS:2,CCO:1,CS:1,CW:2,NIOPS:1,CJF:1,CGB:1 @@ -3333,11 +3333,17 @@ DC:2+ - + + PP:2,CLAN:7 + + recon PP:2,CLAN:7 - + + CLAN:4,CGS:5 + + recon CLAN:4,CGS:5 diff --git a/megamek/data/forcegenerator/2823.xml b/megamek/data/forcegenerator/2823.xml index f272f179076..fec9d585d5d 100644 --- a/megamek/data/forcegenerator/2823.xml +++ b/megamek/data/forcegenerator/2823.xml @@ -883,21 +883,6 @@ General:8 - - CC:2,LA:4,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,LA:8,IS:7,FWL:8,Periphery.Deep:7,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,DC:9 @@ -926,6 +911,21 @@ General:8,CLAN:8 + + CC:2,LA:4,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,CLAN:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -3465,11 +3465,17 @@ DC:2+ - + + CLAN:7 + + recon CLAN:7 - + + CLAN:4,CGS:6 + + recon CLAN:4,CGS:6 diff --git a/megamek/data/forcegenerator/2830.xml b/megamek/data/forcegenerator/2830.xml index f8955655644..edc1f080fc7 100644 --- a/megamek/data/forcegenerator/2830.xml +++ b/megamek/data/forcegenerator/2830.xml @@ -898,21 +898,6 @@ General:8 - - CC:2,LA:4,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,LA:8,IS:7,FWL:8,Periphery.Deep:7,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,DC:9 @@ -941,6 +926,21 @@ General:8,CLAN:8 + + CC:2,LA:4,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,CLAN:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -3566,11 +3566,17 @@ DC:1+ - + + CLAN:7,BAN:3 + + recon CLAN:7,BAN:3 - + + CLAN:4,CGS:6 + + recon CLAN:4,CGS:6 diff --git a/megamek/data/forcegenerator/2835.xml b/megamek/data/forcegenerator/2835.xml index e33671a1748..17b0b60f833 100644 --- a/megamek/data/forcegenerator/2835.xml +++ b/megamek/data/forcegenerator/2835.xml @@ -931,21 +931,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,LA:8,IS:7,FWL:8,Periphery.Deep:7,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,DC:9 @@ -978,6 +963,21 @@ CLAN:2 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,CLAN:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -3817,11 +3817,17 @@ DC:1+ - + + CLAN:7,BAN:3 + + recon CLAN:7,BAN:3 - + + CLAN:4,CGS:6 + + recon CLAN:4,CGS:6 diff --git a/megamek/data/forcegenerator/2855.xml b/megamek/data/forcegenerator/2855.xml index 6684f4941e8..9ed7ee1112f 100644 --- a/megamek/data/forcegenerator/2855.xml +++ b/megamek/data/forcegenerator/2855.xml @@ -942,21 +942,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,LA:8,IS:7,FWL:8,Periphery.Deep:7,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,DC:9 @@ -989,6 +974,21 @@ CLAN:3 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,CLAN:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -3863,11 +3863,17 @@ recon DC:6 - + + CLAN:7,BAN:3 + + recon CLAN:7,BAN:3 - + + CLAN:4,CGS:6 + + recon CLAN:4,CGS:6 diff --git a/megamek/data/forcegenerator/2860.xml b/megamek/data/forcegenerator/2860.xml index d938e972b5c..17c20d2f954 100644 --- a/megamek/data/forcegenerator/2860.xml +++ b/megamek/data/forcegenerator/2860.xml @@ -916,21 +916,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,LA:8,IS:7,FWL:8,Periphery.Deep:7,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,DC:9 @@ -963,6 +948,21 @@ CLAN:5 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,CLAN:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -3773,11 +3773,17 @@ recon DC:6 - + + CLAN:7,BAN:3 + + recon CLAN:7,BAN:3 - + + CLAN:4,CGS:6 + + recon CLAN:4,CGS:6 diff --git a/megamek/data/forcegenerator/2865.xml b/megamek/data/forcegenerator/2865.xml index 6ef83264f39..7cdc3f9abe5 100644 --- a/megamek/data/forcegenerator/2865.xml +++ b/megamek/data/forcegenerator/2865.xml @@ -913,21 +913,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,LA:8,IS:7,FWL:8,Periphery.Deep:7,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,DC:9 @@ -960,6 +945,21 @@ CLAN:6 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,CLAN:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -3804,11 +3804,17 @@ recon DC:6 - + + CLAN:7,BAN:3 + + recon CLAN:7,BAN:3 - + + CLAN:4,CGS:6 + + recon CLAN:4,CGS:6 diff --git a/megamek/data/forcegenerator/2870.xml b/megamek/data/forcegenerator/2870.xml index 7ed7458218f..32859236ea3 100644 --- a/megamek/data/forcegenerator/2870.xml +++ b/megamek/data/forcegenerator/2870.xml @@ -1028,21 +1028,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,LA:8,IS:7,FWL:8,Periphery.Deep:7,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,DC:9 @@ -1075,6 +1060,21 @@ CLAN:8 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,CLAN:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -4119,11 +4119,17 @@ recon DC:6 - + + CLAN:7,BAN:3 + + recon CLAN:7,BAN:3 - + + CLAN:4,CGS:6 + + recon CLAN:4,CGS:6 diff --git a/megamek/data/forcegenerator/2900.xml b/megamek/data/forcegenerator/2900.xml index 024c97cfbf7..ab8b0d72130 100644 --- a/megamek/data/forcegenerator/2900.xml +++ b/megamek/data/forcegenerator/2900.xml @@ -1055,21 +1055,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,HL:5,IS:7,Periphery.Deep:6,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,LA:8,FWL:8,DC:9 @@ -1102,6 +1087,21 @@ CLAN:8 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,CLAN:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -4251,11 +4251,17 @@ recon DC:6 - + + CLAN:7,BAN:3 + + recon CLAN:7,BAN:3 - + + CLAN:4,CGS:6 + + recon CLAN:4,CGS:6 diff --git a/megamek/data/forcegenerator/2950.xml b/megamek/data/forcegenerator/2950.xml index 4b833f26197..15a690127dc 100644 --- a/megamek/data/forcegenerator/2950.xml +++ b/megamek/data/forcegenerator/2950.xml @@ -1147,21 +1147,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,HL:5,IS:7,Periphery.Deep:6,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,LA:7,FWL:7,DC:8 @@ -1194,6 +1179,21 @@ CLAN:8 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,CLAN:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -4424,11 +4424,17 @@ recon DC:6 - + + CLAN:7,BAN:2 + + recon CLAN:7,BAN:2 - + + CLAN:3,CGS:6 + + recon CLAN:3,CGS:6 diff --git a/megamek/data/forcegenerator/3019.xml b/megamek/data/forcegenerator/3019.xml index 311ce895fc8..8193f503c55 100644 --- a/megamek/data/forcegenerator/3019.xml +++ b/megamek/data/forcegenerator/3019.xml @@ -1237,21 +1237,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,HL:5,IS:7,Periphery.Deep:6,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,LA:6,FWL:6,DC:8 @@ -1284,6 +1269,21 @@ CLAN:8 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -4663,11 +4663,17 @@ recon DC:6 - + + CLAN:6,BAN:2 + + recon CLAN:6,BAN:2 - + + CLAN:3,CGS:5 + + recon CLAN:3,CGS:5 diff --git a/megamek/data/forcegenerator/3028.xml b/megamek/data/forcegenerator/3028.xml index b091deac7ec..e647ae2cbb6 100644 --- a/megamek/data/forcegenerator/3028.xml +++ b/megamek/data/forcegenerator/3028.xml @@ -1319,21 +1319,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - CC:9,MOC:8,HL:5,FRR:8,IS:7,Periphery.Deep:6,SIC:9,FS:6,CIR:7,MERC:7,Periphery:7,TC:8,LA:6,FWL:6,DC:8 @@ -1366,6 +1351,21 @@ CLAN:8 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -4872,11 +4872,17 @@ recon FRR:6,DC:6 - + + CLAN:6,BAN:1 + + recon CLAN:6,BAN:1 - + + CLAN:3,CGS:5 + + recon CLAN:3,CGS:5 diff --git a/megamek/data/forcegenerator/3039.xml b/megamek/data/forcegenerator/3039.xml index f540a2efc6d..03f71ca0a6d 100644 --- a/megamek/data/forcegenerator/3039.xml +++ b/megamek/data/forcegenerator/3039.xml @@ -1391,21 +1391,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - MOC:8,CC:9,HL:5,FRR:8,IS:7,Periphery.Deep:6,SIC:9,FS:6,CIR:7,MERC:7,TC:8,Periphery:7,LA:6,FWL:6,DC:8 @@ -1438,6 +1423,21 @@ CLAN:8 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:1,CHH:1,CCC:1,CSR:2,CW:2,CSV:1,NIOPS:1,CGS:2,CCO:1,CJF:1,CGB:1 @@ -5099,11 +5099,17 @@ recon FRR:6,DC:6 - + + CLAN:6,BAN:1 + + recon CLAN:6,BAN:1 - + + CLAN:3,CGS:5 + + recon CLAN:3,CGS:5 diff --git a/megamek/data/forcegenerator/3049.xml b/megamek/data/forcegenerator/3049.xml index 9cca85c9461..bc81a7016be 100644 --- a/megamek/data/forcegenerator/3049.xml +++ b/megamek/data/forcegenerator/3049.xml @@ -1717,21 +1717,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - MOC:8,CC:9,HL:4,FRR:8,IS:6,Periphery.Deep:6,SIC:9,FS:6,CIR:7,MERC:6,TC:8,Periphery:6,LA:6,FWL:6,DC:8 @@ -1770,6 +1755,21 @@ LA:4,General:4,MERC:4 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + LA:3+,FS:4+ @@ -6188,14 +6188,20 @@ recon FRR:5,DC:5 - + + CLAN:6,BAN:1 + + recon CLAN:6,BAN:1 CS:4,WOB:4 - + + CLAN:3,CGS:5 + + recon CLAN:3,CGS:5 diff --git a/megamek/data/forcegenerator/3055.xml b/megamek/data/forcegenerator/3055.xml index fab08c81dee..bce04aa06b6 100644 --- a/megamek/data/forcegenerator/3055.xml +++ b/megamek/data/forcegenerator/3055.xml @@ -1908,21 +1908,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - MOC:8,CC:9,HL:5,FRR:8,IS:6,Periphery.Deep:6,SIC:9,FS:5,CIR:7,MERC:6,Periphery:6,TC:8,LA:5,FWL:5,DC:8 @@ -1964,6 +1949,21 @@ LA:4,General:4,MERC:4 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:2+,LA:3+,FS:4+,MERC:2+ @@ -6997,14 +6997,20 @@ recon FRR:3,DC:4 - + + CLAN:5,BAN:1 + + recon CLAN:5,BAN:1 CS:1,WOB:1 - + + CLAN:3,CGS:5 + + recon CLAN:3,CGS:5 diff --git a/megamek/data/forcegenerator/3058.xml b/megamek/data/forcegenerator/3058.xml index 2515cd8df91..bbdaeea2293 100644 --- a/megamek/data/forcegenerator/3058.xml +++ b/megamek/data/forcegenerator/3058.xml @@ -2004,21 +2004,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - MOC:8,CC:9,HL:5,FRR:8,IS:6,Periphery.Deep:6,SIC:9,FS:5,CIR:7,MERC:6,Periphery:6,TC:8,LA:5,FWL:5,DC:8 @@ -2060,6 +2045,21 @@ LA:4,General:4,MERC:4 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:2+,LA:3+,FS:4+,MERC:2+ @@ -7502,14 +7502,20 @@ recon FRR:3,DC:4 - + + CLAN:5,BAN:1 + + recon CLAN:5,BAN:1 CS:1,WOB:1 - + + CLAN:3,CGS:5 + + recon CLAN:3,CGS:5 diff --git a/megamek/data/forcegenerator/3060.xml b/megamek/data/forcegenerator/3060.xml index 13e5d79746c..b86f234b34f 100644 --- a/megamek/data/forcegenerator/3060.xml +++ b/megamek/data/forcegenerator/3060.xml @@ -2426,21 +2426,6 @@ General:8 - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - MOC:7,CC:8,HL:4,FRR:7,IS:5,Periphery.Deep:7,SIC:8,FS:4,CIR:6,MERC:5,Periphery:5,TC:7,LA:4,FWL:4,DC:7 @@ -2491,6 +2476,21 @@ LA:4,General:3,MERC:4 + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:3,LA:4,FS:5,MERC:3 @@ -2541,6 +2541,13 @@ CLAN:8 + + IS:3 + + support + General:3 + + CC:8,MOC:4,LA:3,Periphery.CM:3,Periphery.HR:3,Periphery.ME:3,MH:3,SIC:5,FS:5,MERC:4,TC:4,Periphery:2 @@ -9248,14 +9255,20 @@ recon FRR:2,DC:3 - + + CLAN:5,BAN:1 + + recon CLAN:5,BAN:1 CS:1,WOB:1 - + + CLAN:3,CGS:5 + + recon CLAN:3,CGS:5 @@ -9328,13 +9341,6 @@ CS:8,WOB:8 - - IS:3 - - support - General:3 - - CHH:4,CIH:5,CDS:3,CSR:3,CBS:3,CLAN:2,CFM:3 diff --git a/megamek/data/forcegenerator/3067.xml b/megamek/data/forcegenerator/3067.xml index 287844ffcae..e7f3a5cae04 100644 --- a/megamek/data/forcegenerator/3067.xml +++ b/megamek/data/forcegenerator/3067.xml @@ -2777,28 +2777,6 @@ WOB:4 - - LA:2 - - support,engineer - General:8 - - - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - MOC:5-,CC:6-,HL:4-,FRR:5-,IS:4-,Periphery.Deep:7,FS:4-,CIR:5-,MERC:4-,TC:6-,Periphery:5-,LA:3-,FWL:3-,DC:5- @@ -2861,6 +2839,28 @@ LA:4,General:3,MERC:4 + + LA:2 + + support,engineer + General:8 + + + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:3,FVC:6,LA:4,FS:6,MERC:3 @@ -2920,6 +2920,13 @@ CLAN:8 + + IS:5 + + support + General:5 + + CC:6,MOC:5,WOB:4,FS:5,MERC:5,CDP:5,TC:5,Periphery:1,FVC:5,LA:3,Periphery.CM:4,Periphery.HR:3,Periphery.ME:3,MH:3 @@ -11609,14 +11616,20 @@ recon FRR:2-,DC:3- - + + CLAN:5,FWL:3,WOB:3,BAN:1 + + recon CLAN:5,FWL:3,WOB:3,BAN:1 CS:1,WOB:1 - + + CLAN:3,FWL:2,WOB:3,CGS:5 + + recon CLAN:3,FWL:2,WOB:3,CGS:5 @@ -11726,13 +11739,6 @@ WOB:8 - - IS:5 - - support - General:5 - - CHH:4,CIH:6,CDS:3,CSR:3,CBS:3,CLAN:2,CFM:3,CWIE:3 @@ -12673,19 +12679,13 @@ - CNC:5,DC:3 + CNC:2,DC:2 General:8 - - - CNC:3,DC:2 General:8 - - - CNC:2,DC:2 General:8 diff --git a/megamek/data/forcegenerator/3075.xml b/megamek/data/forcegenerator/3075.xml index 86a6d1afafe..4517c7306f0 100644 --- a/megamek/data/forcegenerator/3075.xml +++ b/megamek/data/forcegenerator/3075.xml @@ -3165,28 +3165,6 @@ WOB:4 - - LA:2 - - support,engineer - General:8 - - - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - MOC:3-,CC:4-,HL:3-,FRR:3-,IS:3-,Periphery.Deep:7,FS:3-,CIR:4-,MERC:3-,TC:3-,Periphery:4-,LA:2-,FWL:1-,DC:3- @@ -3252,6 +3230,28 @@ LA:4,General:2,MERC:4 + + LA:2 + + support,engineer + General:8 + + + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:4,FVC:6,LA:4,FS:6,MERC:4 @@ -3311,6 +3311,13 @@ CLAN:8 + + IS:5 + + support + General:5 + + CC:6,MOC:5,WOB:5,FS:5,MERC:5,CDP:5,TC:5,Periphery:1,FVC:5,LA:2,Periphery.CM:3,Periphery.HR:2,Periphery.ME:2,MH:2 @@ -12475,14 +12482,20 @@ recon FRR:1-,DC:2- - + + CLAN:5,FWL:4,WOB:4,BAN:1 + + recon CLAN:5,FWL:4,WOB:4,BAN:1 CS:1,WOB:1 - + + CLAN:3,FWL:3,WOB:4,RCM:3,CGS:5 + + recon CLAN:3,FWL:3,WOB:4,RCM:3,CGS:5 @@ -12592,13 +12605,6 @@ WOB:8 - - IS:5 - - support - General:5 - - CHH:4,CDS:3,CSR:3,CBS:3,CLAN:1,CWIE:3 @@ -13608,19 +13614,13 @@ - CNC:6,DC:4 + CNC:2,DC:2 General:8 - - - CNC:4,DC:3 General:8 - - - CNC:2,DC:2 General:8 diff --git a/megamek/data/forcegenerator/3078.xml b/megamek/data/forcegenerator/3078.xml index 747fb7ba229..a8f67f6ed9d 100644 --- a/megamek/data/forcegenerator/3078.xml +++ b/megamek/data/forcegenerator/3078.xml @@ -3394,28 +3394,6 @@ WOB:4 - - LA:2 - - support,engineer - General:8 - - - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - MOC:2-,CC:3-,HL:3-,FRR:2-,IS:3-,Periphery.Deep:7,FS:3-,CIR:4-,MERC:3-,TC:3-,Periphery:4-,LA:2-,CGB.FRR:2-,ROS:3-,FWL:1-,DC:3- @@ -3487,6 +3465,28 @@ LA:4,General:1,MERC:4 + + LA:2 + + support,engineer + General:8 + + + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CIR:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + CS:4,FVC:6,LA:4,FS:6,MERC:4 @@ -3546,6 +3546,13 @@ CLAN:8 + + IS:5 + + support + General:5 + + CC:6,MOC:5,WOB:5,FS:5,MERC:5,CDP:5,TC:5,Periphery:1,FVC:5,LA:1,Periphery.CM:3,Periphery.HR:2,Periphery.ME:2,MH:2 @@ -13143,14 +13150,20 @@ recon FRR:1-,CGB.FRR:1-,DC:2- - + + SC:5,MCM:5,CLAN:5,FWL:4,WOB:4,DGM:5,BAN:1 + + recon SC:5,MCM:5,CLAN:5,FWL:4,WOB:4,DGM:5,BAN:1 CS:1,WOB:1 - + + SC:4,DoO:3,MCM:4,CLAN:3,FWL:3,WOB:4,DO:3,DGM:4,TP:3,DA:3,RCM:3,CGS:5 + + recon SC:4,DoO:3,MCM:4,CLAN:3,FWL:3,WOB:4,DO:3,DGM:4,TP:3,DA:3,RCM:3,CGS:5 @@ -13266,13 +13279,6 @@ WOB:8 - - IS:5 - - support - General:5 - - CHH:4,CDS:3,CSR:2,CBS:3,CLAN:1,CWIE:3 @@ -14332,19 +14338,13 @@ - CNC:6,DC:4 + CNC:2,DC:2 General:8 - - - CNC:4,DC:3 General:8 - - - CNC:2,DC:2 General:8 diff --git a/megamek/data/forcegenerator/3082.xml b/megamek/data/forcegenerator/3082.xml index 8d1f5765e8c..0e8d420a5f5 100644 --- a/megamek/data/forcegenerator/3082.xml +++ b/megamek/data/forcegenerator/3082.xml @@ -3109,28 +3109,6 @@ General:8 - - LA:2 - - support,engineer - General:8 - - - - CC:2,LA:3,FWL:2,FS:2,MERC:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - MOC:2-,CC:3-,HL:2-,IS:2-,Periphery.Deep:7,FS:3,MERC:2,TC:2-,Periphery:3-,LA:2,CGB.FRR:1-,ROS:3,DC:3 @@ -3202,6 +3180,28 @@ LA:4,MERC:4 + + LA:2 + + support,engineer + General:8 + + + + CC:2,LA:3,FWL:2,FS:2,MERC:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + FVC:5,LA:4,FS:5,MERC:4 @@ -3273,6 +3273,13 @@ CLAN:8 + + IS:5 + + support + General:5 + + CC:5,MOC:4,FVC:4,Periphery.CM:3,Periphery.HR:2,Periphery.ME:2,MH:2,FS:4,MERC:4,CDP:4,TC:4 @@ -10589,12 +10596,6 @@ CC:2 - - CC:4,MOC:4,MERC:2 - - General:8 - - CW:5,CLAN:4 @@ -11066,6 +11067,12 @@ CC:7 + + CC:4,MOC:4,MERC:2 + + General:8 + + CHH:4,CCC:4,CSR:2,CW:4,CBS:3,CSL:3,CCO:3,CJF:3,RA:3,CWIE:4 @@ -12286,14 +12293,20 @@ recon DC:1- - + + SC:6,MCM:6,CLAN:5,FWL:4,DGM:6,MSC:6,BAN:1 + + recon SC:6,MCM:6,CLAN:5,FWL:4,DGM:6,MSC:6,BAN:1 MSC:1 - + + CC:3,DoO:4,CLAN:3,DO:4,DGM:5,MERC:3,SC:5,MCM:5,FWL:4,MSC:5,TP:4,DA:4,RCM:4 + + recon CC:3,DoO:4,CLAN:3,DO:4,DGM:5,MERC:3,SC:5,MCM:5,FWL:4,MSC:5,TP:4,DA:4,RCM:4 @@ -12403,13 +12416,6 @@ ROS:8 - - IS:5 - - support - General:5 - - CHH:5,CDS:4,CSR:2,CBS:3,RA:2,CWIE:3 @@ -13333,19 +13339,13 @@ - CNC:7,DC:5 + CNC:3,DC:3 General:8 - - - CNC:5,DC:4 General:8 - - - CNC:3,DC:3 General:8 diff --git a/megamek/data/forcegenerator/3085.xml b/megamek/data/forcegenerator/3085.xml index 7aa7c22f5c5..7d1b7990574 100644 --- a/megamek/data/forcegenerator/3085.xml +++ b/megamek/data/forcegenerator/3085.xml @@ -3167,28 +3167,6 @@ General:8 - - LA:2 - - support,engineer - General:8 - - - - CC:2,LA:3,FWL:2,FS:2,MERC:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - MOC:1-,CC:2-,HL:2-,IS:2-,Periphery.Deep:7,FS:3,MERC:2,TC:2-,Periphery:3-,LA:2,CGB.FRR:1-,ROS:3,DC:3 @@ -3263,6 +3241,28 @@ LA:4,MERC:4 + + LA:2 + + support,engineer + General:8 + + + + CC:2,LA:3,FWL:2,FS:2,MERC:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + RA.OA:4,TC:4,RA:3 @@ -3349,6 +3349,13 @@ CLAN:8 + + IS:5 + + support + General:5 + + ROS:3 @@ -11017,12 +11024,6 @@ CC:2 - - CC:5,MOC:5,MERC:3 - - General:8 - - CW:5,CLAN:4 @@ -11523,6 +11524,12 @@ CC:8 + + CC:5,MOC:5,MERC:3 + + General:8 + + CHH:1,CDS:3,RA:4 @@ -12795,14 +12802,20 @@ recon DC:1- - + + CLAN:5,FWL:4,MSC:6,BAN:1 + + recon CLAN:5,FWL:4,MSC:6,BAN:1 MSC:1 - + + CC:3,OP:4,DoO:4,CLAN:3,FWL:4,DO:4,MSC:5,TP:4,MERC:3,DA:4,RCM:4 + + recon CC:3,OP:4,DoO:4,CLAN:3,FWL:4,DO:4,MSC:5,TP:4,MERC:3,DA:4,RCM:4 @@ -12918,13 +12931,6 @@ ROS:8 - - IS:5 - - support - General:5 - - CHH:5,CDS:4,RA:3,CWIE:3 @@ -13911,16 +13917,16 @@ - CNC:7,DC:5 + CNC:3,DC:3 General:8 - - - CNC:5,DC:4 General:8 + + General:8 + DTA:3,OP:3,ROS:3,CNC:4,MSC:3,MERC:3,DC:4 @@ -13933,12 +13939,6 @@ General:2 - - CNC:3,DC:3 - - General:8 - - General:7,CLAN:3 diff --git a/megamek/data/forcegenerator/3100.xml b/megamek/data/forcegenerator/3100.xml index 9b0df289118..5760c22fcb1 100644 --- a/megamek/data/forcegenerator/3100.xml +++ b/megamek/data/forcegenerator/3100.xml @@ -3305,28 +3305,6 @@ General:8 - - LA:2 - - support,engineer - General:8 - - - - CC:2,LA:3,FWL:2,FS:2,MERC:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - LA:3,ROS:4,FS:4,MERC:3,Periphery:2-,DC:4 @@ -3411,6 +3389,28 @@ LA:3,FS:4,MERC:4 + + LA:2 + + support,engineer + General:8 + + + + CC:2,LA:3,FWL:2,FS:2,MERC:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + RA.OA:6,IS:2,MERC:3,TC:6,RA:5,Periphery:2 @@ -3517,6 +3517,13 @@ General:8 + + IS:5 + + support + General:5 + + ROS:4 @@ -7652,16 +7659,6 @@ FS:4,DC:4 - - LA:6,ROS:4,FS:4 - - General:8 - - - spotter - General:4 - - IS:3,CLAN.IS:3-,CJF:3- @@ -7683,6 +7680,16 @@ General:2 + + LA:6,ROS:4,FS:4 + + General:8 + + + spotter + General:4 + + CHH:3,CDS:5,LA:4,CNC:5,IS:4,DC:4,CWIE:4 @@ -11493,12 +11500,6 @@ CC:2 - - CC:7,MOC:6,MERC:4 - - General:8 - - CW:5,CLAN:4 @@ -12012,6 +12013,12 @@ CC:8 + + CC:7,MOC:6,MERC:4 + + General:8 + + CHH:2,RD:2,CDS:3,CLAN.IS:2,FS:2,RA:5 @@ -13295,14 +13302,20 @@ recon FVC:1-,PIR:2-,MERC:1- - + + CLAN:5,FWL:4,MSC:6,BAN:1 + + recon CLAN:5,FWL:4,MSC:6,BAN:1 MSC:1 - + + CC:4,OP:4,CLAN:3,FWL:4,MSC:5,MERC:4,DA:4,RCM:4 + + recon CC:4,OP:4,CLAN:3,FWL:4,MSC:5,MERC:4,DA:4,RCM:4 @@ -13418,13 +13431,6 @@ ROS:8 - - IS:5 - - support - General:5 - - CHH:6,CDS:5,RA:3,CWIE:3 @@ -14448,16 +14454,16 @@ - CNC:7,DC:5 + CNC:3,DC:3 General:8 - - - CNC:5,DC:4 General:8 + + General:8 + DTA:4,OP:4,CDS:4,ROS:4,CNC:5,FWL:4,MSC:4,MERC:4,CJF:4,DC:5 @@ -14470,12 +14476,6 @@ General:2 - - CNC:3,DC:3 - - General:8 - - General:7,CLAN:3 diff --git a/megamek/data/forcegenerator/3131.xml b/megamek/data/forcegenerator/3131.xml index 9aa91a763e3..05ee4d11543 100644 --- a/megamek/data/forcegenerator/3131.xml +++ b/megamek/data/forcegenerator/3131.xml @@ -3616,28 +3616,6 @@ General:8 - - LA:2 - - support,engineer - General:8 - - - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CP:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - LA:3,ROS:4,FS:4,MERC:3,Periphery:1-,DC:5 @@ -3722,6 +3700,28 @@ LA:4,FS:5,MERC:5 + + LA:2 + + support,engineer + General:8 + + + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CP:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + RA.OA:7,IS:3,MERC:4,TC:7,RA:6,Periphery:3 @@ -3828,6 +3828,13 @@ General:8 + + IS:5 + + support + General:5 + + ROS:4 @@ -8165,16 +8172,6 @@ General:8 - - LA:6,ROS:4,FS:4 - - General:8 - - - spotter - General:4 - - IS:3,CLAN.IS:3-,CJF:4- @@ -8196,6 +8193,16 @@ General:2 + + LA:6,ROS:4,FS:4 + + General:8 + + + spotter + General:4 + + CHH:3,CDS:5,LA:4,CNC:5,IS:4,CP:5,DC:4,CWIE:4 @@ -12204,12 +12211,6 @@ CC:2 - - CC:8,MOC:7,MERC:4 - - General:8 - - CWE:5,CW:5,CLAN:4 @@ -12710,6 +12711,12 @@ CC:8 + + CC:8,MOC:7,MERC:4 + + General:8 + + CHH:3,RD:3,CDS:3,CLAN.IS:3,FS:3,RA:6 @@ -14067,14 +14074,20 @@ recon PIR:1- - + + CLAN:5,FWL:4,MSC:6,CP:4,BAN:1 + + recon CLAN:5,FWL:4,MSC:6,CP:4,BAN:1 MSC:1 - + + CC:4,OP:4,CLAN:3,FWL:4,MSC:5,MERC:4,DA:4,RCM:4,CP:4 + + recon CC:4,OP:4,CLAN:3,FWL:4,MSC:5,MERC:4,DA:4,RCM:4,CP:4 @@ -14187,13 +14200,6 @@ ROS:8 - - IS:5 - - support - General:5 - - CHH:6,CDS:5,CP:5,RA:3,CWIE:3 @@ -15319,16 +15325,16 @@ - CNC:7,CP:7,DC:5 + CNC:3,CP:3,DC:3 General:8 - - - CNC:5,CP:5,DC:4 General:8 + + General:8 + DTA:4,OP:4,CDS:4,ROS:5,CNC:5,FWL:5,MSC:4,MERC:4,CP:4,CJF:4,DC:6 @@ -15341,12 +15347,6 @@ General:2 - - CNC:3,CP:3,DC:3 - - General:8 - - General:7,CLAN:3 diff --git a/megamek/data/forcegenerator/3145.xml b/megamek/data/forcegenerator/3145.xml index 0f4f5e6e4ac..a2213452439 100644 --- a/megamek/data/forcegenerator/3145.xml +++ b/megamek/data/forcegenerator/3145.xml @@ -3448,28 +3448,6 @@ General:8 - - LA:2 - - support,engineer - General:8 - - - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CP:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - LA:3,ROS:4,FS:4,MERC:3,Periphery:1-,DC:5 @@ -3573,6 +3551,28 @@ CJF:8 + + LA:2 + + support,engineer + General:8 + + + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CP:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + RA.OA:7,IS:3,MERC:4,TC:7,RA:6,Periphery:3 @@ -3697,6 +3697,13 @@ General:8 + + IS:5 + + support + General:5 + + ROS:4 @@ -8081,16 +8088,6 @@ General:8 - - LA:6,ROS:4,FS:4 - - General:8 - - - spotter - General:4 - - IS:3,CLAN.IS:3-,CJF:4- @@ -8112,6 +8109,16 @@ General:2 + + LA:6,ROS:4,FS:4 + + General:8 + + + spotter + General:4 + + CHH:3,CDS:5,LA:4,IS:4,CP:5,DC:4,CWIE:4 @@ -12205,12 +12212,6 @@ CC:2 - - CC:8,MOC:7,MERC:4 - - General:8 - - CWE:5,CLAN:4 @@ -12726,6 +12727,12 @@ CC:8 + + CC:8,MOC:7,MERC:4 + + General:8 + + CHH:3,RD:3,CDS:3,CLAN.IS:4,FS:3,RA:6 @@ -14129,11 +14136,17 @@ recon BAN:6,Periphery:1- - + + CLAN:5,FWL:5,CP:5,BAN:1 + + recon CLAN:5,FWL:5,CP:5,BAN:1 - + + CC:4,CLAN:3,FWL:4,MERC:4,DA:4,CP:4 + + recon CC:4,CLAN:3,FWL:4,MERC:4,DA:4,CP:4 @@ -14246,13 +14259,6 @@ ROS:8 - - IS:5 - - support - General:5 - - CHH:6,CDS:5,CP:5,RA:3,CWIE:3 @@ -15441,16 +15447,16 @@ - CP:7,DC:5 + CP:3,DC:3 General:8 - - - CP:5,DC:4 General:8 + + General:8 + ROS:5,FWL:5,MERC:4,CP:5,DC:6 @@ -15463,12 +15469,6 @@ General:2 - - CP:3,DC:3 - - General:8 - - General:7,CLAN:3 diff --git a/megamek/data/forcegenerator/3150.xml b/megamek/data/forcegenerator/3150.xml index 742b0f397b2..7a5b72425d2 100644 --- a/megamek/data/forcegenerator/3150.xml +++ b/megamek/data/forcegenerator/3150.xml @@ -3495,28 +3495,6 @@ General:8 - - LA:2 - - support,engineer - General:8 - - - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CP:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - LA:3,ROS:4,FS:4,MERC:3,Periphery:1-,DC:5 @@ -3620,6 +3598,28 @@ CJF:4 + + LA:2 + + support,engineer + General:8 + + + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CP:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + RA.OA:7,IS:3,MERC:4,TC:7,RA:6,Periphery:3 @@ -3741,6 +3741,13 @@ General:8 + + IS:5 + + support + General:5 + + ROS:4 @@ -8146,16 +8153,6 @@ General:8 - - LA:6,ROS:4,FS:4 - - General:8 - - - spotter - General:4 - - IS:3,CLAN.IS:3-,CJF:4- @@ -8177,6 +8174,16 @@ General:2 + + LA:6,ROS:4,FS:4 + + General:8 + + + spotter + General:4 + + CHH:3,CDS:5,LA:4,IS:4,CP:5,DC:4,CWIE:4 @@ -12279,12 +12286,6 @@ CC:2 - - CC:8,MOC:7,MERC:4 - - General:8 - - CWE:5,CLAN:4 @@ -12800,6 +12801,12 @@ CC:8 + + CC:8,MOC:7,MERC:4 + + General:8 + + CHH:3,RD:3,CDS:3,CLAN.IS:4,FS:2,RA:6 @@ -14203,11 +14210,17 @@ recon BAN:6,Periphery:1- - + + CLAN:5,FWL:5,CP:5,BAN:1 + + recon CLAN:5,FWL:5,CP:5,BAN:1 - + + CC:4,CLAN:3,FWL:4,MERC:4,DA:4,CP:4 + + recon CC:4,CLAN:3,FWL:4,MERC:4,DA:4,CP:4 @@ -14320,13 +14333,6 @@ ROS:8 - - IS:5 - - support - General:5 - - CHH:6,CDS:5,CP:5,RA:3,CWIE:3 @@ -15519,16 +15525,16 @@ - CP:7,DC:5 + CP:3,DC:3 General:8 - - - CP:5,DC:4 General:8 + + General:8 + ROS:5,FWL:5,MERC:4,CP:5,DC:6 @@ -15541,12 +15547,6 @@ General:2 - - CP:3,DC:3 - - General:8 - - General:7,CLAN:3 diff --git a/megamek/data/forcegenerator/3160.xml b/megamek/data/forcegenerator/3160.xml index 583b57626a0..31b4597ce6e 100644 --- a/megamek/data/forcegenerator/3160.xml +++ b/megamek/data/forcegenerator/3160.xml @@ -3369,28 +3369,6 @@ General:8 - - LA:2 - - support,engineer - General:8 - - - - CC:2,LA:3,FWL:2,FS:2,MERC:2,CP:2,DC:2 - - support,engineer - General:8 - - - support,engineer - General:4 - - - support,engineer - General:2 - - LA:3,FS:4,MERC:3,Periphery:1-,DC:5 @@ -3488,6 +3466,28 @@ CJF:4 + + LA:2 + + support,engineer + General:8 + + + + CC:2,LA:3,FWL:2,FS:2,MERC:2,CP:2,DC:2 + + support,engineer + General:8 + + + support,engineer + General:4 + + + support,engineer + General:2 + + RA.OA:7,IS:3,MERC:4,TC:7,RA:6,Periphery:3 @@ -3609,6 +3609,13 @@ General:8 + + IS:5 + + support + General:5 + + CC:4,MOC:3,FVC:3,Periphery.CM:2,Periphery.HR:1,Periphery.ME:1,MH:1,FS:2,MERC:3,CDP:3,TC:3 @@ -7876,16 +7883,6 @@ General:8 - - LA:6,FS:4 - - General:8 - - - spotter - General:4 - - IS:3,CLAN.IS:3-,CJF:4- @@ -7907,6 +7904,16 @@ General:2 + + LA:6,FS:4 + + General:8 + + + spotter + General:4 + + CHH:3,CDS:5,LA:4,IS:4,CP:5,DC:4 @@ -11932,12 +11939,6 @@ CC:2 - - CC:8,MOC:7,MERC:4 - - General:8 - - CWE:5,CLAN:4 @@ -12442,6 +12443,12 @@ CC:8 + + CC:8,MOC:7,MERC:4 + + General:8 + + CHH:3,RD:3,CDS:3,CLAN.IS:4,FS:1,RA:6 @@ -13796,11 +13803,17 @@ recon BAN:6,Periphery:1- - + + CLAN:5,FWL:5,CP:5,BAN:1 + + recon CLAN:5,FWL:5,CP:5,BAN:1 - + + CC:4,CLAN:3,FWL:4,MERC:4,DA:4,CP:4 + + recon CC:4,CLAN:3,FWL:4,MERC:4,DA:4,CP:4 @@ -13907,13 +13920,6 @@ CJF:4 - - IS:5 - - support - General:5 - - CHH:6,CDS:5,CP:5,RA:3 @@ -14986,16 +14992,16 @@ - CP:7,DC:5 + CP:3,DC:3 General:8 - - - CP:5,DC:4 General:8 + + General:8 + FWL:5,MERC:4,CP:5,DC:6 @@ -15008,12 +15014,6 @@ General:2 - - CP:3,DC:3 - - General:8 - - General:7,CLAN:3 diff --git a/megamek/data/mechfiles/battlearmor/3145/NTNU RS/Gray Death Strike Suit (HarJel)(Sqd5).blk b/megamek/data/mechfiles/battlearmor/3145/NTNU RS/Gray Death Strike Suit (HarJel)(Sqd5).blk index fa9be627b24..c283a2e0df2 100644 --- a/megamek/data/mechfiles/battlearmor/3145/NTNU RS/Gray Death Strike Suit (HarJel)(Sqd5).blk +++ b/megamek/data/mechfiles/battlearmor/3145/NTNU RS/Gray Death Strike Suit (HarJel)(Sqd5).blk @@ -12,7 +12,7 @@ Gray Death Strike Suit -(HarJel)(Sqd4) +(HarJel)(Sqd5) diff --git a/megamek/data/mechfiles/battlearmor/3145/NTNU RS/Gray Death Strike Suit (HarJel)(Sqd6).blk b/megamek/data/mechfiles/battlearmor/3145/NTNU RS/Gray Death Strike Suit (HarJel)(Sqd6).blk index 057fa3145b0..48dceeb3eaa 100644 --- a/megamek/data/mechfiles/battlearmor/3145/NTNU RS/Gray Death Strike Suit (HarJel)(Sqd6).blk +++ b/megamek/data/mechfiles/battlearmor/3145/NTNU RS/Gray Death Strike Suit (HarJel)(Sqd6).blk @@ -12,7 +12,7 @@ Gray Death Strike Suit -(HarJel)(Sqd4) +(HarJel)(Sqd6) diff --git a/megamek/data/mechfiles/name_changes.txt b/megamek/data/mechfiles/name_changes.txt index 1a75c6ab701..d3d8bc1e7b8 100644 --- a/megamek/data/mechfiles/name_changes.txt +++ b/megamek/data/mechfiles/name_changes.txt @@ -654,6 +654,7 @@ Mad Dog (Vulture) A|Vulture (Mad Dog) A Mad Dog (Vulture) B|Vulture (Mad Dog) B Mad Dog (Vulture) C|Vulture (Mad Dog) C Mad Dog (Vulture) Prime|Vulture (Mad Dog) Prime +Marauder Red Hunter|Marauder (Red Hunter-3146) Marauder IIC (Standard)|Marauder IIC Mist Lynx (Koshi) A|Koshi (Mist Lynx) A Mist Lynx (Koshi) B|Koshi (Mist Lynx) B diff --git a/megamek/docs/history.txt b/megamek/docs/history.txt index 355396a624c..00a5c6c5a03 100644 --- a/megamek/docs/history.txt +++ b/megamek/docs/history.txt @@ -55,6 +55,7 @@ MEGAMEK VERSION HISTORY: + PR #5800: Bearings-only launches are no longer being prevented at ranges below 51 hexes + PR #5791: Added much-needed whitespace to some menu items of the board right click menu + PR #5798: Fix Reflective armor not appearing in MML dropdown ++ Fix #5803: Removes a number of duplicated infantry weapons 0.49.20 (2024-06-28 2100 UTC) (THIS IS THE LAST VERSION TO SUPPORT JAVA 11) + PR #5281, #5327, #5308, #5336, #5318, #5383, #5369, #5384, #5455, #5505, #5541: Code internals: preparatory work for supporting game types such as SBF, code cleanup for string drawing, superclass change for BoardView, From 4e1b97437b06674f2ef9fa8302f83924ca8f1ded Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 27 Jul 2024 09:37:09 +0200 Subject: [PATCH 10/22] Issue 5790, improve combat comp heat report message --- megamek/i18n/megamek/common/report-messages.properties | 2 +- megamek/i18n/megamek/common/report-messages_de.properties | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/megamek/i18n/megamek/common/report-messages.properties b/megamek/i18n/megamek/common/report-messages.properties index 6a9c54306bc..a0cea53865f 100755 --- a/megamek/i18n/megamek/common/report-messages.properties +++ b/megamek/i18n/megamek/common/report-messages.properties @@ -621,7 +621,7 @@ 5020=Adding heat due to extreme temperatures... 5021=Adding heat due to flawed cooling system... 5025=Subtracting heat due to extreme temperatures... -5026=Subtracting heat due to combat computer... +5026=(Includes heat due to combat computer.) 5027=Subtracting heat due to RISC Emergency Coolant System... 5030=Adding heat from a fire... 5032=Adding heat from magma... diff --git a/megamek/i18n/megamek/common/report-messages_de.properties b/megamek/i18n/megamek/common/report-messages_de.properties index 5ee7c05d34f..38d6f30f1c2 100644 --- a/megamek/i18n/megamek/common/report-messages_de.properties +++ b/megamek/i18n/megamek/common/report-messages_de.properties @@ -615,3 +615,4 @@ 7100= hat die BV-Anteil Siegbedingung mit % erreicht. 7105= hat die BV-Zerst\u00f6rt Siegbedingung mit % erreicht. 7200= hat alle Siegbedingungen erreicht. +5026=(Einschließlich Hitze für den Combat Computer.) From 25f06752fb5f5323ec055cbad7cef5eea46217dc Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 27 Jul 2024 10:40:39 +0200 Subject: [PATCH 11/22] fix lobby copy paste for empty model --- .../client/ui/swing/lobby/ChatLounge.java | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/megamek/src/megamek/client/ui/swing/lobby/ChatLounge.java b/megamek/src/megamek/client/ui/swing/lobby/ChatLounge.java index 309a532abab..e421d7fb83a 100644 --- a/megamek/src/megamek/client/ui/swing/lobby/ChatLounge.java +++ b/megamek/src/megamek/client/ui/swing/lobby/ChatLounge.java @@ -2569,23 +2569,17 @@ public void importClipboard() { StringTokenizer lines = new StringTokenizer(result, "\n"); while (lines.hasMoreTokens()) { String line = lines.nextToken(); - StringTokenizer tabs = new StringTokenizer(line, "\t"); - String unit = ""; - if (tabs.hasMoreTokens()) { - unit = tabs.nextToken(); - } - if (tabs.hasMoreTokens()) { - unit += " " + tabs.nextToken(); - } - MechSummary ms = MechSummaryCache.getInstance().getMech(unit); - if (ms == null) { - continue; - } - Entity newEntity = new MechFileParser(ms.getSourceFile(), - ms.getEntryName()).getEntity(); - if (newEntity != null) { - newEntity.setOwner(localPlayer()); - newEntities.add(newEntity); + String[] tokens = line.split("\t"); + if (tokens.length >= 2) { + String unitName = (tokens[0] + " " + tokens[1]).trim(); + MechSummary ms = MechSummaryCache.getInstance().getMech(unitName); + if (ms != null) { + Entity newEntity = ms.loadEntity(); + if (newEntity != null) { + newEntity.setOwner(localPlayer()); + newEntities.add(newEntity); + } + } } } } catch (Exception ex) { From 593f5d1b8e56b117da16d64236f76dfa838825fb Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 27 Jul 2024 11:18:41 +0200 Subject: [PATCH 12/22] guard against nonexistent weapon --- .../client/ui/swing/boardview/FiringArcSpriteHandler.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/megamek/src/megamek/client/ui/swing/boardview/FiringArcSpriteHandler.java b/megamek/src/megamek/client/ui/swing/boardview/FiringArcSpriteHandler.java index 19e76935acc..eb178c63137 100644 --- a/megamek/src/megamek/client/ui/swing/boardview/FiringArcSpriteHandler.java +++ b/megamek/src/megamek/client/ui/swing/boardview/FiringArcSpriteHandler.java @@ -67,6 +67,11 @@ public FiringArcSpriteHandler(BoardView boardView, ClientGUI clientGUI) { public void update(Entity entity, WeaponMounted weapon, @Nullable MovePath movePath) { firingEntity = entity; int weaponId = entity.getEquipmentNum(weapon); + if (weaponId == -1) { + // entities are replaced all the time by server-sent changes, must always guard + clearValues(); + return; + } // findRanges must be called before any call to testUnderWater due to usage of // global-style variables for some reason findRanges(weapon); From c87f3f77240e18a1f28227d2ac476a73f9c21dcb Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 27 Jul 2024 11:49:08 +0200 Subject: [PATCH 13/22] FiringArcSpriteHandler: more guards --- .../client/ui/swing/boardview/FiringArcSpriteHandler.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/megamek/src/megamek/client/ui/swing/boardview/FiringArcSpriteHandler.java b/megamek/src/megamek/client/ui/swing/boardview/FiringArcSpriteHandler.java index eb178c63137..b3b46f3ab76 100644 --- a/megamek/src/megamek/client/ui/swing/boardview/FiringArcSpriteHandler.java +++ b/megamek/src/megamek/client/ui/swing/boardview/FiringArcSpriteHandler.java @@ -64,8 +64,12 @@ public FiringArcSpriteHandler(BoardView boardView, ClientGUI clientGUI) { * @param weapon the selected weapon * @param movePath planned movement in the movement phase */ - public void update(Entity entity, WeaponMounted weapon, @Nullable MovePath movePath) { + public void update(@Nullable Entity entity, @Nullable WeaponMounted weapon, @Nullable MovePath movePath) { firingEntity = entity; + if ((entity == null) || (weapon == null)) { + clearValues(); + return; + } int weaponId = entity.getEquipmentNum(weapon); if (weaponId == -1) { // entities are replaced all the time by server-sent changes, must always guard From cf02da5ecc0c2157811d81af53b1a14d67790e7c Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 27 Jul 2024 17:30:26 +0200 Subject: [PATCH 14/22] Prevent units from unloading over bay door limits, code cleanup --- .../client/ui/swing/MovementDisplay.java | 7 +- megamek/src/megamek/common/Bay.java | 9 +-- megamek/src/megamek/common/Entity.java | 79 ++++++++++--------- 3 files changed, 47 insertions(+), 48 deletions(-) diff --git a/megamek/src/megamek/client/ui/swing/MovementDisplay.java b/megamek/src/megamek/client/ui/swing/MovementDisplay.java index 614d303fb17..ea5a2e6ef9b 100644 --- a/megamek/src/megamek/client/ui/swing/MovementDisplay.java +++ b/megamek/src/megamek/client/ui/swing/MovementDisplay.java @@ -1255,12 +1255,7 @@ public void clear() { updateAeroButtons(); updateLayMineButton(); - loadedUnits = ce.getLoadedUnits(); - for (Entity e : ce.getUnitsUnloadableFromBays()) { - if (!loadedUnits.contains(e)) { - loadedUnits.add(e); - } - } + loadedUnits = ce.getUnloadableUnits(); towedUnits = ce.getLoadedTrailers(); updateLoadButtons(); diff --git a/megamek/src/megamek/common/Bay.java b/megamek/src/megamek/common/Bay.java index 2c5e4774683..2b72d1ccc6e 100644 --- a/megamek/src/megamek/common/Bay.java +++ b/megamek/src/megamek/common/Bay.java @@ -42,7 +42,7 @@ public class Bay implements Transporter, ITechnology { int doors = 1; int doorsNext = 1; int currentdoors = doors; - protected int unloadedThisTurn = 0; + private int unloadedThisTurn = 0; protected int loadedThisTurn = 0; List recoverySlots = new ArrayList<>(); int bayNumber = 0; @@ -182,10 +182,8 @@ public boolean canLoad(Entity unit) { } /** - * To unload units, a bay must have more doors available than units unloaded - * this turn. Can't load, launch or recover into a damaged bay, but you can unload it - * - * @return True when further doors are available to unload units this turn + * @return True when further doors are available to unload units this turn. This method checks only + * the state of bay doors, not if it has units left to unload or the status of those. */ public boolean canUnloadUnits() { return currentdoors > unloadedThisTurn; @@ -235,6 +233,7 @@ public List getDroppableUnits() { /** @return A (possibly empty) list of units from this bay that can be unloaded on the ground. */ public List getUnloadableUnits() { // TODO: we need to handle aeros and VTOLs differently + // TODO: shouldn't this check the entity state like wasLoadedThisTurn()? It is equal to getLoadedUnits() return troops.stream().map(game::getEntity).filter(Objects::nonNull).collect(toList()); } diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index a42d4d7b6e4..18897ca74fc 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -8614,6 +8614,7 @@ public Bay getBayById(int bayNumber) { * @return the DockingCollar with the given ID or null */ @Nullable + @SuppressWarnings("unused") // Used in MHQ public DockingCollar getCollarById(int collarNumber) { return getDockingCollars().stream() .filter(dc -> dc.getCollarNumber() == collarNumber) @@ -8690,47 +8691,50 @@ public Vector getDroppableUnits() { } /** - * @return only entities in that can be unloaded on ground + * @return All Entities that can at this point be unloaded from any of the bays of this Entity. This + * does not include any units that were loaded this turn or any bays where the door capacity has + * been exceeded this turn. + * Note that the returned list may be unmodifiable. + * + * @see #wasLoadedThisTurn() + * @see Bay#canUnloadUnits() */ - public Vector getUnitsUnloadableFromBays() { - Vector result = new Vector<>(); - - // Walk through this entity's transport components; - // add all of their lists to ours. - - // I should only add entities in bays that are functional - for (Transporter next : transports) { - if ((next instanceof Bay) && (((Bay) next).canUnloadUnits())) { - Bay nextbay = (Bay) next; - for (Entity e : nextbay.getUnloadableUnits()) { - if (!e.wasLoadedThisTurn()) { - result.addElement(e); - } - } - } - } - - // Return the list. - return result; + public List getUnitsUnloadableFromBays() { + return transports.stream() + .filter(t -> t instanceof Bay).map(t -> (Bay) t) + .filter(Bay::canUnloadUnits) + .flatMap(b -> b.getUnloadableUnits().stream()) + .filter(e -> !e.wasLoadedThisTurn()) + .toList(); } - public Bay getLoadedBay(int bayID) { - - Vector bays = getFighterBays(); - for (int nbay = 0; nbay < bays.size(); nbay++) { - Bay currentBay = bays.elementAt(nbay); - Vector currentFighters = currentBay.getLoadedUnits(); - for (int nfighter = 0; nfighter < currentFighters.size(); nfighter++) { - Entity fighter = currentFighters.elementAt(nfighter); - if (fighter.getId() == bayID) { - // then we are in the right bay - return currentBay; - } - } - } - - return null; + /** + * @return All Entities that can at this point be unloaded from any transports of this Entity which are + * no Bays. This does not include any units that were loaded this turn. + * Note that the returned list may be unmodifiable. + * + * @see #wasLoadedThisTurn() + */ + public List getUnitsUnloadableFromNonBays() { + return transports.stream() + .filter(t -> !(t instanceof Bay)) + .flatMap(b -> b.getLoadedUnits().stream()) + .filter(e -> !e.wasLoadedThisTurn()) + .toList(); + } + /** + * @return All Entities that can at this point be unloaded from any transports of this Entity. This does + * not include any units that were loaded this turn nor units from bays where the door capacity has been + * exceeded this turn. + * + * @see #wasLoadedThisTurn() + * @see Bay#canUnloadUnits() + */ + public List getUnloadableUnits() { + List loadedUnits = new ArrayList<>(getUnitsUnloadableFromNonBays()); + loadedUnits.addAll(getUnitsUnloadableFromBays()); + return loadedUnits; } /** @@ -8919,6 +8923,7 @@ public boolean unload(Entity unit) { } @Override + @SuppressWarnings("unused") // Used in MHQ public void resetTransporter() { transports.forEach(Transporter::resetTransporter); } From 50747925d453bb9b933be701467dad9be7a78ae3 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 27 Jul 2024 17:45:15 +0200 Subject: [PATCH 15/22] cleanup --- .../client/ui/swing/MovementDisplay.java | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/megamek/src/megamek/client/ui/swing/MovementDisplay.java b/megamek/src/megamek/client/ui/swing/MovementDisplay.java index ea5a2e6ef9b..66493f0a0d7 100644 --- a/megamek/src/megamek/client/ui/swing/MovementDisplay.java +++ b/megamek/src/megamek/client/ui/swing/MovementDisplay.java @@ -318,10 +318,7 @@ public static MoveCommand[] values(int f, GameOptions opts, boolean forwardIni) // is the shift key held? private boolean shiftheld; - /** - * A local copy of the current entity's loaded units. - */ - private List loadedUnits = null; + private List unloadableUnits = null; /** * A local copy of the current entity's towed trailers. @@ -1255,7 +1252,7 @@ public void clear() { updateAeroButtons(); updateLayMineButton(); - loadedUnits = ce.getUnloadableUnits(); + unloadableUnits = ce.getUnloadableUnits(); towedUnits = ce.getLoadedTrailers(); updateLoadButtons(); @@ -2820,7 +2817,7 @@ private void updateUnloadButton() { } if ((ce instanceof SmallCraft) || ce.isSupportVehicle()) { - setUnloadEnabled(!loadedUnits.isEmpty() && !ce.isAirborne()); + setUnloadEnabled(!unloadableUnits.isEmpty() && !ce.isAirborne()); return; } @@ -2831,13 +2828,13 @@ private void updateUnloadButton() { // A unit that has somehow exited the map is assumed to be unable to unload if (isFinalPositionOnBoard()) { - canUnloadHere = loadedUnits.stream().anyMatch(en -> en.isElevationValid(unloadEl, hex) || (en.getJumpMP() > 0)); + canUnloadHere = unloadableUnits.stream().anyMatch(en -> en.isElevationValid(unloadEl, hex) || (en.getJumpMP() > 0)); // Zip lines, TO pg 219 if (game().getOptions().booleanOption(ADVGRNDMOV_TACOPS_ZIPLINES) && (ce instanceof VTOL)) { - canUnloadHere |= loadedUnits.stream().filter(Entity::isInfantry).anyMatch(en -> !((Infantry) en).isMechanized()); + canUnloadHere |= unloadableUnits.stream().filter(Entity::isInfantry).anyMatch(en -> !((Infantry) en).isMechanized()); } } - setUnloadEnabled(legalGear && canUnloadHere && !loadedUnits.isEmpty()); + setUnloadEnabled(legalGear && canUnloadHere && !unloadableUnits.isEmpty()); } /** Updates the status of the Mount button. */ @@ -3277,21 +3274,21 @@ private Entity getUnloadedUnit() { Entity ce = ce(); Entity choice = null; // Handle error condition. - if (loadedUnits.isEmpty()) { + if (unloadableUnits.isEmpty()) { LogManager.getLogger().error("MovementDisplay#getUnloadedUnit() called without loaded units."); - } else if (loadedUnits.size() > 1) { + } else if (unloadableUnits.size() > 1) { // If we have multiple choices, display a selection dialog. String input = (String) JOptionPane.showInputDialog( clientgui.getFrame(), Messages.getString("MovementDisplay.UnloadUnitDialog.message", ce.getShortName(), ce.getUnusedString()), Messages.getString("MovementDisplay.UnloadUnitDialog.title"), JOptionPane.QUESTION_MESSAGE, null, - SharedUtility.getDisplayArray(loadedUnits), null); - choice = (Entity) SharedUtility.getTargetPicked(loadedUnits, input); + SharedUtility.getDisplayArray(unloadableUnits), null); + choice = (Entity) SharedUtility.getTargetPicked(unloadableUnits, input); } else { // Only one choice. - choice = loadedUnits.get(0); - loadedUnits.remove(0); + choice = unloadableUnits.get(0); + unloadableUnits.remove(0); } // Return the chosen unit. From 8a01be8c8a5436d007359e39a4422acd3b06423a Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 27 Jul 2024 18:36:31 +0200 Subject: [PATCH 16/22] use best hex for FoV highlighting for multi-hex units --- .../swing/boardview/FovHighlightingAndDarkening.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java b/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java index 6d9a1d95d33..5608c515cd0 100644 --- a/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java +++ b/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java @@ -75,10 +75,14 @@ boolean draw(Graphics boardGraph, Coords c, int drawX, int drawY, boolean saveBo Coords src; boolean hasLoS = true; // in movement phase, calc LOS based on selected hex, otherwise use selected Entity - if (this.boardView1.game.getPhase().isMovement() && this.boardView1.selected != null) { - src = this.boardView1.selected; - } else if (this.boardView1.getSelectedEntity() != null) { - src = this.boardView1.getSelectedEntity().getPosition(); + if (boardView1.game.getPhase().isMovement() && this.boardView1.selected != null) { + src = boardView1.selected; + } else if (boardView1.getSelectedEntity() != null) { + Entity viewer = boardView1.getSelectedEntity(); + src = viewer.getPosition(); + // multi-hex units look from the hex closest to the target to avoid self-blocking + src = viewer.getSecondaryPositions().values().stream() + .min(Comparator.comparingInt(co -> co.distance(c))).orElse(src); } else { src = null; } From 8b06aecfc977463299155bc979716ad1241b3670 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 27 Jul 2024 18:52:14 +0200 Subject: [PATCH 17/22] add a test scenario for DS LOS/FoV --- megamek/data/scenarios/Test Setups/DS_LOS.mms | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 megamek/data/scenarios/Test Setups/DS_LOS.mms diff --git a/megamek/data/scenarios/Test Setups/DS_LOS.mms b/megamek/data/scenarios/Test Setups/DS_LOS.mms new file mode 100644 index 00000000000..bdce00a172c --- /dev/null +++ b/megamek/data/scenarios/Test Setups/DS_LOS.mms @@ -0,0 +1,15 @@ +MMSVersion: 2 +name: Grounded DS Test +planet: None +description: A grounded DS on a small map for use in range/LOS/FoV testing + +map: AGoAC Maps/16x17 Grassland 2.board + +factions: +- name: Test Player + + units: + - fullname: Intruder (3056) + at: [ 10, 9 ] + altitude: 0 + \ No newline at end of file From 1cd72491ab65832ad3b13ac6c6e4f1fd76fbd232 Mon Sep 17 00:00:00 2001 From: sleet01 Date: Fri, 26 Jul 2024 00:56:06 -0700 Subject: [PATCH 18/22] Implement TW LOS and forest rules for Low Altitude maps --- megamek/src/megamek/common/Board.java | 4 + megamek/src/megamek/common/LosEffects.java | 365 +++++++++++--------- megamek/src/megamek/server/GameManager.java | 2 + 3 files changed, 201 insertions(+), 170 deletions(-) diff --git a/megamek/src/megamek/common/Board.java b/megamek/src/megamek/common/Board.java index 288a92cec91..0e2eb855cb7 100644 --- a/megamek/src/megamek/common/Board.java +++ b/megamek/src/megamek/common/Board.java @@ -1020,6 +1020,10 @@ public void load(InputStream is, @Nullable List errors, boolean continue args[i++] = st.ttype == StreamTokenizer.TT_NUMBER ? (int) st.nval + "" : st.sval; } int elevation = Integer.parseInt(args[1]); + if (mapType == T_ATMOSPHERE) { + // All foliage on low-altitude maps have height 1 + args[2] = args[2].replaceAll("foliage_elev:\\d{1,}", "foliage_elev:1"); + } // The coordinates in the .board file are ignored! nd[index] = new Hex(elevation, args[2], args[3], new Coords(index % nw, index / nw)); index++; diff --git a/megamek/src/megamek/common/LosEffects.java b/megamek/src/megamek/common/LosEffects.java index 36678acc997..e4d60c49361 100644 --- a/megamek/src/megamek/common/LosEffects.java +++ b/megamek/src/megamek/common/LosEffects.java @@ -33,10 +33,13 @@ public static class AttackInfo { public boolean attUnderWater; public boolean attInWater; public boolean attOnLand; + public boolean attLowAlt = false; public boolean targetUnderWater; public boolean targetInWater; public boolean targetOnLand; + public boolean targetLowAlt = false; public boolean underWaterCombat; + public boolean lowAltitude = false; public boolean targetEntity = true; public boolean targetInfantry; public boolean targetIsMech; @@ -44,25 +47,25 @@ public static class AttackInfo { public boolean attOffBoard; public Coords attackPos; public Coords targetPos; - + /** * The absolute elevation of the attacker, i.e. the number of levels * attacker is placed above a level 0 hex. */ public int attackAbsHeight; - + /** * The absolute elevation of the target, i.e. the number of levels * target is placed above a level 0 hex. */ public int targetAbsHeight; - + /** * The height of the attacker, that is, how many levels above its * elevation it is for LOS purposes. */ public int attackHeight; - + /** * The height of the target, that is, how many levels above its * elevation it is for LOS purposes. @@ -85,7 +88,7 @@ public static class AttackInfo { public static final int COVER_FULL = 0xF; // blocked (blocked) public static final int COVER_75LEFT = 0x7; // 75% cover (blocked) public static final int COVER_75RIGHT = 0xB; // 75% cover (blocked) - + public static final int DAMAGABLE_COVER_NONE = 0; public static final int DAMAGABLE_COVER_DROPSHIP = 0x1; public static final int DAMAGABLE_COVER_BUILDING = 0x2; @@ -118,13 +121,13 @@ public static class AttackInfo { int damagableCoverTypePrimary = DAMAGABLE_COVER_NONE; /** * Indicates if the secondary cover is damageable - */ + */ int damagableCoverTypeSecondary = DAMAGABLE_COVER_NONE; /** * Keeps track of the building that provides cover. This is used * to assign damage for shots that hit cover. The primary cover is used * if there is a sole piece of cover (horizontal cover, 25% cover). - * In the case of a primary and secondary, the primary cover protects the + * In the case of a primary and secondary, the primary cover protects the * right side. */ Building coverBuildingPrimary = null; @@ -132,15 +135,15 @@ public static class AttackInfo { * Keeps track of the building that provides cover. This is used * to assign damage for shots that hit cover. The secondary cover is used * if there are two buildings that provide cover, like in the case of 75% - * cover or two buildings providing 25% cover for a total of horizontal + * cover or two buildings providing 25% cover for a total of horizontal * cover. The secondary cover protects the left side. */ Building coverBuildingSecondary = null; /** * Keeps track of the grounded DropShip that provides cover. This is - * used to assign damage for shots that hit cover. The primary cover is used + * used to assign damage for shots that hit cover. The primary cover is used * if there is a sole piece of cover (horizontal cover, 25% cover). - * In the case of a primary and secondary, the primary cover protects the + * In the case of a primary and secondary, the primary cover protects the * right side. */ Entity coverDropshipPrimary = null; @@ -148,10 +151,10 @@ public static class AttackInfo { * Keeps track of the grounded DropShip that provides cover. This is * used to assign damage for shots that hit cover. The secondary cover is used * if there are two buildings that provide cover, like in the case of 75% - * cover or two buildings providing 25% cover for a total of horizontal + * cover or two buildings providing 25% cover for a total of horizontal * cover. The secondary cover protects the left side. */ - Entity coverDropshipSecondary = null; + Entity coverDropshipSecondary = null; /** * Stores the hex location of the primary cover. */ @@ -165,11 +168,11 @@ public static class AttackInfo { // Arced shots get no modifiers from any intervening terrain boolean arcedShot = false; - + public Coords getTargetPosition() { return targetLoc; } - + public int getMinimumWaterDepth() { return minimumWaterDepth; } @@ -183,18 +186,18 @@ public void add(LosEffects other) { // We need to update cover if it's present, but we don't want to // remove cover if no new cover is present // this assumes that LoS is being drawn from attacker to target - if (other.damagableCoverTypePrimary != DAMAGABLE_COVER_NONE && + if (other.damagableCoverTypePrimary != DAMAGABLE_COVER_NONE && other.targetCover >= targetCover) { damagableCoverTypePrimary = other.damagableCoverTypePrimary; coverDropshipPrimary = other.coverDropshipPrimary; coverBuildingPrimary = other.coverBuildingPrimary; coverLocPrimary = other.coverLocPrimary; - damagableCoverTypeSecondary = other.damagableCoverTypeSecondary; - coverDropshipSecondary = other.coverDropshipSecondary; - coverBuildingSecondary = other.coverBuildingSecondary; + damagableCoverTypeSecondary = other.damagableCoverTypeSecondary; + coverDropshipSecondary = other.coverDropshipSecondary; + coverBuildingSecondary = other.coverBuildingSecondary; coverLocSecondary = other.coverLocSecondary; - } - + } + blocked |= other.blocked; infProtected |= other.infProtected; plantedFields += other.plantedFields; @@ -214,7 +217,7 @@ public void add(LosEffects other) { attackerCover |= other.attackerCover; if ((null != thruBldg) && !thruBldg.equals(other.thruBldg)) { thruBldg = null; - } + } } public int getPlantedFields() { @@ -442,7 +445,7 @@ public static LosEffects calculateLOS(final Game game, final @Nullable Entity at // this will adjust the effective height of a building target by 1 if the hex contains a rooftop gun emplacement final int targetHeightAdjustment = game.hasRooftopGunEmplacement(targetHex.getCoords()) ? 1 : 0; - + final AttackInfo ai = new AttackInfo(); ai.attackerIsMech = attacker instanceof Mech; ai.attackPos = attackerPosition; @@ -455,17 +458,30 @@ public static LosEffects calculateLOS(final Game game, final @Nullable Entity at } else { ai.targetIsMech = false; } - + + // Adjust units' altitudes for low-altitude map LOS caclulations + // Revisit once we have ground units on low-alt and dual-map functional + final boolean lowAlt = game.getBoard().inAtmosphere() && !game.getBoard().onGround(); + if (attacker.isAirborne()) { + ai.attLowAlt = true; + } + if (target.isAirborne()) { + ai.targetLowAlt = true; + } + if (lowAlt) { + ai.lowAltitude = true; + } + ai.targetInfantry = target instanceof Infantry; ai.attackHeight = attacker.getHeight(); - ai.targetHeight = target.getHeight() + targetHeightAdjustment; + ai.targetHeight = (ai.targetLowAlt) ? target.getAltitude() : target.getHeight() + targetHeightAdjustment; - int attackerElevation = attacker.relHeight() + attackerHex.getLevel(); + int attackerElevation = (ai.attLowAlt) ? attacker.getAltitude() : attacker.relHeight() + attackerHex.getLevel(); // for spotting, a mast mount raises our elevation by 1 if (spotting && attacker.hasWorkingMisc(MiscType.F_MAST_MOUNT, -1)) { - attackerElevation += 1; + attackerElevation += (ai.attLowAlt) ? 0 : 1; } - final int targetElevation = target.relHeight() + targetHex.getLevel() + targetHeightAdjustment; + final int targetElevation = (ai.targetLowAlt) ? target.getAltitude() : target.relHeight() + targetHex.getLevel() + targetHeightAdjustment; ai.attackAbsHeight = attackerElevation; ai.targetAbsHeight = targetElevation; @@ -560,7 +576,7 @@ public static LosEffects calculateLos(Game game, AttackInfo ai) { los.targetLoc = ai.targetPos; return los; } - + boolean diagramLos = game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_LOS1); boolean partialCover = game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_PARTIAL_COVER); double degree = ai.attackPos.degree(ai.targetPos); @@ -570,15 +586,15 @@ public static LosEffects calculateLos(Game game, AttackInfo ai) { } else { finalLoS = LosEffects.losStraight(game, ai, diagramLos, partialCover); } - - finalLoS.hasLoS = !finalLoS.blocked && - (finalLoS.screen < 1) && - (finalLoS.plantedFields < 6) && - (finalLoS.heavyIndustrial < 3) && + + finalLoS.hasLoS = !finalLoS.blocked && + (finalLoS.screen < 1) && + (finalLoS.plantedFields < 6) && + (finalLoS.heavyIndustrial < 3) && ((finalLoS.lightWoods + finalLoS.lightSmoke) + ((finalLoS.heavyWoods + finalLoS.heavySmoke) * 2) + (finalLoS.ultraWoods * 3) < 3); - + finalLoS.targetLoc = ai.targetPos; return finalLoS; } @@ -590,7 +606,7 @@ public static LosEffects calculateLos(Game game, AttackInfo ai) { public ToHitData losModifiers(Game game) { return losModifiers(game, 0, false); } - + public ToHitData losModifiers(Game game, boolean underWaterWeapon) { return losModifiers(game, 0, underWaterWeapon); } @@ -753,7 +769,7 @@ private static LosEffects losStraight(Game game, AttackInfo ai, for (Coords c : in) { los.add(LosEffects.losForCoords(game, ai, c, los.getThruBldg(), diagramLoS, partialCover)); - } + } if ((ai.minimumWaterDepth < 1) && ai.underWaterCombat) { los.blocked = true; @@ -853,13 +869,13 @@ private static LosEffects losDivided(Game game, AttackInfo ai, boolean diagramLo rightLos.infProtected = true; } } - + // Check for advanced cover, only 'mechs can get partial cover - if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_PARTIAL_COVER) && + if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_PARTIAL_COVER) && ai.targetIsMech) { // 75% and vertical cover will have blocked LoS boolean losBlockedByCover = false; - if (leftLos.targetCover == COVER_HORIZONTAL && + if (leftLos.targetCover == COVER_HORIZONTAL && rightLos.targetCover == COVER_NONE) { // 25% cover, left leftLos.targetCover = COVER_LOWLEFT; @@ -868,7 +884,7 @@ private static LosEffects losDivided(Game game, AttackInfo ai, boolean diagramLo rightLos.setCoverDropshipPrimary(leftLos.getCoverDropshipPrimary()); rightLos.setDamagableCoverTypePrimary(leftLos.getDamagableCoverTypePrimary()); rightLos.setCoverLocPrimary(leftLos.getCoverLocPrimary()); - } else if ((leftLos.targetCover == COVER_NONE && + } else if ((leftLos.targetCover == COVER_NONE && rightLos.targetCover == COVER_HORIZONTAL)) { // 25% cover, right leftLos.targetCover = COVER_LOWRIGHT; @@ -877,7 +893,7 @@ private static LosEffects losDivided(Game game, AttackInfo ai, boolean diagramLo leftLos.setCoverDropshipPrimary(rightLos.getCoverDropshipPrimary()); leftLos.setDamagableCoverTypePrimary(rightLos.getDamagableCoverTypePrimary()); leftLos.setCoverLocPrimary(rightLos.getCoverLocPrimary()); - } else if (leftLos.targetCover == COVER_FULL && + } else if (leftLos.targetCover == COVER_FULL && rightLos.targetCover == COVER_NONE) { // vertical cover, left leftLos.targetCover = COVER_LEFT; @@ -887,7 +903,7 @@ private static LosEffects losDivided(Game game, AttackInfo ai, boolean diagramLo rightLos.setDamagableCoverTypePrimary(leftLos.getDamagableCoverTypePrimary()); rightLos.setCoverLocPrimary(leftLos.getCoverLocPrimary()); losBlockedByCover = true; - } else if (leftLos.targetCover == COVER_NONE && + } else if (leftLos.targetCover == COVER_NONE && rightLos.targetCover == COVER_FULL) { // vertical cover, right leftLos.targetCover = COVER_RIGHT; @@ -897,40 +913,40 @@ private static LosEffects losDivided(Game game, AttackInfo ai, boolean diagramLo leftLos.setDamagableCoverTypePrimary(rightLos.getDamagableCoverTypePrimary()); leftLos.setCoverLocPrimary(rightLos.getCoverLocPrimary()); losBlockedByCover = true; - } else if (leftLos.targetCover == COVER_FULL && + } else if (leftLos.targetCover == COVER_FULL && rightLos.targetCover == COVER_HORIZONTAL) { // 75% cover, left leftLos.targetCover = COVER_75LEFT; rightLos.targetCover = COVER_75LEFT; - setSecondaryCover(leftLos, rightLos); - losBlockedByCover = true; - } else if (leftLos.targetCover == COVER_HORIZONTAL && - rightLos.targetCover == COVER_FULL) { + setSecondaryCover(leftLos, rightLos); + losBlockedByCover = true; + } else if (leftLos.targetCover == COVER_HORIZONTAL && + rightLos.targetCover == COVER_FULL) { // 75% cover, right leftLos.targetCover = COVER_75RIGHT; rightLos.targetCover = COVER_75RIGHT; setSecondaryCover(leftLos, rightLos); losBlockedByCover = true; - } else if (leftLos.targetCover == COVER_HORIZONTAL && - rightLos.targetCover == COVER_HORIZONTAL) { + } else if (leftLos.targetCover == COVER_HORIZONTAL && + rightLos.targetCover == COVER_HORIZONTAL) { // 50% cover // Cover will be set properly, but we need to set secondary // cover in case there are two buildings providing 25% cover setSecondaryCover(leftLos, rightLos); } - // In the case of vertical and 75% cover, LoS will be blocked. + // In the case of vertical and 75% cover, LoS will be blocked. // We need to unblock it, unless Los is already blocked. - if (!los.blocked && (!leftLos.blocked || !rightLos.blocked) && losBlockedByCover) { + if (!los.blocked && (!leftLos.blocked || !rightLos.blocked) && losBlockedByCover) { leftLos.blocked = false; rightLos.blocked = false; - } + } } - - if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_PARTIAL_COVER) && + + if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_PARTIAL_COVER) && ai.attackerIsMech) { // 75% and vertical cover will have blocked LoS boolean losBlockedByCover = false; - if (leftLos.attackerCover == COVER_HORIZONTAL && + if (leftLos.attackerCover == COVER_HORIZONTAL && rightLos.attackerCover == COVER_NONE) { // 25% cover, left leftLos.attackerCover = COVER_LOWLEFT; @@ -965,7 +981,7 @@ private static LosEffects losDivided(Game game, AttackInfo ai, boolean diagramLo && (rightLos.attackerCover == COVER_HORIZONTAL)) { // 75% cover, left leftLos.attackerCover = COVER_75LEFT; - rightLos.attackerCover = COVER_75LEFT; + rightLos.attackerCover = COVER_75LEFT; losBlockedByCover = true; } else if ((leftLos.attackerCover == COVER_HORIZONTAL) && (rightLos.attackerCover == COVER_FULL)) { @@ -974,22 +990,22 @@ private static LosEffects losDivided(Game game, AttackInfo ai, boolean diagramLo rightLos.attackerCover = COVER_75RIGHT; losBlockedByCover = true; } - + // In the case of vertical and 75% cover, LoS will be blocked. // We need to unblock it, unless Los is already blocked. if (!los.blocked && (!leftLos.blocked || !rightLos.blocked) && - losBlockedByCover) { + losBlockedByCover) { leftLos.blocked = false; rightLos.blocked = false; - } + } } totalLeftLos.add(leftLos); - totalRightLos.add(rightLos); + totalRightLos.add(rightLos); } //Determine whether left or right is worse and update los with it int lVal = totalLeftLos.losModifiers(game).getValue(); int rVal = totalRightLos.losModifiers(game).getValue(); - if ((lVal > rVal) || + if ((lVal > rVal) || ((lVal == rVal) && totalLeftLos.isAttackerCover())) { los.add(totalLeftLos); } else { @@ -997,17 +1013,17 @@ private static LosEffects losDivided(Game game, AttackInfo ai, boolean diagramLo } return los; } - + /** * Convenience method for setting the secondary cover values. The left LoS - * has retains it's primary cover, and its secondary cover becomes the - * primary of the right los while the right los has its primary become + * has retains it's primary cover, and its secondary cover becomes the + * primary of the right los while the right los has its primary become * secondary and its primary becomes the primary of the left side. * This ensures that the primary protects the left side and the secondary * protects the right side which is important to determine which to pick * later on when damage is handled. - * - * @param leftLos The left side of the line of sight for a divided hex + * + * @param leftLos The left side of the line of sight for a divided hex * LoS computation * @param rightLos The right side of the line of sight for a dividied hex * LoS computation @@ -1017,7 +1033,7 @@ private static void setSecondaryCover(LosEffects leftLos, LosEffects rightLos) { leftLos.setDamagableCoverTypeSecondary(rightLos.getDamagableCoverTypePrimary()); leftLos.setCoverBuildingSecondary(rightLos.getCoverBuildingPrimary()); leftLos.setCoverDropshipSecondary(rightLos.getCoverDropshipPrimary()); - leftLos.setCoverLocSecondary(rightLos.getCoverLocPrimary()); + leftLos.setCoverLocSecondary(rightLos.getCoverLocPrimary()); //Set right secondary to right primary rightLos.setDamagableCoverTypeSecondary(rightLos.getDamagableCoverTypePrimary()); rightLos.setCoverBuildingSecondary(rightLos.getCoverBuildingPrimary()); @@ -1026,7 +1042,7 @@ private static void setSecondaryCover(LosEffects leftLos, LosEffects rightLos) { //Set right primary to left primary rightLos.setDamagableCoverTypePrimary(leftLos.getDamagableCoverTypePrimary()); rightLos.setCoverBuildingPrimary(leftLos.getCoverBuildingPrimary()); - rightLos.setCoverDropshipPrimary(leftLos.getCoverDropshipPrimary()); + rightLos.setCoverDropshipPrimary(leftLos.getCoverDropshipPrimary()); rightLos.setCoverLocPrimary(leftLos.getCoverLocPrimary()); } @@ -1035,7 +1051,7 @@ private static void setSecondaryCover(LosEffects leftLos, LosEffects rightLos) { * the specified coordinate. */ private static LosEffects losForCoords(Game game, AttackInfo ai, - Coords coords, Building thruBldg, + Coords coords, Building thruBldg, boolean diagramLoS, boolean partialCover) { LosEffects los = new LosEffects(); // ignore hexes not on board @@ -1085,55 +1101,57 @@ private static LosEffects losForCoords(Game game, AttackInfo ai, // Attacks thru a building are not blocked by that building. // ASSUMPTION: bridges don't block LOS. int bldgEl = 0; - if ((null == los.getThruBldg()) - && hex.containsTerrain(Terrains.BLDG_ELEV)) { - bldgEl = hex.terrainLevel(Terrains.BLDG_ELEV); - } - - if ((null == los.getThruBldg()) - && hex.containsTerrain(Terrains.FUEL_TANK_ELEV) - && hex.terrainLevel(Terrains.FUEL_TANK_ELEV) > bldgEl) { - bldgEl = hex.terrainLevel(Terrains.FUEL_TANK_ELEV); - } - boolean coveredByDropship = false; Entity coveringDropship = null; - // check for grounded dropships - treat like a building 10 elevations tall - if (bldgEl < 10) { - for (Entity inHex : game.getEntitiesVector(coords)) { - if (ai.attackerId == inHex.getId() || ai.targetId == inHex.getId()) { - continue; - } - if (inHex instanceof Dropship && !inHex.isAirborne() && !inHex.isSpaceborne()) { - bldgEl = 10; - coveredByDropship = true; - coveringDropship = inHex; + if (!ai.lowAltitude) { + if ((null == los.getThruBldg()) + && hex.containsTerrain(Terrains.BLDG_ELEV)) { + bldgEl = hex.terrainLevel(Terrains.BLDG_ELEV); + } + + if ((null == los.getThruBldg()) + && hex.containsTerrain(Terrains.FUEL_TANK_ELEV) + && hex.terrainLevel(Terrains.FUEL_TANK_ELEV) > bldgEl) { + bldgEl = hex.terrainLevel(Terrains.FUEL_TANK_ELEV); + } + + // check for grounded dropships - treat like a building 10 elevations tall + if (bldgEl < 10) { + for (Entity inHex : game.getEntitiesVector(coords)) { + if (ai.attackerId == inHex.getId() || ai.targetId == inHex.getId()) { + continue; + } + if (inHex instanceof Dropship && !inHex.isAirborne() && !inHex.isSpaceborne()) { + bldgEl = 10; + coveredByDropship = true; + coveringDropship = inHex; + } } } } - + // check for block by terrain - - - // All unit heights report as 1 less in MM than what they really are + + + // All unit heights report as 1 less in MM than what they really are // (1 for mechs, 0 for tanks...) // A level 4 hill will not block a mech on a level 3 hill - // (height of the mech in here = 3+"1" = "4"), as + // (height of the mech in here = 3+"1" = "4"), as // hill elevation is not > unit elevation (normal LOS rules) // With diagramming LOS it will block LOS as soon as the sightline // drops by 0.1 to 3.9, even though that means it would be at 4.9 in // "real" height values, so still well above the level 4 hill // Therefore we need to add 1 from the diagramming LOS elevation // to correct the calculation - // This is still hacky as Entity should simply report the real heights + // This is still hacky as Entity should simply report the real heights // and the comparison in here should follow TW/TO "higher or equal" rules. - + // The interpolated elevation for TacOps LOS diagramming - double weightedHeight = ai.targetAbsHeight * ai.attackPos.distance(coords) + double weightedHeight = ai.targetAbsHeight * ai.attackPos.distance(coords) + ai.attackAbsHeight * ai.targetPos.distance(coords); double totalDistance = ai.targetPos.distance(coords) + ai.attackPos.distance(coords); double losElevation = 1 + weightedHeight / totalDistance; - + // The higher of the attacker's height and defender's height int maxUnitHeight = Math.max(ai.attackAbsHeight, ai.targetAbsHeight); boolean attackerAdjc = ai.attackPos.distance(coords) == 1; @@ -1174,38 +1192,42 @@ private static LosEffects losForCoords(Game game, AttackInfo ai, //number of screens doesn't matter. One is enough to block los.screen++; } - //heavy industrial zones can vary in height up to 10 levels, so lets - //put all of this into a for loop - int industrialLevel = hex.terrainLevel(Terrains.INDUSTRIAL); - if (industrialLevel != Terrain.LEVEL_NONE) { - for (int level = 1; level < 11; level++) { - if ((hexEl + level > maxUnitHeight) - || ((hexEl + level > ai.attackAbsHeight) && attackerAdjc) - || ((hexEl + level > ai.targetAbsHeight) && targetAdjc)) { - // check industrial zone - if (industrialLevel == level) { - los.heavyIndustrial++; + + if (!ai.lowAltitude) { + //heavy industrial zones can vary in height up to 10 levels, so lets + //put all of this into a for loop + int industrialLevel = hex.terrainLevel(Terrains.INDUSTRIAL); + if (industrialLevel != Terrain.LEVEL_NONE) { + for (int level = 1; level < 11; level++) { + if ((hexEl + level > maxUnitHeight) + || ((hexEl + level > ai.attackAbsHeight) && attackerAdjc) + || ((hexEl + level > ai.targetAbsHeight) && targetAdjc)) { + // check industrial zone + if (industrialLevel == level) { + los.heavyIndustrial++; + } } } } - } - //planted fields only rise one level above the terrain - if (hex.containsTerrain(Terrains.FIELDS)) { - if (((hexEl + 1 > ai.attackAbsHeight) && (hexEl + 2 > ai.targetAbsHeight)) - || ((hexEl + 1 > ai.attackAbsHeight) && attackerAdjc) - || ((hexEl + 1 > ai.targetAbsHeight) && targetAdjc)) { - los.plantedFields++; + //planted fields only rise one level above the terrain + if (hex.containsTerrain(Terrains.FIELDS)) { + if (((hexEl + 1 > ai.attackAbsHeight) && (hexEl + 2 > ai.targetAbsHeight)) + || ((hexEl + 1 > ai.attackAbsHeight) && attackerAdjc) + || ((hexEl + 1 > ai.targetAbsHeight) && targetAdjc)) { + los.plantedFields++; + } } } - + + // Intervening Smoke and Woods - int smokeLevel = hex.terrainLevel(Terrains.SMOKE); int woodsLevel = hex.terrainLevel(Terrains.WOODS); int jungleLevel = hex.terrainLevel(Terrains.JUNGLE); int foliageElev = hex.terrainLevel(Terrains.FOLIAGE_ELEV); + int smokeLevel = hex.terrainLevel(Terrains.SMOKE); boolean hasFoliage = (woodsLevel != Terrain.LEVEL_NONE) || (jungleLevel != Terrain.LEVEL_NONE); - + // Check 1 level high woods and jungle if (hasFoliage && foliageElev == 1) { int terrainEl = hexEl + 1; @@ -1226,15 +1248,15 @@ private static LosEffects losForCoords(Game game, AttackInfo ai, } } } - + // Intervening smoke and elevation 2 light/heavy woods/jungle - if (smokeLevel != Terrain.LEVEL_NONE + if (smokeLevel != Terrain.LEVEL_NONE || (hasFoliage && foliageElev > 1)) { int terrainEl = hexEl + 2; if (diagramLoS) { affectsLos = terrainEl >= losElevation; } else { - affectsLos = (terrainEl > maxUnitHeight) + affectsLos = (terrainEl > maxUnitHeight) || ((terrainEl > ai.attackAbsHeight) && attackerAdjc) || ((terrainEl > ai.targetAbsHeight) && targetAdjc); } @@ -1259,13 +1281,13 @@ private static LosEffects losForCoords(Game game, AttackInfo ai, los.heavyWoods++; } } - + // Ultra woods/jungle rise 3 levels above the hex level terrainEl = hexEl + 3; if (diagramLoS) { affectsLos = terrainEl >= losElevation; } else { - affectsLos = (terrainEl > maxUnitHeight) + affectsLos = (terrainEl > maxUnitHeight) || ((terrainEl > ai.attackAbsHeight) && attackerAdjc) || ((terrainEl > ai.targetAbsHeight) && targetAdjc); } @@ -1277,48 +1299,51 @@ private static LosEffects losForCoords(Game game, AttackInfo ai, } } - // Partial Cover related code - boolean potentialCover = false; - // check for target partial cover - if (targetAdjc && ai.targetIsMech) { - if (los.blocked && partialCover) { - los.targetCover = COVER_FULL; - potentialCover = true; - } else if ((totalEl == ai.targetAbsHeight) - && (ai.attackAbsHeight <= ai.targetAbsHeight) - && (ai.targetHeight > 0)) { - los.targetCover |= COVER_HORIZONTAL; - potentialCover = true; + if (!ai.lowAltitude) { + // Partial Cover related code + boolean potentialCover = false; + // check for target partial cover + if (targetAdjc && ai.targetIsMech) { + if (los.blocked && partialCover) { + los.targetCover = COVER_FULL; + potentialCover = true; + } else if ((totalEl == ai.targetAbsHeight) + && (ai.attackAbsHeight <= ai.targetAbsHeight) + && (ai.targetHeight > 0)) { + los.targetCover |= COVER_HORIZONTAL; + potentialCover = true; + } } - } - // check for attacker partial (horizontal) cover - if (attackerAdjc && ai.attackerIsMech) { - if (los.blocked && partialCover) { - los.attackerCover = COVER_FULL; - potentialCover = true; - } else if ((totalEl == ai.attackAbsHeight) - && (ai.attackAbsHeight >= ai.targetAbsHeight) - && (ai.attackHeight > 0)) { - los.attackerCover |= COVER_HORIZONTAL; - potentialCover = true; + // check for attacker partial (horizontal) cover + if (attackerAdjc && ai.attackerIsMech) { + if (los.blocked && partialCover) { + los.attackerCover = COVER_FULL; + potentialCover = true; + } else if ((totalEl == ai.attackAbsHeight) + && (ai.attackAbsHeight >= ai.targetAbsHeight) + && (ai.attackHeight > 0)) { + los.attackerCover |= COVER_HORIZONTAL; + potentialCover = true; + } } - } - - // If there's a partial cover situation, we may need to keep track of - // damageable assets that are providing cover, so we can damage them if - // they block a shot. - if (potentialCover) { - if (coveredByDropship) { - los.setDamagableCoverTypePrimary(DAMAGABLE_COVER_DROPSHIP); - los.coverDropshipPrimary = coveringDropship; - } else if (bldg != null) { - los.setDamagableCoverTypePrimary(DAMAGABLE_COVER_BUILDING); - los.coverBuildingPrimary = bldg; - } else { - los.setDamagableCoverTypePrimary(DAMAGABLE_COVER_NONE); + + // If there's a partial cover situation, we may need to keep track of + // damageable assets that are providing cover, so we can damage them if + // they block a shot. + if (potentialCover) { + if (coveredByDropship) { + los.setDamagableCoverTypePrimary(DAMAGABLE_COVER_DROPSHIP); + los.coverDropshipPrimary = coveringDropship; + } else if (bldg != null) { + los.setDamagableCoverTypePrimary(DAMAGABLE_COVER_BUILDING); + los.coverBuildingPrimary = bldg; + } else { + los.setDamagableCoverTypePrimary(DAMAGABLE_COVER_NONE); + } + los.coverLocPrimary = coords; } - los.coverLocPrimary = coords; - } + } + return los; } @@ -1482,14 +1507,14 @@ private static boolean isDeadZone(Game game, AttackInfo ai) { } return false; } - - + + /** * Returns the text name of a particular type of cover, given its id. * TacOps partial cover is assigned from the perspective of the attacker, * so it's possible that the sides should be switched to make sense * from the perspective of the target. - * + * * @param cover The int id that represents the cover type. * @param switchSides A boolean that determines if left/right side should * be switched. This is useful since cover is given @@ -1528,7 +1553,7 @@ static public String getCoverName(int cover, boolean switchSides) { case COVER_HORIZONTAL: return Messages.getString("LosEffects.name_cover_horizontal"); case COVER_UPPER: - return Messages.getString("LosEffects.name_cover_upper"); + return Messages.getString("LosEffects.name_cover_upper"); case COVER_FULL: return Messages.getString("LosEffects.name_cover_full"); case COVER_75LEFT: @@ -1547,7 +1572,7 @@ static public String getCoverName(int cover, boolean switchSides) { return Messages.getString("LosEffects.name_cover_unknown"); } } - + public Building getCoverBuildingPrimary() { return coverBuildingPrimary; } @@ -1611,7 +1636,7 @@ public Coords getCoverLocSecondary() { public void setCoverLocSecondary(Coords coverLocSecondary) { this.coverLocSecondary = coverLocSecondary; } - + public boolean infantryProtected() { return infProtected; } diff --git a/megamek/src/megamek/server/GameManager.java b/megamek/src/megamek/server/GameManager.java index df130b2c0f4..2eca511c570 100644 --- a/megamek/src/megamek/server/GameManager.java +++ b/megamek/src/megamek/server/GameManager.java @@ -2104,6 +2104,8 @@ public void applyBoardSettings() { List rotateBoard = new ArrayList<>(); for (int i = 0; i < (mapSettings.getMapWidth() * mapSettings.getMapHeight()); i++) { sheetBoards[i] = new Board(); + // Need to set map type prior to loading to adjust foliage height, etc. + sheetBoards[i].setType(mapSettings.getMedium()); String name = mapSettings.getBoardsSelectedVector().get(i); boolean isRotated = false; if (name.startsWith(Board.BOARD_REQUEST_ROTATION)) { From 6827413d45918d4725acdb8b2342c40dabc3a532 Mon Sep 17 00:00:00 2001 From: sleet01 Date: Sat, 27 Jul 2024 22:08:36 -0700 Subject: [PATCH 19/22] Remove map ingest munging and replace with elevation adjustments --- .../i18n/megamek/client/messages.properties | 1 + .../client/ui/swing/tooltip/HexTooltip.java | 17 +++++++- megamek/src/megamek/common/Board.java | 4 -- megamek/src/megamek/common/Hex.java | 39 ++++++++----------- megamek/src/megamek/common/LosEffects.java | 2 +- megamek/src/megamek/common/Terrains.java | 4 +- 6 files changed, 36 insertions(+), 31 deletions(-) diff --git a/megamek/i18n/megamek/client/messages.properties b/megamek/i18n/megamek/client/messages.properties index 0328aa11b82..621e5822504 100644 --- a/megamek/i18n/megamek/client/messages.properties +++ b/megamek/i18n/megamek/client/messages.properties @@ -559,6 +559,7 @@ BoardView1.Tooltip.ZZ=ZZ #Buildings and Bridges BoardView1.Tooltip.Hex=Hex: {0} - Level: {1} +BoardView1.Tooltip.HexAlt=Hex: {0} - Altitude: {1} BoardView1.Tooltip.Building={1}
Height: {0}, CF: {2}
Armor: {3}; Basement: {4} BoardView1.Tooltip.BuildingLine=Height: {0}; CF: {1} Armor: {2} BoardView1.Tooltip.BldgBasementCollapsed=
(collapsed) diff --git a/megamek/src/megamek/client/ui/swing/tooltip/HexTooltip.java b/megamek/src/megamek/client/ui/swing/tooltip/HexTooltip.java index 34a7d9bbd02..994a7dd8bcf 100644 --- a/megamek/src/megamek/client/ui/swing/tooltip/HexTooltip.java +++ b/megamek/src/megamek/client/ui/swing/tooltip/HexTooltip.java @@ -22,6 +22,7 @@ import megamek.common.enums.BasementType; import megamek.common.planetaryconditions.IlluminationLevel; +import java.util.List; import java.util.Vector; import static megamek.client.ui.swing.util.UIUtil.*; @@ -193,16 +194,30 @@ public static String getOneLineSummary(BuildingTarget target, Board board) { } public static String getTerrainTip(Hex mhex, GUIPreferences GUIP, Game game) { + boolean inAtmosphere = game.getBoard().inAtmosphere(); Coords mcoords = mhex.getCoords(); String indicator = IlluminationLevel.determineIlluminationLevel(game, mcoords).getIndicator(); String illuminated = DOT_SPACER + guiScaledFontHTML(GUIP.getCautionColor()) + " " + indicator + ""; String result = ""; - StringBuilder sTerrain = new StringBuilder(Messages.getString("BoardView1.Tooltip.Hex", mcoords.getBoardNum(), mhex.getLevel()) + illuminated + "
"); + StringBuilder sTerrain = new StringBuilder( + Messages.getString( + (inAtmosphere) ? "BoardView1.Tooltip.HexAlt": "BoardView1.Tooltip.Hex", + mcoords.getBoardNum(), + mhex.getLevel() + ) + illuminated + "
" + ); + // Types that represent Elevations need converting and possibly zeroing if board is in Atmosphere (Low Alt.) + List typesThatNeedAltitudeChecked = List.of( + Terrains.INDUSTRIAL, Terrains.BLDG_ELEV, Terrains.BRIDGE_ELEV, Terrains.FOLIAGE_ELEV + ); // cycle through the terrains and report types found for (int terType: mhex.getTerrainTypes()) { int tf = mhex.getTerrain(terType).getTerrainFactor(); int ttl = mhex.getTerrain(terType).getLevel(); + if (typesThatNeedAltitudeChecked.contains(terType)) { + ttl = Terrains.getTerrainElevation(terType, ttl, inAtmosphere); + } String name = Terrains.getDisplayName(terType, ttl); if (name != null) { diff --git a/megamek/src/megamek/common/Board.java b/megamek/src/megamek/common/Board.java index 0e2eb855cb7..288a92cec91 100644 --- a/megamek/src/megamek/common/Board.java +++ b/megamek/src/megamek/common/Board.java @@ -1020,10 +1020,6 @@ public void load(InputStream is, @Nullable List errors, boolean continue args[i++] = st.ttype == StreamTokenizer.TT_NUMBER ? (int) st.nval + "" : st.sval; } int elevation = Integer.parseInt(args[1]); - if (mapType == T_ATMOSPHERE) { - // All foliage on low-altitude maps have height 1 - args[2] = args[2].replaceAll("foliage_elev:\\d{1,}", "foliage_elev:1"); - } // The coordinates in the .board file are ignored! nd[index] = new Hex(elevation, args[2], args[3], new Coords(index % nw, index / nw)); index++; diff --git a/megamek/src/megamek/common/Hex.java b/megamek/src/megamek/common/Hex.java index 81af514a622..5f7449ebf54 100644 --- a/megamek/src/megamek/common/Hex.java +++ b/megamek/src/megamek/common/Hex.java @@ -15,16 +15,9 @@ import megamek.common.annotations.Nullable; import megamek.common.enums.BasementType; -import org.apache.logging.log4j.LogManager; -import java.awt.*; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.StringSelection; -import java.awt.datatransfer.Transferable; import java.io.Serializable; import java.util.*; -import java.util.List; import java.util.stream.Collectors; /** @@ -187,10 +180,10 @@ public void setExits(Hex other, int direction, boolean roadsAutoExit) { } cTerr.setExit(direction, cTerr.exitsTo(oTerr)); - + // Water gets a special treatment: Water at the board edge - // (hex == null) should usually look like ocean and - // therefore always gets connection to outside the board + // (hex == null) should usually look like ocean and + // therefore always gets connection to outside the board if ((cTerr.getType() == Terrains.WATER) && (other == null)) { cTerr.setExit(direction, true); } @@ -601,12 +594,12 @@ public void getUnstuckModifier(int elev, PilotingRollData rollTarget) { terrain.getUnstuckModifier(elev, rollTarget); } } - - /** + + /** * True if this hex has a clifftop towards otherHex. This hex * must have the terrain CLIFF_TOP, it must have exits * specified (exits set to active) for the CLIFF_TOP terrain, - * and must have an exit in the direction of otherHex. + * and must have an exit in the direction of otherHex. */ public boolean hasCliffTopTowards(Hex otherHex) { return containsTerrain(Terrains.CLIFF_TOP) @@ -619,10 +612,10 @@ public Coords getCoords() { return coords; } - /** + /** * Sets the coords of this hex. DO NOT USE outside board.java! - * WILL NOT MOVE THE HEX. Only the position of the hex in the - * board's data[] determines the actual location of the hex. + * WILL NOT MOVE THE HEX. Only the position of the hex in the + * board's data[] determines the actual location of the hex. */ public void setCoords(Coords c) { coords = c; @@ -685,10 +678,10 @@ && containsTerrain(Terrains.FOLIAGE_ELEV)) { int wl = terrainLevel(Terrains.WOODS); int jl = terrainLevel(Terrains.JUNGLE); int el = terrainLevel(Terrains.FOLIAGE_ELEV); - + boolean isLightOrHeavy = wl == 1 || jl == 1 || wl == 2 || jl == 2; boolean isUltra = wl == 3 || jl == 3; - + if (! ((el == 1) || (isLightOrHeavy && el == 2) || (isUltra && el == 3))) { newErrors.add("Foliage elevation is wrong, must be 1 or 2 for Light/Heavy and 1 or 3 for Ultra Woods/Jungle."); } @@ -697,9 +690,9 @@ && containsTerrain(Terrains.FOLIAGE_ELEV)) { && containsTerrain(Terrains.FOLIAGE_ELEV)) { newErrors.add("Woods and Jungle Elevation terrain present without Woods or Jungle."); } - + // Buildings must have at least BUILDING, BLDG_ELEV and BLDG_CF - if (containsAnyTerrainOf(Terrains.BUILDING, Terrains.BLDG_ELEV, Terrains.BLDG_CF, Terrains.BLDG_FLUFF, + if (containsAnyTerrainOf(Terrains.BUILDING, Terrains.BLDG_ELEV, Terrains.BLDG_CF, Terrains.BLDG_FLUFF, Terrains.BLDG_ARMOR, Terrains.BLDG_CLASS, Terrains.BLDG_BASE_COLLAPSED, Terrains.BLDG_BASEMENT_TYPE) && !containsAllTerrainsOf(Terrains.BUILDING, Terrains.BLDG_ELEV, Terrains.BLDG_CF)) { newErrors.add("Incomplete Building! A hex with any building terrain must at least contain " @@ -714,14 +707,14 @@ && containsTerrain(Terrains.FOLIAGE_ELEV)) { } // Fuel Tanks must have all of FUEL_TANK, _ELEV, _CF and _MAGN - if (containsAnyTerrainOf(Terrains.FUEL_TANK, Terrains.FUEL_TANK_CF, + if (containsAnyTerrainOf(Terrains.FUEL_TANK, Terrains.FUEL_TANK_CF, Terrains.FUEL_TANK_ELEV, Terrains.FUEL_TANK_MAGN) - && !containsAllTerrainsOf(Terrains.FUEL_TANK, Terrains.FUEL_TANK_CF, + && !containsAllTerrainsOf(Terrains.FUEL_TANK, Terrains.FUEL_TANK_CF, Terrains.FUEL_TANK_ELEV, Terrains.FUEL_TANK_MAGN)) { newErrors.add("Incomplete Fuel Tank! A hex with any fuel tank terrain must contain " + "the fuel tank type, elevation, CF and the fuel tank magnitude."); } - + if (containsAllTerrainsOf(Terrains.FUEL_TANK, Terrains.BUILDING)) { newErrors.add("A hex cannot have both a Building and a Fuel Tank."); } diff --git a/megamek/src/megamek/common/LosEffects.java b/megamek/src/megamek/common/LosEffects.java index e4d60c49361..35fa215426d 100644 --- a/megamek/src/megamek/common/LosEffects.java +++ b/megamek/src/megamek/common/LosEffects.java @@ -1224,7 +1224,7 @@ private static LosEffects losForCoords(Game game, AttackInfo ai, // Intervening Smoke and Woods int woodsLevel = hex.terrainLevel(Terrains.WOODS); int jungleLevel = hex.terrainLevel(Terrains.JUNGLE); - int foliageElev = hex.terrainLevel(Terrains.FOLIAGE_ELEV); + int foliageElev = Terrains.getTerrainElevation(Terrains.FOLIAGE_ELEV, hex.terrainLevel(Terrains.FOLIAGE_ELEV), ai.lowAltitude); int smokeLevel = hex.terrainLevel(Terrains.SMOKE); boolean hasFoliage = (woodsLevel != Terrain.LEVEL_NONE) || (jungleLevel != Terrain.LEVEL_NONE); diff --git a/megamek/src/megamek/common/Terrains.java b/megamek/src/megamek/common/Terrains.java index 41c6976cda6..e7bad47cfd5 100644 --- a/megamek/src/megamek/common/Terrains.java +++ b/megamek/src/megamek/common/Terrains.java @@ -57,7 +57,6 @@ public class Terrains implements Serializable { // LI smoke 4: Heavy LI smoke public static final int GEYSER = 21; // 1: dormant 2: active 3: magma vent // unimplemented - // Black Ice // Bug Storm // Extreme Depths // Hazardous Liquid Pools @@ -476,7 +475,8 @@ public static int getTerrainFactor(int type, int level) { /** * Returns the number of elevations or altitudes above the hex level a given - * terrainType rises. + * terrainType rises. Has to be explicit about the *_ELEV values, because _everything else_ + * that comes through here is a "level", a ranking of "denseness", not an elevation _or_ altitude. * * @param terrainType this specifies the type of terrain to get the information for * @param inAtmosphere From 36da6759690fb0cadba1fbdc2b88bedc590b5630 Mon Sep 17 00:00:00 2001 From: sleet01 Date: Sat, 27 Jul 2024 22:48:26 -0700 Subject: [PATCH 20/22] Prevent NPE when removing forces from Force that exists but isn not registered --- megamek/src/megamek/common/force/Forces.java | 257 ++++++++++--------- 1 file changed, 131 insertions(+), 126 deletions(-) diff --git a/megamek/src/megamek/common/force/Forces.java b/megamek/src/megamek/common/force/Forces.java index ba0c09c6508..7bb754b7fa0 100644 --- a/megamek/src/megamek/common/force/Forces.java +++ b/megamek/src/megamek/common/force/Forces.java @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with MegaMek. If not, see . - */ + */ package megamek.common.force; @@ -36,26 +36,26 @@ /** * Manages a collection of Forces for a game. The game only needs to hold one Forces object. * Like in Campaign.java in MHQ this is mainly a map of id to Force along with many utility functions. - * Force management and changes are directed through this object. - * + * Force management and changes are directed through this object. + * * @author Simon (Juliez) */ public final class Forces implements Serializable { private static final long serialVersionUID = -1382468145554363945L; - + private final HashMap forces = new HashMap<>(); private transient IGame game; - + public Forces(IGame g) { game = g; } - - /** + + /** * Adds a top-level force with the provided name and the provided owner. Verifies the name * and the force before applying the change. - * Returns the id of the newly created Force or Force.NO_FORCE if no force was - * created. + * Returns the id of the newly created Force or Force.NO_FORCE if no force was + * created. */ public synchronized int addTopLevelForce(final Force force, final @Nullable Player owner) { if (!verifyForceName(force.getName()) || (owner == null)) { @@ -67,7 +67,7 @@ public synchronized int addTopLevelForce(final Force force, final @Nullable Play return newId; } - /** + /** * Adds the provided subforce to the provided parent. Verifies the name and the force before * applying the change. * @return the id of the newly created Force or Force.NO_FORCE if no new subforce was created. @@ -92,45 +92,45 @@ public List forcelessEntities() { .filter(e -> !e.partOfForce()) .collect(toList()); } - + /** Returns the number of top-level forces present, i.e. forces with no parent force. */ public int getTopLevelForceCount() { return getTopLevelForces().size(); } - + /** Returns a List of the top-level forces. */ public List getTopLevelForces() { return forces.values().stream().filter(Force::isTopLevel).collect(toList()); } - - /** + + /** * Returns true if the provided force is part of the present forces either - * as a top-level or a subforce. + * as a top-level or a subforce. */ public boolean contains(@Nullable Force force) { return (force != null) && forces.containsValue(force); } - - /** + + /** * Returns true if the provided forceId is part of the present forces either - * as a top-level or a subforce. + * as a top-level or a subforce. */ public boolean contains(int forceId) { return forces.containsKey(forceId); } - - /** - * Returns the force with the given force id or null if there is no force with this id. + + /** + * Returns the force with the given force id or null if there is no force with this id. */ public Force getForce(int id) { return forces.get(id); } - + /** * Adds the provided Entity to the provided force. Does nothing if the force doesn't exist * or if the entity is already in the targeted force. Removes the entity from any former force. * Returns a list of all changed forces, i.e. the former force, if any, and the new force. - * The list will be empty if no actual change occurred. + * The list will be empty if no actual change occurred. */ public ArrayList addEntity(ForceAssignable entity, int forceId) { ArrayList result = new ArrayList<>(); @@ -142,7 +142,7 @@ public ArrayList addEntity(ForceAssignable entity, int forceId) { if (formerForce == forceId) { return result; } - + forces.get(forceId).addEntity(entity); entity.setForceId(forceId); result.add(getForce(forceId)); @@ -153,10 +153,10 @@ public ArrayList addEntity(ForceAssignable entity, int forceId) { return result; } - /** + /** * Removes the provided entities from their current forces, if any. Does nothing if an entity * is already force-less (forceId == Force.NO_FORCE). Returns a list of all changed forces. - * The list will be empty if no actual change occurred. + * The list will be empty if no actual change occurred. */ public synchronized LinkedHashSet removeEntityFromForces(Collection entities) { LinkedHashSet result = new LinkedHashSet<>(); @@ -166,12 +166,12 @@ public synchronized LinkedHashSet removeEntityFromForces(Collection removeEntityFromForces(ForceAssignable entity) { ArrayList result = new ArrayList<>(); @@ -180,21 +180,26 @@ public synchronized ArrayList removeEntityFromForces(ForceAssignable enti return result; } entity.setForceId(NO_FORCE); - + if (contains(formerForce)) { - result.add(getForce(formerForce)); - getForce(formerForce).removeEntity(entity); + Force former = getForce(formerForce); + if (former != null) { + result.add(former); + former.removeEntity(entity); + } else { + LogManager.getLogger().warn("Removing entity from Force that has not yet been registered!"); + } } else { LogManager.getLogger().warn("Removed entity from non-existent force!"); } return result; } - - /** + + /** * Removes the provided entity ID from its current force, if any. Does nothing if the entity - * is already force-less (forceId == Force.NO_FORCE). + * is already force-less (forceId == Force.NO_FORCE). * Returns a list of all changed forces, i.e. the former force, if any. - * The list will be empty if no actual change occurred. + * The list will be empty if no actual change occurred. */ public synchronized ArrayList removeEntityFromForces(int entityId) { ArrayList result = new ArrayList<>(); @@ -215,8 +220,8 @@ public synchronized ArrayList removeEntityFromForces(int entityId) { } return result; } - - /** + + /** * Renames the Force with forceId to the provided name. The provided values are * fully verified before applying the change. A null name or empty name can safely * be passed. Duplicate names may be given; forces are identified via id. @@ -228,8 +233,8 @@ public void renameForce(String name, int forceId) { Force force = forces.get(forceId); force.setName(name); } - - /** + + /** * Returns true if the provided name can be used as a Force name. It cannot * be empty or contain "|" or "\". */ @@ -237,49 +242,49 @@ public boolean verifyForceName(String name) { return name != null && !name.isBlank() && !name.contains("|") && !name.contains("\\"); } - /** + /** * @return the force owner's id */ public int getOwnerId(Force force) { return force.getOwnerId(); } - /** + /** * @return the owner of this force. */ public Player getOwner(Force force) { return game.getPlayer(getOwnerId(force)); } - - /** + + /** * @return the owner of this force. */ public Player getOwner(int forceId) { return getOwner(getForce(forceId)); } - - /** + + /** * Returns the Force that the provided entity is a direct part of. * E.g., If it is part of a lance in a company, the lance will be returned. - * If it is part of no force, returns null. + * If it is part of no force, returns null. */ public @Nullable Force getForce(final ForceAssignable entity) { return forces.get(getForceId(entity.getId())); } - /** + /** * Returns the id of the force that the provided entity is a direct part of. * E.g., If it is part of a lance in a company, the lance id will be returned. - * If it is part of no force, returns Force.NO_FORCE. + * If it is part of no force, returns Force.NO_FORCE. */ public int getForceId(ForceAssignable entity) { return getForceId(entity.getId()); } - - /** + + /** * Returns the id of the force that the provided entity (id) is a direct part of. * E.g., If it is part of a lance in a company, the lance id will be returned. - * If it is part of no force, returns Force.NO_FORCE. + * If it is part of no force, returns Force.NO_FORCE. */ public int getForceId(int id) { for (Force force: forces.values()) { @@ -291,10 +296,10 @@ public int getForceId(int id) { } /** - * Parses the force string of the provided entity. + * Parses the force string of the provided entity. * Returns a List of Force stubs in the order of highest to lowest force. - * The Force stubs cannot be added to a Forces object directly! They - * contain only the name and id and have no parent and no owner and + * The Force stubs cannot be added to a Forces object directly! They + * contain only the name and id and have no parent and no owner and * the passed entity is not added to them! */ public static List parseForceString(ForceAssignable entity) { @@ -321,9 +326,9 @@ public static List parseForceString(ForceAssignable entity) { return forces; } - /** + /** * Returns a list of all subforces of the provided force, including - * subforces of subforces to any depth. + * subforces of subforces to any depth. */ public ArrayList getFullSubForces(Force force) { ArrayList result = new ArrayList<>(); @@ -335,9 +340,9 @@ public ArrayList getFullSubForces(Force force) { } return result; } - - /** - * For the given player, returns a list of forces that are his own or belong to his team. + + /** + * For the given player, returns a list of forces that are his own or belong to his team. */ public ArrayList getAvailableForces(Player player) { ArrayList result = new ArrayList<>(); @@ -349,12 +354,12 @@ public ArrayList getAvailableForces(Player player) { } return result; } - + private boolean isAvailable(Force force, Player player) { Player owner = game.getPlayer(getOwnerId(force)); return (owner != null) && !owner.isEnemyOf(player); } - + public String forceStringFor(final ForceAssignable entity) { final StringBuilder result = new StringBuilder(); for (final Force ancestor : forceChain(entity)) { @@ -366,10 +371,10 @@ public String forceStringFor(final ForceAssignable entity) { } return result.toString(); } - - /** + + /** * Returns a ArrayList of Forces that make up the chain of forces to the provided entity. - * The list starts with the top-level force containing the entity and ends with + * The list starts with the top-level force containing the entity and ends with * the force that the entity is an immediate member of. */ public ArrayList forceChain(ForceAssignable entity) { @@ -379,10 +384,10 @@ public ArrayList forceChain(ForceAssignable entity) { return new ArrayList<>(); } } - - /** + + /** * Returns a ArrayList of Forces that make up the chain of forces to the provided force. - * The list starts with the top-level force containing the provided force and ends with + * The list starts with the top-level force containing the provided force and ends with * (includes!) the provided force itself. */ public ArrayList forceChain(Force force) { @@ -393,7 +398,7 @@ public ArrayList forceChain(Force force) { result.add(force); return result; } - + /** Return a free Force id. */ private int newId() { int result = 0; @@ -402,24 +407,24 @@ private int newId() { } return result; } - - /** + + /** * Overwrites the previous force mapped to forceId with the provided force - * or adds it if no force was present with that forceId. - * Only used when the server sends force updates. + * or adds it if no force was present with that forceId. + * Only used when the server sends force updates. */ public void replace(int forceId, Force force) { forces.put(forceId, force); } - - /** + + /** * Sets the game reference to the provided Game. Used when transferring * the forces between client and server. */ public void setGame(IGame g) { game = g; } - + /** Returns a clone of this Forces object, including clones of all contained forces. */ @Override public Forces clone() { @@ -430,16 +435,16 @@ public Forces clone() { return clone; } - /** - * Returns true if this Forces object is valid. + /** + * Returns true if this Forces object is valid. * @see #isValid(Collection) */ public boolean isValid() { return isValid(new ArrayList<>()); } - - /** + + /** * Returns true if this Forces object is valid. If any updatedEntities are given, * the validity check will test these instead of the current game's. * @see #isValid() @@ -452,7 +457,7 @@ public boolean isValid(Collection updatedEntities) { if (entry.getKey() != entry.getValue().getId()) { return false; } - + // Create a copy of the game's entity list and overwrite with the given entities LinkedHashMap allEntities = new LinkedHashMap<>(); List forceRelevantGameObjects = game.getInGameObjects().stream() @@ -464,14 +469,14 @@ public boolean isValid(Collection updatedEntities) { for (ForceAssignable entity: updatedEntities) { allEntities.put(entity.getId(), entity); } - + // check if all entities exist/live // check if owner exists // check if entities match owners/team // check if no entity is contained twice // check if entity.forceId matches forceId for (int entityId: entry.getValue().getEntities()) { - if (!allEntities.containsKey(entityId) + if (!allEntities.containsKey(entityId) || game.getPlayer(getOwnerId(entry.getValue())) == null || game.getPlayer(allEntities.get(entityId).getOwnerId()).isEnemyOf(game.getPlayer(getOwnerId(entry.getValue()))) || !entIds.add(entityId) @@ -484,7 +489,7 @@ public boolean isValid(Collection updatedEntities) { // check if subforces agree on the parent // check if subforces and parents share teams for (int subforceId: entry.getValue().getSubForces()) { - if (!contains(subforceId) + if (!contains(subforceId) || !subIds.add(subforceId) || entry.getKey() != getForce(subforceId).getParentId() || getOwner(getForce(subforceId)).isEnemyOf(getOwner(entry.getValue()))) { @@ -492,7 +497,7 @@ public boolean isValid(Collection updatedEntities) { } } } - // check if no circular parents + // check if no circular parents Set forceIds = new TreeSet<>(forces.keySet()); for (Force toplevel: getTopLevelForces()) { for (Force subforce: getFullSubForces(toplevel)) { @@ -505,8 +510,8 @@ public boolean isValid(Collection updatedEntities) { } return true; } - - /** + + /** * Corrects this Forces object as much as possible. Also corrects entities * when necessary (wrong forceId). *
    @@ -576,8 +581,8 @@ public void correct() { } } } - - /** + + /** * Removes the given force from these forces if it is empty. Returns a list * of affected forces which contains the parent if the deleted force was a subforce * and is empty otherwise. @@ -595,12 +600,12 @@ public ArrayList deleteForce(int forceId) { } return result; } - - /** + + /** * Removes the given forces and all their subforces from these Forces. Returns a list * of affected surviving forces. This method does not check if the forces are empty. *

    NOTE: Any entities in the removed forces are NOT updated by this method! - * It is necessary to update any entities' forceId unless these are deleted as well. + * It is necessary to update any entities' forceId unless these are deleted as well. */ public ArrayList deleteForces(Collection delForces) { ArrayList result = new ArrayList<>(); @@ -625,8 +630,8 @@ public ArrayList deleteForces(Collection delForces) { public ArrayList getAllForces() { return new ArrayList<>(forces.values()); } - - /** + + /** * Attaches a force to a new parent. The new parent force cannot be a subforce * of the force and cannot belong to an enemy of its owner. * Returns a list of affected forces. This may be empty and may contain up to @@ -636,7 +641,7 @@ public ArrayList attachForce(Force force, Force newParent) { ArrayList result = new ArrayList<>(); Player forceOwner = game.getPlayer(getOwnerId(force)); Player parentOwner = game.getPlayer(getOwnerId(newParent)); - if (isSubForce(force, newParent) || forceOwner == null + if (isSubForce(force, newParent) || forceOwner == null || forceOwner.isEnemyOf(parentOwner) || force.getParentId() == newParent.getId()) { return result; } @@ -653,15 +658,15 @@ public ArrayList attachForce(Force force, Force newParent) { result.add(newParent); return result; } - + /** Returns true when possibleSubForce is one of the subforces (in any depth) of the given force. */ public boolean isSubForce(Force force, Force possibleSubForce) { return getFullSubForces(force).contains(possibleSubForce); } - - /** - * Promotes a force to top-level (unattaches it from its parent force if it has one). - * Returns a list of affected forces which may be empty. + + /** + * Promotes a force to top-level (unattaches it from its parent force if it has one). + * Returns a list of affected forces which may be empty. */ public ArrayList promoteForce(Force force) { ArrayList result = new ArrayList<>(); @@ -676,18 +681,18 @@ public ArrayList promoteForce(Force force) { } return result; } - - /** + + /** * Changes the owner of the given force to the given newOwner without affecting - * anything else. Will only do something if the new owner is a teammate of the - * present owner. Returns a list of affected forces containing the force if it + * anything else. Will only do something if the new owner is a teammate of the + * present owner. Returns a list of affected forces containing the force if it * was changed, empty otherwise. */ public ArrayList assignForceOnly(Force force, Player newOwner) { ArrayList result = new ArrayList<>(); if (getOwner(force).isEnemyOf(newOwner)) { LogManager.getLogger().error("Tried to reassign a force without units to an enemy."); - return result; + return result; } if (getOwnerId(force) != newOwner.getId()) { force.setOwnerId(newOwner.getId()); @@ -695,10 +700,10 @@ public ArrayList assignForceOnly(Force force, Player newOwner) { } return result; } - - /** - * Changes the owner of the given force and all subforces to the given newOwner. - * Promotes the force to top-level if the parent force is now an enemy force. + + /** + * Changes the owner of the given force and all subforces to the given newOwner. + * Promotes the force to top-level if the parent force is now an enemy force. * Returns a list of affected forces. */ public Set assignFullForces(Force force, Player newOwner) { @@ -725,17 +730,17 @@ public Set assignFullForces(Force force, Player newOwner) { } } } - return result; + return result; } - + @Override public String toString() { List forceStrings = forces.values().stream().map(Force::toString).collect(toList()); return String.join("\n", forceStrings); } - - /** - * Returns a list of all entities of the given force and all its subforces to any depth. + + /** + * Returns a list of all entities of the given force and all its subforces to any depth. */ public List getFullEntities(final @Nullable Force force) { final List result = new ArrayList<>(); @@ -750,10 +755,10 @@ public List getFullEntities(final @Nullable Force force) { } return result; } - + /** * Moves up the given entity in the list of entities of its force if possible. - * Returns true when an actual change occurred. + * Returns true when an actual change occurred. */ public ArrayList moveUp(ForceAssignable entity) { ArrayList result = new ArrayList<>(); @@ -765,10 +770,10 @@ public ArrayList moveUp(ForceAssignable entity) { } return result; } - - /** + + /** * Moves down the given entity in the list of entities of its force if possible. - * Returns true when an actual change occurred. + * Returns true when an actual change occurred. */ public ArrayList moveDown(ForceAssignable entity) { ArrayList result = new ArrayList<>(); @@ -780,10 +785,10 @@ public ArrayList moveDown(ForceAssignable entity) { } return result; } - - /** + + /** * Moves up the given subforce in the list of subforces of its parent if possible. - * Returns true when an actual change occurred. + * Returns true when an actual change occurred. */ public ArrayList moveUp(Force subForce) { ArrayList result = new ArrayList<>(); @@ -795,10 +800,10 @@ public ArrayList moveUp(Force subForce) { } return result; } - - /** + + /** * Moves down the given subforce in the list of subforces of its parent if possible. - * Returns true when an actual change occurred. + * Returns true when an actual change occurred. */ public ArrayList moveDown(Force subForce) { ArrayList result = new ArrayList<>(); From 9bdac291826de9b8cc0201c98672ababc14d0263 Mon Sep 17 00:00:00 2001 From: SJuliez Date: Sun, 28 Jul 2024 08:34:53 +0200 Subject: [PATCH 21/22] Update history.txt --- megamek/docs/history.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/megamek/docs/history.txt b/megamek/docs/history.txt index 00a5c6c5a03..d54996c426b 100644 --- a/megamek/docs/history.txt +++ b/megamek/docs/history.txt @@ -56,6 +56,13 @@ MEGAMEK VERSION HISTORY: + PR #5791: Added much-needed whitespace to some menu items of the board right click menu + PR #5798: Fix Reflective armor not appearing in MML dropdown + Fix #5803: Removes a number of duplicated infantry weapons ++ Fix #5795: Terrain altitude rules and line of sight are now implemented for Low Altitude maps ++ Fix #5790: The combat computer heat report message is now clearer, indicating that the heat bonus has already been applied in the reported values ++ Fix #5740: Lobby copy-paste will now also work for units that have no model name ++ Fix #5789: Prevent errors with showing the firing arcs ++ Fix #5793: Units are no longer able to be unloaded without regard for the bay door limits ++ Fix #5611: Prevent NPE when removing forces from Force that exists but is not registered yet (when quickly closing MM after an MHQ scenario start) + 0.49.20 (2024-06-28 2100 UTC) (THIS IS THE LAST VERSION TO SUPPORT JAVA 11) + PR #5281, #5327, #5308, #5336, #5318, #5383, #5369, #5384, #5455, #5505, #5541: Code internals: preparatory work for supporting game types such as SBF, code cleanup for string drawing, superclass change for BoardView, From 1c5f80f967fa0d552825ed8d184e6ea165d18c60 Mon Sep 17 00:00:00 2001 From: repligator Date: Sun, 28 Jul 2024 19:33:40 -0400 Subject: [PATCH 22/22] Data, spelling, typos Adds a few manufacturers/primaryfactorys. --- .../fighters/TRO3085u/Cutting Edge/Wusun Prime.blk | 3 +++ megamek/data/mechfiles/mechs/3060u/Beowulf BEO-12.mtf | 3 ++- megamek/data/mechfiles/mechs/3060u/Helios HEL-3D.mtf | 2 ++ megamek/data/mechfiles/mechs/3067/Arcas.mtf | 2 ++ .../mechfiles/mechs/3085u/Cutting Edge/Karhu Prime.mtf | 3 ++- megamek/data/mechfiles/mechs/3085u/Cutting Edge/Kuma.mtf | 2 ++ .../data/mechfiles/mechs/3085u/Cutting Edge/Onager.mtf | 2 ++ .../mechfiles/mechs/3085u/Cutting Edge/Shadow Cat II.mtf | 3 ++- .../mechs/3145/Clans/Vulture (Mad Dog) Mk III (Prime).mtf | 3 ++- .../data/mechfiles/mechs/3145/Davion/Gunsmith CH11-NG.mtf | 3 ++- .../data/mechfiles/mechs/3145/Republic/Kheper KHP-7R.mtf | 3 ++- megamek/data/mechfiles/mechs/3145/Steiner/Ursa URA-2A.mtf | 3 ++- .../mechs/WoR Supplemental/Pariah (Septicemia) US.mtf | 2 +- megamek/i18n/megamek/client/messages.properties | 8 ++++---- megamek/i18n/megamek/common/messages.properties | 2 +- megamek/i18n/megamek/common/options/messages.properties | 8 ++++---- megamek/i18n/megamek/common/report-messages.properties | 4 ++-- 17 files changed, 37 insertions(+), 19 deletions(-) diff --git a/megamek/data/mechfiles/fighters/TRO3085u/Cutting Edge/Wusun Prime.blk b/megamek/data/mechfiles/fighters/TRO3085u/Cutting Edge/Wusun Prime.blk index bdf3a86f98c..acc4d2cca0b 100644 --- a/megamek/data/mechfiles/fighters/TRO3085u/Cutting Edge/Wusun Prime.blk +++ b/megamek/data/mechfiles/fighters/TRO3085u/Cutting Edge/Wusun Prime.blk @@ -132,3 +132,6 @@ TRO: 3085 55.0 + +manufacturer:United Outworlders Corporation +primaryfactory:Ramora \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3060u/Beowulf BEO-12.mtf b/megamek/data/mechfiles/mechs/3060u/Beowulf BEO-12.mtf index 47e5dc56327..04048e32936 100644 --- a/megamek/data/mechfiles/mechs/3060u/Beowulf BEO-12.mtf +++ b/megamek/data/mechfiles/mechs/3060u/Beowulf BEO-12.mtf @@ -157,4 +157,5 @@ Ferro-Fibrous -Empty- -Empty- - +manufacturer:Odin Manufacturing +primaryfactory:Orestes \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3060u/Helios HEL-3D.mtf b/megamek/data/mechfiles/mechs/3060u/Helios HEL-3D.mtf index daa489ee79b..aa0bf0ba4e0 100644 --- a/megamek/data/mechfiles/mechs/3060u/Helios HEL-3D.mtf +++ b/megamek/data/mechfiles/mechs/3060u/Helios HEL-3D.mtf @@ -157,3 +157,5 @@ Jump Jet -Empty- +manufacturer:Ceres Metals Industries +primaryfactory:Warlock \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3067/Arcas.mtf b/megamek/data/mechfiles/mechs/3067/Arcas.mtf index b4cbfef580c..e561cedd76b 100644 --- a/megamek/data/mechfiles/mechs/3067/Arcas.mtf +++ b/megamek/data/mechfiles/mechs/3067/Arcas.mtf @@ -156,3 +156,5 @@ Jump Jet -Empty- -Empty- +manufacturer:Bergan Industries +primaryfactory:Alshain \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Karhu Prime.mtf b/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Karhu Prime.mtf index 5eeb9ce5e41..58a15206658 100644 --- a/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Karhu Prime.mtf +++ b/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Karhu Prime.mtf @@ -153,4 +153,5 @@ Clan Endo Steel -Empty- -Empty- - +manufacturer:Odin Manufacturing +primaryfactory:Orestes \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Kuma.mtf b/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Kuma.mtf index 6f1413706cf..d2582f627a3 100644 --- a/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Kuma.mtf +++ b/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Kuma.mtf @@ -154,3 +154,5 @@ Clan Improved Jump Jet -Empty- +manufacturer:Alshain Battleworx +primaryfactory:Alshain \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Onager.mtf b/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Onager.mtf index 49a06767db3..a0e58f0b577 100644 --- a/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Onager.mtf +++ b/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Onager.mtf @@ -161,3 +161,5 @@ CLDoubleHeatSink -Empty- +manufacturer:Red Devil Industries +primaryfactory:Pandora \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Shadow Cat II.mtf b/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Shadow Cat II.mtf index be222457c22..e0b79bc39c6 100644 --- a/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Shadow Cat II.mtf +++ b/megamek/data/mechfiles/mechs/3085u/Cutting Edge/Shadow Cat II.mtf @@ -154,4 +154,5 @@ Foot Actuator -Empty- -Empty- - +manufacturer:Olivetti Weaponry +primaryfactory:Sudeten \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3145/Clans/Vulture (Mad Dog) Mk III (Prime).mtf b/megamek/data/mechfiles/mechs/3145/Clans/Vulture (Mad Dog) Mk III (Prime).mtf index 8c902f8a74f..2c55aa6e380 100644 --- a/megamek/data/mechfiles/mechs/3145/Clans/Vulture (Mad Dog) Mk III (Prime).mtf +++ b/megamek/data/mechfiles/mechs/3145/Clans/Vulture (Mad Dog) Mk III (Prime).mtf @@ -164,4 +164,5 @@ Foot Actuator -Empty- -Empty- - +manufacturer:Alshain Weapons +primaryfactory:Alshain \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3145/Davion/Gunsmith CH11-NG.mtf b/megamek/data/mechfiles/mechs/3145/Davion/Gunsmith CH11-NG.mtf index c1e0ef5c93c..948cc575938 100644 --- a/megamek/data/mechfiles/mechs/3145/Davion/Gunsmith CH11-NG.mtf +++ b/megamek/data/mechfiles/mechs/3145/Davion/Gunsmith CH11-NG.mtf @@ -152,4 +152,5 @@ IS Endo Steel -Empty- -Empty- - +manufacturer:Jalastar Aerospace +primaryfactory:Panpour \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3145/Republic/Kheper KHP-7R.mtf b/megamek/data/mechfiles/mechs/3145/Republic/Kheper KHP-7R.mtf index 2e24d1e284c..f36716baa66 100644 --- a/megamek/data/mechfiles/mechs/3145/Republic/Kheper KHP-7R.mtf +++ b/megamek/data/mechfiles/mechs/3145/Republic/Kheper KHP-7R.mtf @@ -152,4 +152,5 @@ IS Endo Steel -Empty- -Empty- - +manufacturer:New Earth Trading Company +primaryfactory:New Earth \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/3145/Steiner/Ursa URA-2A.mtf b/megamek/data/mechfiles/mechs/3145/Steiner/Ursa URA-2A.mtf index 587389b6c40..5cb29b7e535 100644 --- a/megamek/data/mechfiles/mechs/3145/Steiner/Ursa URA-2A.mtf +++ b/megamek/data/mechfiles/mechs/3145/Steiner/Ursa URA-2A.mtf @@ -158,4 +158,5 @@ IS Endo Steel -Empty- -Empty- - +manufacturer:TharHes Industries +primaryfactory:Tharkad \ No newline at end of file diff --git a/megamek/data/mechfiles/mechs/WoR Supplemental/Pariah (Septicemia) US.mtf b/megamek/data/mechfiles/mechs/WoR Supplemental/Pariah (Septicemia) US.mtf index 6537479a33a..a7832379005 100644 --- a/megamek/data/mechfiles/mechs/WoR Supplemental/Pariah (Septicemia) US.mtf +++ b/megamek/data/mechfiles/mechs/WoR Supplemental/Pariah (Septicemia) US.mtf @@ -160,7 +160,7 @@ Talons (omnipod) overview:The backbone of The Society's military forces, the Septicemia was a utilitarian medium-class workhorse. Devoid of the more experimental technology utilized by the Cephalus and Osteon to allow it to be built in higher volumes, the Septicemia saves weight with an XL Engine, Endo Steel chassis, and nine tons of Ferro-Fibrous armor. While the location of its weaponry in its torsos hampers its ability to carry Battle Armor, this was intentional to try and ensure hand actuators were retained to maximize its physical combat abilities. -capabilities:This configuration is apparently intended for space operations. Each arm carries a Spot Welder and an ER Medium Laser. Two ER Small Lasers are in the right and left torso, while a single ER PPC is installed in the left torso. Seven Improved Jump Jets and two tons of Liquid Storage provide mobility in the depths of space. To maintain grip on spacecraft, the Septimecia US has talons on each leg. +capabilities:This configuration is apparently intended for space operations. Each arm carries a Spot Welder and an ER Medium Laser. Two ER Small Lasers are in the right and left torso, while a single ER PPC is installed in the left torso. Seven Improved Jump Jets and two tons of Liquid Storage provide mobility in the depths of space. To maintain grip on spacecraft, the Septicemia US has talons on each leg. deployment:Planning their OmniMech forces around a single mass-produced design intended to work in concert with two rarer but cutting-edge units, the Septicemia was built using proven technology with a focus towards mutual support on the battlefield, its every aspect intended to allow it to engage the Clan toumans using methods of warfare they found dezgra. Appearing during the Wars of Reaving when Clan warriors were even more intent on an exceedingly strict adherence of zellbrigen to avoid accusations of Taint, the Septicemia would prove frighteningly effective, earning it the nickname of "Pariah" by the Clan Diamond Shark forces that first faced it on Babylon in 3072. diff --git a/megamek/i18n/megamek/client/messages.properties b/megamek/i18n/megamek/client/messages.properties index 621e5822504..3900958cd39 100644 --- a/megamek/i18n/megamek/client/messages.properties +++ b/megamek/i18n/megamek/client/messages.properties @@ -577,7 +577,7 @@ BoardView1.Tooltip.HiddenActivating=Hidden unit will activate in #Bomb hex dialog BombPayloadDialog.FighterBombDesc=Select the number and type of bombs you wish to drop. -BombPayloadDialog.SquadronBombDesc=Select the number of salvos for each bomb type you wish to drop.
    The number in parenthesis represents the number of bombs that will be dropped. +BombPayloadDialog.SquadronBombDesc=Select the number of salvos for each bomb type you wish to drop.
    The number in parentheses represents the number of bombs that will be dropped. #CamoChooser CamoChoiceDialog.btnParent.text=Reset @@ -2068,7 +2068,7 @@ MechDisplay.TaserInterference= to gunnery and piloting due to taser interference MechDisplay.TSEMPInterference=+2 to gunnery due to TSEMP interference MechDisplay.TSEMPShutdown=Shutdown due to TSEMP MechDisplay.SelectMulti.title=Choose Ammobin -MechDisplay.SelectMulti.question=Which ammobin do you want do select? +MechDisplay.SelectMulti.question=Which ammobin do you want to select? MechDisplay.over=over MechDisplay.NoTarget=No Target Selected MechDisplay.AimingAt=Aiming at %s @@ -2629,9 +2629,9 @@ MovementDisplay.MicroliteMove.title=Microlite VTOL movement MovementDisplay.Move=Move MovementDisplay.MoveEnvelope=Show possible moves MovementDisplay.NoMinefield=No minefield in hex\! -MovementDisplay.NoPlaceToEject.message=The are no available hexes for the crew to escape into. +MovementDisplay.NoPlaceToEject.message=There are no available hexes for the crew to escape into. MovementDisplay.NoPlaceToEject.title=No Place To Abandon Ship! -MovementDisplay.NoPlaceToUnload.message=The are no available hexes for this unit to unload into. +MovementDisplay.NoPlaceToUnload.message=There are no available hexes for this unit to unload into. MovementDisplay.NoPlaceToUnload.title=No Place To Unload! MovementDisplay.NoTarget=No target\! MovementDisplay.NoTakeOffDialog.title=Cannot Liftoff diff --git a/megamek/i18n/megamek/common/messages.properties b/megamek/i18n/megamek/common/messages.properties index d4c0b723486..b80318f319a 100644 --- a/megamek/i18n/megamek/common/messages.properties +++ b/megamek/i18n/megamek/common/messages.properties @@ -551,7 +551,7 @@ TROView.InfantryNote.AA=Anti-Aircraft equipment; may attack airborne units that TROView.InfantryNote.Heat=Can cause heat damage to heat-tracking units. TROView.InfantryNote.EncumberingArmor=Cannot make anti-'Mech attacks. TROView.InfantryNote.DESTArmor=+1 to-hit modifier to attackers if unit does not move.\nNon-infantry units suffer a +1/+1/+2 to-hit modifier for S/M/L ranges. -TROView.InfantryNote.CamoArmor=+3/+2/+1 to-hit modifier to attackers if unit does moves 0/1/2 hexes. +TROView.InfantryNote.CamoArmor=+3/+2/+1 to-hit modifier to attackers if unit moves 0/1/2 hexes. TROView.InfantryNote.IRArmor=Non-infantry units suffer a +1/+1/+2 to-hit modifier for S/M/L ranges. TROView.InfantryNote.ECMArmor=Invisible to standard/light active probes. TROView.InfantryNote.Augmented=Cybernetically enhanced infantry: diff --git a/megamek/i18n/megamek/common/options/messages.properties b/megamek/i18n/megamek/common/options/messages.properties index 6bc9f5c4bce..837dc6e4052 100644 --- a/megamek/i18n/megamek/common/options/messages.properties +++ b/megamek/i18n/megamek/common/options/messages.properties @@ -316,11 +316,11 @@ GameOptionsInfo.option.tacops_coolant_failure.description=Possible for Heat Sink GameOptionsInfo.option.tacops_ba_vs_ba.displayableName=TacOps BattleArmor vs BattleArmor Damage GameOptionsInfo.option.tacops_ba_vs_ba.description=Increases the effectiveness of certain BA weapons vs other BA, TO pg 109 GameOptionsInfo.option.no_tac.displayableName=(Unofficial) No through-armor criticals -GameOptionsInfo.option.no_tac.description=If checked, rolls of '2' on hit location will only result in a torso hit, and no critical roll. Only applies to Meks. Supercedes the floating criticals option. \nUnchecked by default. +GameOptionsInfo.option.no_tac.description=If checked, rolls of '2' on hit location will only result in a torso hit, and no critical roll. Only applies to Meks. Supersedes the floating criticals option. \nUnchecked by default. GameOptionsInfo.option.vehicles_threshold.displayableName=(Unofficial) Vehicle damage thresholds -GameOptionsInfo.option.vehicles_threshold.description=If checked, Vehicles gain damage thresholds similar to those of Warshipsas described on page 239 of TW. +GameOptionsInfo.option.vehicles_threshold.description=If checked, Vehicles gain damage thresholds similar to those of Warships as described on page 239 of TW. GameOptionsInfo.option.vehicles_threshold_variable.displayableName=(Unofficial) Variable vehicle damage thresholds -GameOptionsInfo.option.vehicles_threshold_variable.description=If checked, Vehicle damage thresholds are variableas described on page 117 of StratOps. +GameOptionsInfo.option.vehicles_threshold_variable.description=If checked, Vehicle damage thresholds are variable as described on page 117 of StratOps. GameOptionsInfo.option.vehicles_threshold_divisor.displayableName=(Unofficial) Vehicle damage threshold divisor (defaults to 10) GameOptionsInfo.option.vehicles_threshold_divisor.description=Which divisor to use for the damage thresholds of vehicles. Default is 10 per the damage threshold rules for Aerospace assets on page 239 of TW. GameOptionsInfo.option.vtol_strafing.displayableName=(Unofficial) VTOL Strafing @@ -581,7 +581,7 @@ PilotOptionsInfo.option.tm_forest_ranger.description=Movement in woods or jungle PilotOptionsInfo.option.tm_frogman.displayableName=Terrain Master [Frogman] (CamOps) PilotOptionsInfo.option.tm_frogman.description=Movement in depth 2 or greater water costs 1 MP less.\nAlso grants -1 to all PSR checks (including physicals) as well as -2 to Crush Depth checks. PilotOptionsInfo.option.tm_mountaineer.displayableName=Terrain Master [Mountaineer] (CamOps) -PilotOptionsInfo.option.tm_mountaineer.description=Movement in rubble or rough cost 1 less MP and elevation changes also cost 1 MP less.\nThe mountaineer also recieves a -1 to PSR checks for the given terrain. +PilotOptionsInfo.option.tm_mountaineer.description=Movement in rubble or rough cost 1 less MP and elevation changes also cost 1 MP less.\nThe mountaineer also receives a -1 to PSR checks for the given terrain. PilotOptionsInfo.option.tm_nightwalker.displayableName=Terrain Master [Nightwalker] (CamOps) PilotOptionsInfo.option.tm_nightwalker.description=Nightwalker ignores all darkness move penalties when using Walk / Cruise movement but does not affect gunnery modifiers for lighting conditions. PilotOptionsInfo.option.tm_swamp_beast.displayableName=Terrain Master [Swamp Beast] (CamOps) diff --git a/megamek/i18n/megamek/common/report-messages.properties b/megamek/i18n/megamek/common/report-messages.properties index a0cea53865f..76152ddda06 100755 --- a/megamek/i18n/megamek/common/report-messages.properties +++ b/megamek/i18n/megamek/common/report-messages.properties @@ -226,7 +226,7 @@ 2405= () is damaged by the extreme heat of liquid magma! 2410= () breaks through ice from below 2412= () runs out of air and is destroyed. -2415= collapes due to nuclear explosion ground zero. +2415= collapses due to nuclear explosion ground zero. 2420= () automatically avoids the skid. 2425= () needs to avoid the skid (), rolls . 2426= () automatically fails to avoid the skid (). @@ -1177,7 +1177,7 @@ 9385= suffers damage for launching from an out-of-control vessel. 9386= drops units: 9387= unloads : -9388= attempts to be dock with . Needs , rolls : +9388= attempts to dock with . Needs , rolls : 9389=successful docking! #Out of order because of cramped space. 9398=failed docking!