From 35a41f0204883b7263009bfdd5623757b4defd0d Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 4 Feb 2019 10:57:44 -0600 Subject: [PATCH 01/69] Merge branch 'master' of /home/cwspain/IdeaProjects/megamek with conflicts. --- .idea/compiler.xml | 11 ++++++ ..._sun_activation_javax_activation_1_2_0.xml | 11 ++++++ ...un_istack_istack_commons_runtime_3_0_5.xml | 11 ++++++ ...sun_xml_fastinfoset_FastInfoset_1_2_13.xml | 11 ++++++ ...om_thoughtworks_xstream_xstream_1_4_10.xml | 11 ++++++ .../Gradle__javax_xml_bind_jaxb_api_2_3_0.xml | 11 ++++++ .idea/libraries/Gradle__junit_junit_4_12.xml | 11 ++++++ .../libraries/Gradle__log4j_log4j_1_2_17.xml | 11 ++++++ ...radle__net_bytebuddy_byte_buddy_1_8_13.xml | 11 ++++++ ..._net_bytebuddy_byte_buddy_agent_1_8_13.xml | 11 ++++++ ...le__org_glassfish_jaxb_jaxb_core_2_3_0.xml | 11 ++++++ ..._org_glassfish_jaxb_jaxb_runtime_2_3_0.xml | 11 ++++++ .../Gradle__org_glassfish_jaxb_txw2_2_3_0.xml | 11 ++++++ ...Gradle__org_hamcrest_hamcrest_core_1_3.xml | 11 ++++++ ...Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml | 11 ++++++ ...radle__org_mockito_mockito_core_2_20_1.xml | 11 ++++++ .../Gradle__org_objenesis_objenesis_2_6.xml | 11 ++++++ .../Gradle__xmlpull_xmlpull_1_1_3_1.xml | 9 +++++ .../Gradle__xpp3_xpp3_min_1_1_4c.xml | 11 ++++++ .idea/modules/MegaMek.iml | 13 +++++++ .idea/modules/MegaMek_main.iml | 10 ++++++ .idea/modules/MegaMek_test.iml | 12 +++++++ .idea/modules/megamek/megamek_main.iml | 30 ++++++++++++++++ .idea/modules/megamek/megamek_test.iml | 35 +++++++++++++++++++ gradle/wrapper/gradle-wrapper.properties | 6 ++++ .../megamek/common/loaders/JR7-D Jenner.xml | 0 .../common/loaders/ZPH-1A Tarantula.xml | 0 .../verifier/empty-verifier-options.xml | 0 28 files changed, 313 insertions(+) create mode 100644 .idea/compiler.xml create mode 100644 .idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml create mode 100644 .idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml create mode 100644 .idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml create mode 100644 .idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml create mode 100644 .idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml create mode 100644 .idea/libraries/Gradle__junit_junit_4_12.xml create mode 100644 .idea/libraries/Gradle__log4j_log4j_1_2_17.xml create mode 100644 .idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml create mode 100644 .idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml create mode 100644 .idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml create mode 100644 .idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml create mode 100644 .idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml create mode 100644 .idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml create mode 100644 .idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml create mode 100644 .idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml create mode 100644 .idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml create mode 100644 .idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml create mode 100644 .idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml create mode 100644 .idea/modules/MegaMek.iml create mode 100644 .idea/modules/MegaMek_main.iml create mode 100644 .idea/modules/MegaMek_test.iml create mode 100644 .idea/modules/megamek/megamek_main.iml create mode 100644 .idea/modules/megamek/megamek_test.iml create mode 100644 gradle/wrapper/gradle-wrapper.properties rename megamek/{unittests => testresources}/megamek/common/loaders/JR7-D Jenner.xml (100%) rename megamek/{unittests => testresources}/megamek/common/loaders/ZPH-1A Tarantula.xml (100%) rename megamek/{unittests => testresources}/megamek/common/verifier/empty-verifier-options.xml (100%) diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 00000000000..4df4df5b364 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml b/.idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml new file mode 100644 index 00000000000..5ca47b1055e --- /dev/null +++ b/.idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml b/.idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml new file mode 100644 index 00000000000..44b84c1d524 --- /dev/null +++ b/.idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml b/.idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml new file mode 100644 index 00000000000..1fc2a6cb19c --- /dev/null +++ b/.idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml b/.idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml new file mode 100644 index 00000000000..0f877877a5e --- /dev/null +++ b/.idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml b/.idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml new file mode 100644 index 00000000000..b9f55fcec6f --- /dev/null +++ b/.idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__junit_junit_4_12.xml b/.idea/libraries/Gradle__junit_junit_4_12.xml new file mode 100644 index 00000000000..04c10dd5a46 --- /dev/null +++ b/.idea/libraries/Gradle__junit_junit_4_12.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__log4j_log4j_1_2_17.xml b/.idea/libraries/Gradle__log4j_log4j_1_2_17.xml new file mode 100644 index 00000000000..07be0a37e62 --- /dev/null +++ b/.idea/libraries/Gradle__log4j_log4j_1_2_17.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml b/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml new file mode 100644 index 00000000000..3ba0f6dfc79 --- /dev/null +++ b/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml b/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml new file mode 100644 index 00000000000..fc6f1c05900 --- /dev/null +++ b/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml b/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml new file mode 100644 index 00000000000..41427eb69d4 --- /dev/null +++ b/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml b/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml new file mode 100644 index 00000000000..1399717fd3d --- /dev/null +++ b/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml b/.idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml new file mode 100644 index 00000000000..d6c7a390fbf --- /dev/null +++ b/.idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml new file mode 100644 index 00000000000..8262f729c28 --- /dev/null +++ b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml b/.idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml new file mode 100644 index 00000000000..dc412c33285 --- /dev/null +++ b/.idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml b/.idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml new file mode 100644 index 00000000000..a229d8fedc7 --- /dev/null +++ b/.idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml b/.idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml new file mode 100644 index 00000000000..a37a39cddc3 --- /dev/null +++ b/.idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml b/.idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml new file mode 100644 index 00000000000..bb8ebc9b65b --- /dev/null +++ b/.idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml b/.idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml new file mode 100644 index 00000000000..fa9b59fe316 --- /dev/null +++ b/.idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/MegaMek.iml b/.idea/modules/MegaMek.iml new file mode 100644 index 00000000000..d8cd59e78ed --- /dev/null +++ b/.idea/modules/MegaMek.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/MegaMek_main.iml b/.idea/modules/MegaMek_main.iml new file mode 100644 index 00000000000..9043590a42a --- /dev/null +++ b/.idea/modules/MegaMek_main.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/MegaMek_test.iml b/.idea/modules/MegaMek_test.iml new file mode 100644 index 00000000000..280b8d6e08e --- /dev/null +++ b/.idea/modules/MegaMek_test.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/megamek/megamek_main.iml b/.idea/modules/megamek/megamek_main.iml new file mode 100644 index 00000000000..150b3627daf --- /dev/null +++ b/.idea/modules/megamek/megamek_main.iml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/megamek/megamek_test.iml b/.idea/modules/megamek/megamek_test.iml new file mode 100644 index 00000000000..dc17e68f08f --- /dev/null +++ b/.idea/modules/megamek/megamek_test.iml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..5c7590e87db --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Aug 13 21:03:56 CDT 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip diff --git a/megamek/unittests/megamek/common/loaders/JR7-D Jenner.xml b/megamek/testresources/megamek/common/loaders/JR7-D Jenner.xml similarity index 100% rename from megamek/unittests/megamek/common/loaders/JR7-D Jenner.xml rename to megamek/testresources/megamek/common/loaders/JR7-D Jenner.xml diff --git a/megamek/unittests/megamek/common/loaders/ZPH-1A Tarantula.xml b/megamek/testresources/megamek/common/loaders/ZPH-1A Tarantula.xml similarity index 100% rename from megamek/unittests/megamek/common/loaders/ZPH-1A Tarantula.xml rename to megamek/testresources/megamek/common/loaders/ZPH-1A Tarantula.xml diff --git a/megamek/unittests/megamek/common/verifier/empty-verifier-options.xml b/megamek/testresources/megamek/common/verifier/empty-verifier-options.xml similarity index 100% rename from megamek/unittests/megamek/common/verifier/empty-verifier-options.xml rename to megamek/testresources/megamek/common/verifier/empty-verifier-options.xml From 37e8c09559769f906c3e429a2600f17218554f82 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 27 Mar 2019 16:39:45 -0500 Subject: [PATCH 02/69] Created enums for handling support vee chassis mod construction data. --- megamek/src/megamek/common/MiscType.java | 34 ++++++++- .../common/verifier/TestSupportVehicle.java | 72 +++++++++++++++++++ .../verifier/TestSupportVehicleTest.java | 24 +++++++ 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 megamek/unittests/megamek/common/verifier/TestSupportVehicleTest.java diff --git a/megamek/src/megamek/common/MiscType.java b/megamek/src/megamek/common/MiscType.java index d52c0f348da..c4beef2be26 100644 --- a/megamek/src/megamek/common/MiscType.java +++ b/megamek/src/megamek/common/MiscType.java @@ -1742,6 +1742,7 @@ public static void initializeTypes() { EquipmentType.addType(MiscType.createHydroFoilChassisModification()); EquipmentType.addType(MiscType.createMonocycleModification()); EquipmentType.addType(MiscType.createISOffRoadChassis()); + EquipmentType.addType(MiscType.createOmniChassisMod()); EquipmentType.addType(MiscType.createPropChassisModification()); EquipmentType.addType(MiscType.createSnomobileChassis()); EquipmentType.addType(MiscType.createSTOLChassisMod()); @@ -10022,6 +10023,7 @@ public static MiscType createEnvironmentalSealedChassis() { misc.name = "Combat Vehicle Chassis Mod [Environmental Sealing]"; misc.setInternalName("Environmental Sealed Chassis"); + misc.addLookupName("EnvironmentalSealingChassisMod"); misc.tonnage = 0; misc.criticals = 0; misc.cost = 0; // Cost accounted as part of unit cost @@ -10045,6 +10047,7 @@ public static MiscType createAmphibiousChassis() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Amphibious]"; misc.setInternalName("AmphibiousChassis"); + misc.addLookupName("AmphibiousChassisMod"); misc.tonnage = 0; misc.criticals = 0; misc.tankslots = 0; @@ -10066,6 +10069,7 @@ public static MiscType createArmoredChassis() { misc.name = "SV Chassis Mod [Armored Chassis]"; misc.setInternalName("Armored Chassis"); + misc.addLookupName("ArmoredChassisMod"); misc.tonnage = 0; misc.criticals = 0; misc.cost = 0; // Cost accounted as part of unit cost @@ -10134,6 +10138,7 @@ public static MiscType createISSVDuneBuggyChassis() { misc.addLookupName("ISSVDuneBuggy"); misc.addLookupName("ClanSVDuneBuggyChassis"); misc.addLookupName("ClanSVDuneBuggy"); + misc.addLookupName("DuneBuggyChassisMod"); misc.tonnage = 0; misc.criticals = 0; misc.tankslots = 0; @@ -10226,6 +10231,7 @@ public static MiscType createISOffRoadChassis() { misc.addLookupName("ISOffRoad"); misc.addLookupName("ClanOffRoadChassis"); misc.addLookupName("CLOffRoad"); + misc.addLookupName("OffroadChassisMod"); misc.tonnage = 0; misc.criticals = 0; misc.tankslots = 0; @@ -10243,13 +10249,36 @@ public static MiscType createISOffRoadChassis() { return misc; } + public static MiscType createOmniChassisMod() { + MiscType misc = new MiscType(); + misc.name = "SV Chassis Mod [Omni]"; + misc.setInternalName("OmniChassisMod"); + misc.tonnage = 0; + misc.criticals = 0; + misc.tankslots = 0; + misc.cost = 0; // Cost accounted as part of unit cost + misc.flags = misc.flags.or(F_CHASSIS_MODIFICATION).or(F_SUPPORT_TANK_EQUIPMENT); + misc.omniFixedOnly = true; + misc.bv = 0; + misc.rulesRefs = "122,TM"; + + misc.techAdvancement.setTechBase(TECH_BASE_ALL) + .setISAdvancement(DATE_NONE, DATE_NONE, 3052) + .setClanAdvancement(2854, 2856, 2864).setClanApproximate(true) + .setPrototypeFactions(F_CCY, F_CSF).setProductionFactions(F_CCY, F_DC) + .setTechRating(RATING_E).setAvailability(RATING_X, RATING_E, RATING_E, RATING_D) + .setStaticTechLevel(SimpleTechLevel.STANDARD); + return misc; + } + public static MiscType createPropChassisModification() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Propeller-Driven]"; misc.setInternalName("PropChassisMod"); misc.cost = 0; // Cost accounted as part of unit cost misc.tankslots = 0; - misc.flags = misc.flags.andNot(F_FIGHTER_EQUIPMENT).or(F_CHASSIS_MODIFICATION).or(F_PROP); + misc.flags = misc.flags.andNot(F_FIGHTER_EQUIPMENT).or(F_CHASSIS_MODIFICATION).or(F_PROP) + .or(F_SUPPORT_TANK_EQUIPMENT); misc.omniFixedOnly = true; misc.rulesRefs = "122,TM"; // Setting this Pre-Spaceflight @@ -10264,6 +10293,7 @@ public static MiscType createSnomobileChassis() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Snowmobile]"; misc.setInternalName("SnowmobileChassis"); + misc.addLookupName("SnowmobileChassisMod"); misc.cost = 0; // Cost accounted as part of unit cost misc.tonnage = 0; misc.criticals = 0; @@ -10326,6 +10356,7 @@ public static MiscType createTractorModification() { misc.name = "SV Chassis Mod [Tractor]"; misc.setInternalName(misc.name); misc.addLookupName("Tractor"); + misc.addLookupName("TractorChassisMod"); misc.tonnage = 0; // accounted as part of the unit Construction misc.criticals = 0; misc.cost = 0; // Cost accounted as part of unit cost @@ -10368,6 +10399,7 @@ public static MiscType createTrailerModification() { misc.name = "SV Chassis Mod [Trailer]"; misc.setInternalName(misc.name); misc.addLookupName("Trailer"); + misc.addLookupName("TrailerChassisMod"); misc.tonnage = 0; // accounted as part of the unit Construction misc.criticals = 0; misc.cost = 0; // Cost accounted as part of unit cost diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index ffe7b2fa534..4fcea34b4fa 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -17,11 +17,83 @@ import megamek.common.Tank; import megamek.common.util.StringUtil; +import java.util.EnumSet; +import java.util.Set; + /** * Author: arlith */ public class TestSupportVehicle extends TestTank { + /** + * Types of support vehicles used for determining compatibility with chassis mods and engine types. + * This is nearly identical with motive type, but there some differences in naval, rail, and aerospace + * units. + */ + public enum SVType { + AIRSHIP, + FIXED_WING, + HOVERCRAFT, + NAVAL, + TRACKED, + VTOL, + WHEELED, + WIGE, + RAIL, + SATELLITE; + + static Set allBut(SVType type) { + return EnumSet.complementOf(EnumSet.of(type)); + } + + static Set allBut(SVType first, SVType... rest) { + return EnumSet.complementOf(EnumSet.of(first, rest)); + } + }; + + public enum ChassisModification { + AMPHIBIOUS ("AmphibiousChassisMod", SVType.allBut(SVType.HOVERCRAFT, SVType.NAVAL)), + ARMORED ("ArmoredChassisMod", SVType.allBut(SVType.AIRSHIP)), + BICYCLE ("BicycleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED)), + CONVERTIBLE ("ConvertibleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED, SVType.TRACKED), true), + DUNE_BUGGY ("DuneBuggyChassisMod", EnumSet.of(SVType.WHEELED)), + ENVIRONMENTAL_SEALING ("EnvironmentalSealingChassisMod", EnumSet.allOf(SVType.class)), + HYDROFOIL ("HydrofoilChassisMod", EnumSet.of(SVType.NAVAL)), + MONOCYCLE ("MonocycleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED), true), + OFFROAD ("OffroadChassisMod", EnumSet.of(SVType.WHEELED)), + OMNI ("OmniChassisMod"), + PROP ("PropChassisMod", EnumSet.of(SVType.FIXED_WING)), + SNOWMOBILE ("SnowmobileChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED)), + STOL ("STOLChassisMod", EnumSet.of(SVType.FIXED_WING)), + SUBMERSIBLE ("SubmersibleChassisMod", EnumSet.of(SVType.NAVAL)), + TRACTOR ("TractorChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.NAVAL)), + TRAILER ("TrailerChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED)), + ULTRA_LIGHT ("UltraLightChassisMod", true), + VSTOL ("VSTOLChassisMod", EnumSet.of(SVType.FIXED_WING)); + + public final String eqTypeKey; + public final boolean smallOnly; + public final Set allowedTypes; + + ChassisModification(String eqTypeKey) { + this(eqTypeKey, EnumSet.allOf(SVType.class), false); + } + + ChassisModification(String eqTypeKey, boolean smallOnly) { + this(eqTypeKey, EnumSet.allOf(SVType.class), smallOnly); + } + + ChassisModification(String eqTypeKey, Set allowedTypes) { + this(eqTypeKey, allowedTypes, false); + } + + ChassisModification(String eqTypeKey, Set allowedTypes, boolean smallOnly) { + this.eqTypeKey = eqTypeKey; + this.allowedTypes = allowedTypes; + this.smallOnly = smallOnly; + } + } + /** * Gives the weight of a single point of armor at a particular BAR for a * given tech level. diff --git a/megamek/unittests/megamek/common/verifier/TestSupportVehicleTest.java b/megamek/unittests/megamek/common/verifier/TestSupportVehicleTest.java new file mode 100644 index 00000000000..7787aaf2b62 --- /dev/null +++ b/megamek/unittests/megamek/common/verifier/TestSupportVehicleTest.java @@ -0,0 +1,24 @@ +package megamek.common.verifier; + +import megamek.common.EquipmentType; +import megamek.common.MiscType; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * + */ +public class TestSupportVehicleTest { + + @Test + public void testChassisModLookup() { + for (TestSupportVehicle.ChassisModification mod : TestSupportVehicle.ChassisModification.values()) { + EquipmentType eq = EquipmentType.get(mod.eqTypeKey); + assertNotNull(eq); + assertTrue(eq.hasFlag(MiscType.F_SUPPORT_TANK_EQUIPMENT)); + assertTrue(eq.hasFlag(MiscType.F_CHASSIS_MODIFICATION)); + } + } + +} \ No newline at end of file From 626343cd220068dee30b081a663950a62b915638 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Thu, 28 Mar 2019 08:59:59 -0500 Subject: [PATCH 03/69] Added enums for engine construction data. Added external power pickup chassis mod. --- megamek/src/megamek/common/MiscType.java | 19 +++++++ .../common/verifier/TestSupportVehicle.java | 56 +++++++++++++++++-- 2 files changed, 70 insertions(+), 5 deletions(-) diff --git a/megamek/src/megamek/common/MiscType.java b/megamek/src/megamek/common/MiscType.java index c4beef2be26..bd10f36bd9c 100644 --- a/megamek/src/megamek/common/MiscType.java +++ b/megamek/src/megamek/common/MiscType.java @@ -1739,6 +1739,7 @@ public static void initializeTypes() { EquipmentType.addType(MiscType.createConvertibleModification()); EquipmentType.addType(MiscType.createISCVDuneBuggyChassis()); EquipmentType.addType(MiscType.createEnvironmentalSealedChassis()); + EquipmentType.addType(MiscType.createExternalPowerPickup()); EquipmentType.addType(MiscType.createHydroFoilChassisModification()); EquipmentType.addType(MiscType.createMonocycleModification()); EquipmentType.addType(MiscType.createISOffRoadChassis()); @@ -10182,6 +10183,24 @@ public static MiscType createEnvironmentalSealing() { return misc; } + public static MiscType createExternalPowerPickup() { + MiscType misc = new MiscType(); + misc.name = "External Power Pickup"; + misc.setInternalName("ExternalPowerPickupChassisMod"); + misc.tonnage = 0; + misc.criticals = 0; + misc.cost = 0; // Cost accounted as part of unit cost + misc.flags = misc.flags.or(F_SUPPORT_TANK_EQUIPMENT).or(F_CHASSIS_MODIFICATION); + misc.omniFixedOnly = true; + misc.bv = 0; + misc.rulesRefs = "243,TO"; + misc.tankslots = 0; + misc.industrial = true; + misc.techAdvancement.setTechBase(TECH_BASE_ALL).setAdvancement(DATE_NONE, DATE_NONE, DATE_PS) + .setTechRating(RATING_B).setAvailability(new int[] { RATING_C, RATING_D, RATING_C, RATING_C }); + return misc; + } + public static MiscType createHydroFoilChassisModification() { MiscType misc = new MiscType(); diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 4fcea34b4fa..096fd162dea 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -14,6 +14,7 @@ */ package megamek.common.verifier; +import megamek.common.Engine; import megamek.common.Tank; import megamek.common.util.StringUtil; @@ -26,9 +27,8 @@ public class TestSupportVehicle extends TestTank { /** - * Types of support vehicles used for determining compatibility with chassis mods and engine types. - * This is nearly identical with motive type, but there some differences in naval, rail, and aerospace - * units. + * Support vehicle categories for construction purposes. Most of these match with a particular movement + * mode, but the construction rules treat naval and rail units as single types. */ public enum SVType { AIRSHIP, @@ -51,6 +51,10 @@ static Set allBut(SVType first, SVType... rest) { } }; + /** + * Additional construction data for chassis mods, used to determine whether they are legal for particular + * units. + */ public enum ChassisModification { AMPHIBIOUS ("AmphibiousChassisMod", SVType.allBut(SVType.HOVERCRAFT, SVType.NAVAL)), ARMORED ("ArmoredChassisMod", SVType.allBut(SVType.AIRSHIP)), @@ -58,6 +62,7 @@ public enum ChassisModification { CONVERTIBLE ("ConvertibleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED, SVType.TRACKED), true), DUNE_BUGGY ("DuneBuggyChassisMod", EnumSet.of(SVType.WHEELED)), ENVIRONMENTAL_SEALING ("EnvironmentalSealingChassisMod", EnumSet.allOf(SVType.class)), + EXTERNAL_POWER_PICKUP ("ExternalPowerPickupChassisMod", EnumSet.of(SVType.RAIL)), HYDROFOIL ("HydrofoilChassisMod", EnumSet.of(SVType.NAVAL)), MONOCYCLE ("MonocycleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED), true), OFFROAD ("OffroadChassisMod", EnumSet.of(SVType.WHEELED)), @@ -66,8 +71,8 @@ public enum ChassisModification { SNOWMOBILE ("SnowmobileChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED)), STOL ("STOLChassisMod", EnumSet.of(SVType.FIXED_WING)), SUBMERSIBLE ("SubmersibleChassisMod", EnumSet.of(SVType.NAVAL)), - TRACTOR ("TractorChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.NAVAL)), - TRAILER ("TrailerChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED)), + TRACTOR ("TractorChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.NAVAL, SVType.RAIL)), + TRAILER ("TrailerChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.RAIL)), ULTRA_LIGHT ("UltraLightChassisMod", true), VSTOL ("VSTOLChassisMod", EnumSet.of(SVType.FIXED_WING)); @@ -94,6 +99,47 @@ public enum ChassisModification { } } + /** + * Additional construction data for engine types, used to determine which ones are available for which + * vehicle types. + */ + public enum SVEngine { + STEAM (Engine.STEAM, EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.AIRSHIP, SVType.NAVAL)), + COMBUSTION (Engine.COMBUSTION_ENGINE), + BATTERY (Engine.BATTERY, true), + FUEL_CELL (Engine.FUEL_CELL, true), + SOLAR (Engine.SOLAR, EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.AIRSHIP, SVType.FIXED_WING, + SVType.NAVAL, SVType.WIGE), true), + FISSION (Engine.FISSION), + FUSION (Engine.NORMAL_ENGINE), + MAGLEV (Engine.MAGLEV, EnumSet.of(SVType.RAIL)), + EXTERNAL (Engine.NONE, EnumSet.of(SVType.RAIL), true); + + /** The engine type constant used to create a new {@link Engine}. */ + public final int engineType; + /** Fixed-wing must have prop chassis mod to use an electric engine */ + public final boolean electric; + private final Set allowedTypes; + + SVEngine(int engineType) { + this(engineType, EnumSet.allOf(SVType.class), false); + } + + SVEngine(int engineType, boolean electric) { + this(engineType, EnumSet.allOf(SVType.class), electric); + } + + SVEngine(int engineType, Set allowedTypes) { + this(engineType, allowedTypes, false); + } + + SVEngine(int engineType, Set allowedTypes, boolean electric) { + this.engineType = engineType; + this.allowedTypes = allowedTypes; + this.electric = electric; + } + } + /** * Gives the weight of a single point of armor at a particular BAR for a * given tech level. From d26d9134cf8aefebca7eeedf458ca12a1cd1fed9 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sat, 30 Mar 2019 13:24:30 -0500 Subject: [PATCH 04/69] Added some tech advancement data for SV components. --- .../megamek/common/EntityMovementMode.java | 2 + .../src/megamek/common/FixedWingSupport.java | 35 +++++++- megamek/src/megamek/common/SupportTank.java | 73 ++++++++------- .../common/verifier/TestSupportVehicle.java | 88 +++++++++++++++---- 4 files changed, 144 insertions(+), 54 deletions(-) diff --git a/megamek/src/megamek/common/EntityMovementMode.java b/megamek/src/megamek/common/EntityMovementMode.java index bdb46f3e794..12bb754d842 100644 --- a/megamek/src/megamek/common/EntityMovementMode.java +++ b/megamek/src/megamek/common/EntityMovementMode.java @@ -40,6 +40,8 @@ public enum EntityMovementMode { SPHEROID ("spheroid"), INF_UMU ("umu", "scuba", "motorized scuba"), AEROSPACE, // this might be a synonym for AERODYNE. + AIRSHIP ("airship"), + STATION_KEEPING ("station", "station_keeping", "satellite"), RAIL ("rail"), MAGLEV ("maglev"); diff --git a/megamek/src/megamek/common/FixedWingSupport.java b/megamek/src/megamek/common/FixedWingSupport.java index 522e7fba2a0..6d60fe23cc6 100644 --- a/megamek/src/megamek/common/FixedWingSupport.java +++ b/megamek/src/megamek/common/FixedWingSupport.java @@ -111,14 +111,43 @@ public boolean isSTOL() { protected static final TechAdvancement TA_FIXED_WING_SUPPORT = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) - .setTechRating(RATING_B).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D); + .setTechRating(RATING_B).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C); protected static final TechAdvancement TA_FIXED_WING_SUPPORT_LARGE = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) - .setTechRating(RATING_B).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C); + .setTechRating(RATING_B).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D); + protected static final TechAdvancement TA_AIRSHIP_SUPPORT_SMALL = new TechAdvancement(TECH_BASE_ALL) + .setAdvancement(DATE_PS, DATE_PS, DATE_PS) + .setTechRating(RATING_A).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C); + protected static final TechAdvancement TA_AIRSHIP_SUPPORT_MEDIUM = new TechAdvancement(TECH_BASE_ALL) + .setAdvancement(DATE_PS, DATE_PS, DATE_PS) + .setTechRating(RATING_B).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D); + // Availability missing from TO. Using medium + protected static final TechAdvancement TA_AIRSHIP_SUPPORT_LARGE = new TechAdvancement(TECH_BASE_ALL) + .setAdvancement(DATE_PS, DATE_PS, DATE_PS) + .setTechRating(RATING_C).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D); + // Availability missing from TO. Using similar values from other support vees. + // Also using early spaceflight for intro dates based on common sense. + protected static final TechAdvancement TA_SATELLITE = new TechAdvancement(TECH_BASE_ALL) + .setAdvancement(DATE_ES, DATE_ES, DATE_ES) + .setTechRating(RATING_C).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D); @Override public TechAdvancement getConstructionTechAdvancement() { - if (getWeightClass() == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + return getTechAdvancement(getMovementMode(), getWeightClass()); + } + + public static TechAdvancement getTechAdvancement(EntityMovementMode movementMode, int weightClass) { + if (movementMode.equals(EntityMovementMode.AIRSHIP)) { + if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + return TA_AIRSHIP_SUPPORT_LARGE; + } else if (weightClass == EntityWeightClass.WEIGHT_MEDIUM_SUPPORT) { + return TA_AIRSHIP_SUPPORT_MEDIUM; + } else { + return TA_AIRSHIP_SUPPORT_SMALL; + } + } else if (movementMode.equals(EntityMovementMode.STATION_KEEPING)) { + return TA_SATELLITE; + } else if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { return TA_FIXED_WING_SUPPORT_LARGE; } else { return TA_FIXED_WING_SUPPORT; diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index 02557d802e3..8ba15c8f477 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -126,41 +126,50 @@ public boolean hasArmoredChassis() { @Override public TechAdvancement getConstructionTechAdvancement() { + return getConstructionTechAdvancement(getMovementMode(), getWeightClass()); + } + + public static TechAdvancement getConstructionTechAdvancement(EntityMovementMode movementMode, int weightClass) { /* Support vehicle dates and tech ratings are found in TM 120, 122. DA availability is assumed to * be the same as Clan invasion era. */ - switch(getMovementMode()) { - case HOVER: - if (getWeightClass() == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { - return TA_HOVER_LARGE; - } else { - return TA_HOVER; - } - case NAVAL: - case HYDROFOIL: - case SUBMARINE: - return TA_NAVAL; - case TRACKED: - if (getWeightClass() == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { - return TA_TRACKED_LARGE; - } else { - return TA_TRACKED; - } - case WHEELED: - if (getWeightClass() == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { - return TA_WHEELED_LARGE; - } else if (getWeightClass() == EntityWeightClass.WEIGHT_MEDIUM_SUPPORT) { - return TA_WHEELED_MEDIUM; - } else { + switch(movementMode) { + case HOVER: + if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + return TA_HOVER_LARGE; + } else { + return TA_HOVER; + } + case NAVAL: + case HYDROFOIL: + case SUBMARINE: + return TA_NAVAL; + case TRACKED: + if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + return TA_TRACKED_LARGE; + } else { + return TA_TRACKED; + } + case WHEELED: + if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + return TA_WHEELED_LARGE; + } else if (weightClass == EntityWeightClass.WEIGHT_MEDIUM_SUPPORT) { + return TA_WHEELED_MEDIUM; + } else { + return TA_WHEELED_SMALL; + } + case WIGE: + if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + return TA_WIGE_LARGE; + } else { + return TA_WIGE; + } + case RAIL: + case MAGLEV: + // TacOps gives a minimum tech rating of A but no availability data. Assuming A, the same + // as small wheeled. Maglev will be higher based on the required engine. return TA_WHEELED_SMALL; - } - case WIGE: - if (getWeightClass() == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { - return TA_WIGE_LARGE; - } else { - return TA_WIGE; - } - default: - return TA_TRACKED; // average + default: + return TA_TRACKED; // average } } diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 096fd162dea..9a027dff344 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -14,8 +14,7 @@ */ package megamek.common.verifier; -import megamek.common.Engine; -import megamek.common.Tank; +import megamek.common.*; import megamek.common.util.StringUtil; import java.util.EnumSet; @@ -31,16 +30,22 @@ public class TestSupportVehicle extends TestTank { * mode, but the construction rules treat naval and rail units as single types. */ public enum SVType { - AIRSHIP, - FIXED_WING, - HOVERCRAFT, - NAVAL, - TRACKED, - VTOL, - WHEELED, - WIGE, - RAIL, - SATELLITE; + AIRSHIP (EntityMovementMode.AIRSHIP), + FIXED_WING (EntityMovementMode.AERODYNE), + HOVERCRAFT (EntityMovementMode.HOVER), + NAVAL (EntityMovementMode.NAVAL), + TRACKED (EntityMovementMode.TRACKED), + VTOL (EntityMovementMode.VTOL), + WHEELED (EntityMovementMode.WHEELED), + WIGE (EntityMovementMode.WIGE), + RAIL (EntityMovementMode.RAIL), + SATELLITE (EntityMovementMode.STATION_KEEPING); + + public final EntityMovementMode defaultMovementMode; + + SVType(EntityMovementMode defaultMovementMode) { + this.defaultMovementMode = defaultMovementMode; + } static Set allBut(SVType type) { return EnumSet.complementOf(EnumSet.of(type)); @@ -49,13 +54,13 @@ static Set allBut(SVType type) { static Set allBut(SVType first, SVType... rest) { return EnumSet.complementOf(EnumSet.of(first, rest)); } - }; + } /** * Additional construction data for chassis mods, used to determine whether they are legal for particular * units. */ - public enum ChassisModification { + public enum ChassisModification implements ITechnologyDelegator { AMPHIBIOUS ("AmphibiousChassisMod", SVType.allBut(SVType.HOVERCRAFT, SVType.NAVAL)), ARMORED ("ArmoredChassisMod", SVType.allBut(SVType.AIRSHIP)), BICYCLE ("BicycleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED)), @@ -76,7 +81,7 @@ public enum ChassisModification { ULTRA_LIGHT ("UltraLightChassisMod", true), VSTOL ("VSTOLChassisMod", EnumSet.of(SVType.FIXED_WING)); - public final String eqTypeKey; + public final MiscType equipment; public final boolean smallOnly; public final Set allowedTypes; @@ -93,17 +98,22 @@ public enum ChassisModification { } ChassisModification(String eqTypeKey, Set allowedTypes, boolean smallOnly) { - this.eqTypeKey = eqTypeKey; + this.equipment = (MiscType) EquipmentType.get(eqTypeKey); this.allowedTypes = allowedTypes; this.smallOnly = smallOnly; } + + @Override + public ITechnology getTechSource() { + return equipment; + } } /** * Additional construction data for engine types, used to determine which ones are available for which * vehicle types. */ - public enum SVEngine { + public enum SVEngine implements ITechnologyDelegator { STEAM (Engine.STEAM, EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.AIRSHIP, SVType.NAVAL)), COMBUSTION (Engine.COMBUSTION_ENGINE), BATTERY (Engine.BATTERY, true), @@ -116,7 +126,7 @@ public enum SVEngine { EXTERNAL (Engine.NONE, EnumSet.of(SVType.RAIL), true); /** The engine type constant used to create a new {@link Engine}. */ - public final int engineType; + public final Engine engine; /** Fixed-wing must have prop chassis mod to use an electric engine */ public final boolean electric; private final Set allowedTypes; @@ -134,12 +144,52 @@ public enum SVEngine { } SVEngine(int engineType, Set allowedTypes, boolean electric) { - this.engineType = engineType; + this.engine = new Engine(0, engineType, Engine.SUPPORT_VEE_ENGINE); this.allowedTypes = allowedTypes; this.electric = electric; } + + @Override + public ITechnology getTechSource() { + return engine; + } } + /** + * Tech advancement data for structural components with variable tech levels (structure, + * armor, engine). This is assembled from the tables on TM, p. 122 and IO, p. 49, primitive construction + * rules (IO, p. 120-121) and a pending proposal to the rules committee for E. + */ + public static final TechAdvancement[] TECH_LEVEL_TA = { + new TechAdvancement(ITechnology.TECH_BASE_ALL).setTechRating(ITechnology.RATING_A) + .setAdvancement(ITechnology.DATE_PS, ITechnology.DATE_PS, ITechnology.DATE_PS) + .setAvailability(ITechnology.RATING_A, ITechnology.RATING_A, + ITechnology.RATING_A, ITechnology.RATING_A), + new TechAdvancement(ITechnology.TECH_BASE_ALL).setTechRating(ITechnology.RATING_B) + .setAdvancement(ITechnology.DATE_ES, ITechnology.DATE_ES, ITechnology.DATE_ES) + .setAvailability(ITechnology.RATING_B, ITechnology.RATING_B, + ITechnology.RATING_B, ITechnology.RATING_A), + new TechAdvancement(ITechnology.TECH_BASE_ALL).setTechRating(ITechnology.RATING_C) + .setAdvancement(2250, 2300, 2305).setApproximate(true, false, false) + .setPrototypeFactions(ITechnology.F_TA).setProductionFactions(ITechnology.F_TA) + .setAvailability(ITechnology.RATING_C, ITechnology.RATING_B, + ITechnology.RATING_B, ITechnology.RATING_B), + new TechAdvancement(ITechnology.TECH_BASE_ALL).setTechRating(ITechnology.RATING_D) + .setAdvancement(2420, 2430, 2435).setApproximate(true, true, false) + .setPrototypeFactions(ITechnology.F_TH).setProductionFactions(ITechnology.F_TH) + .setAvailability(ITechnology.RATING_C, ITechnology.RATING_C, + ITechnology.RATING_C, ITechnology.RATING_B), + new TechAdvancement(ITechnology.TECH_BASE_ALL).setTechRating(ITechnology.RATING_E) + .setISAdvancement(2557, 2571, 3055).setClanAdvancement(2557, 2571, 2815) + .setAvailability(ITechnology.RATING_D, ITechnology.RATING_F, + ITechnology.RATING_D, ITechnology.RATING_C), + new TechAdvancement(ITechnology.TECH_BASE_ALL).setTechRating(ITechnology.RATING_F) + .setISAdvancement(ITechnology.DATE_NONE, ITechnology.DATE_NONE, 3065).setISApproximate(false, false, true) + .setClanAdvancement(2820, 2825, 2830).setClanApproximate(true, true, false) + .setAvailability(ITechnology.RATING_E, ITechnology.RATING_E, + ITechnology.RATING_D, ITechnology.RATING_C) + }; + /** * Gives the weight of a single point of armor at a particular BAR for a * given tech level. From 20b7abdd75076d89af278c01e471b1cdc2ccd20e Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sat, 30 Mar 2019 13:50:46 -0500 Subject: [PATCH 05/69] Changed intro date on WiGE support vee to ES (TM, p. 287). --- megamek/src/megamek/common/SupportTank.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index 8ba15c8f477..964d2b1078e 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -116,7 +116,7 @@ public boolean hasArmoredChassis() { .setAvailability(RATING_B, RATING_C, RATING_B, RATING_B) .setStaticTechLevel(SimpleTechLevel.STANDARD); private static final TechAdvancement TA_WIGE = new TechAdvancement(TECH_BASE_ALL) - .setAdvancement(DATE_PS, DATE_PS, DATE_PS).setTechRating(RATING_C) + .setAdvancement(DATE_ES, DATE_ES, DATE_ES).setTechRating(RATING_C) .setAvailability(RATING_B, RATING_C, RATING_B, RATING_B) .setStaticTechLevel(SimpleTechLevel.STANDARD); private static final TechAdvancement TA_WIGE_LARGE = new TechAdvancement(TECH_BASE_ALL) From 052ed31f9f45e58aa74e9ec0a107b33562281657 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sat, 30 Mar 2019 21:31:13 -0500 Subject: [PATCH 06/69] Added lookup methods for SVType and SVEngine. --- .../common/verifier/TestSupportVehicle.java | 83 ++++++++++++++++--- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 9a027dff344..a9aa9fa869b 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -15,8 +15,10 @@ package megamek.common.verifier; import megamek.common.*; +import megamek.common.annotations.Nullable; import megamek.common.util.StringUtil; +import java.util.Arrays; import java.util.EnumSet; import java.util.Set; @@ -30,20 +32,25 @@ public class TestSupportVehicle extends TestTank { * mode, but the construction rules treat naval and rail units as single types. */ public enum SVType { - AIRSHIP (EntityMovementMode.AIRSHIP), - FIXED_WING (EntityMovementMode.AERODYNE), - HOVERCRAFT (EntityMovementMode.HOVER), - NAVAL (EntityMovementMode.NAVAL), - TRACKED (EntityMovementMode.TRACKED), - VTOL (EntityMovementMode.VTOL), - WHEELED (EntityMovementMode.WHEELED), - WIGE (EntityMovementMode.WIGE), - RAIL (EntityMovementMode.RAIL), - SATELLITE (EntityMovementMode.STATION_KEEPING); + AIRSHIP (300, EntityMovementMode.AIRSHIP), + FIXED_WING (200, EntityMovementMode.AERODYNE), + HOVERCRAFT (100, EntityMovementMode.HOVER), + NAVAL (300, EntityMovementMode.NAVAL), + TRACKED (200, EntityMovementMode.TRACKED), + VTOL (60, EntityMovementMode.VTOL), + WHEELED (160, EntityMovementMode.WHEELED), + WIGE (240, EntityMovementMode.WIGE), + RAIL (600, EntityMovementMode.RAIL), + SATELLITE (300, EntityMovementMode.STATION_KEEPING); + /** The maximum tonnage for a large support vehicle of this type; for airship this is the + * maximum for a medium for now. + */ + public final int maxTonnage; public final EntityMovementMode defaultMovementMode; - SVType(EntityMovementMode defaultMovementMode) { + SVType(int maxTonnage, EntityMovementMode defaultMovementMode) { + this.maxTonnage = maxTonnage; this.defaultMovementMode = defaultMovementMode; } @@ -54,6 +61,44 @@ static Set allBut(SVType type) { static Set allBut(SVType first, SVType... rest) { return EnumSet.complementOf(EnumSet.of(first, rest)); } + + /** + * Finds the enum value corresponding to a support vehicle based on movement mode. + * + * @param entity The support vehicle + * @return The support vehicle type, or {@code null} if the entity's movement type is not + * a valid one for a support vehicle. + */ + public static @Nullable + SVType getVehicleType(Entity entity) { + switch (entity.getMovementMode()) { + case AIRSHIP: + return AIRSHIP; + case AERODYNE: + return FIXED_WING; + case HOVER: + return HOVERCRAFT; + case TRACKED: + return TRACKED; + case WHEELED: + return WHEELED; + case NAVAL: + case HYDROFOIL: + case SUBMARINE: + return NAVAL; + case VTOL: + return VTOL; + case WIGE: + return WIGE; + case RAIL: + case MAGLEV: + return RAIL; + case STATION_KEEPING: + return SATELLITE; + default: + return null; + } + } } /** @@ -149,6 +194,22 @@ public enum SVEngine implements ITechnologyDelegator { this.electric = electric; } + /** + * Finds the enum value corresponding to an {@link Engine}. + * + * @param engine The engine + * @return The enum value for the engine, or {@code null} if it is not a valid SV engine type. + */ + public @Nullable + static SVEngine getEngineType(Engine engine) { + for (SVEngine e : values()) { + if (e.engine.getEngineType() == engine.getEngineType()) { + return e; + } + } + return null; + } + @Override public ITechnology getTechSource() { return engine; From 92b00e583020f3330d8f16f6fb1e80fea1b8b4a6 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sat, 30 Mar 2019 22:05:40 -0500 Subject: [PATCH 07/69] Fixed validation for steam and maglev engines. --- .../i18n/megamek/common/messages.properties | 1 + megamek/src/megamek/common/Engine.java | 51 +++++-------------- 2 files changed, 13 insertions(+), 39 deletions(-) diff --git a/megamek/i18n/megamek/common/messages.properties b/megamek/i18n/megamek/common/messages.properties index 65ec1fc9065..a0b27102f57 100644 --- a/megamek/i18n/megamek/common/messages.properties +++ b/megamek/i18n/megamek/common/messages.properties @@ -408,4 +408,5 @@ MovementType.Aerodyne=Aerodyne MovementType.Spheroid=Spheroid MovementType.AirMech=AirMech MovementType.Fighter=Fighter +Engine.MagLev=MagLev diff --git a/megamek/src/megamek/common/Engine.java b/megamek/src/megamek/common/Engine.java index 919a2765b2f..e118fd967ee 100644 --- a/megamek/src/megamek/common/Engine.java +++ b/megamek/src/megamek/common/Engine.java @@ -70,6 +70,12 @@ public class Engine implements Serializable, ITechnology { public final static int STEAM = 10; public final static int BATTERY = 11; public final static int SOLAR = 12; + + /** Keys for retrieving engine name from {@link Messages} */ + private final static String[] TYPE_KEYS = { + "ICE", "Fusion", "XL", "XXL", "FuelCell", "Light", "Compact", "Fission", "None", + "MagLev", "Steam", "Battery", "Solar" + }; //These are the SUPPORT VEHICLE ENGINE WEIGHT MULTIPLIERS from TM PG 127 //The other engine types are assumed to have a value of ) in the array @@ -212,6 +218,7 @@ private boolean isValidEngine() { case MAGLEV: case BATTERY: case SOLAR: + case STEAM: break; case COMPACT_ENGINE: if (hasFlag(LARGE_ENGINE)) { @@ -413,49 +420,15 @@ public int integralHeatSinkCapacity(boolean compact) { /** * Get the name of this engine, this is the localized name used in displays. - * The name of an Engine is based on it's type. + * The name of an Engine is based on its type. * * @return the engine name. */ public String getShortEngineName() { - switch (engineType) { - case COMBUSTION_ENGINE: - return Integer.toString(engineRating) - + Messages.getString("Engine.ICE"); - case NORMAL_ENGINE: - return Integer.toString(engineRating); - case XL_ENGINE: - return Integer.toString(engineRating) - + Messages.getString("Engine.XL"); - case LIGHT_ENGINE: - return Integer.toString(engineRating) - + Messages.getString("Engine.Light"); - case XXL_ENGINE: - return Integer.toString(engineRating) - + Messages.getString("Engine.XXL"); - case COMPACT_ENGINE: - return Integer.toString(engineRating) - + Messages.getString("Engine.Compact"); - case FISSION: - return Integer.toString(engineRating) - + Messages.getString("Engine.Fission"); - case FUEL_CELL: - return Integer.toString(engineRating) - + Messages.getString("Engine.FuelCell"); - case NONE: - return Integer.toString(engineRating) - + Messages.getString("Engine.None"); - case STEAM: - return Integer.toString(engineRating) - + Messages.getString("Engine.Steam"); - case BATTERY: - return Integer.toString(engineRating) - + Messages.getString("Engine.Battery"); - case SOLAR: - return Integer.toString(engineRating) - + Messages.getString("Engine.Solar"); - default: - return Messages.getString("Engine.invalid"); + if (engineType < TYPE_KEYS.length) { + return String.format("%d%s", engineRating, Messages.getString("Engine." + TYPE_KEYS[engineType])); + } else { + return Messages.getString("Engine.invalid"); } } From 75fb4ee141e4b10b48eae3b619fa3e7793ce0294 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sun, 31 Mar 2019 16:19:04 -0500 Subject: [PATCH 08/69] Account for minimum weights for support vee engines. --- megamek/src/megamek/common/Engine.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/megamek/src/megamek/common/Engine.java b/megamek/src/megamek/common/Engine.java index e118fd967ee..e5f312af601 100644 --- a/megamek/src/megamek/common/Engine.java +++ b/megamek/src/megamek/common/Engine.java @@ -326,6 +326,17 @@ && isValidEngine()) { double weight = entity.getBaseEngineValue() * movementFactor * engineWeightMult * entity.getWeight(); weight = TestEntity.setPrecision(weight, 4); + // Fusion engines have a minimum weight of 0.25t at D+ and 0.5t at C. Fission engines have + // a minimum of 0.5t at all tech ratings. + if ((engineType == NORMAL_ENGINE) && (entity.getEngineTechRating() >= RATING_D)) { + weight = Math.max(weight, 0.25); + } else if ((engineType == NORMAL_ENGINE) || (engineType == FISSION)) { + weight = Math.max(weight, 0.5); + } + // Hovercraft have a minimum engine weight of 20% of the vehicle. + if (entity.getMovementMode().equals(EntityMovementMode.HOVER)) { + weight = Math.max(weight, entity.getWeight() * 0.2); + } roundWeight = TestEntity.Ceil.HALFTON; if (entity.getWeight() < 5) { roundWeight = TestEntity.Ceil.KILO; From 437dbbee7eab5b5d359581c76d86482dd6b674a0 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sun, 31 Mar 2019 21:56:59 -0500 Subject: [PATCH 09/69] Fuel weight calculations for fixed wing and airship support vehicles. --- megamek/src/megamek/common/Aero.java | 4 ++ .../src/megamek/common/FixedWingSupport.java | 50 ++++++++++++++++--- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/megamek/src/megamek/common/Aero.java b/megamek/src/megamek/common/Aero.java index 8d8b968158b..93688fa1b41 100644 --- a/megamek/src/megamek/common/Aero.java +++ b/megamek/src/megamek/common/Aero.java @@ -804,6 +804,10 @@ public int getRightThrustHits() { return rightThrustHits; } + public int getOriginalFuel() { + return fuel; + } + public int getFuel() { if ((getPartialRepairs().booleanOption("aero_asf_fueltank_crit")) || (getPartialRepairs().booleanOption("aero_fueltank_crit"))) { diff --git a/megamek/src/megamek/common/FixedWingSupport.java b/megamek/src/megamek/common/FixedWingSupport.java index 6d60fe23cc6..f267e3343b4 100644 --- a/megamek/src/megamek/common/FixedWingSupport.java +++ b/megamek/src/megamek/common/FixedWingSupport.java @@ -92,21 +92,55 @@ public void autoSetSI() { initializeSI(getOriginalWalkMP()); } - @Override public boolean isVSTOL() { - if (hasWorkingMisc(MiscType.F_VSTOL_CHASSIS, -1)) { - return true; - } - return false; + return hasWorkingMisc(MiscType.F_VSTOL_CHASSIS); } @Override public boolean isSTOL() { - if (hasWorkingMisc(MiscType.F_STOL_CHASSIS, -1)) { - return true; + return hasWorkingMisc(MiscType.F_STOL_CHASSIS); + } + + public boolean hasPropChassisMod() { + return hasWorkingMisc(MiscType.F_PROP); + } + + /** + * The mass of each point of fuel in kg, based on weight class and engine tech rating. + */ + private static final int[][] KG_PER_FUEL_POINT = { + {50, 30, 23, 15, 13, 10}, // small + {63, 38, 25, 20, 18, 15}, // medium + {83, 50, 35, 28, 23, 20} // large + }; + + /** + * While most aerospace units measure fuel weight in points per ton, support vehicles measure + * in kg per point. + * + * @return The mass of each point of fuel in kg. + */ + public int kgPerFuelPoint() { + int kg = KG_PER_FUEL_POINT[getWeightClass() - EntityWeightClass.WEIGHT_SMALL_SUPPORT][getEngineTechRating()]; + if (hasPropChassisMod() || getMovementMode().equals(EntityMovementMode.AIRSHIP)) { + kg = (int) Math.ceil(kg * 0.75); } - return false; + return kg; + } + + @Override + public double getFuelTonnage() { + double weight = getOriginalFuel() * kgPerFuelPoint() / 1000.0; + if (getWeightClass() != EntityWeightClass.WEIGHT_SMALL_SUPPORT) { + weight = Math.ceil(weight * 2.0) * 0.5; + } + return weight; + } + + @Override + public double getFuelPointsPerTon() { + return 1000.0 / kgPerFuelPoint(); } protected static final TechAdvancement TA_FIXED_WING_SUPPORT = new TechAdvancement(TECH_BASE_ALL) From 3a317f05bd881988c823aef154de66bb3f201c71 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sun, 31 Mar 2019 22:51:50 -0500 Subject: [PATCH 10/69] Changed TestSupportVehicle to extend TestEntity instead of TestTank. This results in a little more duplicated code, but not as much as having to have separate classes for ground and air support vees. Filled in most of the weight calculations. Turrets are still to be done. --- .../megamek/common/verifier/TestEntity.java | 15 +- .../common/verifier/TestSupportVehicle.java | 410 +++++++++++++++--- 2 files changed, 370 insertions(+), 55 deletions(-) diff --git a/megamek/src/megamek/common/verifier/TestEntity.java b/megamek/src/megamek/common/verifier/TestEntity.java index adf28d5c672..12a10e371d5 100755 --- a/megamek/src/megamek/common/verifier/TestEntity.java +++ b/megamek/src/megamek/common/verifier/TestEntity.java @@ -498,11 +498,24 @@ public double getWeightAllocatedArmor() { } } + /** + * Gives subclasses a chance to exclude certain misc equipment if it is accounted for in a different + * category. + * + * @param misc The misc equipment type + * @return Whether to include the equipment in the misc equipment category + * @see #getWeightMiscEquip() + */ + protected boolean includeMiscEquip(MiscType misc) { + return true; + } + public double getWeightMiscEquip() { double weightSum = 0.0; for (Mounted m : getEntity().getMisc()) { MiscType mt = (MiscType) m.getType(); - if (mt.hasFlag(MiscType.F_ENDO_STEEL) + if (!includeMiscEquip(mt) + || mt.hasFlag(MiscType.F_ENDO_STEEL) || mt.hasFlag(MiscType.F_ENDO_COMPOSITE) || mt.hasFlag(MiscType.F_ENDO_STEEL_PROTO) || mt.hasFlag(MiscType.F_ENDO_COMPOSITE) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index a9aa9fa869b..ed47338e785 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -16,42 +16,62 @@ package megamek.common.verifier; import megamek.common.*; import megamek.common.annotations.Nullable; +import megamek.common.logging.DefaultMmLogger; import megamek.common.util.StringUtil; +import megamek.common.weapons.flamers.VehicleFlamerWeapon; +import megamek.common.weapons.lasers.CLChemicalLaserWeapon; -import java.util.Arrays; +import java.math.BigInteger; import java.util.EnumSet; import java.util.Set; /** * Author: arlith */ -public class TestSupportVehicle extends TestTank { +public class TestSupportVehicle extends TestEntity { /** * Support vehicle categories for construction purposes. Most of these match with a particular movement * mode, but the construction rules treat naval and rail units as single types. */ public enum SVType { - AIRSHIP (300, EntityMovementMode.AIRSHIP), - FIXED_WING (200, EntityMovementMode.AERODYNE), - HOVERCRAFT (100, EntityMovementMode.HOVER), - NAVAL (300, EntityMovementMode.NAVAL), - TRACKED (200, EntityMovementMode.TRACKED), - VTOL (60, EntityMovementMode.VTOL), - WHEELED (160, EntityMovementMode.WHEELED), - WIGE (240, EntityMovementMode.WIGE), - RAIL (600, EntityMovementMode.RAIL), - SATELLITE (300, EntityMovementMode.STATION_KEEPING); + AIRSHIP (300, EntityMovementMode.AIRSHIP, + new double[]{0.2, 0.25, 0.3}, new double[]{0.004, 0.008, 0.012}), + FIXED_WING (200, EntityMovementMode.AERODYNE, + new double[]{0.8, 0.1, 0.15}, new double[]{0.005, 0.01, 0.015}), + HOVERCRAFT (100, EntityMovementMode.HOVER, + new double[]{0.2, 0.25, 0.3}, new double[]{0.0025, 0.004, 0.007}), + NAVAL (300, EntityMovementMode.NAVAL, + new double[]{0.12, 0.15, 0.17}, new double[]{0.004, 0.007, 0.009}), + TRACKED (200, EntityMovementMode.TRACKED, + new double[]{0.13, 0.15, 0.25}, new double[]{0.006, 0.013, 0.025}), + VTOL (60, EntityMovementMode.VTOL, + new double[]{0.2, 0.25, 0.3}, new double[]{0.002, 0.0025, 0.004}), + WHEELED (160, EntityMovementMode.WHEELED, + new double[]{0.12, 0.15, 0.18}, new double[]{0.0025, 0.0075, 0.015}), + WIGE (240, EntityMovementMode.WIGE, + new double[]{0.12, 0.15, 0.17}, new double[]{0.003, 0.005, 0.006}), + RAIL (600, EntityMovementMode.RAIL, + new double[]{0.15, 0.2, 0.3}, new double[]{0.003, 0.004, 0.005}), + SATELLITE (300, EntityMovementMode.STATION_KEEPING, + new double[]{0.8, 0.12, 0.16}, new double[]{0.1, 0.1, 0.1}); /** The maximum tonnage for a large support vehicle of this type; for airship this is the * maximum for a medium for now. */ public final int maxTonnage; public final EntityMovementMode defaultMovementMode; + /** Used to calculate chassis weight for small, medium, large weight classes */ + private final double[] baseChassisValue; + /** Used to calculate engine weight for small, medium, large weight classes */ + private final double[] baseEngineValue; - SVType(int maxTonnage, EntityMovementMode defaultMovementMode) { + SVType(int maxTonnage, EntityMovementMode defaultMovementMode, + double[] baseChassisValue, double[] baseEngineValue) { this.maxTonnage = maxTonnage; this.defaultMovementMode = defaultMovementMode; + this.baseChassisValue = baseChassisValue; + this.baseEngineValue = baseEngineValue; } static Set allBut(SVType type) { @@ -99,6 +119,64 @@ SVType getVehicleType(Entity entity) { return null; } } + + /** + * The base chassis value is used for calculating the chassis weight. + * + * @param sizeClass The {@link EntityWeightClass} of the support vehicle. + * @return The base chassis value. Returns 0 if not a support vehicle weight class. + */ + public double getBaseChassisValue(int sizeClass) { + int index = sizeClass - EntityWeightClass.WEIGHT_SMALL_SUPPORT; + if ((index >= 0) && (index < baseChassisValue.length)) { + return baseChassisValue[index]; + } else { + return 0.0; + } + } + + /** + * The base chassis value is used for calculating the chassis weight. + * + * @param sv A support vehicle + * @return The base chassis value. Returns 0 if the entity is not a support vehicle. + */ + public static double getBaseChassisValue(Entity sv) { + SVType type = getVehicleType(sv); + if (null != type) { + return type.getBaseChassisValue(sv.getWeightClass()); + } + return 0.0; + } + + /** + * The base engine value is used for calculating the engine weight. + * + * @param sizeClass The {@link EntityWeightClass} of the support vehicle. + * @return The base engine value. Returns 0 if not a support vehicle weight class. + */ + public double getBaseEngineValue(int sizeClass) { + int index = sizeClass - EntityWeightClass.WEIGHT_SMALL_SUPPORT; + if ((index >= 0) && (index < baseEngineValue.length)) { + return baseEngineValue[index]; + } else { + return 0.0; + } + } + + /** + * The base engine value is used for calculating the engine weight. + * + * @param sv A support vehicle + * @return The base engine value. Returns 0 if the entity is not a support vehicle. + */ + public static double getBaseEngineValue(Entity sv) { + SVType type = getVehicleType(sv); + if (null != type) { + return type.getBaseEngineValue(sv.getWeightClass()); + } + return 0.0; + } } /** @@ -106,43 +184,45 @@ SVType getVehicleType(Entity entity) { * units. */ public enum ChassisModification implements ITechnologyDelegator { - AMPHIBIOUS ("AmphibiousChassisMod", SVType.allBut(SVType.HOVERCRAFT, SVType.NAVAL)), - ARMORED ("ArmoredChassisMod", SVType.allBut(SVType.AIRSHIP)), - BICYCLE ("BicycleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED)), - CONVERTIBLE ("ConvertibleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED, SVType.TRACKED), true), - DUNE_BUGGY ("DuneBuggyChassisMod", EnumSet.of(SVType.WHEELED)), - ENVIRONMENTAL_SEALING ("EnvironmentalSealingChassisMod", EnumSet.allOf(SVType.class)), - EXTERNAL_POWER_PICKUP ("ExternalPowerPickupChassisMod", EnumSet.of(SVType.RAIL)), - HYDROFOIL ("HydrofoilChassisMod", EnumSet.of(SVType.NAVAL)), - MONOCYCLE ("MonocycleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED), true), - OFFROAD ("OffroadChassisMod", EnumSet.of(SVType.WHEELED)), - OMNI ("OmniChassisMod"), - PROP ("PropChassisMod", EnumSet.of(SVType.FIXED_WING)), - SNOWMOBILE ("SnowmobileChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED)), - STOL ("STOLChassisMod", EnumSet.of(SVType.FIXED_WING)), - SUBMERSIBLE ("SubmersibleChassisMod", EnumSet.of(SVType.NAVAL)), - TRACTOR ("TractorChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.NAVAL, SVType.RAIL)), - TRAILER ("TrailerChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.RAIL)), - ULTRA_LIGHT ("UltraLightChassisMod", true), - VSTOL ("VSTOLChassisMod", EnumSet.of(SVType.FIXED_WING)); + AMPHIBIOUS (1.75,"AmphibiousChassisMod", SVType.allBut(SVType.HOVERCRAFT, SVType.NAVAL)), + ARMORED (1.5,"ArmoredChassisMod", SVType.allBut(SVType.AIRSHIP)), + BICYCLE (0.75,"BicycleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED)), + CONVERTIBLE (1.1,"ConvertibleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED, SVType.TRACKED), true), + DUNE_BUGGY (1.5,"DuneBuggyChassisMod", EnumSet.of(SVType.WHEELED)), + ENVIRONMENTAL_SEALING (2.0,"EnvironmentalSealingChassisMod", EnumSet.allOf(SVType.class)), + EXTERNAL_POWER_PICKUP (1.1,"ExternalPowerPickupChassisMod", EnumSet.of(SVType.RAIL)), + HYDROFOIL (1.7,"HydrofoilChassisMod", EnumSet.of(SVType.NAVAL)), + MONOCYCLE (0.5,"MonocycleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED), true), + OFFROAD (1.5,"OffroadChassisMod", EnumSet.of(SVType.WHEELED)), + OMNI (1.0,"OmniChassisMod"), + PROP (1.2,"PropChassisMod", EnumSet.of(SVType.FIXED_WING)), + SNOWMOBILE (1.75,"SnowmobileChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED)), + STOL (1.5,"STOLChassisMod", EnumSet.of(SVType.FIXED_WING)), + SUBMERSIBLE (1.8,"SubmersibleChassisMod", EnumSet.of(SVType.NAVAL)), + TRACTOR (1.2,"TractorChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.NAVAL, SVType.RAIL)), + TRAILER (0.8,"TrailerChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.RAIL)), + ULTRA_LIGHT (0.5,"UltraLightChassisMod", true), + VSTOL (2.0,"VSTOLChassisMod", EnumSet.of(SVType.FIXED_WING)); + public final double multiplier; public final MiscType equipment; public final boolean smallOnly; public final Set allowedTypes; - ChassisModification(String eqTypeKey) { - this(eqTypeKey, EnumSet.allOf(SVType.class), false); + ChassisModification(double multiplier, String eqTypeKey) { + this(multiplier, eqTypeKey, EnumSet.allOf(SVType.class), false); } - ChassisModification(String eqTypeKey, boolean smallOnly) { - this(eqTypeKey, EnumSet.allOf(SVType.class), smallOnly); + ChassisModification(double multiplier, String eqTypeKey, boolean smallOnly) { + this(multiplier, eqTypeKey, EnumSet.allOf(SVType.class), smallOnly); } - ChassisModification(String eqTypeKey, Set allowedTypes) { - this(eqTypeKey, allowedTypes, false); + ChassisModification(double multiplier, String eqTypeKey, Set allowedTypes) { + this(multiplier, eqTypeKey, allowedTypes, false); } - ChassisModification(String eqTypeKey, Set allowedTypes, boolean smallOnly) { + ChassisModification(double multiplier, String eqTypeKey, Set allowedTypes, boolean smallOnly) { + this.multiplier = multiplier; this.equipment = (MiscType) EquipmentType.get(eqTypeKey); this.allowedTypes = allowedTypes; this.smallOnly = smallOnly; @@ -152,6 +232,22 @@ public enum ChassisModification implements ITechnologyDelegator { public ITechnology getTechSource() { return equipment; } + + /** + * Find the enum value that corresponds to an {@link EquipmentType} instance. + * + * @param eq The equipment to match + * @return The corresponding enum value, or {@code null} if there is no match. + */ + public @Nullable + static ChassisModification getChassisMod(EquipmentType eq) { + for (ChassisModification mod : values()) { + if (mod.equipment.equals(eq)) { + return mod; + } + } + return null; + } } /** @@ -159,12 +255,13 @@ public ITechnology getTechSource() { * vehicle types. */ public enum SVEngine implements ITechnologyDelegator { - STEAM (Engine.STEAM, EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.AIRSHIP, SVType.NAVAL)), - COMBUSTION (Engine.COMBUSTION_ENGINE), + STEAM (Engine.STEAM, EnumSet.of(SVType.WHEELED, SVType.TRACKED, + SVType.AIRSHIP, SVType.NAVAL, SVType.RAIL)), + COMBUSTION (Engine.COMBUSTION_ENGINE, SVType.allBut(SVType.SATELLITE)), BATTERY (Engine.BATTERY, true), FUEL_CELL (Engine.FUEL_CELL, true), SOLAR (Engine.SOLAR, EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.AIRSHIP, SVType.FIXED_WING, - SVType.NAVAL, SVType.WIGE), true), + SVType.NAVAL, SVType.WIGE, SVType.SATELLITE), true), FISSION (Engine.FISSION), FUSION (Engine.NORMAL_ENGINE), MAGLEV (Engine.MAGLEV, EnumSet.of(SVType.RAIL)), @@ -202,9 +299,11 @@ public enum SVEngine implements ITechnologyDelegator { */ public @Nullable static SVEngine getEngineType(Engine engine) { - for (SVEngine e : values()) { - if (e.engine.getEngineType() == engine.getEngineType()) { - return e; + if (null != engine) { + for (SVEngine e : values()) { + if (e.engine.getEngineType() == engine.getEngineType()) { + return e; + } } } return null; @@ -251,6 +350,13 @@ public ITechnology getTechSource() { ITechnology.RATING_D, ITechnology.RATING_C) }; + /** + * The chassis weight multiplier for tech ratings A-F + */ + private static final double[] STRUCTURE_TECH_MULTIPLIER = { + 1.6, 1.3, 1.15, 1.0, 0.85, 0.66 + }; + /** * Gives the weight of a single point of armor at a particular BAR for a * given tech level. @@ -267,10 +373,13 @@ public ITechnology getTechSource() { {.000, .000, .000, .051, .045, .042}, {.000, .000, .000, .057, .051, .047}, {.000, .000, .000, .063, .056, .052},}; + + private final Entity supportVee; - public TestSupportVehicle(Tank sv, TestEntityOption options, + public TestSupportVehicle(Entity sv, TestEntityOption options, String fileString) { - super(sv, options, fileString); + super(options, sv.getEngine(), null, null); + this.supportVee = sv; } @Override @@ -279,17 +388,211 @@ public String printWeightStructure() { "Chassis: ", getPrintSize() - 5) + TestEntity.makeWeightString(getWeightStructure()) + "\n"; } - + + @Override + public Entity getEntity() { + return supportVee; + } + + @Override + public boolean isTank() { + return supportVee instanceof Tank; + } + + @Override + public boolean isMech() { + return false; + } + + @Override + public boolean isAero() { + return supportVee.isAero(); + } + + @Override + public boolean isSmallCraft() { + return false; + } + + @Override + public boolean isAdvancedAerospace() { + return false; + } + + @Override + public boolean isProtomech() { + return false; + } + + @Override + public double getWeightStructure() { + double weight = supportVee.getWeight(); + weight *= SVType.getBaseChassisValue(supportVee); + weight *= STRUCTURE_TECH_MULTIPLIER[supportVee.getStructuralTechRating()]; + for (Mounted m : supportVee.getMisc()) { + if (m.getType().hasFlag(MiscType.F_CHASSIS_MODIFICATION)) { + ChassisModification mod = ChassisModification.getChassisMod(m.getType()); + if (null != mod) { + weight *= mod.multiplier; + } else { + DefaultMmLogger.getInstance().warning(getClass(), "getWeightStructure()", + "Could not find multiplier for " + m.getType().getName() + " chassis mod."); + } + } + } + return weight; + } + + public double getFuelTonnage() { + if (supportVee instanceof Aero) { + return ((Aero) supportVee).getFuelTonnage(); + } else { + return ((Tank) supportVee).getFuelTonnage(); + } + } + + private double getWeightFireControl() { + for (Mounted m : supportVee.getMisc()) { + if (m.getType().hasFlag(MiscType.F_BASIC_FIRECONTROL) + || m.getType().hasFlag(MiscType.F_ADVANCED_FIRECONTROL)) { + return m.getType().getTonnage(supportVee); + } + } + return 0.0; + } + + private double getWeightCrewAccomodations() { + double weight = 0; + for (Transporter t : supportVee.getTransports()) { + if ((t instanceof Bay) && ((Bay) t).isQuarters()) { + weight += ((Bay) t).getWeight(); + } + } + return weight; + } + @Override public double getWeightControls() { - return 0; + return getWeightFireControl() + getWeightCrewAccomodations(); } - + @Override - public double getTankWeightLifting() { + public double getWeightMisc() { + // TODO: turret weight return 0; } - + + @Override + public double getWeightPowerAmp() { + if (supportVee.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT) { + return 0.0; + } + + if (!engine.isFusion() && (engine.getEngineType() != Engine.FISSION)) { + double weight = 0; + for (Mounted m : supportVee.getWeaponList()) { + WeaponType wt = (WeaponType) m.getType(); + if (wt.hasFlag(WeaponType.F_ENERGY) && !(wt instanceof CLChemicalLaserWeapon) && !(wt instanceof VehicleFlamerWeapon)) { + weight += wt.getTonnage(supportVee); + } + if ((m.getLinkedBy() != null) && (m.getLinkedBy().getType() instanceof + MiscType) && m.getLinkedBy().getType(). + hasFlag(MiscType.F_PPC_CAPACITOR)) { + weight += ((MiscType)m.getLinkedBy().getType()).getTonnage(supportVee); + } + } + return TestEntity.ceil(weight / 10, getWeightCeilingPowerAmp()); + } + return 0.0; + } + + @Override + protected boolean includeMiscEquip(MiscType eq) { + // fire control is counted with control system weight and chassis mods are part of + // the structure weight + final BigInteger exclude = MiscType.F_BASIC_FIRECONTROL.or(MiscType.F_ADVANCED_FIRECONTROL) + .or(MiscType.F_CHASSIS_MODIFICATION); + return !eq.hasFlag(exclude); + } + + @Override + public double getWeightHeatSinks() { + // Unlike other units, support vehicles do not get any free engine heat sinks. + return getCountHeatSinks(); + } + + @Override + public boolean hasDoubleHeatSinks() { + return false; + } + + @Override + public int getCountHeatSinks() { + // Small support vees can't mount heavy weapons, so no reason to iterate through them to check. + if (supportVee.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT) { + return 0; + } + return heatNeutralHSRequirement(); + } + + @Override + public String printWeightMisc() { + // TODO: turret weight + return ""; + } + + @Override + public String printWeightControls() { + String fireCon = ""; + for (Mounted m : supportVee.getMisc()) { + if (m.getType().hasFlag(MiscType.F_BASIC_FIRECONTROL) + || m.getType().hasFlag(MiscType.F_ADVANCED_FIRECONTROL)) { + fireCon = StringUtil.makeLength(m.getName(), getPrintSize() - 5) + + TestEntity.makeWeightString(m.getType().getTonnage(supportVee)) + "\n"; + break; + } + } + double weight = getWeightCrewAccomodations(); + String crewStr = weight > 0 ? + StringUtil.makeLength("Crew Accomodations:", getPrintSize() - 5) + + TestEntity.makeWeightString(weight) + "\n" : ""; + return fireCon + crewStr; + } + + @Override + public boolean correctEntity(StringBuffer buff) { + return false; + } + + @Override + public boolean correctEntity(StringBuffer buff, int ammoTechLvl) { + return false; + } + + @Override + public StringBuffer printEntity() { + StringBuffer buff = new StringBuffer(); + buff.append(getName()).append("\n"); + buff.append("Found in: ").append(fileString).append("\n"); + buff.append(printTechLevel()); + buff.append("Intro year: ").append(supportVee.getYear()); + buff.append(printSource()); + buff.append(printShortMovement()); + if (correctWeight(buff, true, true)) { + buff.append("Weight: ").append(getWeight()).append(" (").append( + calculateWeight()).append(")\n"); + } + + buff.append(printWeightCalculation()).append("\n"); + printFailedEquipment(buff); + return buff; + } + + @Override + public String getName() { + return "Support Vehicle: " + supportVee.getDisplayName(); + } + @Override public double getWeightArmor() { int totalArmorPoints = 0; @@ -305,6 +608,5 @@ public double getWeightArmor() { return TestEntity.ceil(weight, Ceil.HALFTON); } - } - + } } From 94e940bfc1ebc09478cb541a3da31b1ad1742c23 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 1 Apr 2019 09:43:16 -0500 Subject: [PATCH 11/69] Added turret weight calculations. --- .../common/verifier/TestSupportVehicle.java | 34 ++++++++++++++++--- .../src/megamek/common/verifier/TestTank.java | 10 +----- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index ed47338e785..e1b1705a89c 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -375,11 +375,14 @@ public ITechnology getTechSource() { {.000, .000, .000, .063, .056, .052},}; private final Entity supportVee; + /** Used by support tanks for calculation of turret weight */ + private final TestTank testTank; public TestSupportVehicle(Entity sv, TestEntityOption options, String fileString) { super(options, sv.getEngine(), null, null); this.supportVee = sv; + testTank = sv instanceof Tank ? new TestTank((Tank) sv, options, fileString) : null; } @Override @@ -478,8 +481,24 @@ public double getWeightControls() { @Override public double getWeightMisc() { - // TODO: turret weight - return 0; + return getTankWeightTurret() + + getTankWeightDualTurret(); + } + + public double getTankWeightTurret() { + if (null != testTank) { + return testTank.getTankWeightTurret(); + } else { + return 0.0; + } + } + + public double getTankWeightDualTurret() { + if (null != testTank) { + return testTank.getTankWeightDualTurret(); + } else { + return 0.0; + } } @Override @@ -498,7 +517,7 @@ public double getWeightPowerAmp() { if ((m.getLinkedBy() != null) && (m.getLinkedBy().getType() instanceof MiscType) && m.getLinkedBy().getType(). hasFlag(MiscType.F_PPC_CAPACITOR)) { - weight += ((MiscType)m.getLinkedBy().getType()).getTonnage(supportVee); + weight += m.getLinkedBy().getType().getTonnage(supportVee); } } return TestEntity.ceil(weight / 10, getWeightCeilingPowerAmp()); @@ -537,8 +556,13 @@ public int getCountHeatSinks() { @Override public String printWeightMisc() { - // TODO: turret weight - return ""; + if (null != testTank) { + return testTank.printWeightMisc(); + } else { + return getWeightPowerAmp() != 0 ? StringUtil.makeLength( + "Power Amp:", getPrintSize() - 5) + + TestEntity.makeWeightString(getWeightPowerAmp()) + "\n" : ""; + } } @Override diff --git a/megamek/src/megamek/common/verifier/TestTank.java b/megamek/src/megamek/common/verifier/TestTank.java index 6aa041f65de..32af13a6984 100755 --- a/megamek/src/megamek/common/verifier/TestTank.java +++ b/megamek/src/megamek/common/verifier/TestTank.java @@ -192,15 +192,7 @@ public double getTankWeightTurret() { weight = weight / 10.0f; } - if (tank.isSupportVehicle()) { - if (getEntity().getWeight() < 5) { - return TestEntity.ceil(weight, Ceil.KILO); - } else { - return TestEntity.ceil(weight, Ceil.HALFTON); - } - } else { - return TestEntity.ceilMaxHalf(weight, getWeightCeilingTurret()); - } + return TestEntity.ceilMaxHalf(weight, getWeightCeilingTurret()); } public double getTankWeightDualTurret() { From 52f8931d5d9af5368722e709ce9ed819ccbd25e6 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 1 Apr 2019 14:32:05 -0500 Subject: [PATCH 12/69] Added slot calculations. --- megamek/src/megamek/common/EquipmentType.java | 12 ++ megamek/src/megamek/common/MiscType.java | 3 + megamek/src/megamek/common/Tank.java | 9 +- .../common/verifier/TestSupportVehicle.java | 174 +++++++++++++++++- .../common/weapons/artillery/CLArrowIV.java | 1 + .../common/weapons/artillery/ISArrowIV.java | 1 + .../weapons/artillery/ISCruiseMissile120.java | 1 + .../weapons/artillery/ISCruiseMissile50.java | 1 + .../weapons/artillery/ISCruiseMissile70.java | 1 + .../weapons/artillery/ISCruiseMissile90.java | 1 + .../common/weapons/artillery/LongTom.java | 1 + .../common/weapons/artillery/Sniper.java | 1 + .../common/weapons/artillery/Thumper.java | 1 + .../common/weapons/other/CLFluidGun.java | 1 + .../common/weapons/other/ISFluidGun.java | 1 + 15 files changed, 202 insertions(+), 7 deletions(-) diff --git a/megamek/src/megamek/common/EquipmentType.java b/megamek/src/megamek/common/EquipmentType.java index 7f6d34c3eb5..3da8c335a16 100644 --- a/megamek/src/megamek/common/EquipmentType.java +++ b/megamek/src/megamek/common/EquipmentType.java @@ -47,6 +47,10 @@ public class EquipmentType implements ITechnology { public static final int CRITICALS_VARIABLE = Integer.MIN_VALUE; public static final int BV_VARIABLE = Integer.MIN_VALUE; public static final int COST_VARIABLE = Integer.MIN_VALUE; + /** Default value for support vehicle slot cost. Those that differ from mechs are assigned + * a value >= 0 + */ + public static final int MECH_SLOT_COST = -1; public static final int T_ARMOR_UNKNOWN = -1; public static final int T_ARMOR_STANDARD = 0; @@ -158,6 +162,7 @@ public class EquipmentType implements ITechnology { protected double tonnage = 0; protected int criticals = 0; protected int tankslots = 1; + protected int svslots = MECH_SLOT_COST; protected boolean explosive = false; protected boolean hittable = true; // if false, reroll critical hits @@ -324,6 +329,13 @@ public int getTankslots(Entity entity) { return tankslots; } + public int getSupportVeeSlots(Entity entity) { + if (svslots == MECH_SLOT_COST) { + return getCriticals(entity); + } + return svslots; + } + public boolean isExplosive(Mounted mounted) { return isExplosive(mounted, false); } diff --git a/megamek/src/megamek/common/MiscType.java b/megamek/src/megamek/common/MiscType.java index bd10f36bd9c..68580b03969 100644 --- a/megamek/src/megamek/common/MiscType.java +++ b/megamek/src/megamek/common/MiscType.java @@ -6477,6 +6477,7 @@ public static MiscType createISHyperspectralImager() { misc.tonnage = 7.5; misc.cost = 550000; misc.criticals = 1; + misc.svslots = 2; misc.flags = misc.flags.or(F_HIRES_IMAGER).or(F_VTOL_EQUIPMENT).or(F_FIGHTER_EQUIPMENT) .or(F_SC_EQUIPMENT).or(F_DS_EQUIPMENT).or(F_JS_EQUIPMENT).or(F_WS_EQUIPMENT).or(F_SS_EQUIPMENT); misc.bv = 0; @@ -7656,6 +7657,7 @@ public static MiscType createLightSail() { public static MiscType createISSmallNavalCommScannerSuite() { MiscType misc = new MiscType(); misc.tonnage = 100; + misc.svslots = 1; misc.cost = 50000000; misc.name = "Naval Comm-Scanner Suite (Small)"; misc.setInternalName("ISSmallNavalCommScannerSuite"); @@ -7676,6 +7678,7 @@ public static MiscType createISSmallNavalCommScannerSuite() { public static MiscType createISLargeNavalCommScannerSuite() { MiscType misc = new MiscType(); misc.tonnage = 500; + misc.svslots = 1; misc.cost = 250000000; misc.name = "Naval Comm-Scanner Suite (Large)"; misc.setInternalName("ISLargeNavalCommScannerSuite"); diff --git a/megamek/src/megamek/common/Tank.java b/megamek/src/megamek/common/Tank.java index 64b61073329..49f10479cf4 100644 --- a/megamek/src/megamek/common/Tank.java +++ b/megamek/src/megamek/common/Tank.java @@ -3577,17 +3577,16 @@ public int getFreeSlots() { } // for ammo, each type of ammo takes one slots, regardless of // submunition type - Map foundAmmo = new HashMap(); + Set foundAmmo = new HashSet<>(); for (Mounted ammo : getAmmo()) { // don't count oneshot ammo - if ((ammo.getLocation() == Entity.LOC_NONE) - && (ammo.getBaseShotsLeft() == 1)) { + if (ammo.isOneShotAmmo()) { continue; } AmmoType at = (AmmoType) ammo.getType(); - if (foundAmmo.get(at.getAmmoType() + ":" + at.getRackSize()) == null) { + if (!foundAmmo.contains(at.getAmmoType() + ":" + at.getRackSize())) { usedSlots++; - foundAmmo.put(at.getAmmoType() + ":" + at.getRackSize(), true); + foundAmmo.add(at.getAmmoType() + ":" + at.getRackSize()); } } // if a tank has an infantry bay, add 1 slots (multiple bays take 1 slot diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index e1b1705a89c..445472e1bfa 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -23,6 +23,7 @@ import java.math.BigInteger; import java.util.EnumSet; +import java.util.HashSet; import java.util.Set; /** @@ -377,12 +378,15 @@ public ITechnology getTechSource() { private final Entity supportVee; /** Used by support tanks for calculation of turret weight */ private final TestTank testTank; + /** Used by fixed wing, airship, and satellite for some calculations and validation */ + private final TestAero testAero; public TestSupportVehicle(Entity sv, TestEntityOption options, String fileString) { super(options, sv.getEngine(), null, null); this.supportVee = sv; testTank = sv instanceof Tank ? new TestTank((Tank) sv, options, fileString) : null; + testAero = sv instanceof Aero ? new TestAero((Aero) sv, options, fileString) : null; } @Override @@ -619,11 +623,15 @@ public String getName() { @Override public double getWeightArmor() { + if (supportVee.hasPatchworkArmor() + || (supportVee.getArmorType(supportVee.firstArmorIndex()) != EquipmentType.T_ARMOR_STANDARD)) { + return super.getWeightArmor(); + } int totalArmorPoints = 0; for (int loc = 0; loc < getEntity().locations(); loc++) { totalArmorPoints += getEntity().getOArmor(loc); } - int bar = getEntity().getBARRating(Tank.LOC_BODY); + int bar = getEntity().getBARRating(supportVee.firstArmorIndex()); int techRating = getEntity().getArmorTechRating(); double weight = totalArmorPoints * SV_ARMOR_WEIGHT[bar][techRating]; if (getEntity().getWeight() < 5) { @@ -631,6 +639,168 @@ public double getWeightArmor() { } else { return TestEntity.ceil(weight, Ceil.HALFTON); } - + } + + /** + * @return The number of slots taken up by installed equipment + */ + public int occupiedSlotCount() { + return getArmorSlots() + getAmmoSlots() + getWeaponSlots() + getMiscEquipSlots(); + } + + /** + * @return The number of slots taken up by armor + */ + public int getArmorSlots() { + if (!supportVee.hasPatchworkArmor()) { + int at = supportVee.getArmorType(supportVee.firstArmorIndex()); + if (at == EquipmentType.T_ARMOR_STANDARD) { + // Support vehicle armor takes slots like ferro-fibrous at BAR 10/TL E/F + if (supportVee.getBARRating(supportVee.firstArmorIndex()) == 10) { + if (supportVee.getArmorTechRating() == ITechnology.RATING_E) { + return 2; // IS FF + } else if (supportVee.getArmorTechRating() == ITechnology.RATING_F) { + return 1; // Clan FF + } + } + return 0; + } else { + AdvancedSVArmor armor = AdvancedSVArmor.getArmor(at, + TechConstants.isClan(supportVee.getArmorTechLevel(supportVee.firstArmorIndex()))); + if (null != armor) { + return armor.space; + } else { + return 0; + } + } + } else { + int space = 0; + for (int loc = 0; loc < supportVee.locations(); loc++) { + AdvancedSVArmor armor = AdvancedSVArmor.getArmor(supportVee.getArmorType(loc), + TechConstants.isClan(supportVee.getArmorTechLevel(loc))); + if (null != armor) { + space += armor.patchworkSpace; + } + } + return space; + } + } + + /** + * @return The number of slots taken up by weapons + */ + public int getWeaponSlots() { + int slots = 0; + for (Mounted m : supportVee.getWeaponList()) { + slots += m.getType().getSupportVeeSlots(supportVee); + } + return slots; + } + + /** + * @return The number of slots taken up by ammo. + */ + public int getAmmoSlots() { + int slots = 0; + Set foundAmmo = new HashSet<>(); + for (Mounted ammo : supportVee.getAmmo()) { + // don't count oneshot ammo + if (ammo.isOneShotAmmo()) { + continue; + } + AmmoType at = (AmmoType) ammo.getType(); + if (!foundAmmo.contains(at.getAmmoType() + ":" + at.getRackSize())) { + slots++; + foundAmmo.add(at.getAmmoType() + ":" + at.getRackSize()); + } + } + return slots; + } + + /** + * @return The number of slots taken by miscellaneous equipment. + */ + public int getMiscEquipSlots() { + int slots = 0; + for (Mounted m : supportVee.getMisc()) { + slots += m.getType().getSupportVeeSlots(supportVee); + } + return slots; + } + + public enum AdvancedSVArmor { + CLAN_FERRO_FIBROUS(EquipmentType.T_ARMOR_FERRO_FIBROUS, 1, 1, true), + CLAN_FERRO_ALUM(EquipmentType.T_ARMOR_ALUM, 1, 1, true), + FERRO_LAMELLOR(EquipmentType.T_ARMOR_FERRO_LAMELLOR, 2, 1, true), + CLAN_REACTIVE(EquipmentType.T_ARMOR_REACTIVE, 1, 1, true), + CLAN_REFLECTIVE(EquipmentType.T_ARMOR_REFLECTIVE, 1, 1, true), + ANTI_PENETRATIVE_ABLATION( + EquipmentType.T_ARMOR_ANTI_PENETRATIVE_ABLATION, 1, 1, false), + BALLISTIC_REINFORCED( + EquipmentType.T_ARMOR_BALLISTIC_REINFORCED, 2, 1, false), + FERRO_FIBROUS(EquipmentType.T_ARMOR_ALUM, 2, 1, false), + FERRO_ALUM(EquipmentType.T_ARMOR_ALUM, 2, 1, false), + FERRO_FIBROUS_PROTO(EquipmentType.T_ARMOR_FERRO_FIBROUS_PROTO, 3, 1, false), + FERRO__ALUM_PROTO(EquipmentType.T_ARMOR_FERRO_ALUM_PROTO, 3, 1, false), + HEAVY_FERRO_FIBROUS(EquipmentType.T_ARMOR_HEAVY_FERRO, 4, 2, false), + LIGHT_FERRO_FIBROUS(EquipmentType.T_ARMOR_LIGHT_FERRO, 1, 1, false), + HEAVY_FERRO_ALUM(EquipmentType.T_ARMOR_HEAVY_ALUM, 4, 2, false), + LIGHT_FERRO_ALUM(EquipmentType.T_ARMOR_LIGHT_ALUM, 1, 1, false), + PRIMITIVE(EquipmentType.T_ARMOR_PRIMITIVE_FIGHTER, 0, 0, false), + REACTIVE(EquipmentType.T_ARMOR_REACTIVE, 3, 1, false), + REFLECTIVE(EquipmentType.T_ARMOR_REFLECTIVE, 2, 1, false), + STEALTH_VEHICLE(EquipmentType.T_ARMOR_STEALTH_VEHICLE, 2, 1, false); + + public final int armorType; + /** + * The type, corresponding to types defined in + * EquipmentType. + */ + public final EquipmentType eqType; + + /** + * The number of spaces occupied by the armor type. Armors that take + * up 1 space take up space in the aft, those with 2 take up space in + * each wing, 3 takes up space in both wings and the aft, 4 takes up + * space in each possible arc (nose, aft, left wing, right wing). + */ + public final int space; + + /** + * The number of weapon spaces occupied by patchwork armor. Unlike standard armor, patchwork + * armor takes up slots in the location where it's used. + */ + public final int patchworkSpace; + + /** + * Denotes whether this armor is Clan or not. + */ + public boolean isClan; + + AdvancedSVArmor(int at, int space, int patchworkSpace, boolean clan){ + this.armorType = at; + eqType = EquipmentType.get(EquipmentType.getArmorTypeName(at, clan)); + this.space = space; + this.patchworkSpace = patchworkSpace; + isClan = clan; + } + + /** + * Given an armor type, return the AeroArmor instance that + * represents that type. + * + * @param at The armor type. + * @param c Whether this armor type is Clan or not. + * @return The AeroArmor that correspondes to the given + * type or null if no match was found. + */ + public static @Nullable AdvancedSVArmor getArmor(int at, boolean c){ + for (AdvancedSVArmor a : values()){ + if ((a.armorType == at) && (a.isClan == c)) { + return a; + } + } + return null; + } } } diff --git a/megamek/src/megamek/common/weapons/artillery/CLArrowIV.java b/megamek/src/megamek/common/weapons/artillery/CLArrowIV.java index 44515bff1f0..a303797599d 100644 --- a/megamek/src/megamek/common/weapons/artillery/CLArrowIV.java +++ b/megamek/src/megamek/common/weapons/artillery/CLArrowIV.java @@ -50,6 +50,7 @@ public CLArrowIV() { extremeRange = 9; // No extreme range. tonnage = 12; criticals = 12; + svslots = 6; bv = 240; cost = 450000; this.flags = flags.or(F_MISSILE); diff --git a/megamek/src/megamek/common/weapons/artillery/ISArrowIV.java b/megamek/src/megamek/common/weapons/artillery/ISArrowIV.java index 499acc9d687..61da6b30c7f 100644 --- a/megamek/src/megamek/common/weapons/artillery/ISArrowIV.java +++ b/megamek/src/megamek/common/weapons/artillery/ISArrowIV.java @@ -49,6 +49,7 @@ public ISArrowIV() { extremeRange = 8; // No extreme range. tonnage = 15; criticals = 15; + svslots = 7; bv = 240; cost = 450000; this.flags = flags.or(F_MISSILE); diff --git a/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile120.java b/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile120.java index 35467a7e7fe..eb347cec12d 100644 --- a/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile120.java +++ b/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile120.java @@ -46,6 +46,7 @@ public ISCruiseMissile120() { this.extremeRange = 150; // No extreme range. this.tonnage = 135; this.criticals = 120; + this.svslots = 60; this.flags = flags.or(F_CRUISE_MISSILE); this.bv = 2281; this.cost = 3000000; diff --git a/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile50.java b/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile50.java index 64ff5683608..16d03a5313c 100644 --- a/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile50.java +++ b/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile50.java @@ -46,6 +46,7 @@ public ISCruiseMissile50() { this.extremeRange = 50; // No extreme range. this.tonnage = 55; this.criticals = 55; + this.svslots = 25; this.flags = flags.or(F_CRUISE_MISSILE); this.bv = 601; this.cost = 900000; diff --git a/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile70.java b/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile70.java index bf6a85715a8..c2b551ba29e 100644 --- a/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile70.java +++ b/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile70.java @@ -46,6 +46,7 @@ public ISCruiseMissile70() { this.extremeRange = 90; // No extreme range. this.tonnage = 80; this.criticals = 80; + this.svslots = 35; this.flags = flags.or(F_CRUISE_MISSILE); this.bv = 1031; this.cost = 1250000; diff --git a/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile90.java b/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile90.java index b364e503a27..73abeff1b8c 100644 --- a/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile90.java +++ b/megamek/src/megamek/common/weapons/artillery/ISCruiseMissile90.java @@ -46,6 +46,7 @@ public ISCruiseMissile90() { this.extremeRange = 120; // No extreme range. this.tonnage = 100; this.criticals = 100; + this.svslots = 45; this.flags = flags.or(F_CRUISE_MISSILE); this.bv = 1530; this.cost = 1250000; diff --git a/megamek/src/megamek/common/weapons/artillery/LongTom.java b/megamek/src/megamek/common/weapons/artillery/LongTom.java index b37196b8f07..29fffce1fd4 100644 --- a/megamek/src/megamek/common/weapons/artillery/LongTom.java +++ b/megamek/src/megamek/common/weapons/artillery/LongTom.java @@ -51,6 +51,7 @@ public LongTom() { extremeRange = 30; // No extreme range. tonnage = 30; criticals = 30; + svslots = 15; bv = 368; cost = 450000; rulesRefs = "284,TO"; diff --git a/megamek/src/megamek/common/weapons/artillery/Sniper.java b/megamek/src/megamek/common/weapons/artillery/Sniper.java index 553ec3863f6..a1d83f49654 100644 --- a/megamek/src/megamek/common/weapons/artillery/Sniper.java +++ b/megamek/src/megamek/common/weapons/artillery/Sniper.java @@ -53,6 +53,7 @@ public Sniper() { extremeRange = 18; // No extreme range. tonnage = 20; criticals = 20; + svslots = 10; bv = 85; cost = 300000; rulesRefs = "284,TO"; diff --git a/megamek/src/megamek/common/weapons/artillery/Thumper.java b/megamek/src/megamek/common/weapons/artillery/Thumper.java index 7fb05d65e0d..ed6d2f6d25c 100644 --- a/megamek/src/megamek/common/weapons/artillery/Thumper.java +++ b/megamek/src/megamek/common/weapons/artillery/Thumper.java @@ -52,6 +52,7 @@ public Thumper() { extremeRange = 21; // No extreme range. tonnage = 15; criticals = 15; + svslots = 7; bv = 43; cost = 187500; rulesRefs = "284,TO"; diff --git a/megamek/src/megamek/common/weapons/other/CLFluidGun.java b/megamek/src/megamek/common/weapons/other/CLFluidGun.java index 16c52759db9..2de22362ef4 100644 --- a/megamek/src/megamek/common/weapons/other/CLFluidGun.java +++ b/megamek/src/megamek/common/weapons/other/CLFluidGun.java @@ -40,6 +40,7 @@ public CLFluidGun() { bv = 6; heat = 0; criticals = 2; + svslots = 1; tonnage = 2; cost = 35000; rulesRefs = "313,TO"; diff --git a/megamek/src/megamek/common/weapons/other/ISFluidGun.java b/megamek/src/megamek/common/weapons/other/ISFluidGun.java index 126f9f0cc8e..db30123c9ee 100644 --- a/megamek/src/megamek/common/weapons/other/ISFluidGun.java +++ b/megamek/src/megamek/common/weapons/other/ISFluidGun.java @@ -40,6 +40,7 @@ public ISFluidGun() { bv = 6; heat = 0; criticals = 2; + svslots = 1; tonnage = 2; cost = 35000; rulesRefs = "313,TO"; From 04ab25818391a91fe153e67f53c3cece052b09bb Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 2 Apr 2019 10:35:07 -0500 Subject: [PATCH 13/69] Added transport and crew slot calculations. Added field for combat seats for combat and support vehicles. --- .../src/megamek/common/FixedWingSupport.java | 14 +++- megamek/src/megamek/common/Tank.java | 14 ++++ .../common/verifier/TestSupportVehicle.java | 69 ++++++++++++++++--- .../src/megamek/common/verifier/TestTank.java | 29 +++++++- 4 files changed, 115 insertions(+), 11 deletions(-) diff --git a/megamek/src/megamek/common/FixedWingSupport.java b/megamek/src/megamek/common/FixedWingSupport.java index f267e3343b4..6012802f896 100644 --- a/megamek/src/megamek/common/FixedWingSupport.java +++ b/megamek/src/megamek/common/FixedWingSupport.java @@ -35,6 +35,8 @@ public class FixedWingSupport extends ConvFighter { private static String[] LOCATION_NAMES = { "Nose", "Left Wing", "Right Wing", "Aft", "Wings", "Body" }; private int[] barRating; + /** Vehicles can be constructed with seating for additional crew. This has no effect on play */ + private int extraCrewSeats = 0; public FixedWingSupport() { super(); @@ -253,7 +255,17 @@ public double getBaseChassisValue() { public int getTotalSlots() { return 5 + (int) Math.floor(getWeight() / 10); } - + + /** + * @return Additional seats beyond the minimum crew requirements + */ + public int getExtraCrewSeats() { + return extraCrewSeats; + } + + public void setExtraCrewSeats(int seats) { + this.extraCrewSeats = seats; + } @Override public void addBattleForceSpecialAbilities(Map specialAbilities) { diff --git a/megamek/src/megamek/common/Tank.java b/megamek/src/megamek/common/Tank.java index 49f10479cf4..d858d467800 100644 --- a/megamek/src/megamek/common/Tank.java +++ b/megamek/src/megamek/common/Tank.java @@ -141,6 +141,8 @@ public int getLocTurret2() { //If there is a cockpit command console, the tank does not suffer the effects of the first commander critical, //but the command console benefits are lost as the backup has to take command. private boolean usingConsoleCommander = false; + /** Vehicles can be constructed with seating for additional crew. This has no effect on play */ + private int extraCrewSeats = 0; // set up some vars for what the critical effects would be private int potCrit = CRIT_NONE; @@ -438,6 +440,17 @@ public void setUsingConsoleCommander(boolean b) { usingConsoleCommander = b; } + /** + * @return Additional seats beyond the minimum crew requirements + */ + public int getExtraCrewSeats() { + return extraCrewSeats; + } + + public void setExtraCrewSeats(int seats) { + this.extraCrewSeats = seats; + } + public boolean isDriverHitPS() { return driverHitPS; } @@ -3609,6 +3622,7 @@ public int getFreeSlots() { usedSlots++; } } + usedSlots += extraCrewSeats; // different armor types take different amount of slots if (!hasPatchworkArmor()) { int type = getArmorType(1); diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 445472e1bfa..0077e9e1b5c 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -431,6 +431,14 @@ public boolean isProtomech() { return false; } + private double roundWeight(double val) { + if (supportVee.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT) { + return round(val, Ceil.KILO); + } else { + return ceil(val, Ceil.HALFTON); + } + } + @Override public double getWeightStructure() { double weight = supportVee.getWeight(); @@ -447,7 +455,7 @@ public double getWeightStructure() { } } } - return weight; + return roundWeight(weight); } public double getFuelTonnage() { @@ -475,7 +483,12 @@ private double getWeightCrewAccomodations() { weight += ((Bay) t).getWeight(); } } - return weight; + if (supportVee instanceof FixedWingSupport) { + weight += ((FixedWingSupport) supportVee).getExtraCrewSeats() * 0.5; + } else { + weight += ((Tank) supportVee).getExtraCrewSeats() * 0.5; + } + return roundWeight(weight); } @Override @@ -524,7 +537,7 @@ public double getWeightPowerAmp() { weight += m.getLinkedBy().getType().getTonnage(supportVee); } } - return TestEntity.ceil(weight / 10, getWeightCeilingPowerAmp()); + return roundWeight(weight / 10); } return 0.0; } @@ -634,18 +647,15 @@ public double getWeightArmor() { int bar = getEntity().getBARRating(supportVee.firstArmorIndex()); int techRating = getEntity().getArmorTechRating(); double weight = totalArmorPoints * SV_ARMOR_WEIGHT[bar][techRating]; - if (getEntity().getWeight() < 5) { - return TestEntity.floor(weight, Ceil.KILO); - } else { - return TestEntity.ceil(weight, Ceil.HALFTON); - } + return roundWeight(weight); } /** * @return The number of slots taken up by installed equipment */ public int occupiedSlotCount() { - return getArmorSlots() + getAmmoSlots() + getWeaponSlots() + getMiscEquipSlots(); + return getCrewSlots() + getArmorSlots() + getAmmoSlots() + + getWeaponSlots() + getMiscEquipSlots() + getTransportSlots(); } /** @@ -728,6 +738,47 @@ public int getMiscEquipSlots() { return slots; } + public int getCrewSlots() { + int firstClass = 0; + int secondClass = 0; + int steerage = 0; + int extraSeat = 0; + for (Transporter t : supportVee.getTransports()) { + if (t instanceof FirstClassQuartersCargoBay) { + firstClass++; + } else if ((t instanceof SecondClassQuartersCargoBay) + || (t instanceof CrewQuartersCargoBay)) { + secondClass++; + } else if (t instanceof SteerageQuartersCargoBay) { + steerage++; + } + } + return (int) (Math.ceil(firstClass / 5.0) + Math.ceil(secondClass / 20.0) + Math.ceil(steerage / 50.0)) + + (supportVee instanceof FixedWingSupport ? + ((FixedWingSupport) supportVee).getExtraCrewSeats() : + ((Tank) supportVee).getExtraCrewSeats()); + } + + /** + * Each distinct bay requires a slot, regardless of size. All {@link TroopSpace} is treated as a single + * bay. + * + * @return The number of slots required by transporters. + */ + public int getTransportSlots() { + int slots = 0; + boolean foundTroopSpace = false; + for (Transporter t : supportVee.getTransports()) { + if ((t instanceof Bay) && !((Bay) t).isQuarters()) { + slots++; + } else if ((t instanceof TroopSpace) && !foundTroopSpace) { + slots++; + foundTroopSpace = true; + } + } + return slots; + } + public enum AdvancedSVArmor { CLAN_FERRO_FIBROUS(EquipmentType.T_ARMOR_FERRO_FIBROUS, 1, 1, true), CLAN_FERRO_ALUM(EquipmentType.T_ARMOR_ALUM, 1, 1, true), diff --git a/megamek/src/megamek/common/verifier/TestTank.java b/megamek/src/megamek/common/verifier/TestTank.java index 32af13a6984..691208b6b68 100755 --- a/megamek/src/megamek/common/verifier/TestTank.java +++ b/megamek/src/megamek/common/verifier/TestTank.java @@ -192,7 +192,15 @@ public double getTankWeightTurret() { weight = weight / 10.0f; } - return TestEntity.ceilMaxHalf(weight, getWeightCeilingTurret()); + if (tank.isSupportVehicle()) { + if (getEntity().getWeight() < 5) { + return TestEntity.ceil(weight, Ceil.KILO); + } else { + return TestEntity.ceil(weight, Ceil.HALFTON); + } + } else { + return TestEntity.ceilMaxHalf(weight, getWeightCeilingTurret()); + } } public double getTankWeightDualTurret() { @@ -288,6 +296,21 @@ public String printWeightControls() { + TestEntity.makeWeightString(getWeightControls()) + "\n"; } + @Override + public double getWeightCarryingSpace() { + return super.getWeightCarryingSpace() + tank.getExtraCrewSeats() * 0.5; + } + + public String printWeightCarryingSpace() { + if (tank.getExtraCrewSeats() > 0) { + return super.printWeightCarryingSpace() + + StringUtil.makeLength("Combat Seats:", getPrintSize() - 5) + + TestEntity.makeWeightString(tank.getExtraCrewSeats() * 0.5) + "\n"; + } else { + return super.printWeightCarryingSpace(); + } + } + public Tank getTank() { return tank; } @@ -505,6 +528,10 @@ public StringBuffer printSlotCalculation() { buff.append(mount.getType().getTankslots(tank)).append("\n"); } } + if (tank.getExtraCrewSeats() > 0) { + buff.append(StringUtil.makeLength("Combat Crew Seats:", 30)); + buff.append(tank.getExtraCrewSeats()).append("\n"); + } // different armor types take different amount of slots int armorSlots = 0; if (!tank.hasPatchworkArmor()) { From 9c9c221622463327ee30626ba75fd561d8b33a84 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 8 Apr 2019 16:30:38 -0500 Subject: [PATCH 14/69] Fixed Engine validation and name problems with Steam and MagLev. --- megamek/src/megamek/common/Engine.java | 30 +++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/megamek/src/megamek/common/Engine.java b/megamek/src/megamek/common/Engine.java index e5f312af601..8b043d8ff14 100644 --- a/megamek/src/megamek/common/Engine.java +++ b/megamek/src/megamek/common/Engine.java @@ -194,7 +194,7 @@ private boolean isValidEngine() { && (engineType != COMBUSTION_ENGINE) && (engineType != BATTERY) && (engineType != FUEL_CELL) && (engineType != SOLAR) && (engineType != FISSION) && (engineType != NORMAL_ENGINE) - && (engineType != NONE)) { + && (engineType != MAGLEV) && (engineType != NONE)) { problem.append("Invalid Engine type for support vehicle engines!"); return false; } @@ -457,37 +457,43 @@ public String getEngineName() { } switch (engineType) { case COMBUSTION_ENGINE: - sb.append(" ICE"); //$NON-NLS-1$ + sb.append(" ICE"); break; case NORMAL_ENGINE: - sb.append(" Fusion"); //$NON-NLS-1$ + sb.append(" Fusion"); break; case XL_ENGINE: - sb.append(" XL"); //$NON-NLS-1$ + sb.append(" XL"); break; case LIGHT_ENGINE: - sb.append(" Light"); //$NON-NLS-1$ + sb.append(" Light"); break; case XXL_ENGINE: - sb.append(" XXL"); //$NON-NLS-1$ + sb.append(" XXL"); break; case COMPACT_ENGINE: - sb.append(" Compact"); //$NON-NLS-1$ + sb.append(" Compact"); break; case FUEL_CELL: - sb.append(" Fuel Cell"); //$NON-NLS-1$ + sb.append(" Fuel Cell"); break; case FISSION: - sb.append(" Fission"); //$NON-NLS-1$ + sb.append(" Fission"); + break; + case STEAM: + sb.append(" Steam"); break; case BATTERY: - sb.append(" Battery"); //$NON-NLS-1$ + sb.append(" Battery"); break; case SOLAR: - sb.append(" Solar"); //$NON-NLS-1$ + sb.append(" Solar"); + break; + case MAGLEV: + sb.append(" MagLev"); break; case NONE: - sb.append(" NONE"); //$NON-NLS-1$ + sb.append(" NONE"); break; default: return problem.toString(); From 905d8a2a2fa96730a4db55807c0bea1036741153 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 9 Apr 2019 16:46:23 -0500 Subject: [PATCH 15/69] Validate engine type against support vehicle type. --- .../common/verifier/TestSupportVehicle.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 0077e9e1b5c..dc37a73b003 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -310,6 +310,22 @@ static SVEngine getEngineType(Engine engine) { return null; } + /** + * @param type The support vehicle type + * @return Whether the engine is valid for the support vee. + */ + public boolean isValidFor(SVType type) { + return allowedTypes.contains(type); + } + + /** + * @param entity A support vehicle + * @return Whether the engine is valid for the support vee. + */ + public boolean isValidFor(Entity entity) { + return isValidFor(SVType.getVehicleType(entity)); + } + @Override public ITechnology getTechSource() { return engine; From 6d6d45eee4a164496fc266935f8db5b53b341f96 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 9 Apr 2019 16:46:50 -0500 Subject: [PATCH 16/69] Weight class categories for fixed wing. --- .../src/megamek/common/EntityWeightClass.java | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/megamek/src/megamek/common/EntityWeightClass.java b/megamek/src/megamek/common/EntityWeightClass.java index 5337804e753..a0983efcce5 100644 --- a/megamek/src/megamek/common/EntityWeightClass.java +++ b/megamek/src/megamek/common/EntityWeightClass.java @@ -56,10 +56,11 @@ public class EntityWeightClass { private static double[] hoverSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 50, 100 }; // Twelve padding 0s private static double[] vtolSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 30, 60 }; // Twelve padding 0s private static double[] wigeSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 80, 160 }; // Twelve padding 0s - //private static double[] airshipSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 300, 1000 }; // Twelve padding 0s - //private static double[] fixedwingSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 100, 200 }; // Twelve padding 0s + private static double[] airshipSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 300, 1000 }; // Twelve padding 0s + private static double[] fixedwingSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 100, 200 }; // Twelve padding 0s private static double[] navalSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 300, 100000 }; // Twelve padding 0s private static double[] railSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 300, 600 }; // Twelve padding 0s + private static double[] satelliteSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 100, 300 }; // Twelve padding 0s //private static double[] mobilestructuresSupportVehicleWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, LESS_THAN_5, 80, 160 }; // Twelve padding 0s private static double[] ASFWeightLimits = { 0, 45, 70, 100 }; // One padding 0 private static double[] dropshipWeightLimits = { 0, 0, 0, 0, 0, 0, 0, 2499, 9999, 100000 }; // Seven padding 0s @@ -91,6 +92,13 @@ public static double[] getWeightLimitByType(String type) { } } + /** + * Retrieves the weight class based on the type string in the unit file. + * + * @param tonnage The entity weight + * @param type The type string + * @return The weight class + */ public static int getWeightClass(double tonnage, String type) { int i; @@ -159,6 +167,13 @@ public static int getWeightClass(double tonnage, String type) { return i; } + /** + * Retrieves the weight class for support vehicles based on the subtype string from the unit file + * + * @param tonnage The entity weight + * @param type The subtype string + * @return The weight class + */ public static int getSupportWeightClass(double tonnage, String type) { int i = 0; @@ -216,6 +231,24 @@ public static int getSupportWeightClass(double tonnage, String type) { break; } } + } else if (type.equals("Aerodyne")) { + for (i = WEIGHT_SMALL_SUPPORT; i < (fixedwingSupportVehicleWeightLimits.length - 1); i++) { + if (tonnage <= fixedwingSupportVehicleWeightLimits[i]) { + break; + } + } + } else if (type.equals("Airship")) { + for (i = WEIGHT_SMALL_SUPPORT; i < (airshipSupportVehicleWeightLimits.length - 1); i++) { + if (tonnage <= airshipSupportVehicleWeightLimits[i]) { + break; + } + } + } else if (type.equals("Satellite")) { + for (i = WEIGHT_SMALL_SUPPORT; i < (satelliteSupportVehicleWeightLimits.length - 1); i++) { + if (tonnage <= satelliteSupportVehicleWeightLimits[i]) { + break; + } + } } return i; @@ -243,6 +276,12 @@ public static int getWeightClass(double tonnage, Entity en) { break; } } + } else if (en instanceof FixedWingSupport) { + for (i = WEIGHT_LIGHT; i < (fixedwingSupportVehicleWeightLimits.length - 1); i++) { // Started late to bypass padding & save a loop execution + if (tonnage <= fixedwingSupportVehicleWeightLimits[i]) { + break; + } + } } else if (en instanceof ConvFighter) { return WEIGHT_LIGHT; } else if (en instanceof SmallCraft) { From 652653d0c320137171067f2c4cea283f9ab21835 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 1 May 2019 11:05:01 -0500 Subject: [PATCH 17/69] Method to check chassis mod compatibility --- megamek/src/megamek/common/verifier/TestSupportVehicle.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index dc37a73b003..345c72789cb 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -229,6 +229,11 @@ public enum ChassisModification implements ITechnologyDelegator { this.smallOnly = smallOnly; } + public boolean isValidFor(Entity sv) { + return sv.isSupportVehicle() && allowedTypes.contains(SVType.getVehicleType(sv)) + && (!smallOnly || (sv.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT)); + } + @Override public ITechnology getTechSource() { return equipment; From 1dd4d575ccf5b9badcc9e6f4d3ae4d97f0ffabf3 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 1 May 2019 11:06:05 -0500 Subject: [PATCH 18/69] short names for sv chassis mods --- megamek/src/megamek/common/MiscType.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/megamek/src/megamek/common/MiscType.java b/megamek/src/megamek/common/MiscType.java index 68580b03969..c96f82a9e0b 100644 --- a/megamek/src/megamek/common/MiscType.java +++ b/megamek/src/megamek/common/MiscType.java @@ -10026,6 +10026,7 @@ public static MiscType createEnvironmentalSealedChassis() { MiscType misc = new MiscType(); misc.name = "Combat Vehicle Chassis Mod [Environmental Sealing]"; + misc.shortName = "Environmental Sealing"; misc.setInternalName("Environmental Sealed Chassis"); misc.addLookupName("EnvironmentalSealingChassisMod"); misc.tonnage = 0; @@ -10050,6 +10051,7 @@ public static MiscType createEnvironmentalSealedChassis() { public static MiscType createAmphibiousChassis() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Amphibious]"; + misc.shortName = "Amphibious"; misc.setInternalName("AmphibiousChassis"); misc.addLookupName("AmphibiousChassisMod"); misc.tonnage = 0; @@ -10072,6 +10074,7 @@ public static MiscType createArmoredChassis() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Armored Chassis]"; + misc.shortName = "Armored Chassis"; misc.setInternalName("Armored Chassis"); misc.addLookupName("ArmoredChassisMod"); misc.tonnage = 0; @@ -10095,6 +10098,7 @@ public static MiscType createBicycleModification() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Bicycle]"; + misc.shortName = "Bicycle"; misc.setInternalName("BicycleChassisMod"); misc.tonnage = 0; misc.criticals = 0; @@ -10116,6 +10120,7 @@ public static MiscType createConvertibleModification() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Convertible]"; + misc.shortName = "Convertible"; misc.setInternalName("ConvertibleChassisMod"); misc.tonnage = 0; misc.criticals = 0; @@ -10138,6 +10143,7 @@ public static MiscType createISSVDuneBuggyChassis() { // TODO this is Combat Vee, and SV combined chassis. Their really needs // to be two different chassis types. misc.name = "SV Chassis Mod [Dune Buggy]"; + misc.shortName = "Dune Buggy"; misc.setInternalName("ISSVDuneBuggyChassis"); misc.addLookupName("ISSVDuneBuggy"); misc.addLookupName("ClanSVDuneBuggyChassis"); @@ -10208,6 +10214,7 @@ public static MiscType createHydroFoilChassisModification() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [HydroFoil]"; + misc.shortName = "Hydrofoil"; misc.setInternalName("HydroFoilChassisMod"); misc.tonnage = 0; misc.criticals = 0; @@ -10229,6 +10236,7 @@ public static MiscType createMonocycleModification() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Monocycle]"; + misc.shortName = "Monocycle"; misc.setInternalName("MonocycleChassisMod"); misc.tonnage = 0; misc.criticals = 0; @@ -10249,6 +10257,7 @@ public static MiscType createMonocycleModification() { public static MiscType createISOffRoadChassis() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Off-Road]"; + misc.shortName = "Off-Road"; misc.setInternalName("ISOffRoadChassis"); misc.addLookupName("ISOffRoad"); misc.addLookupName("ClanOffRoadChassis"); @@ -10274,6 +10283,7 @@ public static MiscType createISOffRoadChassis() { public static MiscType createOmniChassisMod() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Omni]"; + misc.shortName = "Omni"; misc.setInternalName("OmniChassisMod"); misc.tonnage = 0; misc.criticals = 0; @@ -10296,6 +10306,7 @@ public static MiscType createOmniChassisMod() { public static MiscType createPropChassisModification() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Propeller-Driven]"; + misc.shortName = "Propeller-Driven"; misc.setInternalName("PropChassisMod"); misc.cost = 0; // Cost accounted as part of unit cost misc.tankslots = 0; @@ -10314,6 +10325,7 @@ public static MiscType createPropChassisModification() { public static MiscType createSnomobileChassis() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Snowmobile]"; + misc.shortName = "Snowmobile"; misc.setInternalName("SnowmobileChassis"); misc.addLookupName("SnowmobileChassisMod"); misc.cost = 0; // Cost accounted as part of unit cost @@ -10336,6 +10348,7 @@ public static MiscType createSnomobileChassis() { public static MiscType createSTOLChassisMod() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [STOL]"; + misc.shortName = "STOL"; misc.setInternalName("STOLChassisMod"); misc.tonnage = 0; misc.cost = 0; // Cost accounted as part of unit cost @@ -10355,6 +10368,7 @@ public static MiscType createSubmersibleChassisMod() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Submersible]"; + misc.shortName = "Submersible"; misc.setInternalName("SubmersibleChassisMod"); misc.tonnage = 0; misc.criticals = 0; @@ -10376,6 +10390,7 @@ public static MiscType createTractorModification() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Tractor]"; + misc.shortName = "Tractor"; misc.setInternalName(misc.name); misc.addLookupName("Tractor"); misc.addLookupName("TractorChassisMod"); @@ -10419,6 +10434,7 @@ public static MiscType createTrailerModification() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [Trailer]"; + misc.shortName = "Trailer"; misc.setInternalName(misc.name); misc.addLookupName("Trailer"); misc.addLookupName("TrailerChassisMod"); @@ -10441,6 +10457,7 @@ public static MiscType createTrailerModification() { public static MiscType createUltraLightChassisModification() { MiscType misc = new MiscType(); + misc.shortName = "Ultra-Light"; misc.name = "SV Chassis Mod [Ultra-Light]"; misc.setInternalName("UltraLightChassisMod"); misc.tankslots = 0; @@ -10459,6 +10476,7 @@ public static MiscType createUltraLightChassisModification() { public static MiscType createVSTOLChassisMod() { MiscType misc = new MiscType(); misc.name = "SV Chassis Mod [VSTOL]"; + misc.shortName = "VSTOL"; misc.setInternalName("VSTOLChassisMod"); misc.tonnage = 0; misc.cost = 0; // Cost accounted as part of unit cost From a953503e5f66ba643f15b2b3ee10f9525ce80b56 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 7 May 2019 13:52:27 -0500 Subject: [PATCH 19/69] Changed TestSupportVehicle#ChassisModification Added method to check compatibility with other chassis mods. --- .idea/compiler.xml | 2 + .idea/modules/megamek/megamek_main.iml | 3 +- .idea/modules/megamek/megamek_test.iml | 5 ++- .../common/verifier/TestSupportVehicle.java | 41 ++++++++++++++++++- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 4df4df5b364..b1d507daaf6 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -6,6 +6,8 @@ + + \ No newline at end of file diff --git a/.idea/modules/megamek/megamek_main.iml b/.idea/modules/megamek/megamek_main.iml index 150b3627daf..585c871a9e0 100644 --- a/.idea/modules/megamek/megamek_main.iml +++ b/.idea/modules/megamek/megamek_main.iml @@ -1,5 +1,5 @@ - + @@ -15,6 +15,7 @@ + diff --git a/.idea/modules/megamek/megamek_test.iml b/.idea/modules/megamek/megamek_test.iml index dc17e68f08f..43f21ccfbb8 100644 --- a/.idea/modules/megamek/megamek_test.iml +++ b/.idea/modules/megamek/megamek_test.iml @@ -1,5 +1,5 @@ - + @@ -13,11 +13,12 @@ + - + diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 345c72789cb..3a399c0ed98 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -229,11 +229,50 @@ public enum ChassisModification implements ITechnologyDelegator { this.smallOnly = smallOnly; } - public boolean isValidFor(Entity sv) { + /** + * Checks for compatibility with a support vehicle type and weight class + * + * @param sv The support vehicle + * @return Whether the mod is valid for the vehicle + */ + public boolean validFor(Entity sv) { return sv.isSupportVehicle() && allowedTypes.contains(SVType.getVehicleType(sv)) && (!smallOnly || (sv.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT)); } + /** + * Checks for compatibility between different chassis modifications + * + * @param other Another chassis mod + * @return Whether this chassis mod can be installed on the same vehicle as another mod. + */ + public boolean compatibleWith(ChassisModification other) { + switch (this) { + case ARMORED: + return other != ULTRA_LIGHT; + case ULTRA_LIGHT: + return other != ARMORED; + case BICYCLE: + return other != MONOCYCLE; + case MONOCYCLE: + return other != BICYCLE; + case SNOWMOBILE: + return other != DUNE_BUGGY + && other != AMPHIBIOUS + && other != OFFROAD; + case DUNE_BUGGY: + return other != SNOWMOBILE + && other != AMPHIBIOUS + && other != OFFROAD; + case AMPHIBIOUS: + case OFFROAD: + return other != SNOWMOBILE + && other != DUNE_BUGGY; + default: + return true; + } + } + @Override public ITechnology getTechSource() { return equipment; From cb2c3206433ae07cb6a1daa9e25bf074ff050092 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 8 May 2019 12:10:48 -0500 Subject: [PATCH 20/69] Slot calculations. --- .../src/megamek/common/verifier/TestSupportVehicle.java | 7 +++++++ .../megamek/common/weapons/infantry/InfantryWeapon.java | 1 + 2 files changed, 8 insertions(+) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 3a399c0ed98..22e225d6a81 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -710,6 +710,13 @@ public double getWeightArmor() { return roundWeight(weight); } + /** + * @return The total slot space + */ + public int totalSlotCount() { + return 5 + (int) Math.floor(supportVee.getWeight() / 10.0); + } + /** * @return The number of slots taken up by installed equipment */ diff --git a/megamek/src/megamek/common/weapons/infantry/InfantryWeapon.java b/megamek/src/megamek/common/weapons/infantry/InfantryWeapon.java index b15b6cef86d..c38ea8c8157 100644 --- a/megamek/src/megamek/common/weapons/infantry/InfantryWeapon.java +++ b/megamek/src/megamek/common/weapons/infantry/InfantryWeapon.java @@ -53,6 +53,7 @@ public InfantryWeapon() { tonnage = 0.0; criticals = 0; tankslots = 0; + svslots = 1; infantryDamage = 0; crew = 1; infantryRange = 0; From f4ef7d82a0a7a7f802b96310352e5de3e4d4aefe Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 8 May 2019 13:21:24 -0500 Subject: [PATCH 21/69] Override isSupportVehicle to return true for FixedWingSupport --- megamek/src/megamek/common/FixedWingSupport.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/megamek/src/megamek/common/FixedWingSupport.java b/megamek/src/megamek/common/FixedWingSupport.java index 6012802f896..96824abd0a2 100644 --- a/megamek/src/megamek/common/FixedWingSupport.java +++ b/megamek/src/megamek/common/FixedWingSupport.java @@ -89,6 +89,11 @@ public int locations() { return 6; } + @Override + public boolean isSupportVehicle() { + return true; + } + @Override public void autoSetSI() { initializeSI(getOriginalWalkMP()); From 732b91938b363b83b57407854b68db71feb130f4 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sat, 18 May 2019 12:29:49 -0500 Subject: [PATCH 22/69] Track base chassis fire control weight for omni support vehicles. Added base chassis turret weight processing to support vees and VTOLs. --- megamek/src/megamek/common/Entity.java | 24 +++++++++++++++++++ .../src/megamek/common/loaders/BLKFile.java | 5 ++++ .../loaders/BLKFixedWingSupportFile.java | 5 ++++ .../loaders/BLKLargeSupportTankFile.java | 17 +++++++++++++ .../common/loaders/BLKSupportTankFile.java | 18 ++++++++++---- .../common/loaders/BLKSupportVTOLFile.java | 13 ++++++++++ .../megamek/common/loaders/BLKTankFile.java | 4 ++++ .../megamek/common/loaders/BLKVTOLFile.java | 9 +++++++ 8 files changed, 91 insertions(+), 4 deletions(-) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index 195453788da..45902da21e1 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -219,6 +219,11 @@ public static enum WeaponSortOrder { * the engine and structural tech ratings match. */ protected int engineTechRating = USE_STRUCTURAL_RATING; + + /** + * Used by omni support vehicles to track the weight of optional fire control systems. + */ + private double baseChassisFireConWeight = 0.0; /** * Year to use calculating engine and control system weight and fuel efficiency for primitive * support vehicles and aerospace units. This needs to be tracked separately from intro year to @@ -14944,6 +14949,25 @@ public void setEngineTechRating(int engineTechRating) { this.engineTechRating = engineTechRating; } + /** + * Used by omni support vehicles to track the weight of fire control systems. + * This limits the tonnage that can be devoted to weapons in pods. + * + * @return The fixed weight of fire control systems. + */ + public double getBaseChassisFireConWeight() { + return baseChassisFireConWeight; + } + + /** + * Used by omni support vehicles to set the weight of fixed fire control systems in the base chassis. + * + * @param weight The weight of fixed fire control systems. + */ + public void setBaseChassisFireConWeight(double weight) { + baseChassisFireConWeight = weight; + } + /** * Units with construction data that varies by year (such as engine and control system weight * for some primitive aerospace units) require tracking the original build year separately diff --git a/megamek/src/megamek/common/loaders/BLKFile.java b/megamek/src/megamek/common/loaders/BLKFile.java index f4647e58555..15aef0da292 100644 --- a/megamek/src/megamek/common/loaders/BLKFile.java +++ b/megamek/src/megamek/common/loaders/BLKFile.java @@ -887,6 +887,11 @@ public static BuildingBlock getBlock(Entity t) { } } + if (t.isSupportVehicle() && t.isOmni()) { + blk.writeBlockData("baseChassisFireConWeight", + t.getBaseChassisFireConWeight()); + } + if (t instanceof Tank) { Tank tank = (Tank) t; if (tank.hasNoControlSystems()) { diff --git a/megamek/src/megamek/common/loaders/BLKFixedWingSupportFile.java b/megamek/src/megamek/common/loaders/BLKFixedWingSupportFile.java index 22f39473672..f9bfc65eb82 100644 --- a/megamek/src/megamek/common/loaders/BLKFixedWingSupportFile.java +++ b/megamek/src/megamek/common/loaders/BLKFixedWingSupportFile.java @@ -194,6 +194,11 @@ public Entity getEntity() throws EntityLoadingException { // support vees need equipment for this a.autoSetMaxBombPoints(); a.setArmorTonnage(a.getArmorWeight()); + + if (dataFile.exists("baseChassisFireConWeight")) { + a.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); + } + return a; } diff --git a/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java b/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java index 36374a758d1..e356eeb453b 100644 --- a/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java @@ -187,6 +187,23 @@ public Entity getEntity() throws EntityLoadingException { t.setOmni(true); } t.setArmorTonnage(t.getArmorWeight()); + + if (dataFile.exists("baseChassisTurretWeight")) { + t.setBaseChassisTurretWeight(dataFile.getDataAsDouble("baseChassisTurretWeight")[0]); + } + + if (dataFile.exists("baseChassisTurret2Weight")) { + t.setBaseChassisTurret2Weight(dataFile.getDataAsDouble("baseChassisTurret2Weight")[0]); + } + + if (dataFile.exists("hasNoControlSystems")) { + t.setHasNoControlSystems(true); + } + + if (dataFile.exists("baseChassisFireConWeight")) { + t.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); + } + return t; } } diff --git a/megamek/src/megamek/common/loaders/BLKSupportTankFile.java b/megamek/src/megamek/common/loaders/BLKSupportTankFile.java index 283443ce86f..7936d635b77 100644 --- a/megamek/src/megamek/common/loaders/BLKSupportTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKSupportTankFile.java @@ -16,9 +16,6 @@ * BLkFile.java * * Created on April 6, 2002, 2:06 AM - */ - -/** * * @author njrkrynn * @version @@ -139,7 +136,7 @@ public Entity getEntity() throws EntityLoadingException { int[] armor = dataFile.getDataAsInt("armor"); - if ((armor.length < 4) || (armor.length > 5)) { + if ((armor.length < 4) || (armor.length > 6)) { throw new EntityLoadingException("Incorrect armor array length"); } @@ -188,6 +185,19 @@ public Entity getEntity() throws EntityLoadingException { t.setOmni(true); } t.setArmorTonnage(t.getArmorWeight()); + + if (dataFile.exists("baseChassisTurretWeight")) { + t.setBaseChassisTurretWeight(dataFile.getDataAsDouble("baseChassisTurretWeight")[0]); + } + + if (dataFile.exists("baseChassisTurret2Weight")) { + t.setBaseChassisTurret2Weight(dataFile.getDataAsDouble("baseChassisTurret2Weight")[0]); + } + + if (dataFile.exists("baseChassisFireConWeight")) { + t.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); + } + return t; } } diff --git a/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java b/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java index 600da204779..c11e35d6135 100644 --- a/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java +++ b/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java @@ -179,6 +179,19 @@ public Entity getEntity() throws EntityLoadingException { t.setOmni(true); } t.setArmorTonnage(t.getArmorWeight()); + + if (dataFile.exists("baseChassisTurretWeight")) { + t.setBaseChassisTurretWeight(dataFile.getDataAsDouble("baseChassisTurretWeight")[0]); + } + + if (dataFile.exists("hasNoControlSystems")) { + t.setHasNoControlSystems(true); + } + + if (dataFile.exists("baseChassisFireConWeight")) { + t.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); + } + return t; } diff --git a/megamek/src/megamek/common/loaders/BLKTankFile.java b/megamek/src/megamek/common/loaders/BLKTankFile.java index 908b44bcb70..b6cc9308296 100644 --- a/megamek/src/megamek/common/loaders/BLKTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKTankFile.java @@ -239,6 +239,10 @@ public Entity getEntity() throws EntityLoadingException { t.setHasNoControlSystems(true); } + if (dataFile.exists("baseChassisFireConWeight")) { + t.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); + } + return t; } } diff --git a/megamek/src/megamek/common/loaders/BLKVTOLFile.java b/megamek/src/megamek/common/loaders/BLKVTOLFile.java index e5441cb80db..aae186b4048 100644 --- a/megamek/src/megamek/common/loaders/BLKVTOLFile.java +++ b/megamek/src/megamek/common/loaders/BLKVTOLFile.java @@ -149,6 +149,15 @@ public Entity getEntity() throws EntityLoadingException { t.setOmni(true); } t.setArmorTonnage(t.getArmorWeight()); + + if (dataFile.exists("baseChassisTurretWeight")) { + t.setBaseChassisTurretWeight(dataFile.getDataAsDouble("baseChassisTurretWeight")[0]); + } + + if (dataFile.exists("baseChassisFireConWeight")) { + t.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); + } + return t; } } From 7f495d718988ec34fc975985f22804c3153d1044 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sat, 25 May 2019 14:51:53 -0500 Subject: [PATCH 23/69] Advanced armor filtering for support vees. --- megamek/src/megamek/common/MiscType.java | 22 ++++++---- .../megamek/common/verifier/TestEntity.java | 2 + .../common/verifier/TestSupportVehicle.java | 42 +++++++++++++++++-- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/megamek/src/megamek/common/MiscType.java b/megamek/src/megamek/common/MiscType.java index c96f82a9e0b..3926a057883 100644 --- a/megamek/src/megamek/common/MiscType.java +++ b/megamek/src/megamek/common/MiscType.java @@ -2486,7 +2486,8 @@ public static MiscType createStandard() { misc.addLookupName("IS Standard Armor"); misc.addLookupName("Clan Standard Armor"); misc.flags = misc.flags.or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT) - .or(F_VTOL_EQUIPMENT).or(F_FIGHTER_EQUIPMENT).or(F_PROTOMECH_EQUIPMENT); + .or(F_VTOL_EQUIPMENT).or(F_FIGHTER_EQUIPMENT).or(F_PROTOMECH_EQUIPMENT) + .or(F_SUPPORT_TANK_EQUIPMENT); misc.criticals = 0; misc.techAdvancement.setTechBase(TECH_BASE_ALL); @@ -2528,7 +2529,7 @@ public static MiscType createAntiPenetrativeAblation() { misc.hittable = false; misc.spreadable = true; misc.flags = misc.flags.or(F_ANTI_PENETRATIVE_ABLATIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT) - .or(F_VTOL_EQUIPMENT).or(F_FIGHTER_EQUIPMENT); + .or(F_VTOL_EQUIPMENT).or(F_FIGHTER_EQUIPMENT).or(F_SUPPORT_TANK_EQUIPMENT); misc.omniFixedOnly = true; misc.bv = 0; misc.rulesRefs = "86,IO"; @@ -2549,7 +2550,7 @@ public static MiscType createISBallisticReinforced() { misc.hittable = false; misc.spreadable = true; misc.flags = misc.flags.or(F_BALLISTIC_REINFORCED).or(F_MECH_EQUIPMENT).or(F_FIGHTER_EQUIPMENT) - .or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT); + .or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT).or(F_SUPPORT_TANK_EQUIPMENT); misc.omniFixedOnly = true; misc.bv = 0; misc.rulesRefs = "87,IO"; @@ -2876,7 +2877,8 @@ public static MiscType createISReflective() { misc.criticals = CRITICALS_VARIABLE; misc.hittable = false; misc.spreadable = true; - misc.flags = misc.flags.or(F_REFLECTIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT); + misc.flags = misc.flags.or(F_REFLECTIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT) + .or(F_SUPPORT_TANK_EQUIPMENT); misc.omniFixedOnly = true; misc.bv = 0; misc.rulesRefs = "280,TO"; @@ -2899,7 +2901,8 @@ public static MiscType createCLReflective() { misc.criticals = CRITICALS_VARIABLE; misc.hittable = false; misc.spreadable = true; - misc.flags = misc.flags.or(F_REFLECTIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT); + misc.flags = misc.flags.or(F_REFLECTIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT) + .or(F_SUPPORT_TANK_EQUIPMENT); misc.omniFixedOnly = true; misc.bv = 0; misc.rulesRefs = "280,TO"; @@ -2950,7 +2953,8 @@ public static MiscType createISReactive() { misc.criticals = CRITICALS_VARIABLE; misc.spreadable = true; misc.hittable = false; - misc.flags = misc.flags.or(F_REACTIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT); + misc.flags = misc.flags.or(F_REACTIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT) + .or(F_SUPPORT_TANK_EQUIPMENT); misc.omniFixedOnly = true; misc.bv = 0; misc.rulesRefs = "282,TO"; @@ -2973,7 +2977,8 @@ public static MiscType createCLReactive() { misc.criticals = CRITICALS_VARIABLE; misc.spreadable = true; misc.hittable = false; - misc.flags = misc.flags.or(F_REACTIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT); + misc.flags = misc.flags.or(F_REACTIVE).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT) + .or(F_SUPPORT_TANK_EQUIPMENT); misc.omniFixedOnly = true; misc.bv = 0; misc.rulesRefs = "282,TO"; @@ -3025,7 +3030,8 @@ public static MiscType createVehicularStealth() { misc.tankslots = 1; misc.hittable = false; misc.spreadable = true; - misc.flags = misc.flags.or(F_STEALTH).or(F_TANK_EQUIPMENT).or(F_FIGHTER_EQUIPMENT).or(F_VTOL_EQUIPMENT); + misc.flags = misc.flags.or(F_STEALTH).or(F_TANK_EQUIPMENT).or(F_FIGHTER_EQUIPMENT).or(F_VTOL_EQUIPMENT) + .or(F_SUPPORT_TANK_EQUIPMENT); misc.omniFixedOnly = true; String[] saModes = { "Off", "On" }; misc.setModes(saModes); diff --git a/megamek/src/megamek/common/verifier/TestEntity.java b/megamek/src/megamek/common/verifier/TestEntity.java index 12a10e371d5..e67fd7aa07b 100755 --- a/megamek/src/megamek/common/verifier/TestEntity.java +++ b/megamek/src/megamek/common/verifier/TestEntity.java @@ -311,6 +311,8 @@ public static List legalArmorsFor(long etype, boolean industrial, return TestSmallCraft.legalArmorsFor(techManager); } else if ((etype & Entity.ETYPE_JUMPSHIP) != 0) { return TestAdvancedAerospace.legalArmorsFor(techManager); + } else if ((etype & (Entity.ETYPE_FIXED_WING_SUPPORT | Entity.ETYPE_SUPPORT_TANK | Entity.ETYPE_SUPPORT_VTOL)) != 0) { + return TestSupportVehicle.legalArmorsFor(techManager); } else if ((etype & Entity.ETYPE_AERO) != 0) { return TestAero.legalArmorsFor(techManager); } else if ((etype & Entity.ETYPE_TANK) != 0) { diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 22e225d6a81..d42dce9562a 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -22,9 +22,7 @@ import megamek.common.weapons.lasers.CLChemicalLaserWeapon; import java.math.BigInteger; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.Set; +import java.util.*; /** * Author: arlith @@ -433,7 +431,43 @@ public ITechnology getTechSource() { {.000, .000, .056, .045, .040, .037}, {.000, .000, .000, .051, .045, .042}, {.000, .000, .000, .057, .051, .047}, - {.000, .000, .000, .063, .056, .052},}; + {.000, .000, .000, .063, .056, .052}}; + + /** + * Filters all vehicle armor according to given tech constraints. Standard armor is treated as basic + * support vehicle armor. + * + * @param techManager + * @return + */ + public static List legalArmorsFor(ITechManager techManager) { + if (techManager.getTechLevel().ordinal() < SimpleTechLevel.ADVANCED.ordinal()) { + return Collections.singletonList(EquipmentType.get(EquipmentType.armorNames[EquipmentType.T_ARMOR_STANDARD])); + } + List retVal = new ArrayList<>(); + for (int at = 0; at < EquipmentType.armorNames.length; at++) { + if (at == EquipmentType.T_ARMOR_PATCHWORK) { + continue; + } + String name = EquipmentType.getArmorTypeName(at, techManager.useClanTechBase()); + EquipmentType eq = EquipmentType.get(name); + if ((null != eq) + && eq.hasFlag(MiscType.F_SUPPORT_TANK_EQUIPMENT) + && techManager.isLegal(eq)) { + retVal.add(eq); + } + if (techManager.useMixedTech()) { + name = EquipmentType.getArmorTypeName(at, !techManager.useClanTechBase()); + EquipmentType eq2 = EquipmentType.get(name); + if ((null != eq2) && (eq != eq2) + && eq2.hasFlag(MiscType.F_SUPPORT_TANK_EQUIPMENT) + && techManager.isLegal(eq2)) { + retVal.add(eq2); + } + } + } + return retVal; + } private final Entity supportVee; /** Used by support tanks for calculation of turret weight */ From f3346b4541ee571f66436ba2ff996be5b7f29dc3 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sun, 26 May 2019 22:14:14 -0500 Subject: [PATCH 24/69] Support vee armor calculation convenience methods. --- megamek/src/megamek/common/Entity.java | 6 ++ .../src/megamek/common/FixedWingSupport.java | 1 + megamek/src/megamek/common/SupportTank.java | 1 + megamek/src/megamek/common/SupportVTOL.java | 1 + .../common/verifier/TestSupportVehicle.java | 58 +++++++++++++++++++ 5 files changed, 67 insertions(+) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index 45902da21e1..cfc5dcaf51e 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -12553,6 +12553,12 @@ public boolean hasBARArmor(int loc) { return getBARRating(loc) < 10; } + /** + * Sets the barrier armor rating for support vehicles. Has no effect on other unit types. + * @param rating + */ + public void setBARRating(int rating) {} + /** * does this entity have an armored chassis? * diff --git a/megamek/src/megamek/common/FixedWingSupport.java b/megamek/src/megamek/common/FixedWingSupport.java index 96824abd0a2..b162f83e928 100644 --- a/megamek/src/megamek/common/FixedWingSupport.java +++ b/megamek/src/megamek/common/FixedWingSupport.java @@ -48,6 +48,7 @@ public void setBARRating(int rating, int loc) { barRating[loc] = rating; } + @Override public void setBARRating(int rating) { for (int i = 0; i < locations(); i++) { barRating[i] = rating; diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index 964d2b1078e..b491fb49273 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -41,6 +41,7 @@ public void setBARRating(int rating, int loc) { barRating[loc] = rating; } + @Override public void setBARRating(int rating) { for (int i = 0; i < locations(); i++) { barRating[i] = rating; diff --git a/megamek/src/megamek/common/SupportVTOL.java b/megamek/src/megamek/common/SupportVTOL.java index 650a69abcbd..a781e0223da 100644 --- a/megamek/src/megamek/common/SupportVTOL.java +++ b/megamek/src/megamek/common/SupportVTOL.java @@ -36,6 +36,7 @@ public void setBARRating(int rating, int loc) { barRating[loc] = rating; } + @Override public void setBARRating(int rating) { for (int i = 0; i < locations(); i++) { barRating[i] = rating; diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index d42dce9562a..681f90970b4 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -469,6 +469,64 @@ public static List legalArmorsFor(ITechManager techManager) { return retVal; } + /** + * The maximum number of armor points a support vehicle is computed by multiplying the total tonnage by a factor + * determined by the vehicle type and adding four. + * + * @param vee The support vehicle + * @return The maximum number of armor points. If the entity cannot be identified as a support vehicle, returns 0. + */ + public static int maxArmorFactor(Entity vee) { + SVType type = SVType.getVehicleType(vee); + if (null == type) { + return 0; + } + double factor = 0; + switch (type) { + case AIRSHIP: + case NAVAL: + if (vee.getWeightClass() == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + factor = 0.05; + } else { + factor = 0.334; + } + break; + case WIGE: + case RAIL: + case SATELLITE: + factor = 0.5; + break; + case FIXED_WING: + case HOVERCRAFT: + case VTOL: + factor = 1.0; + break; + case TRACKED: + case WHEELED: + factor = 2.0; + break; + } + return 4 + (int) (vee.getWeight() * factor); + } + + /** + * Calculates the weight of each point of armor. For standard SV armor this is based on the tech and BAR + * ratings. For advanced armors this is the reciprocal of the number of points per ton. + * + * @param vee The support vehicle + * @return The weight of each armor point in tons, rounded to the kilogram. + */ + public static double armorWeightPerPoint(Entity vee) { + final int at = vee.getArmorType(vee.firstArmorIndex()); + if (at == EquipmentType.T_ARMOR_STANDARD) { + return SV_ARMOR_WEIGHT[vee.getBARRating(vee.firstArmorIndex())][vee.getArmorTechRating()]; + } else { + final double ppt = 16.0 * EquipmentType.getArmorPointMultiplier( + at, vee.getArmorTechLevel(vee.firstArmorIndex())); + return round(1.0 / ppt, Ceil.KILO); + } + } + private final Entity supportVee; /** Used by support tanks for calculation of turret weight */ private final TestTank testTank; From 12d2153c620f0781eb91a9a6e620cd89310b381f Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 28 May 2019 13:56:46 -0500 Subject: [PATCH 25/69] Calculate support vee armor weight correctly on load. Moved SV armor weights from TestSupportVehicle to EquipmentType to avoid circular dependency between megamek.common and megamek.common.verifier. --- megamek/src/megamek/common/Entity.java | 9 +++++ megamek/src/megamek/common/EquipmentType.java | 35 +++++++++++++++++++ megamek/src/megamek/common/SupportTank.java | 9 +++++ .../common/verifier/TestSupportVehicle.java | 22 ++---------- 4 files changed, 56 insertions(+), 19 deletions(-) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index cfc5dcaf51e..ec847e2935b 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -10643,6 +10643,15 @@ public double getArmorWeight() { double armorWeight = points / armorPerTon; armorWeight = Math.ceil(armorWeight * 2.0) / 2.0; return armorWeight; + } else if (isSupportVehicle() + && getArmorType(firstArmorIndex()) == EquipmentType.T_ARMOR_STANDARD) { + double total = getTotalOArmor() + * EquipmentType.getSupportVehicleArmorWeightPerPoint(getBARRating(firstArmorIndex()), getArmorTechRating()); + if (getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT) { + return Math.round(total * 1000.0) / 1000.0; + } else { + return Math.ceil(total * 2.0) / 2.0; + } } else { double total = 0; for (int loc = 0; loc < locations(); loc++) { diff --git a/megamek/src/megamek/common/EquipmentType.java b/megamek/src/megamek/common/EquipmentType.java index 3da8c335a16..1019c97ba59 100644 --- a/megamek/src/megamek/common/EquipmentType.java +++ b/megamek/src/megamek/common/EquipmentType.java @@ -30,11 +30,14 @@ import megamek.common.options.GameOptions; import megamek.common.weapons.autocannons.HVACWeapon; +import megamek.common.weapons.bayweapons.MMLBayWeapon; import megamek.common.weapons.defensivepods.BPodWeapon; import megamek.common.weapons.defensivepods.MPodWeapon; import megamek.common.weapons.ppc.PPCWeapon; import megamek.server.Server; +import javax.print.attribute.SupportedValuesAttribute; + /** * Represents any type of equipment mounted on a mechs, excluding systems and * actuators. @@ -802,6 +805,38 @@ public static double getProtomechArmorWeightPerPoint(int type) { } return 0.05; } + + /** + * Gives the weight of a single point of armor at a particular BAR for a + * given tech level. + */ + private static final double[][] SV_ARMOR_WEIGHT = + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {.040, .025, .016, .013, .012, .011}, + {.060, .038, .024, .019, .017, .016}, + {.000, .050, .032, .026, .023, .021}, + {.000, .063, .040, .032, .028, .026}, + {.000, .000, .048, .038, .034, .032}, + {.000, .000, .056, .045, .040, .037}, + {.000, .000, .000, .051, .045, .042}, + {.000, .000, .000, .057, .051, .047}, + {.000, .000, .000, .063, .056, .052}}; + + /** + * `Lookup method for the weight of a point of support vehicle armor. + * + * @param bar The armor's barrier armor rating + * @param techRating The armor's tech rating (0-5 corresponds to A-F) + * @return The weight of a point of armor in tons. Returns 0.0 for invalid value. + */ + public static double getSupportVehicleArmorWeightPerPoint(int bar, int techRating) { + if ((bar >= 0) && (techRating >= 0) + && (bar < SV_ARMOR_WEIGHT.length) && (techRating < SV_ARMOR_WEIGHT[bar].length)) { + return SV_ARMOR_WEIGHT[bar][techRating]; + } + return 0.0; + } /* Armor and structure are stored as integers and standard uses a generic MiscType that * does not have its own TechAdvancement. diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index b491fb49273..048175909a8 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -69,6 +69,15 @@ public boolean hasBARArmor(int loc) { return true; } + @Override + public double getArmorWeight() { + if (!hasPatchworkArmor() && getArmorType(firstArmorIndex()) == EquipmentType.T_ARMOR_STANDARD) { + return getTotalOArmor() + * EquipmentType.getSupportVehicleArmorWeightPerPoint(getBARRating(firstArmorIndex()), getArmorTechRating()); + } + return super.getArmorWeight(); + } + /* * (non-Javadoc) * diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 681f90970b4..635bf0bc450 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -416,23 +416,6 @@ public ITechnology getTechSource() { 1.6, 1.3, 1.15, 1.0, 0.85, 0.66 }; - /** - * Gives the weight of a single point of armor at a particular BAR for a - * given tech level. - */ - public static final double[][] SV_ARMOR_WEIGHT = - {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {.040, .025, .016, .013, .012, .011}, - {.060, .038, .024, .019, .017, .016}, - {.000, .050, .032, .026, .023, .021}, - {.000, .063, .040, .032, .028, .026}, - {.000, .000, .048, .038, .034, .032}, - {.000, .000, .056, .045, .040, .037}, - {.000, .000, .000, .051, .045, .042}, - {.000, .000, .000, .057, .051, .047}, - {.000, .000, .000, .063, .056, .052}}; - /** * Filters all vehicle armor according to given tech constraints. Standard armor is treated as basic * support vehicle armor. @@ -519,7 +502,8 @@ public static int maxArmorFactor(Entity vee) { public static double armorWeightPerPoint(Entity vee) { final int at = vee.getArmorType(vee.firstArmorIndex()); if (at == EquipmentType.T_ARMOR_STANDARD) { - return SV_ARMOR_WEIGHT[vee.getBARRating(vee.firstArmorIndex())][vee.getArmorTechRating()]; + return EquipmentType.getSupportVehicleArmorWeightPerPoint(vee.getBARRating(vee.firstArmorIndex()), + vee.getArmorTechRating()); } else { final double ppt = 16.0 * EquipmentType.getArmorPointMultiplier( at, vee.getArmorTechLevel(vee.firstArmorIndex())); @@ -798,7 +782,7 @@ public double getWeightArmor() { } int bar = getEntity().getBARRating(supportVee.firstArmorIndex()); int techRating = getEntity().getArmorTechRating(); - double weight = totalArmorPoints * SV_ARMOR_WEIGHT[bar][techRating]; + double weight = totalArmorPoints * EquipmentType.getSupportVehicleArmorWeightPerPoint(bar, techRating); return roundWeight(weight); } From 83702f3933af6461eff0e751cda68f6ca27aba4b Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 28 May 2019 14:24:26 -0500 Subject: [PATCH 26/69] Cleanup in TestSupportVehicle advanced armors. --- .../common/verifier/TestSupportVehicle.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 635bf0bc450..44498387ff5 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -811,9 +811,9 @@ public int getArmorSlots() { // Support vehicle armor takes slots like ferro-fibrous at BAR 10/TL E/F if (supportVee.getBARRating(supportVee.firstArmorIndex()) == 10) { if (supportVee.getArmorTechRating() == ITechnology.RATING_E) { - return 2; // IS FF + return AdvancedSVArmor.FERRO_FIBROUS.space; } else if (supportVee.getArmorTechRating() == ITechnology.RATING_F) { - return 1; // Clan FF + return AdvancedSVArmor.CLAN_FERRO_FIBROUS.space; } } return 0; @@ -953,23 +953,19 @@ public enum AdvancedSVArmor { public final EquipmentType eqType; /** - * The number of spaces occupied by the armor type. Armors that take - * up 1 space take up space in the aft, those with 2 take up space in - * each wing, 3 takes up space in both wings and the aft, 4 takes up - * space in each possible arc (nose, aft, left wing, right wing). + * The number of spaces occupied by the armor type. */ public final int space; /** - * The number of weapon spaces occupied by patchwork armor. Unlike standard armor, patchwork - * armor takes up slots in the location where it's used. + * The number of weapon spaces occupied by patchwork armor. */ public final int patchworkSpace; /** * Denotes whether this armor is Clan or not. */ - public boolean isClan; + public final boolean isClan; AdvancedSVArmor(int at, int space, int patchworkSpace, boolean clan){ this.armorType = at; @@ -980,12 +976,12 @@ public enum AdvancedSVArmor { } /** - * Given an armor type, return the AeroArmor instance that + * Given an armor type, return the AdvancedSVArmor instance that * represents that type. * * @param at The armor type. * @param c Whether this armor type is Clan or not. - * @return The AeroArmor that correspondes to the given + * @return The AdvancedSVArmor that correspondes to the given * type or null if no match was found. */ public static @Nullable AdvancedSVArmor getArmor(int at, boolean c){ From 4542135fd8e380c3e59caf0bd725932902080e9b Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 28 May 2019 14:31:23 -0500 Subject: [PATCH 27/69] Fixed logic in calculating armor weight. --- megamek/src/megamek/common/Entity.java | 34 +++++++++++-------- megamek/src/megamek/common/SupportTank.java | 9 ----- .../common/verifier/TestSupportVehicle.java | 13 +------ 3 files changed, 21 insertions(+), 35 deletions(-) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index ec847e2935b..156d03fcb19 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -10634,15 +10634,12 @@ public double getArmorWeight(int loc) { * @return The armor weight in tons. */ public double getArmorWeight() { - if (!hasPatchworkArmor()) { - // this roundabout method is actually necessary to avoid rounding - // weirdness. Yeah, it's dumb. - double armorPerTon = 16.0 * EquipmentType.getArmorPointMultiplier( - armorType[0], armorTechLevel[0]); - double points = getTotalOArmor(); - double armorWeight = points / armorPerTon; - armorWeight = Math.ceil(armorWeight * 2.0) / 2.0; - return armorWeight; + if (hasPatchworkArmor()) { + double total = 0; + for (int loc = 0; loc < locations(); loc++) { + total += getArmorWeight(loc); + } + return Math.ceil(total * 2.0) / 2.0; } else if (isSupportVehicle() && getArmorType(firstArmorIndex()) == EquipmentType.T_ARMOR_STANDARD) { double total = getTotalOArmor() @@ -10653,11 +10650,14 @@ && getArmorType(firstArmorIndex()) == EquipmentType.T_ARMOR_STANDARD) { return Math.ceil(total * 2.0) / 2.0; } } else { - double total = 0; - for (int loc = 0; loc < locations(); loc++) { - total += getArmorWeight(loc); - } - return Math.ceil(total * 2.0) / 2.0; + // this roundabout method is actually necessary to avoid rounding + // weirdness. Yeah, it's dumb. + double armorPerTon = 16.0 * EquipmentType.getArmorPointMultiplier( + armorType[0], armorTechLevel[0]); + double points = getTotalOArmor(); + double armorWeight = points / armorPerTon; + armorWeight = Math.ceil(armorWeight * 2.0) / 2.0; + return armorWeight; } } @@ -14379,6 +14379,12 @@ public double getLabArmorTonnage() { } public int getLabTotalArmorPoints() { + if (isSupportVehicle() && (getArmorType(firstArmorIndex()) == EquipmentType.T_ARMOR_STANDARD) + && !hasPatchworkArmor()) { + return (int) Math.floor(armorTonnage + / EquipmentType.getSupportVehicleArmorWeightPerPoint(getBARRating(firstArmorIndex()), + getArmorTechRating())); + } double armorPerTon = 16.0 * EquipmentType.getArmorPointMultiplier( armorType[0], armorTechLevel[0]); return (int) Math.floor(armorPerTon * armorTonnage); diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index 048175909a8..b491fb49273 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -69,15 +69,6 @@ public boolean hasBARArmor(int loc) { return true; } - @Override - public double getArmorWeight() { - if (!hasPatchworkArmor() && getArmorType(firstArmorIndex()) == EquipmentType.T_ARMOR_STANDARD) { - return getTotalOArmor() - * EquipmentType.getSupportVehicleArmorWeightPerPoint(getBARRating(firstArmorIndex()), getArmorTechRating()); - } - return super.getArmorWeight(); - } - /* * (non-Javadoc) * diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 44498387ff5..2530b741d7a 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -772,18 +772,7 @@ public String getName() { @Override public double getWeightArmor() { - if (supportVee.hasPatchworkArmor() - || (supportVee.getArmorType(supportVee.firstArmorIndex()) != EquipmentType.T_ARMOR_STANDARD)) { - return super.getWeightArmor(); - } - int totalArmorPoints = 0; - for (int loc = 0; loc < getEntity().locations(); loc++) { - totalArmorPoints += getEntity().getOArmor(loc); - } - int bar = getEntity().getBARRating(supportVee.firstArmorIndex()); - int techRating = getEntity().getArmorTechRating(); - double weight = totalArmorPoints * EquipmentType.getSupportVehicleArmorWeightPerPoint(bar, techRating); - return roundWeight(weight); + return supportVee.getLabArmorTonnage(); } /** From ae3216b97c83ae41b86e0983d8cf4d74ea1be56f Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Thu, 30 May 2019 21:20:32 -0500 Subject: [PATCH 28/69] Added support vehicle crew calculations. --- megamek/src/megamek/common/Compute.java | 111 +++++++++++++++++- .../common/verifier/TestSupportVehicle.java | 2 +- 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/megamek/src/megamek/common/Compute.java b/megamek/src/megamek/common/Compute.java index dd9bd26b0e9..8967cede43d 100644 --- a/megamek/src/megamek/common/Compute.java +++ b/megamek/src/megamek/common/Compute.java @@ -6803,6 +6803,8 @@ public static int getTotalGunnerNeeds(Entity entity) { } } return nCapitalW + (int) Math.ceil(nStandardW / 6.0); + } else if (entity.isSupportVehicle()) { + return getSupportVehicleGunnerNeeds(entity); } else if (entity instanceof Tank) { return (getFullCrewSize(entity) - 1); } else if (entity instanceof Infantry) { @@ -6832,9 +6834,116 @@ public static int getAeroCrewNeeds(Entity entity) { return 0; } + /** + * Calculates the base crew requirements for support vehicles. + * + * @param entity The support vehicle + * @return The minimum base crew + */ + public static int getSVBaseCrewNeeds(Entity entity) { + final boolean naval = entity.getMovementMode().equals(EntityMovementMode.NAVAL) + || entity.getMovementMode().equals(EntityMovementMode.HYDROFOIL) + || entity.getMovementMode().equals(EntityMovementMode.SUBMARINE); + int crew; + if (entity.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT) { + crew = 1; + } else if (entity.getWeightClass() == EntityWeightClass.WEIGHT_MEDIUM_SUPPORT) { + if (naval || entity.getMovementMode().equals(EntityMovementMode.AIRSHIP)) { + crew = 4; + } else { + crew = 2; + } + } else { + crew = 3; + if (naval) { + crew += (int) Math.ceil(entity.getWeight() / 5000); + } else if (entity.getMovementMode().equals(EntityMovementMode.AIRSHIP)) { + crew += (int) Math.ceil(entity.getWeight() / 500); + } + } + return crew; + } + + /** + * Calculates number of gunners required for a support vehicle. See TM, 131. + * + * @param entity The support vehicle + * @return The number of gunners required. + */ + public static int getSupportVehicleGunnerNeeds(Entity entity) { + final boolean advFireCon = entity.hasMisc(MiscType.F_ADVANCED_FIRECONTROL); + final boolean basicFireCon = !advFireCon && entity.hasMisc(MiscType.F_BASIC_FIRECONTROL); + if (entity.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT) { + if (!advFireCon && !basicFireCon) { + // No fire control requires one gunner per weapon. + return entity.getWeaponList().size(); + } else { + // Otherwise we require one gunner per facing, with turrets and pintle mounts counting + // as separate facings + Set facings = new HashSet<>(); + int pintles = 0; + for (Mounted m : entity.getWeaponList()) { + if (m.isPintleTurretMounted()) { + pintles++; + } else { + facings.add(m.getLocation()); + } + } + if (advFireCon) { + // Advanced fire control lets the driver count as a gunner, so one fewer dedicated gunners is needed. + return Math.max(0, pintles + facings.size() - 1); + } else { + return pintles + facings.size(); + } + } + } else { + // Medium and large support vehicle gunner requirements are based on weapon tonnage + double tonnage = entity.getWeaponList().stream().filter(m -> !m.getType().hasFlag(WeaponType.F_AMS)) + .mapToDouble(m -> m.getType().getTonnage(entity)).sum(); + if (advFireCon) { + return (int) Math.ceil(tonnage / 4.0); + } else if (basicFireCon) { + return (int) Math.ceil(tonnage / 3.0); + } else { + return (int) Math.ceil(tonnage / 2.0); + } + } + } + + /** + * Calculates addiontal crew required by support vehicles and advanced aerospace vessels + * for certain misc equipment. + * + * @param entity The unit + * @return The number of additional crew required + */ + public static int getAdditionalNonGunner(Entity entity) { + int crew = 0; + for (Mounted m : entity.getMisc()) { + if (m.getType().hasFlag(MiscType.F_COMMUNICATIONS)) { + crew += (int) m.getType().getTonnage(entity); + } else if (m.getType().hasFlag(MiscType.F_FIELD_KITCHEN)) { + crew += 3; + } else if (m.getType().hasFlag(MiscType.F_MASH) + || m.getType().hasFlag(MiscType.F_MASH_EXTRA) + || m.getType().hasFlag(MiscType.F_MOBILE_FIELD_BASE)) { + crew += 5; + } + } + return crew; + } + // Taken from MekHQ, assumptions are whatever Taharqa made for there - Dylan public static int getFullCrewSize(Entity entity) { - if (entity instanceof Tank) { + if (entity.isSupportVehicle()) { + int crew = getSVBaseCrewNeeds(entity) + getSupportVehicleGunnerNeeds(entity) + + getAdditionalNonGunner(entity); + // Add officers. Older editions of the rules give the officer ratio as 1:6 and 4 as the threshold to require officers + if (crew < 5) { + return crew; + } + return (int) Math.ceil(crew * 1.2); + } else if (entity instanceof Tank) { return (int) Math.ceil(entity.getWeight() / 15.0); } else if (entity instanceof BattleArmor) { int ntroopers = 0; diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 2530b741d7a..cb4833d47f0 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -772,7 +772,7 @@ public String getName() { @Override public double getWeightArmor() { - return supportVee.getLabArmorTonnage(); + return supportVee.getArmorWeight(); } /** From 5d0e22b4cbd434eafc45349abf4b8c999b561ae3 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 10 Jun 2019 18:56:34 -0500 Subject: [PATCH 29/69] Fixed chassis mod lookup test. --- .../megamek/common/verifier/TestSupportVehicleTest.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/megamek/unittests/megamek/common/verifier/TestSupportVehicleTest.java b/megamek/unittests/megamek/common/verifier/TestSupportVehicleTest.java index 7787aaf2b62..37b23eda332 100644 --- a/megamek/unittests/megamek/common/verifier/TestSupportVehicleTest.java +++ b/megamek/unittests/megamek/common/verifier/TestSupportVehicleTest.java @@ -1,6 +1,5 @@ package megamek.common.verifier; -import megamek.common.EquipmentType; import megamek.common.MiscType; import org.junit.Test; @@ -14,10 +13,9 @@ public class TestSupportVehicleTest { @Test public void testChassisModLookup() { for (TestSupportVehicle.ChassisModification mod : TestSupportVehicle.ChassisModification.values()) { - EquipmentType eq = EquipmentType.get(mod.eqTypeKey); - assertNotNull(eq); - assertTrue(eq.hasFlag(MiscType.F_SUPPORT_TANK_EQUIPMENT)); - assertTrue(eq.hasFlag(MiscType.F_CHASSIS_MODIFICATION)); + assertNotNull(mod.equipment); + assertTrue(mod.equipment.hasFlag(MiscType.F_SUPPORT_TANK_EQUIPMENT)); + assertTrue(mod.equipment.hasFlag(MiscType.F_CHASSIS_MODIFICATION)); } } From a71508b9fc04e8330cf067deeaa76196232b743f Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 24 Jun 2019 09:32:47 -0500 Subject: [PATCH 30/69] Corrected premature rounding on SV ejection seat. --- megamek/src/megamek/common/MiscType.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/megamek/src/megamek/common/MiscType.java b/megamek/src/megamek/common/MiscType.java index 560364cf52b..d9412b43e4b 100644 --- a/megamek/src/megamek/common/MiscType.java +++ b/megamek/src/megamek/common/MiscType.java @@ -750,12 +750,6 @@ public double getTonnage(Entity entity, int location) { } return TestEntity.ceil(weight, roundWeight); - } else if (hasFlag(F_EJECTION_SEAT)) { - if (entity.isSupportVehicle() && (entity.getWeight() < 5)) { - return .1f; - } else { - return .5f; - } } else if (hasFlag(F_DRONE_CARRIER_CONTROL)) { double weight = 2; for (Mounted mount : entity.getMisc()) { @@ -5905,7 +5899,7 @@ public static MiscType createIMEjectionSeat() { misc.name = "Ejection Seat (Industrial Mech)"; misc.setInternalName(misc.name); misc.shortName = "Ejection Seat"; - misc.tonnage = TONNAGE_VARIABLE; + misc.tonnage = 0.5; misc.criticals = 1; misc.cost = 25000; misc.flags = misc.flags.or(F_EJECTION_SEAT).or(F_MECH_EQUIPMENT); @@ -5928,7 +5922,7 @@ public static MiscType createSVEjectionSeat() { misc.name = "Ejection Seat (Support Vehicle)"; misc.setInternalName(misc.name); misc.shortName = "Ejection Seat"; - misc.tonnage = TONNAGE_VARIABLE; + misc.tonnage = 0.1; // M/L SVs round all kg-scale equipment up to the half ton at the end of the calculation. misc.tankslots = 1; misc.cost = 25000; misc.flags = misc.flags.or(F_EJECTION_SEAT).or(F_SUPPORT_TANK_EQUIPMENT); From 20c50d1d391a2b0f0bf555fcdfc3b05d0f3a4da6 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 24 Jun 2019 10:49:29 -0500 Subject: [PATCH 31/69] Cleaned up SV seating classes. --- .../megamek/common/PillionSeatCargoBay.java | 29 ++++++------------- .../megamek/common/StandardSeatCargoBay.java | 29 ++++++------------- 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/megamek/src/megamek/common/PillionSeatCargoBay.java b/megamek/src/megamek/common/PillionSeatCargoBay.java index 157b1f422da..013d4ab52ba 100644 --- a/megamek/src/megamek/common/PillionSeatCargoBay.java +++ b/megamek/src/megamek/common/PillionSeatCargoBay.java @@ -15,7 +15,7 @@ package megamek.common; /** - * Represents a tiny seat for a passenger. + * Represents an external or exposed support vehicle crew seat. */ public final class PillionSeatCargoBay extends Bay { @@ -38,19 +38,14 @@ protected PillionSeatCargoBay() { // Public constructors and methods. /** - * Create a space for the given tonnage of troops. For this class, only the - * weight of the troops (and their equipment) are considered; if you'd like - * to think that they are stacked like lumber, be my guest. + * Creates pillion crew seating for support vehicles. * - * @param space - * - The weight of troops (in tons) this space can carry. + * @param space The number of seats */ - public PillionSeatCargoBay(double space, int doors) { - totalSpace = (int)(space/0.025); - weight = space; - currentSpace = (int)(space/0.025); - this.doors = doors; - currentdoors = doors; + public PillionSeatCargoBay(double space) { + totalSpace = currentSpace = space; + weight = space * 0.025; + doors = currentdoors = 0; } /** @@ -64,18 +59,12 @@ public PillionSeatCargoBay(double space, int doors) { */ @Override public boolean canLoad(Entity unit) { - // Assume that we cannot carry the unit. - boolean result = false; - - return result; + return false; } @Override public String getUnusedString(boolean showrecovery) { - StringBuffer returnString = new StringBuffer( - "Passenger Pillion Seats (" + getCurrentDoors() + " doors) - "); - returnString.append((int)currentSpace); - return returnString.toString(); + return "Seating (Pillion) - " + currentSpace; } @Override diff --git a/megamek/src/megamek/common/StandardSeatCargoBay.java b/megamek/src/megamek/common/StandardSeatCargoBay.java index ee35ce171a3..ec74b15c366 100644 --- a/megamek/src/megamek/common/StandardSeatCargoBay.java +++ b/megamek/src/megamek/common/StandardSeatCargoBay.java @@ -15,7 +15,7 @@ package megamek.common; /** - * Represents a standard sized passenger seat. + * Represents a standard support vehicle crew seat. */ public final class StandardSeatCargoBay extends Bay { @@ -38,19 +38,14 @@ protected StandardSeatCargoBay() { // Public constructors and methods. /** - * Create a space for the given tonnage of troops. For this class, only the - * weight of the troops (and their equipment) are considered; if you'd like - * to think that they are stacked like lumber, be my guest. + * Creates standard crew seating for support vehicles. * - * @param space - * - The weight of troops (in tons) this space can carry. + * @param space The number of seats */ - public StandardSeatCargoBay(double space, int doors) { - totalSpace = (int)(space/0.075); - weight = space; - currentSpace = (int)(space/0.075); - this.doors = doors; - currentdoors = doors; + public StandardSeatCargoBay(double space) { + totalSpace = currentSpace = space; + weight = space * 0.075; + doors = currentdoors = 0; } /** @@ -64,18 +59,12 @@ public StandardSeatCargoBay(double space, int doors) { */ @Override public boolean canLoad(Entity unit) { - // Assume that we cannot carry the unit. - boolean result = false; - - return result; + return false; } @Override public String getUnusedString(boolean showrecovery) { - StringBuffer returnString = new StringBuffer("Passenger Seats (" - + getCurrentDoors() + " doors) - "); - returnString.append((int)currentSpace); - return returnString.toString(); + return "Seating (Standard) - " + currentSpace; } @Override From 6d8e72c1fa90270d28e3c26033e80ac9a8f3cd49 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 24 Jun 2019 11:55:03 -0500 Subject: [PATCH 32/69] Created SV ejection seat as transporter. MiscType has not bee removed yet. --- .../megamek/common/EjectionSeatCargoBay.java | 68 +++++++++++++++++++ .../megamek/common/PillionSeatCargoBay.java | 38 ++--------- .../megamek/common/StandardSeatCargoBay.java | 9 +-- .../src/megamek/common/loaders/BLKFile.java | 62 ++--------------- 4 files changed, 82 insertions(+), 95 deletions(-) create mode 100644 megamek/src/megamek/common/EjectionSeatCargoBay.java diff --git a/megamek/src/megamek/common/EjectionSeatCargoBay.java b/megamek/src/megamek/common/EjectionSeatCargoBay.java new file mode 100644 index 00000000000..4143c94b297 --- /dev/null +++ b/megamek/src/megamek/common/EjectionSeatCargoBay.java @@ -0,0 +1,68 @@ +/* + * MegaMek - Copyright (C) 2019 - The MegaMek Team + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + */ +package megamek.common; + +/** + * Support vehicle ejection seats. + */ +public final class EjectionSeatCargoBay extends StandardSeatCargoBay { + + private static final long serialVersionUID = 8916801835963112628L; + + /** + * The default constructor is only for serialization. + */ + protected EjectionSeatCargoBay() { + totalSpace = 0; + currentSpace = 0; + } + + // Public constructors and methods. + + /** + * Creates pillion crew seating for support vehicles. + * + * @param space The number of seats + */ + public EjectionSeatCargoBay(double space) { + super(space); + weight = space * 0.1; + } + + @Override + public String getUnusedString(boolean showrecovery) { + return "Seating (Ejection) - " + currentSpace; + } + + @Override + public String getType() { + return "Ejection Seats"; + } + + @Override + public String toString() { + return "ejectionseats:" + currentSpace + ":" + doors; + } + + @Override + public TechAdvancement getTechAdvancement() { + return EjectionSeatCargoBay.techAdvancement(); + } + + public static TechAdvancement techAdvancement() { + return new TechAdvancement(TECH_BASE_ALL) + .setTechRating(RATING_B).setAvailability(RATING_D, RATING_D, RATING_D, RATING_D) + .setAdvancement(DATE_PS, DATE_PS, DATE_PS, DATE_NONE, DATE_NONE); + } +} diff --git a/megamek/src/megamek/common/PillionSeatCargoBay.java b/megamek/src/megamek/common/PillionSeatCargoBay.java index 013d4ab52ba..10e6dd3d70a 100644 --- a/megamek/src/megamek/common/PillionSeatCargoBay.java +++ b/megamek/src/megamek/common/PillionSeatCargoBay.java @@ -18,14 +18,9 @@ * Represents an external or exposed support vehicle crew seat. */ -public final class PillionSeatCargoBay extends Bay { +public final class PillionSeatCargoBay extends StandardSeatCargoBay { - /** - * - */ - private static final long serialVersionUID = 4161027191694822726L; - - private double weight = 0; + private static final long serialVersionUID = 145634308684637504L; /** * The default constructor is only for serialization. @@ -43,23 +38,8 @@ protected PillionSeatCargoBay() { * @param space The number of seats */ public PillionSeatCargoBay(double space) { - totalSpace = currentSpace = space; + super(space); weight = space * 0.025; - doors = currentdoors = 0; - } - - /** - * Determines if this object can accept the given unit. The unit may not be - * of the appropriate type or there may be no room for the unit. - * - * @param unit - * - the Entity to be loaded. - * @return true if the unit can be loaded, false - * otherwise. - */ - @Override - public boolean canLoad(Entity unit) { - return false; } @Override @@ -72,19 +52,9 @@ public String getType() { return "Pillion Seats"; } - @Override - public double getWeight() { - return weight; - } - - @Override - public boolean isQuarters() { - return true; - } - @Override public String toString() { - return "pillionseats:" + weight + ":" + doors; + return "pillionseats:" + currentSpace + ":" + doors; } } \ No newline at end of file diff --git a/megamek/src/megamek/common/StandardSeatCargoBay.java b/megamek/src/megamek/common/StandardSeatCargoBay.java index ec74b15c366..d455608dedc 100644 --- a/megamek/src/megamek/common/StandardSeatCargoBay.java +++ b/megamek/src/megamek/common/StandardSeatCargoBay.java @@ -18,14 +18,11 @@ * Represents a standard support vehicle crew seat. */ -public final class StandardSeatCargoBay extends Bay { +public class StandardSeatCargoBay extends Bay { - /** - * - */ private static final long serialVersionUID = 4161027191694822726L; - private double weight = 0; + protected double weight = 0; /** * The default constructor is only for serialization. @@ -84,7 +81,7 @@ public boolean isQuarters() { @Override public String toString() { - return "standardseats:" + weight + ":" + doors; + return "standardseats:" + currentSpace + ":" + doors; } } \ No newline at end of file diff --git a/megamek/src/megamek/common/loaders/BLKFile.java b/megamek/src/megamek/common/loaders/BLKFile.java index 15aef0da292..e05b14efc9b 100644 --- a/megamek/src/megamek/common/loaders/BLKFile.java +++ b/megamek/src/megamek/common/loaders/BLKFile.java @@ -21,60 +21,8 @@ import java.util.Vector; import java.util.stream.Collectors; -import megamek.common.ASFBay; -import megamek.common.Aero; -import megamek.common.AmmoType; -import megamek.common.BattleArmor; -import megamek.common.BattleArmorBay; -import megamek.common.Bay; -import megamek.common.CargoBay; -import megamek.common.ConvFighter; -import megamek.common.CrewQuartersCargoBay; -import megamek.common.DockingCollar; -import megamek.common.Dropship; -import megamek.common.DropshuttleBay; -import megamek.common.Engine; -import megamek.common.Entity; -import megamek.common.EntityFluff; -import megamek.common.EquipmentType; -import megamek.common.FirstClassQuartersCargoBay; -import megamek.common.FixedWingSupport; -import megamek.common.GunEmplacement; -import megamek.common.HeavyVehicleBay; -import megamek.common.Infantry; -import megamek.common.InfantryBay; +import megamek.common.*; import megamek.common.InfantryBay.PlatoonType; -import megamek.common.InsulatedCargoBay; -import megamek.common.Jumpship; -import megamek.common.LargeSupportTank; -import megamek.common.LightVehicleBay; -import megamek.common.LiquidCargoBay; -import megamek.common.LivestockCargoBay; -import megamek.common.LocationFullException; -import megamek.common.Mech; -import megamek.common.MechBay; -import megamek.common.Mounted; -import megamek.common.NavalRepairFacility; -import megamek.common.PillionSeatCargoBay; -import megamek.common.Protomech; -import megamek.common.ProtomechBay; -import megamek.common.RefrigeratedCargoBay; -import megamek.common.ReinforcedRepairFacility; -import megamek.common.SecondClassQuartersCargoBay; -import megamek.common.SmallCraft; -import megamek.common.SmallCraftBay; -import megamek.common.SpaceStation; -import megamek.common.StandardSeatCargoBay; -import megamek.common.SteerageQuartersCargoBay; -import megamek.common.SuperHeavyVehicleBay; -import megamek.common.SupportTank; -import megamek.common.SupportVTOL; -import megamek.common.Tank; -import megamek.common.TechConstants; -import megamek.common.TroopSpace; -import megamek.common.VTOL; -import megamek.common.Warship; -import megamek.common.WeaponType; import megamek.common.options.IOption; import megamek.common.options.PilotOptions; import megamek.common.util.BuildingBlock; @@ -1067,11 +1015,15 @@ protected void addTransports(Entity e) { } else if (transporter.startsWith("pillionseats:", 0)) { String numbers = transporter.substring(13); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new PillionSeatCargoBay(pbi.getSize(), pbi.getDoors())); + e.addTransporter(new PillionSeatCargoBay(pbi.getSize())); } else if (transporter.startsWith("standardseats:", 0)) { String numbers = transporter.substring(14); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new StandardSeatCargoBay(pbi.getSize(), pbi.getDoors())); + e.addTransporter(new StandardSeatCargoBay(pbi.getSize())); + } else if (transporter.startsWith("ejectionseats:", 0)) { + String numbers = transporter.substring("ejectionseats:".length()); + ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); + e.addTransporter(new EjectionSeatCargoBay(pbi.getSize())); } else if (transporter.startsWith("dockingcollar", 0)) { e.addTransporter(new DockingCollar(1)); } From 303e0f04ea6e9c87f61db530c0d0204f0562f198 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 25 Jun 2019 10:35:09 -0500 Subject: [PATCH 33/69] Adjust tech advancement for ratings B and C. Moved B from ES to PS and C from primitive construction dates to ES. There were some SV unit types (e.g. fixed wing and hovercraft) that could not meet the minimum structural tech rating at their earliest date. --- megamek/src/megamek/common/verifier/TestSupportVehicle.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index cb4833d47f0..ca4b49b00ad 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -376,7 +376,7 @@ public ITechnology getTechSource() { /** * Tech advancement data for structural components with variable tech levels (structure, - * armor, engine). This is assembled from the tables on TM, p. 122 and IO, p. 49, primitive construction + * armor, engine). This is assembled from the table on TM, p. 122 and IO, p. 49, primitive construction * rules (IO, p. 120-121) and a pending proposal to the rules committee for E. */ public static final TechAdvancement[] TECH_LEVEL_TA = { @@ -385,11 +385,11 @@ public ITechnology getTechSource() { .setAvailability(ITechnology.RATING_A, ITechnology.RATING_A, ITechnology.RATING_A, ITechnology.RATING_A), new TechAdvancement(ITechnology.TECH_BASE_ALL).setTechRating(ITechnology.RATING_B) - .setAdvancement(ITechnology.DATE_ES, ITechnology.DATE_ES, ITechnology.DATE_ES) + .setAdvancement(ITechnology.DATE_PS, ITechnology.DATE_PS, ITechnology.DATE_PS) .setAvailability(ITechnology.RATING_B, ITechnology.RATING_B, ITechnology.RATING_B, ITechnology.RATING_A), new TechAdvancement(ITechnology.TECH_BASE_ALL).setTechRating(ITechnology.RATING_C) - .setAdvancement(2250, 2300, 2305).setApproximate(true, false, false) + .setAdvancement(ITechnology.DATE_ES, ITechnology.DATE_ES, ITechnology.DATE_ES) .setPrototypeFactions(ITechnology.F_TA).setProductionFactions(ITechnology.F_TA) .setAvailability(ITechnology.RATING_C, ITechnology.RATING_B, ITechnology.RATING_B, ITechnology.RATING_B), From e540433e35dcc6b67a7766de4622cb3ba8f8016a Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 25 Jun 2019 11:12:08 -0500 Subject: [PATCH 34/69] Added crew quarters constructors for number of crew rather than weight. --- .../megamek/common/CrewQuartersCargoBay.java | 24 ++++++++++++------- .../common/FirstClassQuartersCargoBay.java | 23 +++++++++++------- .../common/SecondClassQuartersCargoBay.java | 24 ++++++++++++------- .../common/SteerageQuartersCargoBay.java | 24 ++++++++++++------- 4 files changed, 60 insertions(+), 35 deletions(-) diff --git a/megamek/src/megamek/common/CrewQuartersCargoBay.java b/megamek/src/megamek/common/CrewQuartersCargoBay.java index bfe190f6b49..e2ac4056692 100644 --- a/megamek/src/megamek/common/CrewQuartersCargoBay.java +++ b/megamek/src/megamek/common/CrewQuartersCargoBay.java @@ -42,17 +42,25 @@ protected CrewQuartersCargoBay() { * weight of the troops (and their equipment) are considered; if you'd like * to think that they are stacked like lumber, be my guest. * - * @param space - * - The weight of troops (in tons) this space can carry. + * @param weight The weight of troops (in tons) this space can carry. */ - public CrewQuartersCargoBay(double space, int doors) { - totalSpace = (int)space/7; - weight = space; - currentSpace = (int)space/7; + public CrewQuartersCargoBay(double weight, int doors) { + totalSpace = (int) weight/7; + this.weight = weight; + currentSpace = (int) weight/7; this.doors = doors; currentdoors = doors; } + /** + * Create space for certain number of crew/passengers + * + * @param space The number of crew or passengers to accomodate + */ + public CrewQuartersCargoBay(int space) { + this(space * 7, 0); + } + /** * Determines if this object can accept the given unit. The unit may not be * of the appropriate type or there may be no room for the unit. @@ -65,9 +73,7 @@ public CrewQuartersCargoBay(double space, int doors) { @Override public boolean canLoad(Entity unit) { // Assume that we cannot carry the unit. - boolean result = false; - - return result; + return false; } @Override diff --git a/megamek/src/megamek/common/FirstClassQuartersCargoBay.java b/megamek/src/megamek/common/FirstClassQuartersCargoBay.java index b9b55df4441..ace82a7d371 100644 --- a/megamek/src/megamek/common/FirstClassQuartersCargoBay.java +++ b/megamek/src/megamek/common/FirstClassQuartersCargoBay.java @@ -42,17 +42,26 @@ protected FirstClassQuartersCargoBay() { * weight of the troops (and their equipment) are considered; if you'd like * to think that they are stacked like lumber, be my guest. * - * @param space + * @param weight * - The weight of troops (in tons) this space can carry. */ - public FirstClassQuartersCargoBay(double space, int doors) { - totalSpace = (int)space/10; - weight = space; - currentSpace = (int)space/10; + public FirstClassQuartersCargoBay(double weight, int doors) { + totalSpace = (int) weight/10; + this.weight = weight; + currentSpace = (int) weight/10; this.doors = doors; currentdoors = doors; } + /** + * Create space for certain number of crew/passengers + * + * @param space The number of crew or passengers to accomodate + */ + public FirstClassQuartersCargoBay(int space) { + this(space * 10, 0); + } + /** * Determines if this object can accept the given unit. The unit may not be * of the appropriate type or there may be no room for the unit. @@ -65,9 +74,7 @@ public FirstClassQuartersCargoBay(double space, int doors) { @Override public boolean canLoad(Entity unit) { // Assume that we cannot carry the unit. - boolean result = false; - - return result; + return false; } @Override diff --git a/megamek/src/megamek/common/SecondClassQuartersCargoBay.java b/megamek/src/megamek/common/SecondClassQuartersCargoBay.java index 1c68511d7cc..1f408057565 100644 --- a/megamek/src/megamek/common/SecondClassQuartersCargoBay.java +++ b/megamek/src/megamek/common/SecondClassQuartersCargoBay.java @@ -42,17 +42,25 @@ protected SecondClassQuartersCargoBay() { * weight of the troops (and their equipment) are considered; if you'd like * to think that they are stacked like lumber, be my guest. * - * @param space - * - The weight of troops (in tons) this space can carry. + * @param weight The weight of troops (in tons) this space can carry. */ - public SecondClassQuartersCargoBay(double space, int doors) { - totalSpace = (int)space/7; - weight = space; - currentSpace = (int)space/7; + public SecondClassQuartersCargoBay(double weight, int doors) { + totalSpace = (int) weight/7; + this.weight = weight; + currentSpace = (int) weight/7; this.doors = doors; currentdoors = doors; } + /** + * Create space for certain number of crew/passengers + * + * @param space The number of crew or passengers to accomodate + */ + public SecondClassQuartersCargoBay(int space) { + this(space * 7, 0); + } + /** * Determines if this object can accept the given unit. The unit may not be * of the appropriate type or there may be no room for the unit. @@ -65,9 +73,7 @@ public SecondClassQuartersCargoBay(double space, int doors) { @Override public boolean canLoad(Entity unit) { // Assume that we cannot carry the unit. - boolean result = false; - - return result; + return false; } @Override diff --git a/megamek/src/megamek/common/SteerageQuartersCargoBay.java b/megamek/src/megamek/common/SteerageQuartersCargoBay.java index 6c9716193fd..c83e070fc6d 100644 --- a/megamek/src/megamek/common/SteerageQuartersCargoBay.java +++ b/megamek/src/megamek/common/SteerageQuartersCargoBay.java @@ -42,17 +42,25 @@ protected SteerageQuartersCargoBay() { * weight of the troops (and their equipment) are considered; if you'd like * to think that they are stacked like lumber, be my guest. * - * @param space - * - The weight of troops (in tons) this space can carry. + * @param weight The weight of troops (in tons) this space can carry. */ - public SteerageQuartersCargoBay(double space, int doors) { - totalSpace = ((int)space)/5; - weight = space; - currentSpace = ((int)space)/5; + public SteerageQuartersCargoBay(double weight, int doors) { + totalSpace = ((int) weight)/5; + this.weight = weight; + currentSpace = ((int) weight)/5; this.doors = doors; currentdoors = doors; } + /** + * Create space for certain number of crew/passengers + * + * @param space The number of crew or passengers to accomodate + */ + public SteerageQuartersCargoBay(int space) { + this(space * 5, 0); + } + /** * Determines if this object can accept the given unit. The unit may not be * of the appropriate type or there may be no room for the unit. @@ -65,9 +73,7 @@ public SteerageQuartersCargoBay(double space, int doors) { @Override public boolean canLoad(Entity unit) { // Assume that we cannot carry the unit. - boolean result = false; - - return result; + return false; } @Override From 16543db98f8c57e940ead77ee08d045373ab96d5 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 26 Jun 2019 15:06:38 -0500 Subject: [PATCH 35/69] Fixed crew quarters slot calculations. Quarters for minimum crew do not take up any equipment slots. --- .../common/verifier/TestSupportVehicle.java | 63 +++++++++++++++---- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index ca4b49b00ad..ea891b668ce 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -870,25 +870,62 @@ public int getMiscEquipSlots() { return slots; } - public int getCrewSlots() { + public static final int INDEX_FIRST_CLASS = 0; + public static final int INDEX_SECOND_CLASS = 1; + public static final int INDEX_STD_CREW = 2; + public static final int INDEX_STEERAGE = 3; + /** + * Calculates capacity of quarters above the minimum crew requirement. Only quarters above the minimum + * crew requirement take up equipment slots. Second class quarters are considered passenger accomodations + * and always count toward slots. Others are assigned to the least bulky type first. + * + * @param sv A support vehicle + * @return An array of the count of each type of quarters that require slots. See INDEX_* constants for + * indices. + */ + public static int[] extraCrewQuartersCount(Entity sv) { int firstClass = 0; - int secondClass = 0; + int stdCrew = 0; int steerage = 0; - int extraSeat = 0; - for (Transporter t : supportVee.getTransports()) { + int[] retVal = { 0, 0, 0, 0 }; + for (Transporter t : sv.getTransports()) { if (t instanceof FirstClassQuartersCargoBay) { - firstClass++; - } else if ((t instanceof SecondClassQuartersCargoBay) - || (t instanceof CrewQuartersCargoBay)) { - secondClass++; + firstClass += ((Bay) t).getCapacity(); + } else if (t instanceof SecondClassQuartersCargoBay) { + retVal[INDEX_SECOND_CLASS] += ((Bay) t).getCapacity(); + } else if (t instanceof CrewQuartersCargoBay) { + stdCrew += ((Bay) t).getCapacity(); } else if (t instanceof SteerageQuartersCargoBay) { - steerage++; + steerage += ((Bay) t).getCapacity(); } } - return (int) (Math.ceil(firstClass / 5.0) + Math.ceil(secondClass / 20.0) + Math.ceil(steerage / 50.0)) - + (supportVee instanceof FixedWingSupport ? - ((FixedWingSupport) supportVee).getExtraCrewSeats() : - ((Tank) supportVee).getExtraCrewSeats()); + int extraCrew = firstClass + stdCrew + steerage - Compute.getFullCrewSize(sv); + if ((extraCrew > 0) && (steerage > 0)) { + retVal[INDEX_STEERAGE] = Math.min(extraCrew, steerage); + extraCrew -= retVal[INDEX_STEERAGE]; + } + if ((extraCrew > 0) && (stdCrew > 0)) { + retVal[INDEX_STD_CREW] = Math.min(extraCrew, stdCrew); + extraCrew -= retVal[INDEX_STD_CREW]; + } + if ((extraCrew > 0) && (firstClass > 0)) { + retVal[INDEX_FIRST_CLASS] = Math.min(extraCrew, firstClass); + } + return retVal; + } + + /** + * Calculates the number of equipment slots taken up by crew quarters. Quarters for minimum crew + * do not take up slots. + * + * @return The number of equipment slots required by crew quarters. + */ + public int getCrewSlots() { + int[] excess = extraCrewQuartersCount(getEntity()); + return (int) Math.ceil(excess[INDEX_FIRST_CLASS] / 5.0) + + (int) Math.ceil(excess[INDEX_SECOND_CLASS] / 20.0) + + (int) Math.ceil(excess[INDEX_STD_CREW] / 20.0) + + (int) Math.ceil(excess[INDEX_STEERAGE] / 50.0); } /** From 71a66412d7bec0ef6de2b1c525b18823d784dffe Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 1 Jul 2019 11:27:26 -0500 Subject: [PATCH 36/69] FLeshed out SV fuel calculations. --- .../src/megamek/common/FixedWingSupport.java | 6 +- megamek/src/megamek/common/SupportTank.java | 35 ++------ megamek/src/megamek/common/SupportVTOL.java | 1 + megamek/src/megamek/common/Tank.java | 79 ++++++++++++++++++- 4 files changed, 87 insertions(+), 34 deletions(-) diff --git a/megamek/src/megamek/common/FixedWingSupport.java b/megamek/src/megamek/common/FixedWingSupport.java index b162f83e928..4260a823eec 100644 --- a/megamek/src/megamek/common/FixedWingSupport.java +++ b/megamek/src/megamek/common/FixedWingSupport.java @@ -125,13 +125,17 @@ public boolean hasPropChassisMod() { /** * While most aerospace units measure fuel weight in points per ton, support vehicles measure - * in kg per point. + * in kg per point. Vehicles that do not require fuel return 0. * * @return The mass of each point of fuel in kg. */ public int kgPerFuelPoint() { int kg = KG_PER_FUEL_POINT[getWeightClass() - EntityWeightClass.WEIGHT_SMALL_SUPPORT][getEngineTechRating()]; if (hasPropChassisMod() || getMovementMode().equals(EntityMovementMode.AIRSHIP)) { + if (getEngine().isFusion() || (getEngine().getEngineType() == Engine.FISSION) + || (getEngine().getEngineType() == Engine.SOLAR)) { + return 0; + } kg = (int) Math.ceil(kg * 0.75); } return kg; diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index b491fb49273..e38942ce25e 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -262,12 +262,6 @@ public int getTotalCommGearTons() { //Support Vee Engine Information public double getBaseChassisValue() { switch (movementMode) { - /*case AIRSHIP: - if (getWeight() < 5) { - return 0.2f; - } else { - return 0.25f; - }*/ case HOVER: if (getWeight() < 5) { return 0.2; @@ -277,17 +271,7 @@ public double getBaseChassisValue() { return 0.3; } case NAVAL: - if (getWeight() < 5) { - return 0.12; - } else { - return 0.15; - } case HYDROFOIL: - if (getWeight() < 5) { - return 0.12; - } else { - return 0.15; - } case SUBMARINE: if (getWeight() < 5) { return 0.12; @@ -326,12 +310,12 @@ public double getBaseChassisValue() { //Support Vee Engine Information public double getBaseEngineValue() { switch (movementMode) { - /*case AIRSHIP: + case AIRSHIP: if (getWeight() < 5) { - return 0.005f; + return 0.005; } else { - return 0.008f; - }*/ + return 0.008; + } case HOVER: if (getWeight() < 5) { return 0.0025; @@ -341,17 +325,7 @@ public double getBaseEngineValue() { return 0.008; } case NAVAL: - if (getWeight() <5) { - return 0.004; - } else { - return 0.007; - } case HYDROFOIL: - if (getWeight() <5) { - return 0.004; - } else { - return 0.007; - } case SUBMARINE: if (getWeight() < 5) { return 0.004; @@ -393,6 +367,7 @@ public double getFuelTonnage() { return fuelTonnage; } + @Override public void setFuelTonnage(double fuel) { fuelTonnage = fuel; } diff --git a/megamek/src/megamek/common/SupportVTOL.java b/megamek/src/megamek/common/SupportVTOL.java index a781e0223da..40e515843e0 100644 --- a/megamek/src/megamek/common/SupportVTOL.java +++ b/megamek/src/megamek/common/SupportVTOL.java @@ -144,6 +144,7 @@ public double getFuelTonnage() { return fuelTonnage; } + @Override public void setFuelTonnage(double fuel) { fuelTonnage = fuel; } diff --git a/megamek/src/megamek/common/Tank.java b/megamek/src/megamek/common/Tank.java index d858d467800..82ee16df4fc 100644 --- a/megamek/src/megamek/common/Tank.java +++ b/megamek/src/megamek/common/Tank.java @@ -166,6 +166,11 @@ public int getLocTurret2() { */ private boolean hasNoControlSystems = false; + /** + * Alternate fuel for ICEs that affects operating range + */ + private boolean alcoholNatGasFueled = false; + public CrewType defaultCrewType() { return CrewType.CREW; } @@ -4138,12 +4143,80 @@ public boolean isDmgLight() { } /** - * Returns a Support units fuel allotment. - * + * Returns the mass of the fuel, which is used for calculating operating range. + * For combat vehicles this is considered part of the engine weight. For support vehicles it is in + * addition to the engine weight. + * * @return fuel tonnage */ public double getFuelTonnage() { - return 0; + if (hasEngine()) { + // For combat vehicles the fuel tonnage is 10% of the engine. + return getEngine().getWeightEngine(this) * 0.1; + } + return 0.0; + } + + /** + * Sets the fuel mass for support vehicles. Has no effect on combat vehicles. + * + * @param fuel The mass of the fuel in tons + */ + public void setFuelTonnage(double fuel) { + // do nothing + } + + /** + * Calculates the operating range of the vehicle based on engine type and fuel mass. + * Vehicles that do not require fuel report an operating range of {@code Integer.MAX_VALUE}. + * + * @return The vehicle's operating range in km + */ + public int operatingRange() { + if (getFuelTonnage() <= 0) { + return 0; + } + double fuelUnit = fuelTonnagePer100km(); + if (fuelUnit > 0) { + return (int) (getFuelTonnage() / fuelUnit * 100); + } + return Integer.MAX_VALUE; + } + + /** + * Calculates fuel mass based on engine type and mass. Engines that do not require allocating + * fuel mass return a value of 0.0. + * + * @return The fuel mass required for every 100 km of vehicle range. + */ + public double fuelTonnagePer100km() { + if (!hasEngine()) { + return 0.0; + } + switch (getEngine().getEngineType()) { + case Engine.STEAM: + return getEngine().getWeightEngine(this) * 0.03; + case Engine.COMBUSTION_ENGINE: + if (isAlcoholOrNaturalGasFueled()) { + return getEngine().getWeightEngine(this) * 0.0125; + } else { + return getEngine().getWeightEngine(this) * 0.01; + } + case Engine.BATTERY: + return getEngine().getWeightEngine(this) * 0.05; + case Engine.FUEL_CELL: + return getEngine().getWeightEngine(this) * 0.015; + default: + return 0.0; + } + } + + public boolean isAlcoholOrNaturalGasFueled() { + return alcoholNatGasFueled; + } + + public void setAlcoholOrNaturalGasFueled(boolean fuel) { + alcoholNatGasFueled = fuel; } /** From be9d3a66b369a72abbf0c1c8ca48260c62e26d6b Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Fri, 2 Aug 2019 13:12:16 -0500 Subject: [PATCH 37/69] /.idea --- .idea/compiler.xml | 13 ------- ..._sun_activation_javax_activation_1_2_0.xml | 11 ------ ...un_istack_istack_commons_runtime_3_0_5.xml | 11 ------ ...sun_xml_fastinfoset_FastInfoset_1_2_13.xml | 11 ------ ...om_thoughtworks_xstream_xstream_1_4_10.xml | 11 ------ .../Gradle__javax_xml_bind_jaxb_api_2_3_0.xml | 11 ------ .idea/libraries/Gradle__junit_junit_4_12.xml | 11 ------ .../libraries/Gradle__log4j_log4j_1_2_17.xml | 11 ------ ...radle__net_bytebuddy_byte_buddy_1_8_13.xml | 11 ------ ..._net_bytebuddy_byte_buddy_agent_1_8_13.xml | 11 ------ ...le__org_glassfish_jaxb_jaxb_core_2_3_0.xml | 11 ------ ..._org_glassfish_jaxb_jaxb_runtime_2_3_0.xml | 11 ------ .../Gradle__org_glassfish_jaxb_txw2_2_3_0.xml | 11 ------ ...Gradle__org_hamcrest_hamcrest_core_1_3.xml | 11 ------ ...Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml | 11 ------ ...radle__org_mockito_mockito_core_2_20_1.xml | 11 ------ .../Gradle__org_objenesis_objenesis_2_6.xml | 11 ------ .../Gradle__xmlpull_xmlpull_1_1_3_1.xml | 9 ----- .../Gradle__xpp3_xpp3_min_1_1_4c.xml | 11 ------ .idea/modules/MegaMek.iml | 13 ------- .idea/modules/MegaMek_main.iml | 10 ------ .idea/modules/MegaMek_test.iml | 12 ------- .idea/modules/megamek/megamek_main.iml | 31 ---------------- .idea/modules/megamek/megamek_test.iml | 36 ------------------- 24 files changed, 311 deletions(-) delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml delete mode 100644 .idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml delete mode 100644 .idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml delete mode 100644 .idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml delete mode 100644 .idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml delete mode 100644 .idea/libraries/Gradle__junit_junit_4_12.xml delete mode 100644 .idea/libraries/Gradle__log4j_log4j_1_2_17.xml delete mode 100644 .idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml delete mode 100644 .idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml delete mode 100644 .idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml delete mode 100644 .idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml delete mode 100644 .idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml delete mode 100644 .idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml delete mode 100644 .idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml delete mode 100644 .idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml delete mode 100644 .idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml delete mode 100644 .idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml delete mode 100644 .idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml delete mode 100644 .idea/modules/MegaMek.iml delete mode 100644 .idea/modules/MegaMek_main.iml delete mode 100644 .idea/modules/MegaMek_test.iml delete mode 100644 .idea/modules/megamek/megamek_main.iml delete mode 100644 .idea/modules/megamek/megamek_test.iml diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index b1d507daaf6..00000000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml b/.idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml deleted file mode 100644 index 5ca47b1055e..00000000000 --- a/.idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml b/.idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml deleted file mode 100644 index 44b84c1d524..00000000000 --- a/.idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml b/.idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml deleted file mode 100644 index 1fc2a6cb19c..00000000000 --- a/.idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml b/.idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml deleted file mode 100644 index 0f877877a5e..00000000000 --- a/.idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml b/.idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml deleted file mode 100644 index b9f55fcec6f..00000000000 --- a/.idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__junit_junit_4_12.xml b/.idea/libraries/Gradle__junit_junit_4_12.xml deleted file mode 100644 index 04c10dd5a46..00000000000 --- a/.idea/libraries/Gradle__junit_junit_4_12.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__log4j_log4j_1_2_17.xml b/.idea/libraries/Gradle__log4j_log4j_1_2_17.xml deleted file mode 100644 index 07be0a37e62..00000000000 --- a/.idea/libraries/Gradle__log4j_log4j_1_2_17.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml b/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml deleted file mode 100644 index 3ba0f6dfc79..00000000000 --- a/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml b/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml deleted file mode 100644 index fc6f1c05900..00000000000 --- a/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml b/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml deleted file mode 100644 index 41427eb69d4..00000000000 --- a/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml b/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml deleted file mode 100644 index 1399717fd3d..00000000000 --- a/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml b/.idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml deleted file mode 100644 index d6c7a390fbf..00000000000 --- a/.idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml deleted file mode 100644 index 8262f729c28..00000000000 --- a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml b/.idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml deleted file mode 100644 index dc412c33285..00000000000 --- a/.idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml b/.idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml deleted file mode 100644 index a229d8fedc7..00000000000 --- a/.idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml b/.idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml deleted file mode 100644 index a37a39cddc3..00000000000 --- a/.idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml b/.idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml deleted file mode 100644 index bb8ebc9b65b..00000000000 --- a/.idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml b/.idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml deleted file mode 100644 index fa9b59fe316..00000000000 --- a/.idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/MegaMek.iml b/.idea/modules/MegaMek.iml deleted file mode 100644 index d8cd59e78ed..00000000000 --- a/.idea/modules/MegaMek.iml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/MegaMek_main.iml b/.idea/modules/MegaMek_main.iml deleted file mode 100644 index 9043590a42a..00000000000 --- a/.idea/modules/MegaMek_main.iml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/MegaMek_test.iml b/.idea/modules/MegaMek_test.iml deleted file mode 100644 index 280b8d6e08e..00000000000 --- a/.idea/modules/MegaMek_test.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/megamek/megamek_main.iml b/.idea/modules/megamek/megamek_main.iml deleted file mode 100644 index 585c871a9e0..00000000000 --- a/.idea/modules/megamek/megamek_main.iml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/megamek/megamek_test.iml b/.idea/modules/megamek/megamek_test.iml deleted file mode 100644 index 43f21ccfbb8..00000000000 --- a/.idea/modules/megamek/megamek_test.iml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From a6de03c33fce236f0b9e7e63ad55b628e1428422 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Fri, 2 Aug 2019 13:17:47 -0500 Subject: [PATCH 38/69] removed /.idea --- .idea/compiler.xml | 11 ------ ..._sun_activation_javax_activation_1_2_0.xml | 11 ------ ...un_istack_istack_commons_runtime_3_0_5.xml | 11 ------ ...sun_xml_fastinfoset_FastInfoset_1_2_13.xml | 11 ------ ...om_thoughtworks_xstream_xstream_1_4_10.xml | 11 ------ .../Gradle__javax_xml_bind_jaxb_api_2_3_0.xml | 11 ------ .idea/libraries/Gradle__junit_junit_4_12.xml | 11 ------ .../libraries/Gradle__log4j_log4j_1_2_17.xml | 11 ------ ...radle__net_bytebuddy_byte_buddy_1_8_13.xml | 11 ------ ..._net_bytebuddy_byte_buddy_agent_1_8_13.xml | 11 ------ ...le__org_glassfish_jaxb_jaxb_core_2_3_0.xml | 11 ------ ..._org_glassfish_jaxb_jaxb_runtime_2_3_0.xml | 11 ------ .../Gradle__org_glassfish_jaxb_txw2_2_3_0.xml | 11 ------ ...Gradle__org_hamcrest_hamcrest_core_1_3.xml | 11 ------ ...Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml | 11 ------ ...radle__org_mockito_mockito_core_2_20_1.xml | 11 ------ .../Gradle__org_objenesis_objenesis_2_6.xml | 11 ------ .../Gradle__xmlpull_xmlpull_1_1_3_1.xml | 9 ----- .../Gradle__xpp3_xpp3_min_1_1_4c.xml | 11 ------ .idea/modules/MegaMek.iml | 13 ------- .idea/modules/MegaMek_main.iml | 10 ------ .idea/modules/MegaMek_test.iml | 12 ------- .idea/modules/megamek/megamek_main.iml | 30 ---------------- .idea/modules/megamek/megamek_test.iml | 35 ------------------- 24 files changed, 307 deletions(-) delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml delete mode 100644 .idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml delete mode 100644 .idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml delete mode 100644 .idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml delete mode 100644 .idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml delete mode 100644 .idea/libraries/Gradle__junit_junit_4_12.xml delete mode 100644 .idea/libraries/Gradle__log4j_log4j_1_2_17.xml delete mode 100644 .idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml delete mode 100644 .idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml delete mode 100644 .idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml delete mode 100644 .idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml delete mode 100644 .idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml delete mode 100644 .idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml delete mode 100644 .idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml delete mode 100644 .idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml delete mode 100644 .idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml delete mode 100644 .idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml delete mode 100644 .idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml delete mode 100644 .idea/modules/MegaMek.iml delete mode 100644 .idea/modules/MegaMek_main.iml delete mode 100644 .idea/modules/MegaMek_test.iml delete mode 100644 .idea/modules/megamek/megamek_main.iml delete mode 100644 .idea/modules/megamek/megamek_test.iml diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 4df4df5b364..00000000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml b/.idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml deleted file mode 100644 index 5ca47b1055e..00000000000 --- a/.idea/libraries/Gradle__com_sun_activation_javax_activation_1_2_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml b/.idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml deleted file mode 100644 index 44b84c1d524..00000000000 --- a/.idea/libraries/Gradle__com_sun_istack_istack_commons_runtime_3_0_5.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml b/.idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml deleted file mode 100644 index 1fc2a6cb19c..00000000000 --- a/.idea/libraries/Gradle__com_sun_xml_fastinfoset_FastInfoset_1_2_13.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml b/.idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml deleted file mode 100644 index 0f877877a5e..00000000000 --- a/.idea/libraries/Gradle__com_thoughtworks_xstream_xstream_1_4_10.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml b/.idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml deleted file mode 100644 index b9f55fcec6f..00000000000 --- a/.idea/libraries/Gradle__javax_xml_bind_jaxb_api_2_3_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__junit_junit_4_12.xml b/.idea/libraries/Gradle__junit_junit_4_12.xml deleted file mode 100644 index 04c10dd5a46..00000000000 --- a/.idea/libraries/Gradle__junit_junit_4_12.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__log4j_log4j_1_2_17.xml b/.idea/libraries/Gradle__log4j_log4j_1_2_17.xml deleted file mode 100644 index 07be0a37e62..00000000000 --- a/.idea/libraries/Gradle__log4j_log4j_1_2_17.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml b/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml deleted file mode 100644 index 3ba0f6dfc79..00000000000 --- a/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_8_13.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml b/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml deleted file mode 100644 index fc6f1c05900..00000000000 --- a/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_8_13.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml b/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml deleted file mode 100644 index 41427eb69d4..00000000000 --- a/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_core_2_3_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml b/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml deleted file mode 100644 index 1399717fd3d..00000000000 --- a/.idea/libraries/Gradle__org_glassfish_jaxb_jaxb_runtime_2_3_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml b/.idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml deleted file mode 100644 index d6c7a390fbf..00000000000 --- a/.idea/libraries/Gradle__org_glassfish_jaxb_txw2_2_3_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml deleted file mode 100644 index 8262f729c28..00000000000 --- a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml b/.idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml deleted file mode 100644 index dc412c33285..00000000000 --- a/.idea/libraries/Gradle__org_jvnet_staxex_stax_ex_1_7_8.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml b/.idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml deleted file mode 100644 index a229d8fedc7..00000000000 --- a/.idea/libraries/Gradle__org_mockito_mockito_core_2_20_1.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml b/.idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml deleted file mode 100644 index a37a39cddc3..00000000000 --- a/.idea/libraries/Gradle__org_objenesis_objenesis_2_6.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml b/.idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml deleted file mode 100644 index bb8ebc9b65b..00000000000 --- a/.idea/libraries/Gradle__xmlpull_xmlpull_1_1_3_1.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml b/.idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml deleted file mode 100644 index fa9b59fe316..00000000000 --- a/.idea/libraries/Gradle__xpp3_xpp3_min_1_1_4c.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/MegaMek.iml b/.idea/modules/MegaMek.iml deleted file mode 100644 index d8cd59e78ed..00000000000 --- a/.idea/modules/MegaMek.iml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/MegaMek_main.iml b/.idea/modules/MegaMek_main.iml deleted file mode 100644 index 9043590a42a..00000000000 --- a/.idea/modules/MegaMek_main.iml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/MegaMek_test.iml b/.idea/modules/MegaMek_test.iml deleted file mode 100644 index 280b8d6e08e..00000000000 --- a/.idea/modules/MegaMek_test.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/megamek/megamek_main.iml b/.idea/modules/megamek/megamek_main.iml deleted file mode 100644 index 150b3627daf..00000000000 --- a/.idea/modules/megamek/megamek_main.iml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/megamek/megamek_test.iml b/.idea/modules/megamek/megamek_test.iml deleted file mode 100644 index dc17e68f08f..00000000000 --- a/.idea/modules/megamek/megamek_test.iml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From b7ce52733b782c892aa30495823556ad743aadd2 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 7 Aug 2019 11:25:22 -0500 Subject: [PATCH 39/69] Added field for omnivehicle sponson/pintle turret fixed weight. --- megamek/src/megamek/common/Tank.java | 49 ++++++++++++++++++- .../src/megamek/common/loaders/BLKFile.java | 4 ++ .../loaders/BLKLargeSupportTankFile.java | 4 ++ .../common/loaders/BLKSupportTankFile.java | 4 ++ .../common/loaders/BLKSupportVTOLFile.java | 4 ++ .../megamek/common/loaders/BLKTankFile.java | 4 ++ .../megamek/common/loaders/BLKVTOLFile.java | 4 +- 7 files changed, 69 insertions(+), 4 deletions(-) diff --git a/megamek/src/megamek/common/Tank.java b/megamek/src/megamek/common/Tank.java index d97acd500bf..1ae1392c85c 100644 --- a/megamek/src/megamek/common/Tank.java +++ b/megamek/src/megamek/common/Tank.java @@ -157,8 +157,10 @@ public int getLocTurret2() { /** * Keeps track of the base weight of the turret for omni tanks. */ - private double baseChassisTurretWeight = -1; - private double baseChassisTurret2Weight = -1; + public static final int BASE_CHASSIS_TURRET_WT_UNASSIGNED = -1; + private double baseChassisTurretWeight = BASE_CHASSIS_TURRET_WT_UNASSIGNED; + private double baseChassisTurret2Weight = BASE_CHASSIS_TURRET_WT_UNASSIGNED; + private double baseChassisSponsonPintleWeight = BASE_CHASSIS_TURRET_WT_UNASSIGNED; /** * Keeps track of whether this vehicle has control systems. Trailers aren't @@ -4244,22 +4246,65 @@ && getCrew().isActive() && !hasQuirk(OptionsConstants.QUIRK_NEG_NO_EJECT); } + /** + * Used for omni vehicles, which must set the weight of turrets + * the base chassis, limiting the amount of pod space in the turret. + * + * @return The weight of the primary turret + */ public double getBaseChassisTurretWeight() { return baseChassisTurretWeight; } + /** + * Sets the fixed weight of the primary turret on a dual-turret omnivehicle. + * + * @param baseChassisTurretWeight The weight of the turret + */ public void setBaseChassisTurretWeight(double baseChassisTurretWeight) { this.baseChassisTurretWeight = baseChassisTurretWeight; } + /** + * Used for omni vehicles, which must set the weight of turrets + * the base chassis, limiting the amount of pod space in the turret. + * + * @return The weight of the second turret + */ public double getBaseChassisTurret2Weight() { return baseChassisTurret2Weight; } + /** + * Sets the fixed weight of the second turret on a dual-turret omnivehicle. + * + * @param baseChassisTurret2Weight The weight of the turret + */ public void setBaseChassisTurret2Weight(double baseChassisTurret2Weight) { this.baseChassisTurret2Weight = baseChassisTurret2Weight; } + /** + * Used for omni vehicles, which must set the weight of sponson or pintle mounts in + * the base chassis, limiting the amount of pod space in the turret(s). + * + * @return The weight of any pintle mounts (small support vee) or sponson mounts + * (combat vee and M/L support vee) + */ + public double getBaseChassisSponsonPintleWeight() { + return baseChassisSponsonPintleWeight; + } + + /** + * Sets the fixed weight of any pintle (small SV) or sponson (CV, M/L SV) turrets + * on an omnivehicle. + * + * @param baseChassisSponsonPintleWeight The weight of the sponson/pintle turrets. + */ + public void setBaseChassisSponsonPintleWeight(double baseChassisSponsonPintleWeight) { + this.baseChassisSponsonPintleWeight = baseChassisSponsonPintleWeight; + } + public boolean hasNoControlSystems() { return hasNoControlSystems; } diff --git a/megamek/src/megamek/common/loaders/BLKFile.java b/megamek/src/megamek/common/loaders/BLKFile.java index 6aae020b8b5..bb8cfd14c3d 100644 --- a/megamek/src/megamek/common/loaders/BLKFile.java +++ b/megamek/src/megamek/common/loaders/BLKFile.java @@ -845,6 +845,10 @@ public static BuildingBlock getBlock(Entity t) { blk.writeBlockData("baseChassisTurret2Weight", tank.getBaseChassisTurret2Weight()); } + if (tank.getBaseChassisSponsonPintleWeight() >= 0) { + blk.writeBlockData("baseChassisSponsonPintleWeight", + tank.getBaseChassisSponsonPintleWeight()); + } } if (t.isSupportVehicle() && t.isOmni()) { diff --git a/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java b/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java index 07b75aa8675..440c0bba043 100644 --- a/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java @@ -218,6 +218,10 @@ public Entity getEntity() throws EntityLoadingException { t.setBaseChassisTurret2Weight(dataFile.getDataAsDouble("baseChassisTurret2Weight")[0]); } + if (dataFile.exists("baseChassisSponsonPintleWeight")) { + t.setBaseChassisSponsonPintleWeight(dataFile.getDataAsDouble("baseChassisSponsonPintleWeight")[0]); + } + if (dataFile.exists("hasNoControlSystems")) { t.setHasNoControlSystems(true); } diff --git a/megamek/src/megamek/common/loaders/BLKSupportTankFile.java b/megamek/src/megamek/common/loaders/BLKSupportTankFile.java index 15927eaf2ae..2a48f342063 100644 --- a/megamek/src/megamek/common/loaders/BLKSupportTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKSupportTankFile.java @@ -211,6 +211,10 @@ public Entity getEntity() throws EntityLoadingException { t.setBaseChassisTurret2Weight(dataFile.getDataAsDouble("baseChassisTurret2Weight")[0]); } + if (dataFile.exists("baseChassisSponsonPintleWeight")) { + t.setBaseChassisSponsonPintleWeight(dataFile.getDataAsDouble("baseChassisSponsonPintleWeight")[0]); + } + if (dataFile.exists("baseChassisFireConWeight")) { t.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); } diff --git a/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java b/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java index f81db2dfebb..0280ac83db6 100644 --- a/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java +++ b/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java @@ -201,6 +201,10 @@ public Entity getEntity() throws EntityLoadingException { t.setBaseChassisTurretWeight(dataFile.getDataAsDouble("baseChassisTurretWeight")[0]); } + if (dataFile.exists("baseChassisSponsonPintleWeight")) { + t.setBaseChassisSponsonPintleWeight(dataFile.getDataAsDouble("baseChassisSponsonPintleWeight")[0]); + } + if (dataFile.exists("hasNoControlSystems")) { t.setHasNoControlSystems(true); } diff --git a/megamek/src/megamek/common/loaders/BLKTankFile.java b/megamek/src/megamek/common/loaders/BLKTankFile.java index 6456a0e9bfc..4625ed18766 100644 --- a/megamek/src/megamek/common/loaders/BLKTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKTankFile.java @@ -273,6 +273,10 @@ public Entity getEntity() throws EntityLoadingException { t.setBaseChassisTurret2Weight(dataFile.getDataAsDouble("baseChassisTurret2Weight")[0]); } + if (dataFile.exists("baseChassisSponsonPintleWeight")) { + t.setBaseChassisSponsonPintleWeight(dataFile.getDataAsDouble("baseChassisSponsonPintleWeight")[0]); + } + if (dataFile.exists("hasNoControlSystems")) { t.setHasNoControlSystems(true); } diff --git a/megamek/src/megamek/common/loaders/BLKVTOLFile.java b/megamek/src/megamek/common/loaders/BLKVTOLFile.java index 493660e3e33..8bac0316f01 100644 --- a/megamek/src/megamek/common/loaders/BLKVTOLFile.java +++ b/megamek/src/megamek/common/loaders/BLKVTOLFile.java @@ -171,8 +171,8 @@ public Entity getEntity() throws EntityLoadingException { t.setBaseChassisTurretWeight(dataFile.getDataAsDouble("baseChassisTurretWeight")[0]); } - if (dataFile.exists("baseChassisFireConWeight")) { - t.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); + if (dataFile.exists("baseChassisSponsonPintleWeight")) { + t.setBaseChassisSponsonPintleWeight(dataFile.getDataAsDouble("baseChassisSponsonPintleWeight")[0]); } return t; From a47fe6e5fe15d2c3789ebb4c845de916eec76c1a Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 7 Aug 2019 17:08:28 -0500 Subject: [PATCH 40/69] Updated TestSupportVehicle Added methods for checking legality of sponson and pintle mounts. --- .../common/verifier/TestSupportVehicle.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index ea891b668ce..c060ce3c956 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -511,6 +511,33 @@ public static double armorWeightPerPoint(Entity vee) { } } + /** + * Checks whether the support vehicle can mount sponson turrets (TO, p. 348) + * + * @param type The support vehicle type + * @param small Whether the {@link Entity} is a small support vehicle + * @return Whether the vehicle can use sponson turrets. + */ + public static boolean sponsonLegal(SVType type, boolean small) { + return !small + && (type != SVType.FIXED_WING) + && (type != SVType.AIRSHIP) + && (type != SVType.SATELLITE); + } + + /** + * Checks whether the support vehicle can mount pintle turrets (TM, p. 348) + * + * @param type The support vehicle type + * @param small Whether the {@link Entity} is a small support vehicle + * @return Whether the vehicle can use pintle turrets. + */ + public static boolean pintleLegal(SVType type, boolean small) { + return small + && (type != SVType.FIXED_WING) + && (type != SVType.NAVAL); + } + private final Entity supportVee; /** Used by support tanks for calculation of turret weight */ private final TestTank testTank; @@ -736,6 +763,16 @@ public String printWeightControls() { return fireCon + crewStr; } + public boolean canUseSponsonTurret() { + return sponsonLegal(SVType.getVehicleType(getEntity()), + getEntity().getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT); + } + + public boolean canUsePintleTurret() { + return pintleLegal(SVType.getVehicleType(getEntity()), + getEntity().getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT); + } + @Override public boolean correctEntity(StringBuffer buff) { return false; From 1fc2455c001cbed62839150a9e728ead53b5736f Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 12 Aug 2019 20:56:28 -0500 Subject: [PATCH 41/69] Account for omni base chassis weight in sponson/pintle tonnage calculations. --- megamek/src/megamek/common/MiscType.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/megamek/src/megamek/common/MiscType.java b/megamek/src/megamek/common/MiscType.java index 34078f606db..b848fcc13f0 100644 --- a/megamek/src/megamek/common/MiscType.java +++ b/megamek/src/megamek/common/MiscType.java @@ -520,6 +520,13 @@ public double getTonnage(Entity entity, int location) { weaponWeight /= 10; return Math.ceil(weaponWeight * 2.0f) / 2.0f; } else if (hasFlag(F_SPONSON_TURRET)) { + // For omni vehicles, this should be set as part of the base chassis. + if ((entity.isOmni() && (entity instanceof Tank) + && ((Tank) entity).getBaseChassisSponsonPintleWeight() >= 0)) { + // Split between the two mounts + return ((Tank) entity).getBaseChassisSponsonPintleWeight() / + entity.countWorkingMisc(MiscType.F_SPONSON_TURRET); + } /* The sponson turret mechanism is equal to 10% of the weight of all mounted weapons, rounded * up to the half ton. Since the turrets come in pairs, splitting the weight between them * may result in a quarter-ton result for a single turret, but the overall unit weight will @@ -534,6 +541,13 @@ public double getTonnage(Entity entity, int location) { weaponWeight /= 10.0; return Math.ceil(weaponWeight * 2.0) / 2.0 / entity.countWorkingMisc(MiscType.F_SPONSON_TURRET); } else if (hasFlag(F_PINTLE_TURRET)) { + // For omnivehicles the weight should be set as chassis fixed weight. + // Split the weight evenly among the mounts to assure the total weight is correct. + if ((entity.isOmni() && (entity instanceof Tank) + && ((Tank) entity).getBaseChassisSponsonPintleWeight() >= 0)) { + return ((Tank) entity).getBaseChassisSponsonPintleWeight() / + entity.countWorkingMisc(MiscType.F_PINTLE_TURRET); + } double weaponWeight = 0; // 5% of linked weapons' weight for (Mounted m : entity.getWeaponList()) { From 1f8d1eb4aed6a5786cd4870447fc97ceeb97e5c8 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 13 Aug 2019 11:32:55 -0500 Subject: [PATCH 42/69] Added boolean field to Tank to mark trailer status. Support vees instead check for trailer chassis modification. --- .../src/megamek/common/SuperHeavyTank.java | 6 ++++- megamek/src/megamek/common/SupportTank.java | 5 ++++ megamek/src/megamek/common/Tank.java | 27 ++++++++++++------- .../src/megamek/common/loaders/BLKFile.java | 3 +++ .../megamek/common/loaders/BLKTankFile.java | 4 +-- 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/megamek/src/megamek/common/SuperHeavyTank.java b/megamek/src/megamek/common/SuperHeavyTank.java index df4a27ba755..da6906b8c6f 100644 --- a/megamek/src/megamek/common/SuperHeavyTank.java +++ b/megamek/src/megamek/common/SuperHeavyTank.java @@ -568,5 +568,9 @@ public String getBattleForceLocationName(int index) { } return "?"; } - + + @Override + public boolean isTrailer() { + return hasWorkingMisc(MiscType.F_TRAILER_MODIFICATION); + } } diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index e38942ce25e..0bd609f0cd4 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -492,4 +492,9 @@ public boolean isSupportVehicle() { return true; } + @Override + public boolean isTrailer() { + return hasWorkingMisc(MiscType.F_TRAILER_MODIFICATION); + } + } diff --git a/megamek/src/megamek/common/Tank.java b/megamek/src/megamek/common/Tank.java index b57d155be5f..69390f068fa 100644 --- a/megamek/src/megamek/common/Tank.java +++ b/megamek/src/megamek/common/Tank.java @@ -162,6 +162,11 @@ public int getLocTurret2() { private double baseChassisTurret2Weight = BASE_CHASSIS_TURRET_WT_UNASSIGNED; private double baseChassisSponsonPintleWeight = BASE_CHASSIS_TURRET_WT_UNASSIGNED; + /** + * Flag to indicate unit is constructed as a trailer. Trailers do not require + * control systems or engines unless they are intended for independent operation. + */ + private boolean trailer = false; /** * Keeps track of whether this vehicle has control systems. Trailers aren't * required to have control systems. @@ -4329,19 +4334,21 @@ public int getSpriteDrawPriority() { /** * Used to determine if this vehicle can be towed by a tractor * - * @return + * @return Whether the unit is constructed as a trailer */ @Override public boolean isTrailer() { - if (hasMisc(MiscType.F_TRAILER_MODIFICATION)) { - return true; - } - //Maybe an exploit here if it starts returning true for vehicles that get disabled - //but maybe we want to be able to tow those off the field too? - if (hasMisc(MiscType.F_HITCH) && getWalkMP() == 0) { - return true; - } - return false; + return trailer; + } + + /** + * Marks whether the tank is constructed as a trailer. This has no effect on + * support vehicles, which determine trailer status by the trailer chassis modification. + * + * @param trailer Whether the tank is constructed as a trailer. + */ + public void setTrailer(boolean trailer) { + this.trailer = trailer; } /** diff --git a/megamek/src/megamek/common/loaders/BLKFile.java b/megamek/src/megamek/common/loaders/BLKFile.java index bb8cfd14c3d..accd05d4aa1 100644 --- a/megamek/src/megamek/common/loaders/BLKFile.java +++ b/megamek/src/megamek/common/loaders/BLKFile.java @@ -861,6 +861,9 @@ public static BuildingBlock getBlock(Entity t) { if (tank.hasNoControlSystems()) { blk.writeBlockData("hasNoControlSystems", 1); } + if (!t.isSupportVehicle() && t.isTrailer()) { + blk.writeBlockData("trailer", 1); + } } if (t instanceof SmallCraft) { diff --git a/megamek/src/megamek/common/loaders/BLKTankFile.java b/megamek/src/megamek/common/loaders/BLKTankFile.java index 4625ed18766..087e3894fd6 100644 --- a/megamek/src/megamek/common/loaders/BLKTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKTankFile.java @@ -281,8 +281,8 @@ public Entity getEntity() throws EntityLoadingException { t.setHasNoControlSystems(true); } - if (dataFile.exists("baseChassisFireConWeight")) { - t.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); + if (dataFile.exists("trailer")) { + t.setHasNoControlSystems(true); } return t; From 8fa62e78a5a1f5538146090fe8693dd6433f8cae Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 19 Aug 2019 13:38:16 -0500 Subject: [PATCH 43/69] Added external engine type. Used by rail support vehicles with external power chassis mod. Code cleanup on Engine.java. --- .../i18n/megamek/common/messages.properties | 1 + megamek/src/megamek/common/Engine.java | 164 +++++++++--------- 2 files changed, 87 insertions(+), 78 deletions(-) diff --git a/megamek/i18n/megamek/common/messages.properties b/megamek/i18n/megamek/common/messages.properties index 2c7c4655d51..f6b0d7d3c85 100644 --- a/megamek/i18n/megamek/common/messages.properties +++ b/megamek/i18n/megamek/common/messages.properties @@ -40,6 +40,7 @@ Engine.None=\ None Engine.Steam=\ Steam Engine.Battery=\ Battery Engine.Solar=\ Solar +Engine.External=\ External Entity.sensor_range_vs_ground_target=Air to Ground Range EntityWeightClass.0=Ultra Light/PA(L)/Exoskeleton EntityWeightClass.1=Light diff --git a/megamek/src/megamek/common/Engine.java b/megamek/src/megamek/common/Engine.java index 8b043d8ff14..41257d942eb 100644 --- a/megamek/src/megamek/common/Engine.java +++ b/megamek/src/megamek/common/Engine.java @@ -32,7 +32,7 @@ public class Engine implements Serializable, ITechnology { */ private static final long serialVersionUID = -246032529363109609L; - public final static double[] ENGINE_RATINGS = { 0.0, 0.25, 0.5, 0.5, + private final static double[] ENGINE_RATINGS = { 0.0, 0.25, 0.5, 0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0, 1.5, 1.5, 1.5, 2.0, 2.0, 2.0, 2.5, 2.5, 3.0, 3.0, 3.0, 3.5, 3.5, 4.0, 4.0, 4.0, 4.5, 4.5, 5.0, 5.0, 5.5, 5.5, 6.0, 6.0, 6.0, 7.0, 7.0, @@ -70,17 +70,19 @@ public class Engine implements Serializable, ITechnology { public final static int STEAM = 10; public final static int BATTERY = 11; public final static int SOLAR = 12; + public final static int EXTERNAL = 13; + private final static int NUM_ENGINE_TYPES = 14; /** Keys for retrieving engine name from {@link Messages} */ private final static String[] TYPE_KEYS = { "ICE", "Fusion", "XL", "XXL", "FuelCell", "Light", "Compact", "Fission", "None", - "MagLev", "Steam", "Battery", "Solar" + "MagLev", "Steam", "Battery", "Solar", "External" }; //These are the SUPPORT VEHICLE ENGINE WEIGHT MULTIPLIERS from TM PG 127 //The other engine types are assumed to have a value of ) in the array //if not listed. - public final static double[][] SV_ENGINE_RATINGS = new double[13][6]; + private final static double[][] SV_ENGINE_RATINGS = new double[NUM_ENGINE_TYPES][6]; static { SV_ENGINE_RATINGS[STEAM][EquipmentType.RATING_A] = 4.0; SV_ENGINE_RATINGS[STEAM][EquipmentType.RATING_B] = 3.5; @@ -123,13 +125,27 @@ public class Engine implements Serializable, ITechnology { SV_ENGINE_RATINGS[FISSION][EquipmentType.RATING_D] = 1.5; SV_ENGINE_RATINGS[FISSION][EquipmentType.RATING_E] = 1.4; SV_ENGINE_RATINGS[FISSION][EquipmentType.RATING_F] = 1.3; - + SV_ENGINE_RATINGS[NORMAL_ENGINE][EquipmentType.RATING_A] = 0.0; SV_ENGINE_RATINGS[NORMAL_ENGINE][EquipmentType.RATING_B] = 0.0; SV_ENGINE_RATINGS[NORMAL_ENGINE][EquipmentType.RATING_C] = 1.5; SV_ENGINE_RATINGS[NORMAL_ENGINE][EquipmentType.RATING_D] = 1.0; SV_ENGINE_RATINGS[NORMAL_ENGINE][EquipmentType.RATING_E] = 0.75; SV_ENGINE_RATINGS[NORMAL_ENGINE][EquipmentType.RATING_F] = 0.5; + + SV_ENGINE_RATINGS[NONE][EquipmentType.RATING_A] = 0.0; + SV_ENGINE_RATINGS[NONE][EquipmentType.RATING_B] = 0.0; + SV_ENGINE_RATINGS[NONE][EquipmentType.RATING_C] = 0.0; + SV_ENGINE_RATINGS[NONE][EquipmentType.RATING_D] = 0.0; + SV_ENGINE_RATINGS[NONE][EquipmentType.RATING_E] = 0.0; + SV_ENGINE_RATINGS[NONE][EquipmentType.RATING_F] = 0.0; + + SV_ENGINE_RATINGS[EXTERNAL][EquipmentType.RATING_A] = 0.0; + SV_ENGINE_RATINGS[EXTERNAL][EquipmentType.RATING_B] = 1.4; + SV_ENGINE_RATINGS[EXTERNAL][EquipmentType.RATING_C] = 1.0; + SV_ENGINE_RATINGS[EXTERNAL][EquipmentType.RATING_D] = 0.8; + SV_ENGINE_RATINGS[EXTERNAL][EquipmentType.RATING_E] = 0.7; + SV_ENGINE_RATINGS[EXTERNAL][EquipmentType.RATING_F] = 0.6; } @@ -172,10 +188,7 @@ public Engine(int engineRating, int engineType, int engineFlags) { * @return true if the flag is set. */ public boolean hasFlag(int flag) { - if ((engineFlags & flag) != 0) { - return true; - } - return false; + return (engineFlags & flag) != 0; } /** @@ -186,7 +199,7 @@ public boolean hasFlag(int flag) { private boolean isValidEngine() { if (hasFlag(~(CLAN_ENGINE | TANK_ENGINE | LARGE_ENGINE | SUPERHEAVY_ENGINE | SUPPORT_VEE_ENGINE))) { - problem.append("Flags:" + engineFlags); + problem.append("Flags:").append(engineFlags); return false; } @@ -194,14 +207,15 @@ private boolean isValidEngine() { && (engineType != COMBUSTION_ENGINE) && (engineType != BATTERY) && (engineType != FUEL_CELL) && (engineType != SOLAR) && (engineType != FISSION) && (engineType != NORMAL_ENGINE) - && (engineType != MAGLEV) && (engineType != NONE)) { + && (engineType != MAGLEV) && (engineType != NONE) + && (engineType != EXTERNAL)) { problem.append("Invalid Engine type for support vehicle engines!"); return false; } if ((((int) Math.ceil(engineRating / 5) > ENGINE_RATINGS.length) || (engineRating < 0)) && !hasFlag(SUPPORT_VEE_ENGINE)) { - problem.append("Rating:" + engineRating); + problem.append("Rating:").append(engineRating); return false; } if ((engineRating > 400) && !hasFlag(SUPPORT_VEE_ENGINE)) { @@ -219,6 +233,7 @@ private boolean isValidEngine() { case BATTERY: case SOLAR: case STEAM: + case EXTERNAL: break; case COMPACT_ENGINE: if (hasFlag(LARGE_ENGINE)) { @@ -236,7 +251,7 @@ private boolean isValidEngine() { } break; default: - problem.append("Type:" + engineType); + problem.append("Type:").append(engineType); return false; } @@ -250,33 +265,33 @@ private boolean isValidEngine() { * @return the type of the engine. */ public static int getEngineTypeByString(String type) { - if (type.toLowerCase().indexOf("xxl") != -1) { + if (type.toLowerCase().contains("xxl")) { return XXL_ENGINE; - } else if (type.toLowerCase().indexOf("xl") != -1) { + } else if (type.toLowerCase().contains("xl")) { return XL_ENGINE; - } else if (type.toLowerCase().indexOf("light") != -1) { + } else if (type.toLowerCase().contains("light")) { return LIGHT_ENGINE; - } else if (type.toLowerCase().indexOf("compact") != -1) { + } else if (type.toLowerCase().contains("compact")) { return COMPACT_ENGINE; - } else if (type.toLowerCase().indexOf("ice") != -1) { + } else if (type.toLowerCase().contains("ice")) { return COMBUSTION_ENGINE; - } else if (type.toLowerCase().indexOf("i.c.e.") != -1) { + } else if (type.toLowerCase().contains("i.c.e.")) { return COMBUSTION_ENGINE; - } else if (type.toLowerCase().indexOf("fission") != -1) { + } else if (type.toLowerCase().contains("fission")) { return FISSION; - } else if (type.toLowerCase().indexOf("fuel cell") != -1) { + } else if (type.toLowerCase().contains("fuel cell")) { return FUEL_CELL; - } else if (type.toLowerCase().indexOf("fuel-cell") != -1) { + } else if (type.toLowerCase().contains("fuel-cell")) { return FUEL_CELL; - } else if (type.toLowerCase().indexOf("none") != -1) { + } else if (type.toLowerCase().contains("none")) { return NONE; - } else if (type.toLowerCase().indexOf("maglev") != -1) { + } else if (type.toLowerCase().contains("maglev")) { return MAGLEV; - } else if (type.toLowerCase().indexOf("steam") != -1) { + } else if (type.toLowerCase().contains("steam")) { return STEAM; - } else if (type.toLowerCase().indexOf("battery") != -1) { + } else if (type.toLowerCase().contains("battery")) { return BATTERY; - } else if (type.toLowerCase().indexOf("solar") != -1) { + } else if (type.toLowerCase().contains("solar")) { return SOLAR; } else { return NORMAL_ENGINE; @@ -289,12 +304,9 @@ public static int getEngineTypeByString(String type) { * @return true if it is not an internal combustion engine. */ public boolean isFusion() { - if ((engineType == COMBUSTION_ENGINE) || (engineType == FISSION) || (engineType == FUEL_CELL) || (engineType == NONE) - || (engineType == BATTERY) || (engineType == SOLAR) || (engineType == STEAM) || (engineType == MAGLEV) - ) { - return false; - } - return true; + return (engineType != COMBUSTION_ENGINE) && (engineType != FISSION) && (engineType != FUEL_CELL) + && (engineType != NONE) && (engineType != BATTERY) && (engineType != SOLAR) + && (engineType != STEAM) && (engineType != MAGLEV) && (engineType != EXTERNAL); } @@ -392,8 +404,7 @@ && isValidEngine()) { } /** - * return the number of heatsinks that fit weight-free into the engine - * @return + * @return the number of heatsinks that fit weight-free into the engine */ public int getWeightFreeEngineHeatSinks() { // Support Vee engines never provide free heat-sinks, TM pg 133 @@ -450,8 +461,8 @@ public String getShortEngineName() { // Don't localize the marked strings below since they are used in mech // file parsing. public String getEngineName() { - StringBuffer sb = new StringBuffer(); - sb.append(Integer.toString(engineRating)); + StringBuilder sb = new StringBuilder(); + sb.append(engineRating); if (hasFlag(LARGE_ENGINE)) { sb.append(Messages.getString("Engine.Large")); } @@ -508,18 +519,14 @@ public String getEngineName() { } /** - * Returns the rating of the engine. - * - * @return + * @return The rating of the engine */ public int getRating() { return engineRating; } /** - * returns the slots taken up by the engine in the center torso. - * - * @return + * @return The slots taken up by the engine in the center torso. */ public int[] getCenterTorsoCriticalSlots(int gyroType) { if (engineType == COMPACT_ENGINE) { @@ -577,9 +584,7 @@ public int[] getCenterTorsoCriticalSlots(int gyroType) { } /** - * Returns the engine criticals in the side torsos. - * - * @return + * @return the engine criticals in the side torsos. */ public int[] getSideTorsoCriticalSlots() { if ((engineType == LIGHT_ENGINE) @@ -616,25 +621,23 @@ public int[] getSideTorsoCriticalSlots() { } return slots; } else { - int[] slots = {}; - return slots; + return new int[]{}; } } /** - * Return the heat generated while the mech is standing still. - * - * @return + * @return the heat generated while the mech is standing still. */ public int getStandingHeat() { - switch (engineType) { - case XXL_ENGINE: - return 2; - default: - return 0; + if (engineType == XXL_ENGINE) { + return 2; } + return 0; } + /** + * @return the heat generated while the mech is walking. + */ public int getWalkHeat(Entity e) { switch (engineType) { case COMBUSTION_ENGINE: @@ -647,6 +650,9 @@ public int getWalkHeat(Entity e) { } } + /** + * @return the heat generated while the mech is running. + */ public int getRunHeat(Entity e) { switch (engineType) { case COMBUSTION_ENGINE: @@ -659,6 +665,9 @@ public int getRunHeat(Entity e) { } } + /** + * @return the heat generated while the mech is sprinting. + */ public int getSprintHeat() { switch (engineType) { case COMBUSTION_ENGINE: @@ -671,13 +680,14 @@ public int getSprintHeat() { } } + /** + * @return the heat generated while the mech is jumping. + */ public int getJumpHeat(int movedMP) { - switch (engineType) { - case XXL_ENGINE: - return Math.max(6, movedMP * 2); - default: - return Math.max(3, movedMP); + if (engineType == XXL_ENGINE) { + return Math.max(6, movedMP * 2); } + return Math.max(3, movedMP); } public double getBVMultiplier() { @@ -875,12 +885,16 @@ public int getBaseCost() { .setAdvancement(DATE_ES, DATE_ES, DATE_ES).setTechRating(RATING_C) .setAvailability(RATING_D, RATING_F, RATING_E, RATING_D) .setStaticTechLevel(SimpleTechLevel.STANDARD); - + private static final TechAdvancement SUPPORT_NONE_TA = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS).setTechRating(RATING_A) .setAvailability(RATING_A, RATING_A, RATING_A, RATING_A) .setStaticTechLevel(SimpleTechLevel.STANDARD); + private static final TechAdvancement SUPPORT_EXTERNAL_TA = new TechAdvancement(TECH_BASE_ALL) + .setAdvancement(DATE_NONE, DATE_NONE, DATE_PS) + .setTechRating(RATING_B).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C); + public TechAdvancement getTechAdvancement() { switch(engineType) { case COMBUSTION_ENGINE: @@ -961,6 +975,8 @@ public TechAdvancement getTechAdvancement() { return SUPPORT_SOLAR_TA; case NONE: return SUPPORT_NONE_TA; + case EXTERNAL: + return SUPPORT_EXTERNAL_TA; default: return new TechAdvancement(); } @@ -968,8 +984,8 @@ public TechAdvancement getTechAdvancement() { /** * Return the tech type (tech level + tech base) for the current engine. * - * @param year - * @return + * @param year The game year + * @return The tech constant */ public int getTechType(int year) { boolean isLarge = hasFlag(LARGE_ENGINE); @@ -1051,7 +1067,6 @@ public int getTechType(int year) { return TechConstants.T_CLAN_UNOFFICIAL; } else if (year <= 3125) { return TechConstants.T_CLAN_EXPERIMENTAL; - } else { return TechConstants.T_CLAN_ADVANCED; } @@ -1071,11 +1086,7 @@ public int getTechType(int year) { } else if (year <= 3130) { return TechConstants.T_IS_EXPERIMENTAL; } else { - if (year <= 3050) { - return TechConstants.T_IS_EXPERIMENTAL; - } else if (year <= 3105) { - return TechConstants.T_IS_ADVANCED; - } + return TechConstants.T_IS_ADVANCED; } } case FISSION: @@ -1166,14 +1177,11 @@ public int getTechType(int year) { return TechConstants.T_ALLOWED_ALL; } case MAGLEV: - return TechConstants.T_ALLOWED_ALL; case STEAM: - return TechConstants.T_ALLOWED_ALL; case BATTERY: - return TechConstants.T_ALLOWED_ALL; case SOLAR: - return TechConstants.T_ALLOWED_ALL; case NONE: + case EXTERNAL: return TechConstants.T_ALLOWED_ALL; case COMPACT_ENGINE: if (isClan) { @@ -1199,21 +1207,21 @@ public int getEngineType() { } /** - * For omnis set the base Chassies HS any variants will only use this and the reset will have to be added. + * For omnis set the base Chassies HS any variants will only use this and the reset + * will have to be added. * - * @param amount - * @return + * @param amount The number to set as base chassis heat sinks */ public void setBaseChassisHeatSinks(int amount) { baseChassisHeatSinks = amount; } /** - * Return the Base Chassies Engine heat Sinks or intergalHeatSinkCapacity which ever is less. + * Return the Base Chassies Engine heat Sinks or integralHeatSinkCapacity which ever is less. * * @param compact Whether this engine uses compact heat sinks or not. * - * @return + * @return The number of integral heat sinks in the base chassis */ public int getBaseChassisHeatSinks(boolean compact) { return Math.min(integralHeatSinkCapacity(compact), baseChassisHeatSinks); From d99e78310ddd71ce3bf2a1127ac5039c2c113352 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 19 Aug 2019 13:43:08 -0500 Subject: [PATCH 44/69] Support for trailers with no engine. --- megamek/src/megamek/common/MiscType.java | 3 ++- .../megamek/common/verifier/TestSupportVehicle.java | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/megamek/src/megamek/common/MiscType.java b/megamek/src/megamek/common/MiscType.java index b848fcc13f0..33a8b4518e1 100644 --- a/megamek/src/megamek/common/MiscType.java +++ b/megamek/src/megamek/common/MiscType.java @@ -282,6 +282,7 @@ public class MiscType extends EquipmentType { public static final BigInteger F_SDS_JAMMER = BigInteger.valueOf(1).shiftLeft(220); public static final BigInteger F_LF_STORAGE_BATTERY = BigInteger.valueOf(1).shiftLeft(199); public static final BigInteger F_PROTOMECH_MELEE = BigInteger.valueOf(1).shiftLeft(200); + public static final BigInteger F_EXTERNAL_POWER_PICKUP = BigInteger.valueOf(1).shiftLeft(201); // Secondary Flags for Physical Weapons @@ -10238,7 +10239,7 @@ public static MiscType createExternalPowerPickup() { misc.tonnage = 0; misc.criticals = 0; misc.cost = 0; // Cost accounted as part of unit cost - misc.flags = misc.flags.or(F_SUPPORT_TANK_EQUIPMENT).or(F_CHASSIS_MODIFICATION); + misc.flags = misc.flags.or(F_SUPPORT_TANK_EQUIPMENT).or(F_CHASSIS_MODIFICATION).or(F_EXTERNAL_POWER_PICKUP); misc.omniFixedOnly = true; misc.bv = 0; misc.rulesRefs = "243,TO"; diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index c060ce3c956..a43b84a0c4b 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -308,7 +308,8 @@ public enum SVEngine implements ITechnologyDelegator { FISSION (Engine.FISSION), FUSION (Engine.NORMAL_ENGINE), MAGLEV (Engine.MAGLEV, EnumSet.of(SVType.RAIL)), - EXTERNAL (Engine.NONE, EnumSet.of(SVType.RAIL), true); + EXTERNAL (Engine.EXTERNAL, EnumSet.of(SVType.RAIL), true), + NONE (Engine.NONE, EnumSet.of(SVType.WHEELED, SVType.TRACKED), false); /** The engine type constant used to create a new {@link Engine}. */ public final Engine engine; @@ -365,6 +366,9 @@ public boolean isValidFor(SVType type) { * @return Whether the engine is valid for the support vee. */ public boolean isValidFor(Entity entity) { + if ((this == NONE) && !entity.isTrailer()) { + return false; + } return isValidFor(SVType.getVehicleType(entity)); } @@ -420,8 +424,8 @@ public ITechnology getTechSource() { * Filters all vehicle armor according to given tech constraints. Standard armor is treated as basic * support vehicle armor. * - * @param techManager - * @return + * @param techManager Applies the filtering criteria + * @return A list of armor equipment that meets the tech constraints */ public static List legalArmorsFor(ITechManager techManager) { if (techManager.getTechLevel().ordinal() < SimpleTechLevel.ADVANCED.ordinal()) { From ba066f4f683b1992b7c392a76c90ca28fc84940e Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 19 Aug 2019 14:05:51 -0500 Subject: [PATCH 45/69] Added method to determine when chassis mod is required. Fixed wing with electric engine -> Prop Rail with external engine -> external power pickup. --- .../common/verifier/TestSupportVehicle.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index a43b84a0c4b..e654ad9bc90 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -238,6 +238,25 @@ public boolean validFor(Entity sv) { && (!smallOnly || (sv.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT)); } + /** + * Checks whether something about the vehicle requires a specific chassis mod. + * + * @param sv A support vehicle + * @return Whether this chassis mod is required by the vehicle. + */ + public boolean requiredFor(Entity sv) { + switch (this) { + case PROP: + return sv instanceof FixedWingSupport + && SVEngine.getEngineType(sv.getEngine()).electric; + case EXTERNAL_POWER_PICKUP: + return sv.getMovementMode().equals(EntityMovementMode.RAIL) + && SVEngine.getEngineType(sv.getEngine()).equals(SVEngine.EXTERNAL); + default: + return false; + } + } + /** * Checks for compatibility between different chassis modifications * From 50838c43c2107117258a936c845a436b9dbe2f7f Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 19 Aug 2019 14:35:55 -0500 Subject: [PATCH 46/69] Fixed rail engine weight calculation. --- megamek/src/megamek/common/Engine.java | 8 ++++++-- megamek/src/megamek/common/SupportTank.java | 9 +++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/megamek/src/megamek/common/Engine.java b/megamek/src/megamek/common/Engine.java index 41257d942eb..184e9c6eee3 100644 --- a/megamek/src/megamek/common/Engine.java +++ b/megamek/src/megamek/common/Engine.java @@ -331,8 +331,12 @@ public double getWeightEngine(Entity entity, TestEntity.Ceil roundWeight) { // Support Vehicles compute engine weight differently if ((entity.isSupportVehicle() || hasFlag(SUPPORT_VEE_ENGINE)) && isValidEngine()) { - double movementFactor = 4 + entity.getOriginalWalkMP() - * entity.getOriginalWalkMP(); + int mp = entity.getOriginalWalkMP(); + if (entity.getMovementMode().equals(EntityMovementMode.RAIL) + || entity.getMovementMode().equals(EntityMovementMode.MAGLEV)) { + mp = Math.max(1, mp - 2); + } + double movementFactor = 4 + mp * mp; double engineWeightMult = SV_ENGINE_RATINGS[engineType][entity .getEngineTechRating()]; double weight = entity.getBaseEngineValue() * movementFactor diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index 0bd609f0cd4..efd0e071bf1 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -356,6 +356,15 @@ public double getBaseEngineValue() { } else { return 0.006; } + case RAIL: + case MAGLEV: + if (getWeight() < 5) { + return 0.003; + } else if (!isSuperHeavy()) { + return 0.004; + } else { + return 0.005; + } default: return 0; } From 0d4d758641d4f65f72b4f430aa2d53e722b3ca5c Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 19 Aug 2019 17:55:29 -0500 Subject: [PATCH 47/69] Added rail as allowable non-engine trailer units. --- .../src/megamek/common/verifier/TestSupportVehicle.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index e654ad9bc90..65e1990b7d8 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -328,7 +328,7 @@ public enum SVEngine implements ITechnologyDelegator { FUSION (Engine.NORMAL_ENGINE), MAGLEV (Engine.MAGLEV, EnumSet.of(SVType.RAIL)), EXTERNAL (Engine.EXTERNAL, EnumSet.of(SVType.RAIL), true), - NONE (Engine.NONE, EnumSet.of(SVType.WHEELED, SVType.TRACKED), false); + NONE (Engine.NONE, EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.RAIL), false); /** The engine type constant used to create a new {@link Engine}. */ public final Engine engine; @@ -669,11 +669,6 @@ private double getWeightCrewAccomodations() { weight += ((Bay) t).getWeight(); } } - if (supportVee instanceof FixedWingSupport) { - weight += ((FixedWingSupport) supportVee).getExtraCrewSeats() * 0.5; - } else { - weight += ((Tank) supportVee).getExtraCrewSeats() * 0.5; - } return roundWeight(weight); } From 8cddf99a0e41c37f9613bb817100abdea4ab3a61 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 19 Aug 2019 20:42:13 -0500 Subject: [PATCH 48/69] Added missing String resources. --- .../i18n/megamek/client/messages.properties | 5 ++- .../i18n/megamek/common/messages.properties | 8 +++- megamek/src/megamek/common/Engine.java | 44 +------------------ 3 files changed, 11 insertions(+), 46 deletions(-) diff --git a/megamek/i18n/megamek/client/messages.properties b/megamek/i18n/megamek/client/messages.properties index e5a36ecf98f..203ca1b4908 100644 --- a/megamek/i18n/megamek/client/messages.properties +++ b/megamek/i18n/megamek/client/messages.properties @@ -1875,7 +1875,10 @@ MovementType.Aerodyne=Aerodyne MovementType.Spheroid=Spheroid MovementType.AirMech=AirMech MovementType.Fighter=Fighter - +MovementType.Rail=Rail +MovementType.MagLev=MagLev +MovementType.Airship=Airship +MovementType.StationKeeping=Station Keeping #Map/Hex Notes NoteDialog.action=Create/Edit Note NoteDialog.Done=Done diff --git a/megamek/i18n/megamek/common/messages.properties b/megamek/i18n/megamek/common/messages.properties index f6b0d7d3c85..58b8ae89f11 100644 --- a/megamek/i18n/megamek/common/messages.properties +++ b/megamek/i18n/megamek/common/messages.properties @@ -32,6 +32,7 @@ Engine.invalidSphereOnly=Light/Fission engines Inner Sphere only Engine.Large=\ Large Engine.Light=\ Light Engine.Vehicle=\ [Vehicle] +Engine.Fusion=\ Fusion Engine.XL=\ XL Engine.XXL=\ XXL Engine.Fission=\ Fission @@ -40,6 +41,7 @@ Engine.None=\ None Engine.Steam=\ Steam Engine.Battery=\ Battery Engine.Solar=\ Solar +Engine.MagLev=\ MagLev Engine.External=\ External Entity.sensor_range_vs_ground_target=Air to Ground Range EntityWeightClass.0=Ultra Light/PA(L)/Exoskeleton @@ -431,5 +433,7 @@ MovementType.Aerodyne=Aerodyne MovementType.Spheroid=Spheroid MovementType.AirMech=AirMech MovementType.Fighter=Fighter -Engine.MagLev=MagLev - +MovementType.Rail=Rail +MovementType.MagLev=MagLev +MovementType.Airship=Airship +MovementType.StationKeeping=Station Keeping \ No newline at end of file diff --git a/megamek/src/megamek/common/Engine.java b/megamek/src/megamek/common/Engine.java index 184e9c6eee3..43b6efd52ae 100644 --- a/megamek/src/megamek/common/Engine.java +++ b/megamek/src/megamek/common/Engine.java @@ -470,49 +470,7 @@ public String getEngineName() { if (hasFlag(LARGE_ENGINE)) { sb.append(Messages.getString("Engine.Large")); } - switch (engineType) { - case COMBUSTION_ENGINE: - sb.append(" ICE"); - break; - case NORMAL_ENGINE: - sb.append(" Fusion"); - break; - case XL_ENGINE: - sb.append(" XL"); - break; - case LIGHT_ENGINE: - sb.append(" Light"); - break; - case XXL_ENGINE: - sb.append(" XXL"); - break; - case COMPACT_ENGINE: - sb.append(" Compact"); - break; - case FUEL_CELL: - sb.append(" Fuel Cell"); - break; - case FISSION: - sb.append(" Fission"); - break; - case STEAM: - sb.append(" Steam"); - break; - case BATTERY: - sb.append(" Battery"); - break; - case SOLAR: - sb.append(" Solar"); - break; - case MAGLEV: - sb.append(" MagLev"); - break; - case NONE: - sb.append(" NONE"); - break; - default: - return problem.toString(); - } + sb.append(Messages.getString("Engine." + TYPE_KEYS[engineType])); if (hasFlag(CLAN_ENGINE)) { sb.append(Messages.getString("Engine.Clan")); } From d1bb4211ace23b77e2a78068d58068d63a2ac29b Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 19 Aug 2019 22:24:21 -0500 Subject: [PATCH 49/69] Handle saving and loading pod mounted bays and quarters. --- .../src/megamek/common/loaders/BLKFile.java | 83 ++++++++++++------- 1 file changed, 53 insertions(+), 30 deletions(-) diff --git a/megamek/src/megamek/common/loaders/BLKFile.java b/megamek/src/megamek/common/loaders/BLKFile.java index accd05d4aa1..930117a405e 100644 --- a/megamek/src/megamek/common/loaders/BLKFile.java +++ b/megamek/src/megamek/common/loaders/BLKFile.java @@ -45,6 +45,7 @@ public class BLKFile { public static final int STEAM = 10; public static final int BATTERY = 11; public static final int SOLAR = 12; + public static final int EXTERNAL = 13; private static final String COMSTAR_BAY = "c*"; @@ -188,7 +189,8 @@ static int translateEngineCode(int code) { return Engine.BATTERY; } else if (code == BLKFile.SOLAR) { return Engine.SOLAR; - + } else if (code == BLKFile.EXTERNAL) { + return Engine.EXTERNAL; } else { return -1; } @@ -463,8 +465,14 @@ public static BuildingBlock getBlock(Entity t) { blk.writeBlockData("motion_type", t.getMovementModeAsString()); String[] transporter_array = new String[t.getTransports().size()]; - for (int i = 0; i < t.getTransports().size(); i++) { - transporter_array[i] = t.getTransports().get(i).toString(); + int index = 0; + for (Transporter transporter : t.getTransports()) { + if (t.isPodMountedTransport(transporter)) { + transporter_array[index] = "omni:" + transporter.toString(); + } else { + transporter_array[index] = transporter.toString(); + } + index++; } blk.writeBlockData("transporters", transporter_array); @@ -520,6 +528,21 @@ public static BuildingBlock getBlock(Entity t) { case Engine.NONE: engineCode = BLKFile.NONE; break; + case Engine.MAGLEV: + engineCode = BLKFile.MAGLEV; + break; + case Engine.STEAM: + engineCode = BLKFile.STEAM; + break; + case Engine.BATTERY: + engineCode = BLKFile.BATTERY; + break; + case Engine.SOLAR: + engineCode = BLKFile.SOLAR; + break; + case Engine.EXTERNAL: + engineCode = BLKFile.EXTERNAL; + break; } blk.writeBlockData("engine_type", engineCode); } @@ -936,113 +959,113 @@ protected void addTransports(Entity e) { // TroopSpace: if (transporter.startsWith("troopspace:", 0)) { // Everything after the ':' should be the space's size. - double fsize = Double.valueOf(transporter.substring(11)); + double fsize = Double.parseDouble(transporter.substring(11)); e.addTransporter(new TroopSpace(fsize), isPod); } else if (transporter.startsWith("cargobay:", 0)) { String numbers = transporter.substring(9); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new CargoBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new CargoBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("liquidcargobay:", 0)) { String numbers = transporter.substring(15); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new LiquidCargoBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new LiquidCargoBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("insulatedcargobay:", 0)) { String numbers = transporter.substring(18); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new InsulatedCargoBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new InsulatedCargoBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("refrigeratedcargobay:", 0)) { String numbers = transporter.substring(21); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new RefrigeratedCargoBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new RefrigeratedCargoBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("livestockcargobay:", 0)) { String numbers = transporter.substring(18); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new LivestockCargoBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new LivestockCargoBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("asfbay:", 0)) { String numbers = transporter.substring(7); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new ASFBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new ASFBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("smallcraftbay:", 0)) { String numbers = transporter.substring(14); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new SmallCraftBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new SmallCraftBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("mechbay:", 0)) { String numbers = transporter.substring(8); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new MechBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new MechBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("lightvehiclebay:", 0)) { String numbers = transporter.substring(16); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new LightVehicleBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new LightVehicleBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("heavyvehiclebay:", 0)) { String numbers = transporter.substring(16); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new HeavyVehicleBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new HeavyVehicleBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("superheavyvehiclebay:", 0)) { String numbers = transporter.substring(21); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new SuperHeavyVehicleBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new SuperHeavyVehicleBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("infantrybay:", 0)) { String numbers = transporter.substring(12); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new InfantryBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber(), pbi.getPlatoonType())); + e.addTransporter(new InfantryBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber(), pbi.getPlatoonType()), isPod); } else if (transporter.startsWith("battlearmorbay:", 0)) { String numbers = transporter.substring(15); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); e.addTransporter(new BattleArmorBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber(), - e.isClan(), pbi.isComstarBay())); + e.isClan(), pbi.isComstarBay()), isPod); } else if (transporter.startsWith("bay:", 0)) { String numbers = transporter.substring(4); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new Bay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new Bay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("protomechbay:", 0)) { String numbers = transporter.substring(13); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new ProtomechBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber())); + e.addTransporter(new ProtomechBay(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber()), isPod); } else if (transporter.startsWith("dropshuttlebay:")) { String numbers = transporter.substring("dropshuttlebay:".length()); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new DropshuttleBay(pbi.getDoors(), pbi.getBayNumber(), pbi.getFacing())); + e.addTransporter(new DropshuttleBay(pbi.getDoors(), pbi.getBayNumber(), pbi.getFacing()), isPod); } else if (transporter.startsWith("navalrepairpressurized:")) { String numbers = transporter.substring("navalrepairpressurized:".length()); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new NavalRepairFacility(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber(), pbi.getFacing(), true)); + e.addTransporter(new NavalRepairFacility(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber(), pbi.getFacing(), true), isPod); } else if (transporter.startsWith("navalrepairunpressurized:")) { String numbers = transporter.substring("navalrepairunpressurized:".length()); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new NavalRepairFacility(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber(), pbi.getFacing(), false)); + e.addTransporter(new NavalRepairFacility(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber(), pbi.getFacing(), false), isPod); } else if (transporter.startsWith("reinforcedrepairfacility:")) { String numbers = transporter.substring("reinforcedrepairfacility:".length()); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new ReinforcedRepairFacility(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber(), pbi.getFacing())); + e.addTransporter(new ReinforcedRepairFacility(pbi.getSize(), pbi.getDoors(), pbi.getBayNumber(), pbi.getFacing()), isPod); } else if (transporter.startsWith("crewquarters:", 0)) { String numbers = transporter.substring(13); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new CrewQuartersCargoBay(pbi.getSize(), pbi.getDoors())); + e.addTransporter(new CrewQuartersCargoBay(pbi.getSize(), pbi.getDoors()), isPod); } else if (transporter.startsWith("steeragequarters:", 0)) { String numbers = transporter.substring(17); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new SteerageQuartersCargoBay(pbi.getSize(), pbi.getDoors())); + e.addTransporter(new SteerageQuartersCargoBay(pbi.getSize(), pbi.getDoors()), isPod); } else if (transporter.startsWith("2ndclassquarters:", 0)) { String numbers = transporter.substring(17); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new SecondClassQuartersCargoBay(pbi.getSize(), pbi.getDoors())); + e.addTransporter(new SecondClassQuartersCargoBay(pbi.getSize(), pbi.getDoors()), isPod); } else if (transporter.startsWith("1stclassquarters:", 0)) { String numbers = transporter.substring(17); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new FirstClassQuartersCargoBay(pbi.getSize(), pbi.getDoors())); + e.addTransporter(new FirstClassQuartersCargoBay(pbi.getSize(), pbi.getDoors()), isPod); } else if (transporter.startsWith("pillionseats:", 0)) { String numbers = transporter.substring(13); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new PillionSeatCargoBay(pbi.getSize())); + e.addTransporter(new PillionSeatCargoBay(pbi.getSize()), isPod); } else if (transporter.startsWith("standardseats:", 0)) { String numbers = transporter.substring(14); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new StandardSeatCargoBay(pbi.getSize())); + e.addTransporter(new StandardSeatCargoBay(pbi.getSize()), isPod); } else if (transporter.startsWith("ejectionseats:", 0)) { String numbers = transporter.substring("ejectionseats:".length()); ParsedBayInfo pbi = new ParsedBayInfo(numbers, usedBayNumbers); - e.addTransporter(new EjectionSeatCargoBay(pbi.getSize())); + e.addTransporter(new EjectionSeatCargoBay(pbi.getSize()), isPod); } else if (transporter.startsWith("dockingcollar", 0)) { //Add values for collars so they can be parsed and assigned a 'bay' number String numbers = "1.0:0"; From e0e58d31964c2d40623dccceb699d250b61cc457 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 20 Aug 2019 09:32:39 -0500 Subject: [PATCH 50/69] Separate spinners for pod-mounted quarters. Switch pod-mounted equipment to fixed when omni chassis mod is removed. --- megamek/src/megamek/common/loaders/BLKFile.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/megamek/src/megamek/common/loaders/BLKFile.java b/megamek/src/megamek/common/loaders/BLKFile.java index 930117a405e..a46d6d14ca3 100644 --- a/megamek/src/megamek/common/loaders/BLKFile.java +++ b/megamek/src/megamek/common/loaders/BLKFile.java @@ -467,10 +467,9 @@ public static BuildingBlock getBlock(Entity t) { String[] transporter_array = new String[t.getTransports().size()]; int index = 0; for (Transporter transporter : t.getTransports()) { + transporter_array[index] = transporter.toString(); if (t.isPodMountedTransport(transporter)) { - transporter_array[index] = "omni:" + transporter.toString(); - } else { - transporter_array[index] = transporter.toString(); + transporter_array[index] += ":omni"; } index++; } From 26763d7acf8bcf06d025efc83302fe3db5c76667 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 20 Aug 2019 13:44:20 -0500 Subject: [PATCH 51/69] Added some rail sprites to keep MM from barfing. --- .../units/defaults/default_maglev_tractor.png | Bin 0 -> 1052 bytes .../units/defaults/default_rail_tractor.png | Bin 0 -> 1307 bytes megamek/data/images/units/mechset.txt | 11402 ++++++++-------- .../Kallon Industries LevCar_ArrowIV.png | Bin 0 -> 972 bytes .../Kallon Industries LevCar_Gauss.png | Bin 0 -> 963 bytes .../Kallon Industries LevCar_LRM15.png | Bin 0 -> 961 bytes .../Kallon Industries LevCar_SRM6.png | Bin 0 -> 944 bytes .../Kallon Industries LevCar_UAC20.png | Bin 0 -> 997 bytes .../Kallon Industries LevCar_Weaponless.png | Bin 0 -> 952 bytes .../vehicles/Kallon Industries Nolan.png | Bin 0 -> 1052 bytes .../units/vehicles/MUSE Ironhorse_Tractor.png | Bin 0 -> 1307 bytes .../units/vehicles/MUSE Ironhorse_Trailer.png | Bin 0 -> 1137 bytes ...lante Passenger-Cargo Train (Standard).blk | 103 + ...TGV Omni Railcar Primary Configuration.blk | 107 + .../megamek/client/ui/swing/MechTileset.java | 32 + 15 files changed, 5948 insertions(+), 5696 deletions(-) create mode 100644 megamek/data/images/units/defaults/default_maglev_tractor.png create mode 100644 megamek/data/images/units/defaults/default_rail_tractor.png create mode 100644 megamek/data/images/units/vehicles/Kallon Industries LevCar_ArrowIV.png create mode 100644 megamek/data/images/units/vehicles/Kallon Industries LevCar_Gauss.png create mode 100644 megamek/data/images/units/vehicles/Kallon Industries LevCar_LRM15.png create mode 100644 megamek/data/images/units/vehicles/Kallon Industries LevCar_SRM6.png create mode 100644 megamek/data/images/units/vehicles/Kallon Industries LevCar_UAC20.png create mode 100644 megamek/data/images/units/vehicles/Kallon Industries LevCar_Weaponless.png create mode 100644 megamek/data/images/units/vehicles/Kallon Industries Nolan.png create mode 100644 megamek/data/images/units/vehicles/MUSE Ironhorse_Tractor.png create mode 100644 megamek/data/images/units/vehicles/MUSE Ironhorse_Trailer.png create mode 100644 megamek/data/mechfiles/vehicles/TRO Vehicle Annex/Rail/Adelante Passenger-Cargo Train (Standard).blk create mode 100644 megamek/data/mechfiles/vehicles/TRO Vehicle Annex/Rail/TGV Omni Railcar Primary Configuration.blk diff --git a/megamek/data/images/units/defaults/default_maglev_tractor.png b/megamek/data/images/units/defaults/default_maglev_tractor.png new file mode 100644 index 0000000000000000000000000000000000000000..88aeed9acf5ce4118d3eed27196223b0b83e90fc GIT binary patch literal 1052 zcmV+%1mpXOP)Zs~`-9j?2O~_l4}sH{4gw!{2z)2-aIk6q#Y_o%;35l~4-+Msu^)X1^c+ zSZ&|8(GI5f-gI3zJ2wo2vDSh%P#eu)#u&{o48}Q^1T@B|4%C-sFcHXc96!$EzH@E@ z^#Syz?WLWa-Nu0)LDF$ekccXNmnAM zTh+v^0p;wZ%u5+1bnLm&qAZni_8V=?b`zMw^8&Cw5ZmaZAq-H%!iegCzUj;+G_r`nwq5trB%4Ncyy9bYp zSyzc}i~;XG(DwIr{%`a1ym{|u_hil&d#{&9eR*laCCO0EC}bJ-wG93CtZEnv0Ldt6 zs}4k6%cCU;gDV1PX=l6WcoL!>W1K{E!H|52bFSwM7(GYE`}zBcMoL^P`@T0Jgz4B? zk)^5wjZ;dU+@7J7Ron$i8L1RI`L(HMR>M%rD9TLA;27g-hKsRMOL8QHkWJqqm`ig_ z?`)DPP(|G)Oy6-9robG>aq8GeW`5OkpY$C8lTRmWDQr-g9N~ox-@v3r4yo%U!G1{r zm;>V|ledg_>jZP|rJZxLMGIZmEnZ)(mEQ}tR{g0KP;`BG0a;4K+qN~D)>^4$CmUq;j+X_0-WSfk{0IBuel+r^T#1KM1R-U{)6_xO9P2GPI>xAG8(Qn8 zn~E{&S?+zC5kT+#OY|cF-ev$Y1<)ANv`$J7>y7|cj}ZA3ND4r$b*;GncP@mWlv2uC zE6%ao3_#X`$E?YM4A&9m*chY8p_Gc=`}lpy@1c}pkJ?eQMsn@0`}~^0DB&A&&Z!nP zglW*jn`1N59GVX2T)aDSw2~Y;h1+x-$B(~v*Z7Tfmg3MFy?968ejJCUmimTcUv#BD z#j#hN9Q$#=N{W0c&ffdzy(h&S27Hg_!e5RK=BDQ*M1BaM7#s|YbB@%rcrHcfy^qd0 zk`Ax8v>#d$YX~3Hx%e}lbLSd8#!$x|0HJ^}#$*8tA&`LO)?6OY8ZM@Q;lTXMhgOIt z1!`&j#{ycjd5RlrICK=SLjf)6NDi2se&vkW@_?4OjN(dso}+E?0+w;?DPQt#j9#LX z_CuvJ_T)J(cGp_7;bSY^D^-E%L|$thz4yu(^J8NG3ManadlsBlx)`GhAt{$vK z=7(ZXj^j{TYZXF(O{?QLlriQ4=T*9;bST!FI5(M|qx2qChiai?)>^x!l!`BKSTDMd z4L#p+OaZ91_J_|HLb#d~deAK&%RA?kwe}KMYprt5b)#F-C~;0c=af@P;I?Y^t&y1SEoD$z)G;cb#&Vy-Hc zIMVD9mwhVH!o26TV{cI3KEXUwlY^)q`qZPWSaQWR;4*w*FtJ{S_?_b3XR>6S{!q$= zdUfPtdE%VN{=_?&skB?q`Z~%y#ifi=i;irWbDrn*-Fcp$9m}WskUB~p!M^WTZ|J`7 z&7Qzpawzp8SI)Q)#^eH(;#6p`EdeO;^1_z{m?>Bkn8uj@a+_)9z1DXv}!eKyhUa&M1xQ5B(a&kpL=JYQ_N1!g8bLu#bp^20!tbD2h zT0|U&oHK-<(*Sxmu>!Bx5SD!1GIFbfU&EbT4q#-n?NC6$fIvkwEhE=(8kGYW-F-I% zP_4Cc&Rx08T24zvJqO?@(ceaK=DzQjm;e=z38h+9Mez}Ok)fn;@1vi49k}$0#M(qwZXsS3)qg5`?yUEpb0jEWAn;7v7hzT0+;{* z(=_eQ*IfUjpSRYBa%<=~j!8i0d4~7;lK&`bfO%tnQdes86z)OQt3bfX{ z^CkUpfjZP;W?|^FJ4%ex+gD#hV_rG66y!YPC!JCZIBRVds7LK;04>_fOJd$50L^8n zBpaYx2ebp)0qxclpd~S8YyEYGc0fCzJNtY-kL~Z($~RAo$`b3KO#w=4qRX;~EiU&d z{}hIn4A4z=t@VFJ<`R~20@?&a{nyQ<1?moH%l&;*Xb^dIf%x|i8e=eI^n9qDF$Udp z{PwYS>))@BPh4Q1TdDU`ODT2HK`NLbl}N~8xi(Tj9i)P3j7d5l*G3Yk>|qlkD*u&k z2+VODlMG!&3>&D3xPeNSjrE#(EJNwwVr!<$j*e`e=OE}lQ#q9*RfGwGo86knN0hC1fW!c69VEaJC9iE1J5DJVPz=ytB)G}vjSQ> zq~YkFEo`FU(y}bU6!^-tCtA?mHP;`9R+N>YZZN*qGiD*+ORhU}{c(g(RRa5%$E7U2 zi=EtYs8|KF12@GyL`<%YKc!&y!9YZqrU|UIS-E_So%FdsrC<)_-Z|`aPR6wl)dp%r z6(Xulp~2^9=|gSK)Keb^XbjXdp;PVTK~#bH3aApm6tRY00hP9s0H#Pla~+hlwNosh zG3V2Ybvfe`76j*Y69UoNCLc`d$xA?eyjbi?zAq&_ zY8p@EnLTWx;Zx}6 zGO-ZoC~S(|N5Uq)aY+F*25!oZ?yCW4_1zh10feTQG&4#SPLA&5-knj@l+VqYO0IJ= uRP2_){xy0%)+U$LouLgeRP}Aw@3nuOBg1{f1UHHR0000^C(g1wIOOU!?eXJz!FfpKJ@;lC$T4PYt&<&WS&zA?<5@Vux?;(T$-g}YuYz#G%H=w)8G)<>%&otD4 z8c;KN18P7Gr~wu1VC~{E&Vsg<@Gc!T-GEnlLm@Vb1*qf6z_d139aX#(mz71 zZ#{q_RH}s>&=S=Aa}Kniy>MEfCDSdzEJ4Ilg3Cdr?Md`c)G1;1M$IDeG)+smGffkW zP5VaVRU>t4evugWejS49Rny@Oqa`xaFYIbx*pC$AN5JoIWj3 z4r&Q32T}t}bqmaEX1etRhz6LdH1w~xGc>?d3G`D<)1sl4ieo@^OBa*>#5DhsV=p-r z9O9vc{C2X|N4pPU@)Ra&n&wRiROdG3FsUbRfod7dE3+sq;nAUi<}fusRIA$LQ%cK1 zNDlM0^@W*yYX@_vtuUp5s!0|rC41$I&hUG0sOr2P$zpfy8v1E4Zzg||_6{>s+EZgM z4V2pmOY8LW5E?qq^V>#P7Ki?ts%x2tqZZQ51Y1r1rOi&NgK9EIN-5$sVH0=WB{G;f zpd8#SSv#)>(C)i4(ghGY#iTQ%t%Z}d^Q3oYRF^E)qNO#*;R?xO+=>#Xl`+Quj&t9s l)oRnw18JyBw(a_^@(=Fw{U+A1MeG0o002ovPDHLkV1iOUyz>A6 literal 0 HcmV?d00001 diff --git a/megamek/data/images/units/vehicles/Kallon Industries LevCar_LRM15.png b/megamek/data/images/units/vehicles/Kallon Industries LevCar_LRM15.png new file mode 100644 index 0000000000000000000000000000000000000000..f993a9a2d4601871393434a73ca2f2dfd954c289 GIT binary patch literal 961 zcmV;y13vtTP)%A9jQ z&pf5%IG^cH5@rYiQc6GDLI^B>nhKz~#TYmDF95> zK9`g_TNO$n;+D7YEebtlkd;Fe|S>WAlj@nuWSCf0@?$WGlE%UaO4x1?*QdoS|c98 zTx%#w;A%kW?{Y>kix1z`T$vc-3i{SD2^UF49olQSoQA48Ut*)lQ~+&R=|KmL^W&ea z5IJ3u&j-5c`p?opcu%^^7x`fr-s;gv)tTynwyys8R=U#``Lmb-JwuUyr)ZX1d2RLU z?Fj!m&dby98kcq-qR3O2s5H$lAy6ILl*6Pgc@I>JU@rKkIaE{VhrTJ@8_+k3U`pvZ z5R$`uOlMe;?|r}=YA;M~plaen>708hFbp>0L-*221dH9YEA(Aw-irK5@;gjV>6?nZ zG|@D&SH9M{c6pdisa(%X3pgp&#lidqQv)>N%|PD#@jA7iwQm6? z0KhnooA#RVKl*uVeJF~d!!RU)PSXUh*X!Fh&og-MlR(#Xg>f836H{LcW#@_Gu&-P~?YCsLB4S54{6_IIbyAhL9U z`1c1c%Yu8h*A4*RE$98z&ij+NK6UlbumVrZ$b21&+GuTQ7>4W$|J~MWg&Bh6u&9lL z)dIEG3Ud!+SnS|n)j*Ywp%h1X4COJ9+Ih@OZ9G=;^YQaYU0ZeKNa%%p7?bDa?0HNj zj|Tv807NY&yoVinL-EkCoz2zpEe<)i(MEZZlvG2Kx5vS>hmYc zcSo5v1|~w5Ga(`L0C4&nu~5uD(b|1&u3XXw3qNidD}XsJTFESDVx}|5}q) z*Ah&=e5~~$1gf=7Axu8kEP-kY=E#I!ljNpppdn1nKdMzdhz&8ttTAlLu1E1Mjv{{WBzB}X+yr@{+hW{y3%7G4K(&3EUmYnO?asH{**Z4 z5%bWGB&RqT@rMbP4*8EaJE;q-CJPUzI(riFlAqP=oeu=%;E1RPXbf)3j*hDVRE5T# zm*#l!Bj=tyb)2-uUe%D#y=y9YUD`v{J~B9bjlUjyPp(&+hc@J)&K|pdt^EUrk&XuI S#-<{*A8zBMDG2zrAqtss+Tss-dLV}oG$90NWyYAF zR~|wzlFxK&38r%nLI^+GoO2?7nhHRdI@7z69N zew5eLCk5)Q6*DWP&&O6{lHR^~ADZ&Yxvrq(8eKZ26mZ`AB2f2^YXP)sFRzJtmjJYs zp_=Rl!v>(E$$x3IbX129KqF?Y-M({?-#wr;8WY*cL97|e*VNZVA8M_Ai#AcV4ySa$ zkew;Eb`R*XEQk6}Y~r;Ht*vh`bToMoWvHnAa*`|&b_?PEm*AWWDZ_mLupLW3@jAI{ z(E22vZ}g!(I;At!HvsJc(9+;Cj)HO_ysl+a4VX2cb_pm2GnOS18|ULOT0p&P1(VK< zPSf-u=IMS6lpv^*!I0)U6tyVTp;Sw9eQK?ZYD`*A^(MU@)2uSj)&fuj)j9Ve%wvL| zgUWw%K(UOJ!({9Z5Wib$Oi-DU0mDYE;krHNal#FziW!dD;vMeyq^S06Q5=n&h ziDZvRH*x;C*VK`Lyxch#?OS7gX{_GMFtn-n6{`OxEsa`BvrEY)bPm?qtW%;62b(=^ zv^?kOX?+roX?Xdo=}>Op(xI$e?75nZaa-L&<%T zOjVI^%L5viS5Jc=bU%7)Tp7YMNbq{yCfue##Yhs5E~S7x8c)4s_%0QC_)q15n+jK7*M~#O1uahW_<5ixy(DoTJJA z5lm#7=9dtt&TZmgQcqq3>d0W;8AWN4N2dmqgQ`uY1(o4_Zm8(I7CH8J?F>CC=0}siNPS~@cW;2EUWBD}_<0J3uIs9LIbzd3 zG=yMk#^K09y1cu#$-mfaq#jUB=143>yhJvo&g&wBIR$76+??&5*8CvnBAsT>erBj7%?FP=+%rd zUmrY#U|L?&ttU+99E1?Q)}3=rel!t4X`1mU{-i(Fvh^P zZ993*c&(t`dTC~5=(FoJt);i`ZbLb*oHGR_=eVR(;=pI^`9p0#%@=9q*fk2F$IC z5dQrWoO2=7QgQ%z^^(t{oQ~Jx`o!f!;|x6BMyB_nP=@!GrfDk9@PE7ArNWFsQdlUX zV5LC4ONE&N87Dg^STRsr+fcNl)P_XFt{JpOw$)lmauxpOXQTT`|)HSTFNw0B6;V*Fd{(5QE4cB-%morASD>y)U& z!D)}3%5$Ecj@QC5sh2-n9GXgkd?F5w$j|*@9aRDwhxCK&JAkmrdVsskay`2T}se zZugXOP;<6kDok-1`y5os%UZEO-_XaXNykS;KpVZh(1LZctlDhmHLPNK0 z+iirUap?c4YHHTusD*Sh!P+VR)MnG_0>xC0q)NnV9;->656)h}%mL-#=GxJ5J%D!K zoslL$=n|8zjB<&SqvKld&M2-}tVT;q-iIp`i*XqxPAk3lzuxCQQ>xXfp#y2C3A*k2 aN81m=?hq{X!s3_!0000Zs~`-9j?2O~_l4}sH{4gw!{2z)2-aIk6q#Y_o%;35l~4-+Msu^)X1^c+ zSZ&|8(GI5f-gI3zJ2wo2vDSh%P#eu)#u&{o48}Q^1T@B|4%C-sFcHXc96!$EzH@E@ z^#Syz?WLWa-Nu0)LDF$ekccXNmnAM zTh+v^0p;wZ%u5+1bnLm&qAZni_8V=?b`zMw^8&Cw5ZmaZAq-H%!iegCzUj;+G_r`nwq5trB%4Ncyy9bYp zSyzc}i~;XG(DwIr{%`a1ym{|u_hil&d#{&9eR*laCCO0EC}bJ-wG93CtZEnv0Ldt6 zs}4k6%cCU;gDV1PX=l6WcoL!>W1K{E!H|52bFSwM7(GYE`}zBcMoL^P`@T0Jgz4B? zk)^5wjZ;dU+@7J7Ron$i8L1RI`L(HMR>M%rD9TLA;27g-hKsRMOL8QHkWJqqm`ig_ z?`)DPP(|G)Oy6-9robG>aq8GeW`5OkpY$C8lTRmWDQr-g9N~ox-@v3r4yo%U!G1{r zm;>V|ledg_>jZP|rJZxLMGIZmEnZ)(mEQ}tR{g0KP;`BG0a;4K+qN~D)>^4$CmUq;j+X_0-WSfk{0IBuel+r^T#1KM1R-U{)6_xO9P2GPI>xAG8(Qn8 zn~E{&S?+zC5kT+#OY|cF-ev$Y1<)ANv`$J7>y7|cj}ZA3ND4r$b*;GncP@mWlv2uC zE6%ao3_#X`$E?YM4A&9m*chY8p_Gc=`}lpy@1c}pkJ?eQMsn@0`}~^0DB&A&&Z!nP zglW*jn`1N59GVX2T)aDSw2~Y;h1+x-$B(~v*Z7Tfmg3MFy?968ejJCUmimTcUv#BD z#j#hN9Q$#=N{W0c&ffdzy(h&S27Hg_!e5RK=BDQ*M1BaM7#s|YbB@%rcrHcfy^qd0 zk`Ax8v>#d$YX~3Hx%e}lbLSd8#!$x|0HJ^}#$*8tA&`LO)?6OY8ZM@Q;lTXMhgOIt z1!`&j#{ycjd5RlrICK=SLjf)6NDi2se&vkW@_?4OjN(dso}+E?0+w;?DPQt#j9#LX z_CuvJ_T)J(cGp_7;bSY^D^-E%L|$thz4yu(^J8NG3ManadlsBlx)`GhAt{$vK z=7(ZXj^j{TYZXF(O{?QLlriQ4=T*9;bST!FI5(M|qx2qChiai?)>^x!l!`BKSTDMd z4L#p+OaZ91_J_|HLb#d~deAK&%RA?kwe}KMYprt5b)#F-C~;0c=af@P;I?Y^t&y1SEoD$z)G;cb#&Vy-Hc zIMVD9mwhVH!o26TV{cI3KEXUwlY^)q`qZPWSaQWR;4*w*FtJ{S_?_b3XR>6S{!q$= zdUfPtdE%VN{=_?&skB?q`Z~%y#ifi=i;irWbDrn*-Fcp$9m}WskUB~p!M^WTZ|J`7 z&7Qzpawzp8SI)Q)#^eH(;#6p`EdeO;^1_z{m?>Bkn8uj@a+_)9z1DXv}!eKyhUa&M1xQ5B(a&kpL=JYQ_N1!g8bLu#bp^20!tbD2h zT0|U&oHK-<(*Sxmu>!Bx5SD!1GIFbfU&EbT4q#-n?NC6$fIvkwEhE=(8kGYW-F-I% zP_4Cc&Rx08T24zvJqO?@(ceaK=DzQjm;e=z38hz1gQ0_=-vp+^0o%*YSRYOYC}~fvb#y=}&^`rRYaO*kL|E6gXrym8w0i z2!Yx<0G0-`st-*K#2E7;#ED4~fcDtc$l5oTO#pxSOk>P*x*B7^T3gKS)Io_0P${7w z3o@ag-(y!g5ETtdpai>1tnh|#Xyy4(i(Ef2Xk2#nCH3ADW3z?*P^-f znxuRoJtyo#DKLvhc>q9bEjs7WT8s2IMQDoB;b*v?OVP#b{7;JTejofk9X{^TGRYr^ zRPu!KD7JB+rX*B&V~dQrhV~>dxr9avO#c{{2uXcUcwR{`5wYx}C;6*snzA(_-yixK zGiF2o^HX$O9VxV#rs*l`PW>#OE4XpVV**NR{j%?8m!x@5X&+9RV3stFbuAV!oGLkz zViN(!{oPyZnxSWG_nxQw8JXHOLpfiWi|9YWP$>vuYK}nlnMwOzjc6C^Pn}@?HDO;Z zQ{U60XVJ0NEPwQn94S7|+BKydLnW-+dk$230|XI4wRrKXb%OaaI@Di$yVLHg(g(fx z^%HgZ+$uSx)JvUeSr(B^tL2Qh9>6?um0XGM>`I5G0up3aD{~QEYSSVx-D>$xZi!56 zF)eN6|6(u4#?H<8*pi9mu6$^iT=t`LF4)BUX0z$u1E4W~CshGl#;K(bz4gSOqtt8W6=wRqz=wN86MvEP!Y?6SocYP?=hf@N|l|N#j(DQq)Z9-iP^raR$aN4q_ z53NyC>XM-V|JRnL8h6fM=wN7hhL(u(gQ0_=gQ0_=zw)HCEKAmwJ7+x0U+7u>-XlY$ z3F7S?qc`6;7#ay4(qDAoe(-8A6!w=c{F;*w;^k{fsh`LQLEHlj$3*VNY=t~^35Lc% zrGf7SMgk`Dp8fTg;^h3@C;qUd4{fsguF;LF;#mIyV71S!fW85c00000NkvXXu0mjf DnLi#9 literal 0 HcmV?d00001 diff --git a/megamek/data/mechfiles/vehicles/TRO Vehicle Annex/Rail/Adelante Passenger-Cargo Train (Standard).blk b/megamek/data/mechfiles/vehicles/TRO Vehicle Annex/Rail/Adelante Passenger-Cargo Train (Standard).blk new file mode 100644 index 00000000000..68d3e004739 --- /dev/null +++ b/megamek/data/mechfiles/vehicles/TRO Vehicle Annex/Rail/Adelante Passenger-Cargo Train (Standard).blk @@ -0,0 +1,103 @@ +#building block data file + +1 + + +##Write the version number just in case... + +MAM0 + + + +LargeSupportTank + + + +Adelante Passenger-Cargo Train + + + +(Standard) + + + +2919 + + + +2919 + + + +IS Level 4 + + + +Rail + + + +crewquarters:35.0:0 +cargobay:28.0:1:2 + + + +12 + + + +0 + + + +-1 + + + +40 +35 +35 +35 +35 +20 + + + +SV Chassis Mod [Tractor] + + + + + + + + + + + + + + + + + + +Hitch + + + +7 + + + +3 + + + +TRO:Vehicle Annex + + + +600.0 + + diff --git a/megamek/data/mechfiles/vehicles/TRO Vehicle Annex/Rail/TGV Omni Railcar Primary Configuration.blk b/megamek/data/mechfiles/vehicles/TRO Vehicle Annex/Rail/TGV Omni Railcar Primary Configuration.blk new file mode 100644 index 00000000000..1eb2950bd05 --- /dev/null +++ b/megamek/data/mechfiles/vehicles/TRO Vehicle Annex/Rail/TGV Omni Railcar Primary Configuration.blk @@ -0,0 +1,107 @@ +#building block data file + +1 + + +##Write the version number just in case... + +MAM0 + + + +SupportTank + + + +TGV Omni Railcar + + + +Primary Configuration + + + +3062 + + + +3062 + + + +IS Level 3 + + + +Rail + + + +1stclassquarters:90.0:0:omni +2ndclassquarters:7.0:0:omni +cargobay:4.5:1:3:omni +BattleArmorHandles - troopers:-1 + + + +0 + + + +8 + + + +-1 + + + +1 + + + +16 +16 +16 +15 + + + +SV Chassis Mod [Trailer] +SV Chassis Mod [Tractor] +OmniChassisMod + + + + + + + + + + + + +Hitch + + + +9 + + + +5 + + + +TRO: Vehicle Annex + + + +120.0 + + + +0.0 + + diff --git a/megamek/src/megamek/client/ui/swing/MechTileset.java b/megamek/src/megamek/client/ui/swing/MechTileset.java index b90cb349d60..7d15e947526 100644 --- a/megamek/src/megamek/client/ui/swing/MechTileset.java +++ b/megamek/src/megamek/client/ui/swing/MechTileset.java @@ -85,6 +85,11 @@ public class MechTileset { private String SUBMARINE_STRING = "default_submarine"; //$NON-NLS-1$ private String HYDROFOIL_STRING = "default_hydrofoil"; //$NON-NLS-1$ private String VTOL_STRING = "default_vtol"; //$NON-NLS-1$ + private String RAIL_TRACTOR_STRING = "default_rail_tractor"; //$NON-NLS-1$ + private String RAIL_MAGLEV_STRING = "default_maglev_tractor"; //$NON-NLS-1$ + private String TRAILER_STRING = "default_trailer"; //$NON-NLS-1$ + private String SMALL_TRAILER_STRING = "default_small_trailer"; //$NON-NLS-1$ + private String LARGE_TRAILER_STRING = "default_large_trailer"; //$NON-NLS-1$ private String INF_STRING = "default_infantry"; //$NON-NLS-1$ private String BA_STRING = "default_ba"; //$NON-NLS-1$ private String PROTO_STRING = "default_proto"; //$NON-NLS-1$ @@ -138,6 +143,11 @@ public class MechTileset { private MechEntry default_submarine; private MechEntry default_hydrofoil; private MechEntry default_vtol; + private MechEntry default_rail_tractor; + private MechEntry default_maglev_tractor; + private MechEntry default_trailer; + private MechEntry default_large_trailer; + private MechEntry default_small_trailer; private MechEntry default_inf; private MechEntry default_ba; private MechEntry default_proto; @@ -306,6 +316,17 @@ public MechEntry genericFor(Entity entity, int secondaryPos) { return default_hydrofoil; } if (entity instanceof Tank) { + if (entity.isTrailer()) { + if (entity.isSuperHeavy()) { + return default_large_trailer; + } else if ((entity.getWeightClass() == EntityWeightClass.WEIGHT_LIGHT) + || (entity.getWeightClass() == EntityWeightClass.WEIGHT_MEDIUM) + || (entity.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT)) { + return default_small_trailer; + } else { + return default_trailer; + } + } if (entity.getMovementMode() == EntityMovementMode.TRACKED) { if (entity.getWeightClass() == EntityWeightClass.WEIGHT_HEAVY) { return default_tracked_heavy; @@ -330,6 +351,12 @@ public MechEntry genericFor(Entity entity, int secondaryPos) { if (entity.getMovementMode() == EntityMovementMode.WIGE) { return default_wige; } + if (entity.getMovementMode() == EntityMovementMode.RAIL) { + return default_rail_tractor; + } + if (entity.getMovementMode() == EntityMovementMode.MAGLEV) { + return default_maglev_tractor; + } } if (entity instanceof GunEmplacement) { return default_gun_emplacement; @@ -487,6 +514,11 @@ public void loadFromFile(String filename) throws IOException { default_submarine = exact.get(SUBMARINE_STRING.toUpperCase()); default_hydrofoil = exact.get(HYDROFOIL_STRING.toUpperCase()); default_vtol = exact.get(VTOL_STRING.toUpperCase()); + default_rail_tractor = exact.get(RAIL_TRACTOR_STRING.toUpperCase()); + default_maglev_tractor = exact.get(RAIL_MAGLEV_STRING.toUpperCase()); + default_trailer = exact.get(TRAILER_STRING.toUpperCase()); + default_small_trailer = exact.get(SMALL_TRAILER_STRING.toUpperCase()); + default_large_trailer = exact.get(LARGE_TRAILER_STRING.toUpperCase()); default_inf = exact.get(INF_STRING.toUpperCase()); default_ba = exact.get(BA_STRING.toUpperCase()); default_proto = exact.get(PROTO_STRING.toUpperCase()); From 37fb42e834b9da8a42e0dfa8e04039f16b82c013 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 21 Aug 2019 10:32:27 -0500 Subject: [PATCH 52/69] Added field for vehicle ICE fuel type. --- megamek/src/megamek/common/FuelType.java | 45 +++++++++++++++++++ megamek/src/megamek/common/Tank.java | 22 +++++---- .../src/megamek/common/loaders/BLKFile.java | 3 ++ .../loaders/BLKLargeSupportTankFile.java | 20 ++++++--- .../common/loaders/BLKSupportTankFile.java | 20 ++++++--- .../common/loaders/BLKSupportVTOLFile.java | 21 ++++++--- .../megamek/common/loaders/BLKTankFile.java | 20 ++++++--- .../megamek/common/loaders/BLKVTOLFile.java | 20 ++++++--- 8 files changed, 132 insertions(+), 39 deletions(-) create mode 100644 megamek/src/megamek/common/FuelType.java diff --git a/megamek/src/megamek/common/FuelType.java b/megamek/src/megamek/common/FuelType.java new file mode 100644 index 00000000000..4db6809c424 --- /dev/null +++ b/megamek/src/megamek/common/FuelType.java @@ -0,0 +1,45 @@ +/* + * MegaMek + * Copyright (C) 2019 The MegaMek Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package megamek.common; + +/** + * Fuel type affects costs of refueling (if tracking fuel) and possibly vehicle operating + * range. See StratOps, p. 179. + */ +public enum FuelType { + HYRDOGEN (15000, ITechnology.RATING_C), + PETROCHEMICALS (1000, ITechnology.RATING_A), + ALCOHOL (1500, ITechnology.RATING_A), + NATURAL_GAS (1200, ITechnology.RATING_A); + + /** + * Cost in C-bills per ton. This is the cost for delivery to a forward military + * base. Costs can vary quite a bit in other situations. + */ + public final int cost; + /** + * Availabilty code, as with equipment + */ + public final int availability; + + FuelType(int cost, int availability) { + this.cost = cost; + this.availability = availability; + } +} diff --git a/megamek/src/megamek/common/Tank.java b/megamek/src/megamek/common/Tank.java index 69390f068fa..60a70a38cab 100644 --- a/megamek/src/megamek/common/Tank.java +++ b/megamek/src/megamek/common/Tank.java @@ -176,7 +176,7 @@ public int getLocTurret2() { /** * Alternate fuel for ICEs that affects operating range */ - private boolean alcoholNatGasFueled = false; + private FuelType fuelType = FuelType.PETROCHEMICALS; public CrewType defaultCrewType() { return CrewType.CREW; @@ -4191,10 +4191,10 @@ public double fuelTonnagePer100km() { case Engine.STEAM: return getEngine().getWeightEngine(this) * 0.03; case Engine.COMBUSTION_ENGINE: - if (isAlcoholOrNaturalGasFueled()) { - return getEngine().getWeightEngine(this) * 0.0125; - } else { + if (getICEFuelType() == FuelType.PETROCHEMICALS) { return getEngine().getWeightEngine(this) * 0.01; + } else { + return getEngine().getWeightEngine(this) * 0.0125; } case Engine.BATTERY: return getEngine().getWeightEngine(this) * 0.05; @@ -4205,12 +4205,18 @@ public double fuelTonnagePer100km() { } } - public boolean isAlcoholOrNaturalGasFueled() { - return alcoholNatGasFueled; + /** + * The type of fuel for internal combustion engines. This has no meaning for + * other engine types. + * + * @return The ICE fuel type + */ + public FuelType getICEFuelType() { + return fuelType; } - public void setAlcoholOrNaturalGasFueled(boolean fuel) { - alcoholNatGasFueled = fuel; + public void setICEFuelType(FuelType fuelType) { + this.fuelType = fuelType; } /** diff --git a/megamek/src/megamek/common/loaders/BLKFile.java b/megamek/src/megamek/common/loaders/BLKFile.java index a46d6d14ca3..89b5d55f3ba 100644 --- a/megamek/src/megamek/common/loaders/BLKFile.java +++ b/megamek/src/megamek/common/loaders/BLKFile.java @@ -880,6 +880,9 @@ public static BuildingBlock getBlock(Entity t) { if (t instanceof Tank) { Tank tank = (Tank) t; + if (tank.getEngine().getEngineType() == Engine.COMBUSTION_ENGINE) { + blk.writeBlockData("fuelType", tank.getICEFuelType().toString()); + } if (tank.hasNoControlSystems()) { blk.writeBlockData("hasNoControlSystems", 1); } diff --git a/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java b/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java index 440c0bba043..5ccd3e8b195 100644 --- a/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKLargeSupportTankFile.java @@ -25,12 +25,8 @@ */ package megamek.common.loaders; -import megamek.common.Engine; -import megamek.common.Entity; -import megamek.common.EntityMovementMode; -import megamek.common.EquipmentType; -import megamek.common.LargeSupportTank; -import megamek.common.Tank; +import megamek.common.*; +import megamek.common.logging.DefaultMmLogger; import megamek.common.util.BuildingBlock; public class BLKLargeSupportTankFile extends BLKFile implements IMechLoader { @@ -230,6 +226,18 @@ public Entity getEntity() throws EntityLoadingException { t.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); } + if (dataFile.exists("fuelType")) { + try { + t.setICEFuelType(FuelType.valueOf(dataFile.getDataAsString("fuelType")[0])); + } catch (IllegalArgumentException ex) { + DefaultMmLogger.getInstance().error(getClass(), "getEntity()", + "While loading " + t.getShortNameRaw() + + ": Could not parse ICE fuel type " + + dataFile.getDataAsString("fuelType")[0]); + t.setICEFuelType(FuelType.PETROCHEMICALS); + } + } + return t; } } diff --git a/megamek/src/megamek/common/loaders/BLKSupportTankFile.java b/megamek/src/megamek/common/loaders/BLKSupportTankFile.java index 2a48f342063..248618299e9 100644 --- a/megamek/src/megamek/common/loaders/BLKSupportTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKSupportTankFile.java @@ -22,12 +22,8 @@ */ package megamek.common.loaders; -import megamek.common.Engine; -import megamek.common.Entity; -import megamek.common.EntityMovementMode; -import megamek.common.EquipmentType; -import megamek.common.SupportTank; -import megamek.common.Tank; +import megamek.common.*; +import megamek.common.logging.DefaultMmLogger; import megamek.common.util.BuildingBlock; public class BLKSupportTankFile extends BLKFile implements IMechLoader { @@ -219,6 +215,18 @@ public Entity getEntity() throws EntityLoadingException { t.setBaseChassisFireConWeight((dataFile.getDataAsDouble("baseChassisFireConWeight")[0])); } + if (dataFile.exists("fuelType")) { + try { + t.setICEFuelType(FuelType.valueOf(dataFile.getDataAsString("fuelType")[0])); + } catch (IllegalArgumentException ex) { + DefaultMmLogger.getInstance().error(getClass(), "getEntity()", + "While loading " + t.getShortNameRaw() + + ": Could not parse ICE fuel type " + + dataFile.getDataAsString("fuelType")[0]); + t.setICEFuelType(FuelType.PETROCHEMICALS); + } + } + return t; } } diff --git a/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java b/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java index 0280ac83db6..876cd11cd79 100644 --- a/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java +++ b/megamek/src/megamek/common/loaders/BLKSupportVTOLFile.java @@ -16,13 +16,8 @@ */ package megamek.common.loaders; -import megamek.common.Engine; -import megamek.common.Entity; -import megamek.common.EntityMovementMode; -import megamek.common.EquipmentType; -import megamek.common.SupportVTOL; -import megamek.common.Tank; -import megamek.common.VTOL; +import megamek.common.*; +import megamek.common.logging.DefaultMmLogger; import megamek.common.util.BuildingBlock; /** @@ -205,6 +200,18 @@ public Entity getEntity() throws EntityLoadingException { t.setBaseChassisSponsonPintleWeight(dataFile.getDataAsDouble("baseChassisSponsonPintleWeight")[0]); } + if (dataFile.exists("fuelType")) { + try { + t.setICEFuelType(FuelType.valueOf(dataFile.getDataAsString("fuelType")[0])); + } catch (IllegalArgumentException ex) { + DefaultMmLogger.getInstance().error(getClass(), "getEntity()", + "While loading " + t.getShortNameRaw() + + ": Could not parse ICE fuel type " + + dataFile.getDataAsString("fuelType")[0]); + t.setICEFuelType(FuelType.PETROCHEMICALS); + } + } + if (dataFile.exists("hasNoControlSystems")) { t.setHasNoControlSystems(true); } diff --git a/megamek/src/megamek/common/loaders/BLKTankFile.java b/megamek/src/megamek/common/loaders/BLKTankFile.java index 087e3894fd6..75856e5b3a3 100644 --- a/megamek/src/megamek/common/loaders/BLKTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKTankFile.java @@ -25,12 +25,8 @@ */ package megamek.common.loaders; -import megamek.common.Engine; -import megamek.common.Entity; -import megamek.common.EntityMovementMode; -import megamek.common.EquipmentType; -import megamek.common.SuperHeavyTank; -import megamek.common.Tank; +import megamek.common.*; +import megamek.common.logging.DefaultMmLogger; import megamek.common.util.BuildingBlock; public class BLKTankFile extends BLKFile implements IMechLoader { @@ -277,6 +273,18 @@ public Entity getEntity() throws EntityLoadingException { t.setBaseChassisSponsonPintleWeight(dataFile.getDataAsDouble("baseChassisSponsonPintleWeight")[0]); } + if (dataFile.exists("fuelType")) { + try { + t.setICEFuelType(FuelType.valueOf(dataFile.getDataAsString("fuelType")[0])); + } catch (IllegalArgumentException ex) { + DefaultMmLogger.getInstance().error(getClass(), "getEntity()", + "While loading " + t.getShortNameRaw() + + ": Could not parse ICE fuel type " + + dataFile.getDataAsString("fuelType")[0]); + t.setICEFuelType(FuelType.PETROCHEMICALS); + } + } + if (dataFile.exists("hasNoControlSystems")) { t.setHasNoControlSystems(true); } diff --git a/megamek/src/megamek/common/loaders/BLKVTOLFile.java b/megamek/src/megamek/common/loaders/BLKVTOLFile.java index 8bac0316f01..1bae7482543 100644 --- a/megamek/src/megamek/common/loaders/BLKVTOLFile.java +++ b/megamek/src/megamek/common/loaders/BLKVTOLFile.java @@ -16,12 +16,8 @@ */ package megamek.common.loaders; -import megamek.common.Engine; -import megamek.common.Entity; -import megamek.common.EntityMovementMode; -import megamek.common.EquipmentType; -import megamek.common.Tank; -import megamek.common.VTOL; +import megamek.common.*; +import megamek.common.logging.DefaultMmLogger; import megamek.common.util.BuildingBlock; /** @@ -167,6 +163,18 @@ public Entity getEntity() throws EntityLoadingException { } t.setArmorTonnage(t.getArmorWeight()); + if (dataFile.exists("fuelType")) { + try { + t.setICEFuelType(FuelType.valueOf(dataFile.getDataAsString("fuelType")[0])); + } catch (IllegalArgumentException ex) { + DefaultMmLogger.getInstance().error(getClass(), "getEntity()", + "While loading " + t.getShortNameRaw() + + ": Could not parse ICE fuel type " + + dataFile.getDataAsString("fuelType")[0]); + t.setICEFuelType(FuelType.PETROCHEMICALS); + } + } + if (dataFile.exists("baseChassisTurretWeight")) { t.setBaseChassisTurretWeight(dataFile.getDataAsDouble("baseChassisTurretWeight")[0]); } From 906ca291132de5715409290b4bd1d066932a8726 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 21 Aug 2019 11:27:59 -0500 Subject: [PATCH 53/69] Replaced string literals with constants for chassis mod lookup names. --- .../megamek/common/EquipmentTypeLookup.java | 39 +++++++++++++ .../common/verifier/TestSupportVehicle.java | 56 ++++++++++++------- 2 files changed, 76 insertions(+), 19 deletions(-) diff --git a/megamek/src/megamek/common/EquipmentTypeLookup.java b/megamek/src/megamek/common/EquipmentTypeLookup.java index 5eafdc82bbe..7138e2c2202 100644 --- a/megamek/src/megamek/common/EquipmentTypeLookup.java +++ b/megamek/src/megamek/common/EquipmentTypeLookup.java @@ -124,6 +124,45 @@ public class EquipmentTypeLookup { @EquipmentName public static final String PINTLE_TURRET = "PintleTurret"; + @EquipmentName + public static final String AMPHIBIOUS_CHASSIS_MOD = "AmphibiousChassisMod"; + @EquipmentName + public static final String ARMORED_CHASSIS_MOD = "ArmoredChassisMod"; + @EquipmentName + public static final String BICYCLE_CHASSIS_MOD = "BicycleChassisMod"; + @EquipmentName + public static final String CONVERTIBLE_CHASSIS_MOD = "ConvertibleChassisMod"; + @EquipmentName + public static final String DUNE_BUGGY_CHASSIS_MOD = "DuneBuggyChassisMod"; + @EquipmentName + public static final String ENVIRONMENTAL_SEALING_CHASSIS_MOD = "EnvironmentalSealingChassisMod"; + @EquipmentName + public static final String EXTERNAL_POWER_PICKUP_CHASSIS_MOD = "ExternalPowerPickupChassisMod"; + @EquipmentName + public static final String HYDROFOIL_CHASSIS_MOD = "HydrofoilChassisMod"; + @EquipmentName + public static final String MONOCYCLE_CHASSIS_MOD = "MonocycleChassisMod"; + @EquipmentName + public static final String OFFROAD_CHASSIS_MOD = "OffroadChassisMod"; + @EquipmentName + public static final String OMNI_CHASSIS_MOD = "OmniChassisMod"; + @EquipmentName + public static final String PROP_CHASSIS_MOD = "PropChassisMod"; + @EquipmentName + public static final String SNOWMOBILE_CHASSIS_MOD = "SnowmobileChassisMod"; + @EquipmentName + public static final String STOL_CHASSIS_MOD = "STOLChassisMod"; + @EquipmentName + public static final String SUBMERSIBLE_CHASSIS_MOD = "SubmersibleChassisMod"; + @EquipmentName + public static final String TRACTOR_CHASSIS_MOD = "TractorChassisMod"; + @EquipmentName + public static final String TRAILER_CHASSIS_MOD = "TrailerChassisMod"; + @EquipmentName + public static final String ULTRALIGHT_CHASSIS_MOD = "UltraLightChassisMod"; + @EquipmentName + public static final String VSTOL_CHASSIS_MOD = "VSTOLChassisMod"; + @EquipmentName public static final String LIMB_CLUB = "Limb Club"; @EquipmentName diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 65e1990b7d8..43fac295da0 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -183,25 +183,43 @@ public static double getBaseEngineValue(Entity sv) { * units. */ public enum ChassisModification implements ITechnologyDelegator { - AMPHIBIOUS (1.75,"AmphibiousChassisMod", SVType.allBut(SVType.HOVERCRAFT, SVType.NAVAL)), - ARMORED (1.5,"ArmoredChassisMod", SVType.allBut(SVType.AIRSHIP)), - BICYCLE (0.75,"BicycleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED)), - CONVERTIBLE (1.1,"ConvertibleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED, SVType.TRACKED), true), - DUNE_BUGGY (1.5,"DuneBuggyChassisMod", EnumSet.of(SVType.WHEELED)), - ENVIRONMENTAL_SEALING (2.0,"EnvironmentalSealingChassisMod", EnumSet.allOf(SVType.class)), - EXTERNAL_POWER_PICKUP (1.1,"ExternalPowerPickupChassisMod", EnumSet.of(SVType.RAIL)), - HYDROFOIL (1.7,"HydrofoilChassisMod", EnumSet.of(SVType.NAVAL)), - MONOCYCLE (0.5,"MonocycleChassisMod", EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED), true), - OFFROAD (1.5,"OffroadChassisMod", EnumSet.of(SVType.WHEELED)), - OMNI (1.0,"OmniChassisMod"), - PROP (1.2,"PropChassisMod", EnumSet.of(SVType.FIXED_WING)), - SNOWMOBILE (1.75,"SnowmobileChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED)), - STOL (1.5,"STOLChassisMod", EnumSet.of(SVType.FIXED_WING)), - SUBMERSIBLE (1.8,"SubmersibleChassisMod", EnumSet.of(SVType.NAVAL)), - TRACTOR (1.2,"TractorChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.NAVAL, SVType.RAIL)), - TRAILER (0.8,"TrailerChassisMod", EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.RAIL)), - ULTRA_LIGHT (0.5,"UltraLightChassisMod", true), - VSTOL (2.0,"VSTOLChassisMod", EnumSet.of(SVType.FIXED_WING)); + AMPHIBIOUS (1.75,EquipmentTypeLookup.AMPHIBIOUS_CHASSIS_MOD, + SVType.allBut(SVType.HOVERCRAFT, SVType.NAVAL)), + ARMORED (1.5,EquipmentTypeLookup.ARMORED_CHASSIS_MOD, + SVType.allBut(SVType.AIRSHIP)), + BICYCLE (0.75,EquipmentTypeLookup.BICYCLE_CHASSIS_MOD, + EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED)), + CONVERTIBLE (1.1,EquipmentTypeLookup.CONVERTIBLE_CHASSIS_MOD, + EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED, SVType.TRACKED), true), + DUNE_BUGGY (1.5,EquipmentTypeLookup.DUNE_BUGGY_CHASSIS_MOD, + EnumSet.of(SVType.WHEELED)), + ENVIRONMENTAL_SEALING (2.0,EquipmentTypeLookup.ENVIRONMENTAL_SEALING_CHASSIS_MOD, + EnumSet.allOf(SVType.class)), + EXTERNAL_POWER_PICKUP (1.1,EquipmentTypeLookup.EXTERNAL_POWER_PICKUP_CHASSIS_MOD, + EnumSet.of(SVType.RAIL)), + HYDROFOIL (1.7,EquipmentTypeLookup.HYDROFOIL_CHASSIS_MOD, + EnumSet.of(SVType.NAVAL)), + MONOCYCLE (0.5,EquipmentTypeLookup.MONOCYCLE_CHASSIS_MOD, + EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED), true), + OFFROAD (1.5,EquipmentTypeLookup.OFFROAD_CHASSIS_MOD, + EnumSet.of(SVType.WHEELED)), + OMNI (1.0,EquipmentTypeLookup.OMNI_CHASSIS_MOD), + PROP (1.2,EquipmentTypeLookup.PROP_CHASSIS_MOD, + EnumSet.of(SVType.FIXED_WING)), + SNOWMOBILE (1.75,EquipmentTypeLookup.SNOWMOBILE_CHASSIS_MOD, + EnumSet.of(SVType.WHEELED, SVType.TRACKED)), + STOL (1.5,EquipmentTypeLookup.STOL_CHASSIS_MOD, + EnumSet.of(SVType.FIXED_WING)), + SUBMERSIBLE (1.8,EquipmentTypeLookup.SUBMERSIBLE_CHASSIS_MOD, + EnumSet.of(SVType.NAVAL)), + TRACTOR (1.2,EquipmentTypeLookup.TRACTOR_CHASSIS_MOD, + EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.NAVAL, SVType.RAIL)), + TRAILER (0.8,EquipmentTypeLookup.TRAILER_CHASSIS_MOD, + EnumSet.of(SVType.WHEELED, SVType.TRACKED, SVType.RAIL)), + ULTRA_LIGHT (0.5,EquipmentTypeLookup.ULTRALIGHT_CHASSIS_MOD, + true), + VSTOL (2.0,EquipmentTypeLookup.VSTOL_CHASSIS_MOD, + EnumSet.of(SVType.FIXED_WING)); public final double multiplier; public final MiscType equipment; From 1623b409ee55e6588e1c4c7bdc360192210260cd Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 21 Aug 2019 14:06:23 -0500 Subject: [PATCH 54/69] Added tech advancement to SVType. --- .../src/megamek/common/FixedWingSupport.java | 22 +++++++++------ megamek/src/megamek/common/SupportTank.java | 28 +++++++++++++++---- megamek/src/megamek/common/SupportVTOL.java | 6 +++- .../common/verifier/TestSupportVehicle.java | 21 +++++++++++++- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/megamek/src/megamek/common/FixedWingSupport.java b/megamek/src/megamek/common/FixedWingSupport.java index 4260a823eec..137af3473ee 100644 --- a/megamek/src/megamek/common/FixedWingSupport.java +++ b/megamek/src/megamek/common/FixedWingSupport.java @@ -157,32 +157,38 @@ public double getFuelPointsPerTon() { protected static final TechAdvancement TA_FIXED_WING_SUPPORT = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) - .setTechRating(RATING_B).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C); + .setTechRating(RATING_B).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C) + .setStaticTechLevel(SimpleTechLevel.STANDARD); protected static final TechAdvancement TA_FIXED_WING_SUPPORT_LARGE = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) - .setTechRating(RATING_B).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D); + .setTechRating(RATING_B).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D) + .setStaticTechLevel(SimpleTechLevel.STANDARD); protected static final TechAdvancement TA_AIRSHIP_SUPPORT_SMALL = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) - .setTechRating(RATING_A).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C); + .setTechRating(RATING_A).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C) + .setStaticTechLevel(SimpleTechLevel.STANDARD); protected static final TechAdvancement TA_AIRSHIP_SUPPORT_MEDIUM = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) - .setTechRating(RATING_B).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D); + .setTechRating(RATING_B).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D) + .setStaticTechLevel(SimpleTechLevel.STANDARD); // Availability missing from TO. Using medium protected static final TechAdvancement TA_AIRSHIP_SUPPORT_LARGE = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) - .setTechRating(RATING_C).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D); + .setTechRating(RATING_C).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D) + .setStaticTechLevel(SimpleTechLevel.ADVANCED); // Availability missing from TO. Using similar values from other support vees. // Also using early spaceflight for intro dates based on common sense. protected static final TechAdvancement TA_SATELLITE = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_ES, DATE_ES, DATE_ES) - .setTechRating(RATING_C).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D); + .setTechRating(RATING_C).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D) + .setStaticTechLevel(SimpleTechLevel.ADVANCED); @Override public TechAdvancement getConstructionTechAdvancement() { - return getTechAdvancement(getMovementMode(), getWeightClass()); + return getConstructionTechAdvancement(getMovementMode(), getWeightClass()); } - public static TechAdvancement getTechAdvancement(EntityMovementMode movementMode, int weightClass) { + public static TechAdvancement getConstructionTechAdvancement(EntityMovementMode movementMode, int weightClass) { if (movementMode.equals(EntityMovementMode.AIRSHIP)) { if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { return TA_AIRSHIP_SUPPORT_LARGE; diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index efd0e071bf1..230799524b5 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -96,6 +96,10 @@ public boolean hasArmoredChassis() { .setAdvancement(DATE_PS, DATE_PS, DATE_PS).setTechRating(RATING_A) .setAvailability(RATING_C, RATING_D, RATING_C, RATING_C) .setStaticTechLevel(SimpleTechLevel.STANDARD); + private static final TechAdvancement TA_NAVAL_LARGE = new TechAdvancement(TECH_BASE_ALL) + .setAdvancement(DATE_PS, DATE_PS, DATE_PS).setTechRating(RATING_A) + .setAvailability(RATING_C, RATING_E, RATING_D, RATING_D) + .setStaticTechLevel(SimpleTechLevel.ADVANCED); private static final TechAdvancement TA_TRACKED = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS).setTechRating(RATING_B) .setAvailability(RATING_B, RATING_C, RATING_B, RATING_B) @@ -121,9 +125,17 @@ public boolean hasArmoredChassis() { .setAvailability(RATING_B, RATING_C, RATING_B, RATING_B) .setStaticTechLevel(SimpleTechLevel.STANDARD); private static final TechAdvancement TA_WIGE_LARGE = new TechAdvancement(TECH_BASE_ALL) - .setAdvancement(DATE_PS, DATE_PS, DATE_PS).setTechRating(RATING_C) + .setAdvancement(DATE_ES, DATE_ES, DATE_ES).setTechRating(RATING_C) .setAvailability(RATING_C, RATING_D, RATING_C, RATING_C) .setStaticTechLevel(SimpleTechLevel.STANDARD); + private static final TechAdvancement TA_RAIL = new TechAdvancement(TECH_BASE_ALL) + .setAdvancement(DATE_PS, DATE_PS, DATE_PS).setTechRating(RATING_A) + .setAvailability(RATING_C, RATING_C, RATING_C, RATING_C) + .setStaticTechLevel(SimpleTechLevel.ADVANCED); + private static final TechAdvancement TA_RAIL_LARGE = new TechAdvancement(TECH_BASE_ALL) + .setAdvancement(DATE_PS, DATE_PS, DATE_PS).setTechRating(RATING_A) + .setAvailability(RATING_C, RATING_D, RATING_D, RATING_D) + .setStaticTechLevel(SimpleTechLevel.ADVANCED); @Override public TechAdvancement getConstructionTechAdvancement() { @@ -143,7 +155,11 @@ public static TechAdvancement getConstructionTechAdvancement(EntityMovementMode case NAVAL: case HYDROFOIL: case SUBMARINE: - return TA_NAVAL; + if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + return TA_NAVAL_LARGE; + } else { + return TA_NAVAL; + } case TRACKED: if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { return TA_TRACKED_LARGE; @@ -166,9 +182,11 @@ public static TechAdvancement getConstructionTechAdvancement(EntityMovementMode } case RAIL: case MAGLEV: - // TacOps gives a minimum tech rating of A but no availability data. Assuming A, the same - // as small wheeled. Maglev will be higher based on the required engine. - return TA_WHEELED_SMALL; + if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + return TA_RAIL_LARGE; + } else { + return TA_RAIL; + } default: return TA_TRACKED; // average } diff --git a/megamek/src/megamek/common/SupportVTOL.java b/megamek/src/megamek/common/SupportVTOL.java index 40e515843e0..487ce882795 100644 --- a/megamek/src/megamek/common/SupportVTOL.java +++ b/megamek/src/megamek/common/SupportVTOL.java @@ -88,9 +88,13 @@ public boolean hasArmoredChassis() { @Override public TechAdvancement getConstructionTechAdvancement() { + return getConstructionTechAdvancement(getWeightClass()); + } + + public static TechAdvancement getConstructionTechAdvancement(int weightClass) { /* Support vehicle dates and tech ratings are found in TM 120, 122. DA availability is assumed to * be the same as Clan invasion era. */ - if (getWeightClass() == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { return TA_VTOL_LARGE; } else { return TA_VTOL; diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 43fac295da0..1b75b30cb5f 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -33,7 +33,7 @@ public class TestSupportVehicle extends TestEntity { * Support vehicle categories for construction purposes. Most of these match with a particular movement * mode, but the construction rules treat naval and rail units as single types. */ - public enum SVType { + public enum SVType implements ITechnologyDelegator { AIRSHIP (300, EntityMovementMode.AIRSHIP, new double[]{0.2, 0.25, 0.3}, new double[]{0.004, 0.008, 0.012}), FIXED_WING (200, EntityMovementMode.AERODYNE, @@ -176,6 +176,25 @@ public static double getBaseEngineValue(Entity sv) { } return 0.0; } + + @Override + public ITechnology getTechSource() { + /* Support vehicle availability advancement can vary with the size class. + The small is the least restrictive, so it serves as the base line for each + type as a whole. */ + switch (defaultMovementMode) { + case AERODYNE: + case AIRSHIP: + case STATION_KEEPING: + return FixedWingSupport.getConstructionTechAdvancement(defaultMovementMode, + EntityWeightClass.WEIGHT_SMALL_SUPPORT); + case VTOL: + return SupportVTOL.getConstructionTechAdvancement(EntityWeightClass.WEIGHT_SMALL_SUPPORT); + default: + return SupportTank.getConstructionTechAdvancement(defaultMovementMode, + EntityWeightClass.WEIGHT_SMALL_SUPPORT); + } + } } /** From 128a4d24a3b668d391fd6ab9b597db4d6a12c84b Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 21 Aug 2019 14:27:28 -0500 Subject: [PATCH 55/69] Remove unused imports. --- megamek/src/megamek/common/EquipmentType.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/megamek/src/megamek/common/EquipmentType.java b/megamek/src/megamek/common/EquipmentType.java index 0d8c30080a2..3e36ccbe74a 100644 --- a/megamek/src/megamek/common/EquipmentType.java +++ b/megamek/src/megamek/common/EquipmentType.java @@ -30,14 +30,11 @@ import megamek.common.options.GameOptions; import megamek.common.weapons.autocannons.HVACWeapon; -import megamek.common.weapons.bayweapons.MMLBayWeapon; import megamek.common.weapons.defensivepods.BPodWeapon; import megamek.common.weapons.defensivepods.MPodWeapon; import megamek.common.weapons.ppc.PPCWeapon; import megamek.server.Server; -import javax.print.attribute.SupportedValuesAttribute; - /** * Represents any type of equipment mounted on a mechs, excluding systems and * actuators. @@ -53,7 +50,7 @@ public class EquipmentType implements ITechnology { /** Default value for support vehicle slot cost. Those that differ from mechs are assigned * a value >= 0 */ - public static final int MECH_SLOT_COST = -1; + private static final int MECH_SLOT_COST = -1; public static final int T_ARMOR_UNKNOWN = -1; public static final int T_ARMOR_STANDARD = 0; From 9169f12978a13a40b0aba8087c7517200e93f928 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 21 Aug 2019 16:43:36 -0500 Subject: [PATCH 56/69] Fix small support vee chassis weight rounding. --- megamek/src/megamek/common/verifier/TestSupportVehicle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 1b75b30cb5f..70c3d545698 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -678,7 +678,7 @@ public double getWeightStructure() { } } } - return roundWeight(weight); + return ceil(weight, usesKgStandard(getEntity()) ? Ceil.KILO : Ceil.HALFTON); } public double getFuelTonnage() { From 883c015ed49a2a3eef7c7f99c9254d95c8a5cd3d Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 21 Aug 2019 16:56:03 -0500 Subject: [PATCH 57/69] Include fuel in SV weight calculation. --- .../src/megamek/common/verifier/TestSupportVehicle.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 70c3d545698..887b64b62e8 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -662,6 +662,13 @@ private double roundWeight(double val) { } } + @Override + public double calculateWeight() { + double weight = super.calculateWeight(); + weight += getFuelTonnage(); + return roundWeight(weight); + } + @Override public double getWeightStructure() { double weight = supportVee.getWeight(); From 57a4c3bf211a43e249f5fdc62583a17e9e792257 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 21 Aug 2019 22:47:16 -0500 Subject: [PATCH 58/69] Take floating point errors into account when rounding kg up. --- .../common/verifier/TestSupportVehicle.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 887b64b62e8..b59a3e34be0 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -654,9 +654,18 @@ public boolean isProtomech() { return false; } - private double roundWeight(double val) { + /** + * Rounds up to the nearest half ton or kilogram as appropriate to the vehicle + * + * @param val The weight to round, in tons + * @return The rounded weight, in tons + */ + private double ceilWeight(double val) { if (supportVee.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT) { - return round(val, Ceil.KILO); + // Deal first with possible variances from floating point precision + // by rounding to the gram, then round the result up to the next kilogram. + // Then convert back to metric tons. + return Math.ceil(Math.round(val * 1000000.0) / 1000.0) / 1000.0; } else { return ceil(val, Ceil.HALFTON); } @@ -666,7 +675,7 @@ private double roundWeight(double val) { public double calculateWeight() { double weight = super.calculateWeight(); weight += getFuelTonnage(); - return roundWeight(weight); + return ceilWeight(weight); } @Override @@ -685,7 +694,7 @@ public double getWeightStructure() { } } } - return ceil(weight, usesKgStandard(getEntity()) ? Ceil.KILO : Ceil.HALFTON); + return ceilWeight(weight); } public double getFuelTonnage() { @@ -713,7 +722,7 @@ private double getWeightCrewAccomodations() { weight += ((Bay) t).getWeight(); } } - return roundWeight(weight); + return ceilWeight(weight); } @Override @@ -745,6 +754,7 @@ public double getTankWeightDualTurret() { @Override public double getWeightPowerAmp() { + // Small support vees only use infantry weapons, which do not require amplifiers. if (supportVee.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT) { return 0.0; } @@ -762,7 +772,7 @@ public double getWeightPowerAmp() { weight += m.getLinkedBy().getType().getTonnage(supportVee); } } - return roundWeight(weight / 10); + return ceilWeight(weight / 10); } return 0.0; } From 8ac588659034bd163c1a3c18c7434ecbb33a09ef Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 21 Aug 2019 22:55:42 -0500 Subject: [PATCH 59/69] Save support vehicle fuel tonnage. --- megamek/src/megamek/common/loaders/BLKFile.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/megamek/src/megamek/common/loaders/BLKFile.java b/megamek/src/megamek/common/loaders/BLKFile.java index 89b5d55f3ba..65f5a0530ba 100644 --- a/megamek/src/megamek/common/loaders/BLKFile.java +++ b/megamek/src/megamek/common/loaders/BLKFile.java @@ -880,6 +880,9 @@ public static BuildingBlock getBlock(Entity t) { if (t instanceof Tank) { Tank tank = (Tank) t; + if (tank.isSupportVehicle()) { + blk.writeBlockData("fuel", tank.getFuelTonnage()); + } if (tank.getEngine().getEngineType() == Engine.COMBUSTION_ENGINE) { blk.writeBlockData("fuelType", tank.getICEFuelType().toString()); } From 365e4dde7252a620e758dbb1c899e5769edc31e0 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Thu, 22 Aug 2019 08:11:10 -0500 Subject: [PATCH 60/69] Don't require base crew for SV trailers with no engine. --- megamek/src/megamek/common/Compute.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/megamek/src/megamek/common/Compute.java b/megamek/src/megamek/common/Compute.java index 7e4954849e6..4d380eb37a0 100644 --- a/megamek/src/megamek/common/Compute.java +++ b/megamek/src/megamek/common/Compute.java @@ -6845,6 +6845,9 @@ public static int getAeroCrewNeeds(Entity entity) { * @return The minimum base crew */ public static int getSVBaseCrewNeeds(Entity entity) { + if (entity.isTrailer() && (entity.getEngine().getEngineType() == Engine.NONE)) { + return 0; + } final boolean naval = entity.getMovementMode().equals(EntityMovementMode.NAVAL) || entity.getMovementMode().equals(EntityMovementMode.HYDROFOIL) || entity.getMovementMode().equals(EntityMovementMode.SUBMARINE); From 8553de9aa117831ba5d4cebcecdd4333cb7a472a Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Thu, 22 Aug 2019 08:20:05 -0500 Subject: [PATCH 61/69] Cleanup for FixedWingSupport Removed extraSeats field which was based on combat vee crew seating. Provided satellite availability from later printing of TacOps. --- .../src/megamek/common/FixedWingSupport.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/megamek/src/megamek/common/FixedWingSupport.java b/megamek/src/megamek/common/FixedWingSupport.java index 137af3473ee..293c2fd17e4 100644 --- a/megamek/src/megamek/common/FixedWingSupport.java +++ b/megamek/src/megamek/common/FixedWingSupport.java @@ -35,8 +35,6 @@ public class FixedWingSupport extends ConvFighter { private static String[] LOCATION_NAMES = { "Nose", "Left Wing", "Right Wing", "Aft", "Wings", "Body" }; private int[] barRating; - /** Vehicles can be constructed with seating for additional crew. This has no effect on play */ - private int extraCrewSeats = 0; public FixedWingSupport() { super(); @@ -155,30 +153,37 @@ public double getFuelPointsPerTon() { return 1000.0 / kgPerFuelPoint(); } - protected static final TechAdvancement TA_FIXED_WING_SUPPORT = new TechAdvancement(TECH_BASE_ALL) + private static final TechAdvancement TA_FIXED_WING_SUPPORT = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) .setTechRating(RATING_B).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C) .setStaticTechLevel(SimpleTechLevel.STANDARD); - protected static final TechAdvancement TA_FIXED_WING_SUPPORT_LARGE = new TechAdvancement(TECH_BASE_ALL) + private static final TechAdvancement TA_FIXED_WING_SUPPORT_LARGE = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) .setTechRating(RATING_B).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D) .setStaticTechLevel(SimpleTechLevel.STANDARD); - protected static final TechAdvancement TA_AIRSHIP_SUPPORT_SMALL = new TechAdvancement(TECH_BASE_ALL) + private static final TechAdvancement TA_AIRSHIP_SUPPORT_SMALL = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) .setTechRating(RATING_A).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C) .setStaticTechLevel(SimpleTechLevel.STANDARD); - protected static final TechAdvancement TA_AIRSHIP_SUPPORT_MEDIUM = new TechAdvancement(TECH_BASE_ALL) + private static final TechAdvancement TA_AIRSHIP_SUPPORT_MEDIUM = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) .setTechRating(RATING_B).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D) .setStaticTechLevel(SimpleTechLevel.STANDARD); // Availability missing from TO. Using medium - protected static final TechAdvancement TA_AIRSHIP_SUPPORT_LARGE = new TechAdvancement(TECH_BASE_ALL) + private static final TechAdvancement TA_AIRSHIP_SUPPORT_LARGE = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_PS, DATE_PS, DATE_PS) .setTechRating(RATING_C).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D) .setStaticTechLevel(SimpleTechLevel.ADVANCED); - // Availability missing from TO. Using similar values from other support vees. // Also using early spaceflight for intro dates based on common sense. - protected static final TechAdvancement TA_SATELLITE = new TechAdvancement(TECH_BASE_ALL) + private static final TechAdvancement TA_SATELLITE_SMALL = new TechAdvancement(TECH_BASE_ALL) + .setAdvancement(DATE_ES, DATE_ES, DATE_ES) + .setTechRating(RATING_C).setAvailability(RATING_C, RATING_D, RATING_C, RATING_C) + .setStaticTechLevel(SimpleTechLevel.ADVANCED); + private static final TechAdvancement TA_SATELLITE_MEDIUM = new TechAdvancement(TECH_BASE_ALL) + .setAdvancement(DATE_ES, DATE_ES, DATE_ES) + .setTechRating(RATING_C).setAvailability(RATING_C, RATING_D, RATING_D, RATING_D) + .setStaticTechLevel(SimpleTechLevel.ADVANCED); + private static final TechAdvancement TA_SATELLITE_LARGE = new TechAdvancement(TECH_BASE_ALL) .setAdvancement(DATE_ES, DATE_ES, DATE_ES) .setTechRating(RATING_C).setAvailability(RATING_D, RATING_E, RATING_D, RATING_D) .setStaticTechLevel(SimpleTechLevel.ADVANCED); @@ -198,7 +203,13 @@ public static TechAdvancement getConstructionTechAdvancement(EntityMovementMode return TA_AIRSHIP_SUPPORT_SMALL; } } else if (movementMode.equals(EntityMovementMode.STATION_KEEPING)) { - return TA_SATELLITE; + if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { + return TA_SATELLITE_LARGE; + } else if (weightClass == EntityWeightClass.WEIGHT_MEDIUM_SUPPORT) { + return TA_SATELLITE_MEDIUM; + } else { + return TA_SATELLITE_SMALL; + } } else if (weightClass == EntityWeightClass.WEIGHT_LARGE_SUPPORT) { return TA_FIXED_WING_SUPPORT_LARGE; } else { @@ -272,17 +283,6 @@ public int getTotalSlots() { return 5 + (int) Math.floor(getWeight() / 10); } - /** - * @return Additional seats beyond the minimum crew requirements - */ - public int getExtraCrewSeats() { - return extraCrewSeats; - } - - public void setExtraCrewSeats(int seats) { - this.extraCrewSeats = seats; - } - @Override public void addBattleForceSpecialAbilities(Map specialAbilities) { super.addBattleForceSpecialAbilities(specialAbilities); From 1702de42a734e5139864fea03318c6694261bc4b Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 2 Sep 2019 13:15:13 -0500 Subject: [PATCH 62/69] Show BAR armor in SV weight breakdown. --- .../common/verifier/TestSupportVehicle.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index b59a3e34be0..44335bb78d0 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -619,6 +619,26 @@ public String printWeightStructure() { + TestEntity.makeWeightString(getWeightStructure()) + "\n"; } + @Override + public String printWeightArmor() { + String name; + if (getEntity().hasBARArmor(getEntity().firstArmorIndex())) { + name = String.format("BAR %d (%s)", + getEntity().getBARRating(getEntity().firstArmorIndex()), + ITechnology.getRatingName(getEntity().getArmorTechRating())); + } else if (!getEntity().hasPatchworkArmor()) { + name = EquipmentType.getArmorTypeName(getEntity() + .getArmorType(getEntity().firstArmorIndex())); + } else { + name = "Patchwork"; + } + return StringUtil.makeLength( + String.format("Armor: %d (%s)", getTotalOArmor(), name), + getPrintSize() - 5) + + TestEntity.makeWeightString(getWeightArmor()) + "\n"; + + } + @Override public Entity getEntity() { return supportVee; From 391a7a21829fea0af7bdcbf593ab1c62da828c74 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 3 Sep 2019 10:17:52 -0500 Subject: [PATCH 63/69] Fix SV engine weight rounding. --- megamek/src/megamek/common/Engine.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/megamek/src/megamek/common/Engine.java b/megamek/src/megamek/common/Engine.java index 43b6efd52ae..480aa475cac 100644 --- a/megamek/src/megamek/common/Engine.java +++ b/megamek/src/megamek/common/Engine.java @@ -334,7 +334,7 @@ && isValidEngine()) { int mp = entity.getOriginalWalkMP(); if (entity.getMovementMode().equals(EntityMovementMode.RAIL) || entity.getMovementMode().equals(EntityMovementMode.MAGLEV)) { - mp = Math.max(1, mp - 2); + mp = Math.max(0, mp - 2); } double movementFactor = 4 + mp * mp; double engineWeightMult = SV_ENGINE_RATINGS[engineType][entity @@ -353,11 +353,10 @@ && isValidEngine()) { if (entity.getMovementMode().equals(EntityMovementMode.HOVER)) { weight = Math.max(weight, entity.getWeight() * 0.2); } - roundWeight = TestEntity.Ceil.HALFTON; if (entity.getWeight() < 5) { - roundWeight = TestEntity.Ceil.KILO; + return TestEntity.round(weight, TestEntity.Ceil.KILO); } - return TestEntity.round(weight, roundWeight); + return TestEntity.ceil(weight, roundWeight); } // Protomech engines with rating < 40 use a special calculation if (entity.hasETypeFlag(Entity.ETYPE_PROTOMECH) && (engineRating < 40)) { From 1db85148e7cda999fc476a2c783bb68de009cd96 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 3 Sep 2019 10:30:02 -0500 Subject: [PATCH 64/69] Apply hydrofoil SV MP boost. --- megamek/src/megamek/common/SupportTank.java | 53 +++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index 230799524b5..d1cacca8d60 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -274,7 +274,60 @@ public int getTotalCommGearTons() { return getExtraCommGearTons(); } + @Override + public int getWalkMP(boolean gravity, boolean ignoreheat, + boolean ignoremodulararmor) { + int mp = getOriginalWalkMP(); + if (engineHit) { + return 0; + } + if (hasWorkingMisc(MiscType.F_HYDROFOIL)) { + mp = (int) Math.round(mp * 1.25); + } + mp = Math.max(0, mp - motiveDamage); + mp = Math.max(0, mp - getCargoMpReduction(this)); + if (null != game) { + int weatherMod = game.getPlanetaryConditions() + .getMovementMods(this); + if (weatherMod != 0) { + mp = Math.max(mp + weatherMod, 0); + } + } + if (!ignoremodulararmor && hasModularArmor()) { + mp--; + } + if (hasWorkingMisc(MiscType.F_DUNE_BUGGY) && (game != null)) { + mp--; + } + + if (gravity) { + mp = applyGravityEffectsOnMP(mp); + } + + //If the unit is towing trailers, adjust its walkMP, TW p205 + if (!getAllTowedUnits().isEmpty()) { + double tractorWeight = getWeight(); + double trailerWeight = 0; + //Add up the trailers + for (int id : getAllTowedUnits()) { + Entity tr = game.getEntity(id); + if (tr == null) { + //this isn't supposed to happen, but it can in rare cases when tr is destroyed + continue; + } + trailerWeight += tr.getWeight(); + } + if (trailerWeight <= (tractorWeight / 4)) { + mp = Math.max((mp - 3), (mp / 2)); + } else { + mp = (mp / 2); + } + } + + return mp; + + } // CONSTRUCTION INFORMATION //Support Vee Engine Information From e2d9dd30cd63650e5f8762b34473bb10ca91bfba Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 3 Sep 2019 11:14:03 -0500 Subject: [PATCH 65/69] Set max weight of 100 tons for hydrofoil chassis mod. --- megamek/src/megamek/common/verifier/TestSupportVehicle.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index 44335bb78d0..c3b03af4708 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -272,7 +272,9 @@ public enum ChassisModification implements ITechnologyDelegator { */ public boolean validFor(Entity sv) { return sv.isSupportVehicle() && allowedTypes.contains(SVType.getVehicleType(sv)) - && (!smallOnly || (sv.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT)); + && (!smallOnly || (sv.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT)) + // Hydrofoil has a specific upper weight limit rather than a weight class. + && (!this.equals(HYDROFOIL) || sv.getWeight() <= 100.0); } /** From fb30731e18cc9dc089eb816f28958016c069a158 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Wed, 4 Sep 2019 16:16:04 -0500 Subject: [PATCH 66/69] Removed incorrect smallOnly flag from convertible chassis mod. Added more detailed message for chassis mod validation failure. --- .../src/megamek/common/verifier/TestSupportVehicle.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/megamek/src/megamek/common/verifier/TestSupportVehicle.java b/megamek/src/megamek/common/verifier/TestSupportVehicle.java index c3b03af4708..94958756ea5 100644 --- a/megamek/src/megamek/common/verifier/TestSupportVehicle.java +++ b/megamek/src/megamek/common/verifier/TestSupportVehicle.java @@ -209,7 +209,7 @@ public enum ChassisModification implements ITechnologyDelegator { BICYCLE (0.75,EquipmentTypeLookup.BICYCLE_CHASSIS_MOD, EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED)), CONVERTIBLE (1.1,EquipmentTypeLookup.CONVERTIBLE_CHASSIS_MOD, - EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED, SVType.TRACKED), true), + EnumSet.of(SVType.HOVERCRAFT, SVType.WHEELED, SVType.TRACKED)), DUNE_BUGGY (1.5,EquipmentTypeLookup.DUNE_BUGGY_CHASSIS_MOD, EnumSet.of(SVType.WHEELED)), ENVIRONMENTAL_SEALING (2.0,EquipmentTypeLookup.ENVIRONMENTAL_SEALING_CHASSIS_MOD, @@ -274,7 +274,10 @@ public boolean validFor(Entity sv) { return sv.isSupportVehicle() && allowedTypes.contains(SVType.getVehicleType(sv)) && (!smallOnly || (sv.getWeightClass() == EntityWeightClass.WEIGHT_SMALL_SUPPORT)) // Hydrofoil has a specific upper weight limit rather than a weight class. - && (!this.equals(HYDROFOIL) || sv.getWeight() <= 100.0); + && (!this.equals(HYDROFOIL) || sv.getWeight() <= 100.0) + // Can't put a turret on a convertible + && (!this.equals(CONVERTIBLE) || !(sv instanceof Tank) + || ((Tank) sv).hasNoTurret()); } /** From 713931e64dd19a83fe62a6b7e03e72b52c3b9e99 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Sat, 7 Sep 2019 10:28:13 -0500 Subject: [PATCH 67/69] Override Entity#hasArmoredChassis in FixedWingSupport. --- megamek/src/megamek/common/FixedWingSupport.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/megamek/src/megamek/common/FixedWingSupport.java b/megamek/src/megamek/common/FixedWingSupport.java index 293c2fd17e4..f0d063ea84f 100644 --- a/megamek/src/megamek/common/FixedWingSupport.java +++ b/megamek/src/megamek/common/FixedWingSupport.java @@ -73,6 +73,11 @@ public boolean hasBARArmor(int loc) { return true; } + @Override + public boolean hasArmoredChassis() { + return hasWorkingMisc(MiscType.F_ARMORED_CHASSIS); + } + @Override public String[] getLocationAbbrs() { return LOCATION_ABBRS; From 693d1fcbba2a97d542804743e7d29ef30819c135 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Mon, 7 Oct 2019 22:28:51 -0500 Subject: [PATCH 68/69] Added missing imports. --- .../src/megamek/common/loaders/BLKSupportTankFile.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/megamek/src/megamek/common/loaders/BLKSupportTankFile.java b/megamek/src/megamek/common/loaders/BLKSupportTankFile.java index 66aed66cb17..9bc6a7824cc 100644 --- a/megamek/src/megamek/common/loaders/BLKSupportTankFile.java +++ b/megamek/src/megamek/common/loaders/BLKSupportTankFile.java @@ -14,12 +14,8 @@ package megamek.common.loaders; -import megamek.common.Engine; -import megamek.common.Entity; -import megamek.common.EntityMovementMode; -import megamek.common.EquipmentType; -import megamek.common.SupportTank; -import megamek.common.Tank; +import megamek.common.*; +import megamek.common.logging.DefaultMmLogger; import megamek.common.util.BuildingBlock; /** From 576e1746aee22c848860088638ed932295be6781 Mon Sep 17 00:00:00 2001 From: Carl Spain Date: Tue, 8 Oct 2019 09:42:39 -0500 Subject: [PATCH 69/69] Added null check There shouldn't be any cases where there are towed units and game is null, but better safe. --- megamek/src/megamek/common/SupportTank.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/megamek/src/megamek/common/SupportTank.java b/megamek/src/megamek/common/SupportTank.java index d1cacca8d60..f2b21ec1ba3 100644 --- a/megamek/src/megamek/common/SupportTank.java +++ b/megamek/src/megamek/common/SupportTank.java @@ -306,7 +306,7 @@ public int getWalkMP(boolean gravity, boolean ignoreheat, } //If the unit is towing trailers, adjust its walkMP, TW p205 - if (!getAllTowedUnits().isEmpty()) { + if ((null != game) && !getAllTowedUnits().isEmpty()) { double tractorWeight = getWeight(); double trailerWeight = 0; //Add up the trailers