diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_1.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_1.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_1.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_1.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_10.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_10.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_10.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_10.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_11.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_11.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_11.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_11.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_12.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_12.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_12.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_12.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_13.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_13.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_13.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_13.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_14.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_14.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_14.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_14.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_15.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_15.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_15.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_15.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_16.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_16.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_16.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_16.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_17.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_17.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_17.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_17.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_18.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_18.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_18.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_18.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_19.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_19.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_19.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_19.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_2.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_2.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_2.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_2.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_20.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_20.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_20.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_20.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_21.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_21.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_21.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_21.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_22.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_22.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_22.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_22.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_23.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_23.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_23.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_23.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_3.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_3.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_3.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_3.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_4.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_4.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_4.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_4.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_5.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_5.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_5.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_5.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_6.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_6.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_6.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_6.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_7.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_7.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_7.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_7.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_8.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_8.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_8.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_8.png diff --git a/MekHQ/data/images/portraits/Female/MekTech/MekTek_F_9.png b/MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_9.png similarity index 100% rename from MekHQ/data/images/portraits/Female/MekTech/MekTek_F_9.png rename to MekHQ/data/images/portraits/Female/Mek Tech/MekTek_F_9.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_1.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_1.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_1.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_1.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_10.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_10.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_10.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_10.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_11.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_11.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_11.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_11.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_12.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_12.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_12.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_12.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_13.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_13.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_13.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_13.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_14.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_14.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_14.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_14.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_15.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_15.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_15.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_15.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_16.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_16.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_16.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_16.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_17.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_17.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_17.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_17.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_18.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_18.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_18.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_18.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_19.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_19.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_19.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_19.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_2.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_2.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_2.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_2.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_20.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_20.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_20.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_20.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_21.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_21.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_21.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_21.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_22.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_22.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_22.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_22.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_23.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_23.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_23.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_23.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_24.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_24.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_24.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_24.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_25.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_25.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_25.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_25.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_26.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_26.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_26.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_26.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_3.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_3.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_3.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_3.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_4.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_4.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_4.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_4.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_5.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_5.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_5.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_5.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_6.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_6.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_6.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_6.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_7.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_7.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_7.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_7.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_8.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_8.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_8.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_8.png diff --git a/MekHQ/data/images/portraits/Male/MekTech/MekTek_M_9.png b/MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_9.png similarity index 100% rename from MekHQ/data/images/portraits/Male/MekTech/MekTek_M_9.png rename to MekHQ/data/images/portraits/Male/Mek Tech/MekTek_M_9.png diff --git a/MekHQ/data/scenariomodifiers/EnemyDropship.xml b/MekHQ/data/scenariomodifiers/EnemyDropship.xml index cf65a40f39..217d977867 100644 --- a/MekHQ/data/scenariomodifiers/EnemyDropship.xml +++ b/MekHQ/data/scenariomodifiers/EnemyDropship.xml @@ -18,9 +18,10 @@ 2 1.0 DropShip - 2 + 3 3 - 4 + 4 + 0 OpFor diff --git a/MekHQ/data/scenariomodifiers/GroundedEnemyDropship.xml b/MekHQ/data/scenariomodifiers/GroundedEnemyDropship.xml index 6f6d6efe50..8732eab250 100644 --- a/MekHQ/data/scenariomodifiers/GroundedEnemyDropship.xml +++ b/MekHQ/data/scenariomodifiers/GroundedEnemyDropship.xml @@ -22,9 +22,10 @@ 2 1.0 DropShip - 2 + 3 3 - 4 + 4 + 0 50 0 SameEdge diff --git a/MekHQ/data/scenariomodifiers/LiaisonGround.xml b/MekHQ/data/scenariomodifiers/LiaisonGround.xml index 47a4208ab5..3c5965f760 100644 --- a/MekHQ/data/scenariomodifiers/LiaisonGround.xml +++ b/MekHQ/data/scenariomodifiers/LiaisonGround.xml @@ -9,7 +9,7 @@ -1 false - 9 + 0 0 false true diff --git a/MekHQ/data/scenariotemplates/Decoy Engagement.xml b/MekHQ/data/scenariotemplates/Decoy Engagement.xml index 27bce72560..cec1b852fb 100644 --- a/MekHQ/data/scenariotemplates/Decoy Engagement.xml +++ b/MekHQ/data/scenariotemplates/Decoy Engagement.xml @@ -110,7 +110,7 @@ Custom 1 false - 2 + 1 ScaledToPrimaryUnitCount diff --git a/MekHQ/data/scenariotemplates/Decoy Interception.xml b/MekHQ/data/scenariotemplates/Decoy Interception.xml index b783af63ef..4db65be897 100644 --- a/MekHQ/data/scenariotemplates/Decoy Interception.xml +++ b/MekHQ/data/scenariotemplates/Decoy Interception.xml @@ -110,7 +110,7 @@ Custom 1 false - 2 + 1 ScaledToPrimaryUnitCount diff --git a/MekHQ/data/scenariotemplates/Deep Raid Defense.xml b/MekHQ/data/scenariotemplates/Deep Raid Defense.xml index 2bf0491b17..c81cdf3c67 100644 --- a/MekHQ/data/scenariotemplates/Deep Raid Defense.xml +++ b/MekHQ/data/scenariotemplates/Deep Raid Defense.xml @@ -42,9 +42,9 @@ NONE Preserve 100 - 30 false - Fixed + 2 + ScaledToPrimaryUnitCount @@ -66,8 +66,7 @@ - Destroy, cripple or force to withdraw 50% of the following force(s) and - unit(s): + Destroy, cripple or force to withdraw 50% of the following force(s) and unit(s): NONE ForceWithdraw 50 diff --git a/MekHQ/data/scenariotemplates/Deep Raid.xml b/MekHQ/data/scenariotemplates/Deep Raid.xml index 6f50f8a49d..4626c7f3f4 100644 --- a/MekHQ/data/scenariotemplates/Deep Raid.xml +++ b/MekHQ/data/scenariotemplates/Deep Raid.xml @@ -155,9 +155,9 @@ NONE ForceWithdraw 100 - 30 - true - Fixed + false + 2 + ScaledToPrimaryUnitCount diff --git a/MekHQ/data/scenariotemplates/DropShip Raid.xml b/MekHQ/data/scenariotemplates/DropShip Raid.xml index 9e6c850c2d..95227ed59a 100644 --- a/MekHQ/data/scenariotemplates/DropShip Raid.xml +++ b/MekHQ/data/scenariotemplates/DropShip Raid.xml @@ -155,9 +155,9 @@ NONE ForceWithdraw 100 - 30 - true - Fixed + false + 1 + ScaledToPrimaryUnitCount diff --git a/MekHQ/data/scenariotemplates/Engagement.xml b/MekHQ/data/scenariotemplates/Engagement.xml new file mode 100644 index 0000000000..027527e143 --- /dev/null +++ b/MekHQ/data/scenariotemplates/Engagement.xml @@ -0,0 +1,143 @@ + + + Engagement + Engage and destroy enemy at the front. + Enemy forces are advancing towards a key landmark. The objective is to either destroy or force them to retreat. At least 50% of the enemy must be neutralized, while maintaining 50% of friendly forces to hold the line and secure the frontline position. + + + false + 0 + 0 + 5 + AllGroundTerrain + true + 5 + + + + Player + + -1 + false + -2 + 0 + true + true + true + true + false + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + 5 + 0 + 0 + 1.0 + Player + 0 + 1 + 4 + 0 + 50 + 0 + None + false + + + + OpFor + + -1 + false + -2 + 0 + true + false + true + false + false + + 5 + 0 + 2 + 1.0 + OpFor + 1 + 5 + 4 + 0 + 50 + 0 + OppositeEdge + Player + false + + + + + + + OpFor + + + + + ScenarioVictory + Fixed + 1 + + + + + ScenarioDefeat + Fixed + 1 + + + + Destroy or rout 50% of the following force(s) and unit(s): + NONE + ForceWithdraw + 50 + true + None + + + + Player + + + + + ScenarioVictory + Fixed + 1 + + + + + ScenarioDefeat + Fixed + 1 + + + + Preserve 50% of the following force(s) and unit(s): + NONE + Preserve + 50 + true + None + + + diff --git a/MekHQ/data/scenariotemplates/Heavy Recon Evasion.xml b/MekHQ/data/scenariotemplates/Heavy Recon Evasion.xml index 7bfb2977d1..03d306dc5b 100644 --- a/MekHQ/data/scenariotemplates/Heavy Recon Evasion.xml +++ b/MekHQ/data/scenariotemplates/Heavy Recon Evasion.xml @@ -114,7 +114,7 @@ Preserve 50 false - 2 + 1 ScaledToPrimaryUnitCount diff --git a/MekHQ/data/scenariotemplates/Isolated DropShip Defense.xml b/MekHQ/data/scenariotemplates/Isolated DropShip Defense.xml index 9c471ee198..a164611a0f 100644 --- a/MekHQ/data/scenariotemplates/Isolated DropShip Defense.xml +++ b/MekHQ/data/scenariotemplates/Isolated DropShip Defense.xml @@ -42,9 +42,9 @@ NONE Preserve 100 - 30 false - Fixed + 1 + ScaledToPrimaryUnitCount diff --git a/MekHQ/data/scenariotemplates/Recon Evasion.xml b/MekHQ/data/scenariotemplates/Recon Evasion.xml index 28a4c294f0..edd5fd4442 100644 --- a/MekHQ/data/scenariotemplates/Recon Evasion.xml +++ b/MekHQ/data/scenariotemplates/Recon Evasion.xml @@ -114,7 +114,7 @@ Preserve 50 false - 2 + 1 ScaledToPrimaryUnitCount diff --git a/MekHQ/data/scenariotemplates/ScenarioManifest.xml b/MekHQ/data/scenariotemplates/ScenarioManifest.xml index 6a68eca3f7..fa42da703a 100644 --- a/MekHQ/data/scenariotemplates/ScenarioManifest.xml +++ b/MekHQ/data/scenariotemplates/ScenarioManifest.xml @@ -180,5 +180,9 @@ 44 VIP Defense.xml + + 45 + Engagement.xml + diff --git a/MekHQ/docs/history.txt b/MekHQ/docs/history.txt index dcc43d3ff7..fb83312316 100644 --- a/MekHQ/docs/history.txt +++ b/MekHQ/docs/history.txt @@ -47,7 +47,7 @@ MEKHQ VERSION HISTORY: + Fix #4771 & #4781: Fixed ConcurrentModificationException in Personnel Removal Process + Fix #4736: Regenerate Personality Descriptions for NPCs + Fix #4721: Removed Automatic Conversion of CVP into SP when Reinforcing in StratCon -+ Fix #4782: Removed TN Modifier for IS Techs working on Clan Tech, Removed Clan Tech Knowledge SPA and Effects #4863 ++ Fix #4782: Removed TN Modifier for IS Techs working on Clan Tech, Removed Clan Tech Knowledge SPA and Effects + PR #4463: Decoupled Dependents from AtB, Reworked Dependents, Reworked New Personnel Ages, Added Documentation + PR #4644: Initial work on CamOps RAW Contract Market + PR #4859: Reworked AtB Morale, Rebranding it as MekHQ Morale @@ -109,6 +109,59 @@ MEKHQ VERSION HISTORY: + PR #5054: Implement CamOps Contract Negotiation + PR #5055: Parts In Use - Filter Mothballed and Spare Part Quality + PR #5064: Bug fix and improvements for calculateContractDifficulty() ++ Fix #5061: Fixed TurretLock Part not saving ++ Fix #4725: Added duplicate kill checking for multi-crewed units ++ Fix #5058: Fixed `isMilitary` and `isPrepSchool` flags; corrected typo ++ Fix #4973: Fixed `isMilitary` and `isPrepSchool` flags; corrected typo ++ Fix #5065: Showed actual amount of armor on order in repair info ++ PR #5066: Parts improvements - minor refactoring and better information ++ PR #5067: Changed "Clear All Items" to "Remove Selected Items" on CC Tab list ++ Fix #5059: Added "No Eligible Personnel" dialog to turnover & retention checks ++ PR #5069: Implemented hiring hall overrides ++ Fix #5045: Added TotalGenericBattleValue tag to MUL export ++ Fix #5037: Fixed hire minimum complement commands ++ Fix #4725: Added duplicate kill checking for multi-crewed units ++ PR #5073: Refactored contract difficulty display and added tooltips ++ PR #5074: Updated primary allies scenario modifiers ++ Fix #5003: Fixed wrapping of personality description ++ Fix #4999: Updated fatigue column of personnel table to use effective fatigue value ++ Fix #4998: Fixed new day reporting ++ Fix #4991: Re-added compatibility handlers for SPA skill prerequisites ++ Fix #5019: ForceRenderer - Bolded unit commanders ++ Fix #5083: StratCon vs normal deployment status of units ++ PR #5085: Improved Force Gen unit substitution ++ Fix #5079: Refined PartQualityReportDialog layout handling and exclusions ++ Fix #4995: Fixed SPA tooltip HTML wrapping in PersonViewPanel ++ Fix #5020: Fixed SPA tooltip HTML wrapping in PersonViewPanel ++ PR #5088: Added 100+ new quirks, refactored personality traits & quirk classes ++ Fix #4988: Added empty jump path check to UnableToAffordJumpNagDialog ++ Fix #4987: Fixed camouflage directory assignment for null faction codes ++ PR #5091: Added minimum number of tracks (1) to StratCon initialization ++ PR #5092: Fixed objective criteria for intercept engagement ++ Fix #4980: Fixed outsourcing of babies ++ Fix #4972: Corrected parameter order in simulated relationship history reports ++ PR #5097: Simplified reputation display ++ PR #5098, #5113: More FG3 scenario adjustments ++ PR #5099: Added award bonuses to award ceremony dialog ++ Fix #5100: PartsStore - Fixed equipment parts and OmniPods (fixes hatchets and maces at least) ++ Fix #4955: Prevented dropout and some graduation events occurring for very young children ++ Fix #5102: Fixed portrait folder names ++ Fix #5023: Fixed Divide by Zero Error in Loans Dialog ++ Fix #4975: Prevent Early Clan Units in Non-Clan Campaigns ++ PR #5103: Globally fix slow mouse wheeling issues, with scaling ++ PR #5104: Fixed Preset Picker Date Issues ++ Fix #4980: Fixed Outsourcing of Babies ++ PR #5105: ResolveScenarioWizardDialog - Some UX Improvements ++ PR #5106: ResolveScenarioWizardDialog - Ransom All Button ++ PR #5107: Updated Interstellar Map View Defaults & Optimized 'ISW' view ++ Fix #5109: Corrected DropShip Scenario Modifier Generation Method ++ PR #5111: Better multi-day repair and refit reports. ++ PR #5112: TechTabelModel - Show Daily Available Time for Techs ++ Fix #5118 && #5117: FG3 Scenario Improvements ++ PR #5121: Label OmniUnits as Omni in the MekHQ UI ++ Fix #5119 && #5108 && #4297 Fixed Position of NewDayEvent Trigger in processNewDay ++ PR #5126: Rebalanced Random Unit Quality + 0.50.0 (2024-09-01 2000 UTC) (THIS MARKS THE START OF JAVA 17 AS THE MINIMUM REQUIRED) + PR #4332: CI Updates for windows build and normalizing diff --git a/MekHQ/resources/mekhq/resources/ContractMarketDialog.properties b/MekHQ/resources/mekhq/resources/ContractMarketDialog.properties index e31f2f2500..b8f7b3021d 100644 --- a/MekHQ/resources/mekhq/resources/ContractMarketDialog.properties +++ b/MekHQ/resources/mekhq/resources/ContractMarketDialog.properties @@ -84,7 +84,7 @@ messageChallengeHard.text=Our analysis of the upcoming mission indicates that th \ be prepared for a tough fight and the possibility of sustaining losses.\
\
This mission will test your tactical abilities and resourcefulness. Victory is achievable, but\ - \ it won't come without cost. >We trust in your leadership to make the right call.\ + \ it won't come without cost. We trust in your leadership to make the right call.\
\
If you are ready to face this challenge, confirm your deployment.\
Otherwise, you may return to assess alternative missions.
diff --git a/MekHQ/resources/mekhq/resources/ResolveScenarioWizardDialog.properties b/MekHQ/resources/mekhq/resources/ResolveScenarioWizardDialog.properties index 69b8050884..edca22639c 100644 --- a/MekHQ/resources/mekhq/resources/ResolveScenarioWizardDialog.properties +++ b/MekHQ/resources/mekhq/resources/ResolveScenarioWizardDialog.properties @@ -10,6 +10,7 @@ mia=MIA kia=KIA prisoner=Captured prisonerRansomed.text=Ransomed +prisonerRansomAllButton.text=Ransom All Prisoners bondsman=Bondsman escaped=Escaped dead=Dead diff --git a/MekHQ/src/mekhq/campaign/Campaign.java b/MekHQ/src/mekhq/campaign/Campaign.java index 0253f308cb..1029dd34da 100644 --- a/MekHQ/src/mekhq/campaign/Campaign.java +++ b/MekHQ/src/mekhq/campaign/Campaign.java @@ -1441,27 +1441,32 @@ public Unit getUnit(UUID id) { // region Personnel // region Person Creation /** - * Creates a new {@link Person} instance who is a dependent. - * If {@code baby} is false and the random dependent origin option is enabled, - * the new person will have a random origin. + * Creates a new dependent with given gender. The origin faction and planet are set to null. * - * @param baby a boolean indicating if the person is a baby or not - * @param gender the Gender enum for the person (should normally be Gender.RANDOMIZE) - * @return a new {@link Person} instance who is a dependent - */ - public Person newDependent(boolean baby, Gender gender) { - Person person; - - if ((!baby) && (getCampaignOptions().getRandomOriginOptions().isRandomizeDependentOrigin())) { - person = newPerson(PersonnelRole.DEPENDENT, PersonnelRole.NONE, - new DefaultFactionSelector(getCampaignOptions().getRandomOriginOptions()), - new DefaultPlanetSelector(getCampaignOptions().getRandomOriginOptions()), - gender); - } else { - person = newPerson(PersonnelRole.DEPENDENT); - } + * @param gender The {@link Gender} of the new dependent. + * @return Return a {@link Person} object representing the new dependent. + */ + public Person newDependent(Gender gender) { + return newDependent(gender, null, null); + } - return person; + /** + * Creates a new dependent with given gender, origin faction and origin planet. + * + * @param gender The {@link Gender} of the new dependent. + * @param originFaction The {@link Faction} that represents the origin faction for the new dependent. + * This can be null, suggesting the faction will be chosen based on campaign options. + * @param originPlanet The {@link Planet} that represents the origin planet for the new dependent. + * This can be null, suggesting the planet will be chosen based on campaign options. + * @return Return a {@link Person} object representing the new dependent. + */ + public Person newDependent(Gender gender, @Nullable Faction originFaction, + @Nullable Planet originPlanet) { + return newPerson(PersonnelRole.DEPENDENT, + PersonnelRole.NONE, + new DefaultFactionSelector(getCampaignOptions().getRandomOriginOptions(), originFaction), + new DefaultPlanetSelector(getCampaignOptions().getRandomOriginOptions(), originPlanet), + gender); } /** @@ -3244,34 +3249,40 @@ public void activate(Unit u) { addReport(report); } - public void refit(Refit r) { - Person tech = (r.getUnit().getEngineer() == null) ? r.getTech() : r.getUnit().getEngineer(); + public void refit(Refit theRefit) { + Person tech = (theRefit.getUnit().getEngineer() == null) ? theRefit.getTech() : theRefit.getUnit().getEngineer(); if (tech == null) { - addReport("No tech is assigned to refit " + r.getOriginalEntity().getShortName() + ". Refit cancelled."); - r.cancel(); + addReport("No tech is assigned to refit " + theRefit.getOriginalEntity().getShortName() + ". Refit cancelled."); + theRefit.cancel(); return; } - TargetRoll target = getTargetFor(r, tech); + TargetRoll target = getTargetFor(theRefit, tech); // check that all parts have arrived - if (!r.acquireParts()) { + if (!theRefit.acquireParts()) { return; } - String report = tech.getHyperlinkedFullTitle() + " works on " + r.getPartName(); - int minutes = r.getTimeLeft(); + String report = tech.getHyperlinkedFullTitle() + " works on " + theRefit.getPartName(); + int minutes = theRefit.getTimeLeft(); // FIXME: Overtime? if (minutes > tech.getMinutesLeft()) { - r.addTimeSpent(tech.getMinutesLeft()); + theRefit.addTimeSpent(tech.getMinutesLeft()); tech.setMinutesLeft(0); - report = report + ", " + r.getTimeLeft() + " minutes left."; + report = report + ", " + theRefit.getTimeLeft() + " minutes left. Completion "; + int daysLeft = (int) Math.ceil(theRefit.getTimeLeft() / tech.getDailyAvailableTechTime()) + 1; + if (daysLeft == 1) { + report += " tomorrow."; + } else { + report += " in " + daysLeft + " days."; + } } else { tech.setMinutesLeft(tech.getMinutesLeft() - minutes); - r.addTimeSpent(minutes); - if (r.hasFailedCheck()) { - report = report + ", " + r.succeed(); + theRefit.addTimeSpent(minutes); + if (theRefit.hasFailedCheck()) { + report = report + ", " + theRefit.succeed(); } else { int roll; String wrongType = ""; - if (tech.isRightTechTypeFor(r)) { + if (tech.isRightTechTypeFor(theRefit)) { roll = Compute.d6(2); } else { roll = Utilities.roll3d6(); @@ -3282,7 +3293,7 @@ public void refit(Refit r) { && tech.getOptions().booleanOption(PersonnelOptions.EDGE_REPAIR_FAILED_REFIT) && (tech.getCurrentEdge() > 0)) { tech.changeCurrentEdge(-1); - roll = tech.isRightTechTypeFor(r) ? Compute.d6(2) : Utilities.roll3d6(); + roll = tech.isRightTechTypeFor(theRefit) ? Compute.d6(2) : Utilities.roll3d6(); // This is needed to update the edge values of individual crewmen if (tech.isEngineer()) { tech.setEdgeUsed(tech.getEdgeUsed() - 1); @@ -3291,18 +3302,25 @@ public void refit(Refit r) { } if (roll >= target.getValue()) { - report += r.succeed(); + report += theRefit.succeed(); } else { - report += r.fail(SkillType.EXP_GREEN); + report += theRefit.fail(SkillType.EXP_GREEN); // try to refit again in case the tech has any time left - if (!r.isBeingRefurbished()) { - refit(r); + if (!theRefit.isBeingRefurbished()) { + refit(theRefit); + report += " Completion "; + int daysLeft = (int) Math.ceil(theRefit.getTimeLeft() / tech.getDailyAvailableTechTime()) + 1; + if (daysLeft == 1) { + report += " tomorrow."; + } else { + report += " in " + daysLeft + " days."; + } } } report += wrongType; } } - MekHQ.triggerEvent(new PartWorkEvent(tech, r)); + MekHQ.triggerEvent(new PartWorkEvent(tech, theRefit)); addReport(report); } @@ -3428,12 +3446,17 @@ public String fixPart(IPartWork partWork, Person tech) { } partWork.setTech(tech); partWork.reservePart(); - report += " - Not enough time, the remainder of the task"; - if (null != partWork.getUnit()) { - report += " on " + partWork.getUnit().getName(); - } - if (minutesUsed > 0) { - report += " will be finished tomorrow."; + report += " - "; + report += partWork.getTimeLeft(); + report += " minutes left. Work"; + if ((minutesUsed > 0) && (tech.getDailyAvailableTechTime() > 0)) { + report += " will be finished "; + int daysLeft = (int) Math.ceil(partWork.getTimeLeft() / tech.getDailyAvailableTechTime()) + 1; + if (daysLeft == 1) { + report += " tomorrow."; + } else { + report += " in " + daysLeft + " days."; + } } else { report += " cannot be finished because there was no time left after maintenance tasks."; partWork.resetTimeSpent(); @@ -4219,8 +4242,6 @@ public boolean newDay() { newReports.clear(); beginReport("" + MekHQ.getMHQOptions().getLongDisplayFormattedDate(getLocalDate()) + ""); - MekHQ.triggerEvent(new NewDayEvent(this)); - // New Year Changes if (getLocalDate().getDayOfYear() == 1) { // News is reloaded @@ -4298,6 +4319,8 @@ public boolean newDay() { } } + // This must be the last step before returning true + MekHQ.triggerEvent(new NewDayEvent(this)); return true; } @@ -4452,7 +4475,7 @@ void dependentsAddNew(int dependentCount, int dependentCapacity) { } if (roll <= (getAtBUnitRatingMod() * 2)) { - final Person dependent = newDependent(false, Gender.RANDOMIZE); + final Person dependent = newDependent(Gender.RANDOMIZE); recruitPerson(dependent, PrisonerStatus.FREE, true, false); diff --git a/MekHQ/src/mekhq/campaign/finances/Loan.java b/MekHQ/src/mekhq/campaign/finances/Loan.java index 8cfc54c498..b4f06602c3 100644 --- a/MekHQ/src/mekhq/campaign/finances/Loan.java +++ b/MekHQ/src/mekhq/campaign/finances/Loan.java @@ -21,18 +21,17 @@ */ package mekhq.campaign.finances; -import java.io.PrintWriter; -import java.time.LocalDate; -import java.util.Objects; - -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - import megamek.common.Compute; import megamek.logging.MMLogger; import mekhq.campaign.finances.enums.FinancialTerm; import mekhq.campaign.finances.financialInstitutions.FinancialInstitutions; import mekhq.utilities.MHQXMLUtility; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.io.PrintWriter; +import java.time.LocalDate; +import java.util.Objects; /** * TODO : Update loan baseline based on latest Campaign Operations Rules @@ -197,9 +196,13 @@ public void calculateAmortization() { final double periodicRate = (getRate() / 100.0) / paymentsPerYear; setRemainingPayments(numberOfPayments); - setPaymentAmount(getPrincipal() + if (periodicRate > 0) { + setPaymentAmount(getPrincipal() .multipliedBy(periodicRate * Math.pow(1 + periodicRate, numberOfPayments)) .dividedBy(Math.pow(1 + periodicRate, numberOfPayments) - 1)); + } else { + setPaymentAmount(getPrincipal().dividedBy(numberOfPayments)); + } } public void paidLoan() { @@ -388,8 +391,7 @@ public boolean equals(final Object other) { return false; } else if (this == other) { return true; - } else if (other instanceof Loan) { - final Loan loan = (Loan) other; + } else if (other instanceof Loan loan) { return getInstitution().equals(loan.getInstitution()) && getReferenceNumber().equals(loan.getReferenceNumber()) && getPrincipal().equals(loan.getPrincipal()) diff --git a/MekHQ/src/mekhq/campaign/market/unitMarket/AbstractUnitMarket.java b/MekHQ/src/mekhq/campaign/market/unitMarket/AbstractUnitMarket.java index 517e509d6d..6d4fe6b1ca 100644 --- a/MekHQ/src/mekhq/campaign/market/unitMarket/AbstractUnitMarket.java +++ b/MekHQ/src/mekhq/campaign/market/unitMarket/AbstractUnitMarket.java @@ -18,15 +18,6 @@ */ package mekhq.campaign.market.unitMarket; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.ResourceBundle; - -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - import megamek.Version; import megamek.client.ratgenerator.MissionRole; import megamek.common.Compute; @@ -40,6 +31,15 @@ import mekhq.campaign.market.enums.UnitMarketType; import mekhq.campaign.universe.Faction; import mekhq.utilities.MHQXMLUtility; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.io.PrintWriter; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.ResourceBundle; public abstract class AbstractUnitMarket { private static final MMLogger logger = MMLogger.create(AbstractUnitMarket.class); @@ -78,7 +78,7 @@ public void setOffers(final List offers) { * This is the primary method for processing the Unit Market. It is executed as * part of * {@link Campaign#newDay()} - * + * * @param campaign the campaign to process the Unit Market new day using */ public abstract void processNewDay(final Campaign campaign); @@ -88,14 +88,14 @@ public void setOffers(final List offers) { * This is the primary Unit Market generation method, which is how the market * specified * generates unit offers - * + * * @param campaign the campaign to generate the unit offers for */ public abstract void generateUnitOffers(final Campaign campaign); /** * This adds a number of unit offers - * + * * @param campaign the campaign to add the offers based on * @param number the number of units to generate * @param market the unit market type the unit is part of @@ -191,8 +191,20 @@ public abstract void addOffers(final Campaign campaign, final int number, UnitMa public String addSingleUnit(final Campaign campaign, final UnitMarketType market, final int unitType, final MekSummary mekSummary, final int percent) { + final LocalDate BATTLE_OF_TUKAYYID = LocalDate.of(3052, 5, 21); + + Faction campaignFaction = campaign.getFaction(); + LocalDate currentDate = campaign.getLocalDate(); + + if (!campaignFaction.isClan()) { + if (mekSummary.isClan() && currentDate.isBefore(BATTLE_OF_TUKAYYID)) { + return null; + } + } + getOffers().add(new UnitMarketOffer(market, unitType, mekSummary, percent, generateTransitDuration(campaign))); + return mekSummary.getName(); } @@ -229,7 +241,7 @@ protected void writeRefreshReport(final Campaign campaign) { * This is the primary Unit Market removal method, which is how the market * specified * removes unit offers - * + * * @param campaign the campaign to use in determining the offers to remove */ protected abstract void removeUnitOffers(final Campaign campaign); @@ -239,7 +251,7 @@ protected void writeRefreshReport(final Campaign campaign) { // region File I/O /** * This writes the Unit Market to XML - * + * * @param pw the PrintWriter to write to * @param indent the base indent level to write at */ @@ -253,7 +265,7 @@ public void writeToXML(final PrintWriter pw, int indent) { * This is meant to be overridden so that a market can have additional elements * added to it, * albeit with this called by super.writeBodyToXML(pw, indent) first. - * + * * @param pw the PrintWriter to write to * @param indent the base indent level to write at */ @@ -267,7 +279,7 @@ protected void writeBodyToXML(final PrintWriter pw, int indent) { * This method fills the market based on the supplied XML node. The market is * initialized as * empty before this is called. - * + * * @param wn the node to fill the market from * @param campaign the campaign the market is being parsed as part of * @param version the version of the market being parsed @@ -291,7 +303,7 @@ public void fillFromXML(final Node wn, final Campaign campaign, final Version ve * This is meant to be overridden so that a market can have additional elements * added to it, * albeit with this called by super.parseXMLNode(wn) first. - * + * * @param wn the node to parse from XML * @param campaign the campaign the market is being parsed as part of * @param version the version of the market being parsed diff --git a/MekHQ/src/mekhq/campaign/mission/AtBContract.java b/MekHQ/src/mekhq/campaign/mission/AtBContract.java index 1bd588e19f..9b45452716 100644 --- a/MekHQ/src/mekhq/campaign/mission/AtBContract.java +++ b/MekHQ/src/mekhq/campaign/mission/AtBContract.java @@ -664,7 +664,7 @@ public void doBonusRoll(Campaign campaign) { campaign.addReport("Bonus: " + number + " dependent" + ((number > 1) ? "s" : "")); for (int i = 0; i < number; i++) { - Person p = campaign.newDependent(false, Gender.RANDOMIZE); + Person p = campaign.newDependent(Gender.RANDOMIZE); campaign.recruitPerson(p); } } diff --git a/MekHQ/src/mekhq/campaign/mission/AtBDynamicScenarioFactory.java b/MekHQ/src/mekhq/campaign/mission/AtBDynamicScenarioFactory.java index 5718438f7b..73c262bbf9 100644 --- a/MekHQ/src/mekhq/campaign/mission/AtBDynamicScenarioFactory.java +++ b/MekHQ/src/mekhq/campaign/mission/AtBDynamicScenarioFactory.java @@ -284,7 +284,9 @@ private static int generateForces(AtBDynamicScenario scenario, AtBContract contr } else { int weightClass = randomForceWeight(); - logger.info(String.format("++ Generating a force for the %s template ++", forceTemplate.getForceName()).toUpperCase()); + if (forceTemplate.isPlayerForce()) { + logger.info(String.format("++ Generating a force for the %s template ++", forceTemplate.getForceName()).toUpperCase()); + } generatedLanceCount += generateForce(scenario, contract, campaign, effectiveBV, effectiveUnitCount, weightClass, forceTemplate, false); } @@ -435,12 +437,17 @@ public static int generateForce(AtBDynamicScenario scenario, AtBContract contrac // determine generation parameters int forceBV = 0; + double forceMultiplier = forceTemplate.getForceMultiplier(); - int forceBVBudget = (int) (effectiveBV * forceTemplate.getForceMultiplier()); + int forceBVBudget = (int) (effectiveBV * forceMultiplier); if (isScenarioModifier) { forceBVBudget = (int) (forceBVBudget * ((double) campaign.getCampaignOptions().getScenarioModBV() / 100) - * forceTemplate.getForceMultiplier()); + * forceMultiplier); + } + + if (forceTemplate.getForceMultiplier() != 1) { + logger.info(String.format("Force BV Multiplier: %s (from scenario template)", forceMultiplier)); } int forceUnitBudget = 0; @@ -574,10 +581,7 @@ public static int generateForce(AtBDynamicScenario scenario, AtBContract contrac while (!stopGenerating) { List generatedLance; - // Generate a number of tactical formations for this force based on the desired - // average weight class. - // This may generate higher numbers of lighter formations, or fewer - // (minimum of one) of heavier formations. + // Generate a tactical formations for this force based on the desired weight class. if (currentLanceWeightString.isEmpty()) { currentLanceWeightString = campaign.getAtBConfig().selectBotLances(parentFactionType, weightClass); } @@ -765,8 +769,8 @@ public static int generateForce(AtBDynamicScenario scenario, AtBContract contrac // For generation methods other than scaled BV, compare to the overall budget stopGenerating = generatedEntities.size() >= forceUnitBudget; } - - currentLanceWeightString = currentLanceWeightString.substring(1); + weightClass = randomForceWeight(); + currentLanceWeightString = campaign.getAtBConfig().selectBotLances(parentFactionType, weightClass); } // If over budget for BV or unit count, pull units until it works @@ -783,7 +787,7 @@ public static int generateForce(AtBDynamicScenario scenario, AtBContract contrac logger.info(String.format("%s generated a force with %s / %s %s BV", forceTemplate.getForceName(), forceBV, forceBVBudget, balancingType)); - int adjustedBvBudget = (int) (forceBVBudget * 1.1); + int adjustedBvBudget = (int) (forceBVBudget * 1.25); while ((forceBV > adjustedBvBudget) && (generatedEntities.size() > 1)) { int targetUnit = Compute.randomInt(generatedEntities.size()); @@ -803,8 +807,8 @@ public static int generateForce(AtBDynamicScenario scenario, AtBContract contrac generatedEntities.remove(targetUnit); } - logger.info(String.format("Final force %s / %s %s BV (adjusted for bounds)", - forceBV, adjustedBvBudget, balancingType)); + logger.info(String.format("Final force %s / %s %s BV (may exceed by *1.25)", + forceBV, forceBVBudget, balancingType)); } // Units with infantry bays get conventional infantry or battle armor added @@ -2710,6 +2714,9 @@ public static int calculateEffectiveBV(AtBDynamicScenario scenario, Campaign cam } } + logger.info(String.format("Total Seed Force %s: %s", + generationMethod, bvBudget)); + double bvMultiplier = scenario.getEffectivePlayerBVMultiplier(); if (bvMultiplier > 0) { @@ -2718,8 +2725,6 @@ public static int calculateEffectiveBV(AtBDynamicScenario scenario, Campaign cam bvBudget = (int) round(bvBudget * difficultyMultiplier); } - logger.info(String.format("Total Player %s: %s (adjusted for campaign difficulty)", generationMethod, bvBudget)); - // allied bot forces that contribute to BV do not get multiplied by the // difficulty even if the player is perfect, the AI doesn't get any better for (int index = 0; index < scenario.getNumBots(); index++) { @@ -2728,12 +2733,12 @@ public static int calculateEffectiveBV(AtBDynamicScenario scenario, Campaign cam if (forceTemplate != null && forceTemplate.getContributesToBV()) { bvBudget += botForce.getTotalBV(campaign); - logger.info(String.format("%s %s: %s", - botForce.getName(), generationMethod, botForce.getTotalBV(campaign))); + logger.info(String.format("%s %s: %s", botForce.getName(), generationMethod, botForce.getTotalBV(campaign))); } } - logger.info(String.format("Total Base %s Budget: %s", generationMethod, bvBudget)); + logger.info(String.format("Total Base %s Budget: %s (adjusted for campaign difficulty)", + generationMethod, bvBudget)); return bvBudget; } diff --git a/MekHQ/src/mekhq/campaign/personnel/marriage/AbstractMarriage.java b/MekHQ/src/mekhq/campaign/personnel/marriage/AbstractMarriage.java index 97560991f9..b586446a38 100644 --- a/MekHQ/src/mekhq/campaign/personnel/marriage/AbstractMarriage.java +++ b/MekHQ/src/mekhq/campaign/personnel/marriage/AbstractMarriage.java @@ -376,7 +376,7 @@ protected void marryRandomSpouse(final Campaign campaign, final LocalDate today, * @return the created external spouse */ Person createExternalSpouse(final Campaign campaign, final LocalDate today, final Person person, Gender gender) { - Person externalSpouse = campaign.newDependent(false, gender); + Person externalSpouse = campaign.newDependent(gender); // Calculate person's age and the maximum and minimum allowable spouse ages diff --git a/MekHQ/src/mekhq/campaign/personnel/procreation/AbstractProcreation.java b/MekHQ/src/mekhq/campaign/personnel/procreation/AbstractProcreation.java index 52f158e69b..9619d90800 100644 --- a/MekHQ/src/mekhq/campaign/personnel/procreation/AbstractProcreation.java +++ b/MekHQ/src/mekhq/campaign/personnel/procreation/AbstractProcreation.java @@ -36,6 +36,8 @@ import mekhq.campaign.personnel.education.EducationController; import mekhq.campaign.personnel.enums.*; import mekhq.campaign.personnel.enums.education.EducationLevel; +import mekhq.campaign.universe.Faction; +import mekhq.campaign.universe.Planet; import java.time.LocalDate; import java.time.temporal.ChronoUnit; @@ -337,7 +339,8 @@ public void birth(final Campaign campaign, final LocalDate today, final Person m // Create Babies for (int i = 0; i < size; i++) { // Create a baby - final Person baby = campaign.newDependent(true, Gender.RANDOMIZE); + final Person baby = campaign.newDependent( + Gender.RANDOMIZE, mother.getOriginFaction(), campaign.getLocation().getPlanet()); baby.setSurname(campaign.getCampaignOptions().getBabySurnameStyle() .generateBabySurname(mother, father, baby.getGender())); baby.setDateOfBirth(today); @@ -436,7 +439,15 @@ public List birthHistoric(final Campaign campaign, final LocalDate today // Create Babies for (int i = 0; i < size; i++) { // Create the babies - final Person baby = campaign.newDependent(true, Gender.RANDOMIZE); + Faction originFaction = mother.getOriginFaction(); + Planet originPlanet = mother.getOriginPlanet(); + + if (father != null && Compute.randomInt(1) == 0) { + originFaction = father.getOriginFaction(); + originPlanet = father.getOriginPlanet(); + } + + final Person baby = campaign.newDependent(Gender.RANDOMIZE, originFaction, originPlanet); baby.setSurname(campaign.getCampaignOptions().getBabySurnameStyle() .generateBabySurname(mother, father, baby.getGender())); diff --git a/MekHQ/src/mekhq/campaign/unit/Unit.java b/MekHQ/src/mekhq/campaign/unit/Unit.java index 86813a1ea2..a9c23b0381 100644 --- a/MekHQ/src/mekhq/campaign/unit/Unit.java +++ b/MekHQ/src/mekhq/campaign/unit/Unit.java @@ -77,6 +77,8 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +import static mekhq.campaign.parts.enums.PartQuality.*; + /** * This is a wrapper class for entity, so that we can add some functionality to * it @@ -274,6 +276,25 @@ public CrewAssignmentState getCrewState() { } } + /** + * Like UnitType.getTypeDisplayableName but prepends "Omni" to omni units + * @return String displayable name with possible "Omni" + */ + public String getTypeDisplayableNameWithOmni() { + Entity ourEntity = getEntity(); + int type = ourEntity.getUnitType(); + if (!ourEntity.isOmni()) { + return UnitType.getTypeDisplayableName(type); + } + StringBuilder toReturn = new StringBuilder(); + toReturn.append("Omni"); + if (!(type == UnitType.TANK || type == UnitType.MEK)) { + toReturn.append(" "); + } + toReturn.append(UnitType.getTypeDisplayableName(type)); + return toReturn.toString(); + } + public void reCalc() { // Do Nothing } @@ -5239,7 +5260,7 @@ public PartQuality getQuality() { } } if (nParts == 0) { - return PartQuality.QUALITY_D; + return QUALITY_D; } return PartQuality.fromNumeric((int) Math.round((1.0 * sumQuality) / nParts)); } @@ -5878,26 +5899,21 @@ public void fixReferences(Campaign campaign) { /** * Generates a random unit quality based on a 2d6 roll and a modifier. - * This table is based on the AtB Mek Quality table, but is still useful outside - * of that ruleset * * @param modifier the modifier to be applied to the 2d6 roll * @return an integer representing the generated unit quality - * @throws IllegalStateException if an unexpected value is encountered during - * the switch statement + * @throws IllegalStateException if an unexpected value is encountered during the switch statement */ public static PartQuality getRandomUnitQuality(int modifier) { - int roll = MathUtility.clamp( - (Compute.d6(2) + modifier), - 2, - 12); + int roll = MathUtility.clamp((Compute.d6(2) + modifier), 2, 12); return switch (roll) { - case 2, 3, 4, 5 -> PartQuality.QUALITY_A; - case 6, 7, 8 -> PartQuality.QUALITY_B; - case 9, 10 -> PartQuality.QUALITY_C; - case 11 -> PartQuality.QUALITY_D; - case 12 -> PartQuality.QUALITY_F; + case 2, 3 -> QUALITY_A; + case 4, 5 -> QUALITY_B; + case 6, 7 -> QUALITY_C; + case 8, 9 -> QUALITY_D; + case 10, 11 -> QUALITY_E; + case 12 -> QUALITY_F; default -> throw new IllegalStateException( "Unexpected value in mekhq/campaign/unit/Unit.java/getRandomUnitQuality: " + roll); }; diff --git a/MekHQ/src/mekhq/gui/BriefingTab.java b/MekHQ/src/mekhq/gui/BriefingTab.java index 0fbcab9b4b..741bb29fc2 100644 --- a/MekHQ/src/mekhq/gui/BriefingTab.java +++ b/MekHQ/src/mekhq/gui/BriefingTab.java @@ -55,6 +55,7 @@ import mekhq.gui.enums.MHQTabType; import mekhq.gui.model.ScenarioTableModel; import mekhq.gui.sorter.DateStringComparator; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.view.AtBScenarioViewPanel; import mekhq.gui.view.LanceAssignmentView; import mekhq.gui.view.MissionViewPanel; @@ -187,7 +188,7 @@ public void initTab() { btnGMGenerateScenarios.addActionListener(ev -> gmGenerateScenarios()); panMissionButtons.add(btnGMGenerateScenarios); - scrollMissionView = new JScrollPane(); + scrollMissionView = new JScrollPaneWithSpeed(); scrollMissionView.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollMissionView.setViewportView(null); gridBagConstraints = new GridBagConstraints(); @@ -272,7 +273,7 @@ public void initTab() { btnClearAssignedUnits.setEnabled(false); panScenarioButtons.add(btnClearAssignedUnits); - scrollScenarioView = new JScrollPane(); + scrollScenarioView = new JScrollPaneWithSpeed(); scrollScenarioView.setViewportView(null); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; @@ -285,7 +286,7 @@ public void initTab() { /* ATB */ panLanceAssignment = new LanceAssignmentView(getCampaign()); - JScrollPane paneLanceDeployment = new JScrollPane(panLanceAssignment); + JScrollPane paneLanceDeployment = new JScrollPaneWithSpeed(panLanceAssignment); paneLanceDeployment.setMinimumSize(new Dimension(200, 300)); paneLanceDeployment.setPreferredSize(new Dimension(200, 300)); paneLanceDeployment.setVisible(getCampaign().getCampaignOptions().isUseAtB()); diff --git a/MekHQ/src/mekhq/gui/CommandCenterTab.java b/MekHQ/src/mekhq/gui/CommandCenterTab.java index 8f9002f51c..61fc8fd744 100644 --- a/MekHQ/src/mekhq/gui/CommandCenterTab.java +++ b/MekHQ/src/mekhq/gui/CommandCenterTab.java @@ -45,6 +45,7 @@ import mekhq.gui.model.ProcurementTableModel; import mekhq.gui.sorter.FormattedNumberSorter; import mekhq.gui.sorter.TargetSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.service.enums.MRMSMode; import mekhq.service.mrms.MRMSService; @@ -374,7 +375,7 @@ private void initObjectivesPanel() { listObjectives.setModel(new DefaultListModel<>()); refreshObjectives(); - panObjectives.add(new JScrollPane(listObjectives), BorderLayout.CENTER); + panObjectives.add(new JScrollPaneWithSpeed(listObjectives), BorderLayout.CENTER); } /** @@ -488,7 +489,7 @@ public void actionPerformed(ActionEvent e) { } }); - JScrollPane scrollProcurement = new JScrollPane(procurementTable); + JScrollPane scrollProcurement = new JScrollPaneWithSpeed(procurementTable); panProcurement = new JPanel(new GridBagLayout()); panProcurement.setBorder(BorderFactory.createTitledBorder(resourceMap.getString("panProcurement.title"))); GridBagConstraints gridBagConstraints = new GridBagConstraints(); diff --git a/MekHQ/src/mekhq/gui/DailyReportLogPanel.java b/MekHQ/src/mekhq/gui/DailyReportLogPanel.java index 322be7a034..85f7ed0f94 100644 --- a/MekHQ/src/mekhq/gui/DailyReportLogPanel.java +++ b/MekHQ/src/mekhq/gui/DailyReportLogPanel.java @@ -23,6 +23,7 @@ import megamek.codeUtilities.StringUtility; import mekhq.Utilities; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.border.EmptyBorder; @@ -91,7 +92,7 @@ public boolean getScrollableTracksViewportWidth() { getTxtLog().getAccessibleContext().setAccessibleName("Daily Log"); getTxtLog().addHyperlinkListener(gui.getReportHLL()); - final JScrollPane logPanel = new JScrollPane(getTxtLog()); + final JScrollPane logPanel = new JScrollPaneWithSpeed(getTxtLog()); logPanel.setBorder(new EmptyBorder(2,5,2,2)); add(logPanel, BorderLayout.CENTER); } diff --git a/MekHQ/src/mekhq/gui/FinancesTab.java b/MekHQ/src/mekhq/gui/FinancesTab.java index 2ba6a4d8ad..0c089d7075 100644 --- a/MekHQ/src/mekhq/gui/FinancesTab.java +++ b/MekHQ/src/mekhq/gui/FinancesTab.java @@ -35,6 +35,8 @@ import mekhq.gui.enums.MHQTabType; import mekhq.gui.model.FinanceTableModel; import mekhq.gui.model.LoanTableModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; + import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; @@ -125,7 +127,7 @@ public void initTab() { } loanTable.setIntercellSpacing(new Dimension(0, 0)); loanTable.setShowGrid(false); - JScrollPane scrollLoanTable = new JScrollPane(loanTable); + JScrollPane scrollLoanTable = new JScrollPaneWithSpeed(loanTable); GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; @@ -135,7 +137,7 @@ public void initTab() { gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; JPanel panBalance = new JPanel(new GridBagLayout()); - panBalance.add(new JScrollPane(financeTable), gridBagConstraints); + panBalance.add(new JScrollPaneWithSpeed(financeTable), gridBagConstraints); panBalance.setMinimumSize(new Dimension(350, 100)); panBalance.setBorder(BorderFactory.createTitledBorder("Balance Sheet")); JPanel panLoan = new JPanel(new GridBagLayout()); @@ -189,7 +191,7 @@ public void initTab() { areaNetWorth.setText(getFormattedFinancialReport()); areaNetWorth.setEditable(false); - JScrollPane descriptionScroll = new JScrollPane(areaNetWorth); + JScrollPane descriptionScroll = new JScrollPaneWithSpeed(areaNetWorth); panelFinanceRight.add(descriptionScroll, BorderLayout.CENTER); areaNetWorth.setCaretPosition(0); descriptionScroll.setMinimumSize(new Dimension(300, 200)); diff --git a/MekHQ/src/mekhq/gui/HangarTab.java b/MekHQ/src/mekhq/gui/HangarTab.java index fb70d2b2d8..43f0eed589 100644 --- a/MekHQ/src/mekhq/gui/HangarTab.java +++ b/MekHQ/src/mekhq/gui/HangarTab.java @@ -38,6 +38,7 @@ import mekhq.gui.enums.MHQTabType; import mekhq.gui.model.UnitTableModel; import mekhq.gui.sorter.*; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.view.UnitViewPanel; import javax.swing.*; @@ -187,9 +188,9 @@ public void initTab() { changeUnitView(); unitTable.getSelectionModel().addListSelectionListener(ev -> refreshUnitView()); - JScrollPane scrollUnitTable = new JScrollPane(unitTable); + JScrollPane scrollUnitTable = new JScrollPaneWithSpeed(unitTable); - scrollUnitView = new JScrollPane(); + scrollUnitView = new JScrollPaneWithSpeed(); scrollUnitView.setMinimumSize(new Dimension(UNIT_VIEW_WIDTH, 600)); scrollUnitView.setPreferredSize(new Dimension(UNIT_VIEW_WIDTH, 600)); scrollUnitView.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); diff --git a/MekHQ/src/mekhq/gui/InfirmaryTab.java b/MekHQ/src/mekhq/gui/InfirmaryTab.java index 8ec1696748..abf943bf4e 100644 --- a/MekHQ/src/mekhq/gui/InfirmaryTab.java +++ b/MekHQ/src/mekhq/gui/InfirmaryTab.java @@ -31,6 +31,7 @@ import mekhq.gui.model.DocTableModel; import mekhq.gui.model.PatientTableModel; import mekhq.gui.sorter.PersonTitleSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import java.awt.*; @@ -84,7 +85,7 @@ public void initTab() { docTable.getColumnModel().getColumn(0).setCellRenderer(doctorsModel.getRenderer()); docTable.getSelectionModel().addListSelectionListener(ev -> docTableValueChanged()); docTable.setOpaque(false); - JScrollPane scrollDocTable = new JScrollPane(docTable); + JScrollPane scrollDocTable = new JScrollPaneWithSpeed(docTable); scrollDocTable.setMinimumSize(new Dimension(300, 300)); scrollDocTable.setPreferredSize(new Dimension(300, 300)); scrollDocTable.setOpaque(false); @@ -125,7 +126,7 @@ public void initTab() { listAssignedPatient.setVisibleRowCount(-1); listAssignedPatient.getSelectionModel().addListSelectionListener(ev -> updateAssignDoctorEnabled()); listAssignedPatient.setOpaque(false); - JScrollPane scrollAssignedPatient = new JScrollPane(listAssignedPatient); + JScrollPane scrollAssignedPatient = new JScrollPaneWithSpeed(listAssignedPatient); scrollAssignedPatient.setMinimumSize(new Dimension(300, 360)); scrollAssignedPatient.setPreferredSize(new Dimension(300, 360)); scrollAssignedPatient.setOpaque(false); @@ -137,7 +138,7 @@ public void initTab() { listUnassignedPatient.setVisibleRowCount(-1); listUnassignedPatient.getSelectionModel().addListSelectionListener(ev -> updateAssignDoctorEnabled()); listUnassignedPatient.setOpaque(false); - JScrollPane scrollUnassignedPatient = new JScrollPane(listUnassignedPatient); + JScrollPane scrollUnassignedPatient = new JScrollPaneWithSpeed(listUnassignedPatient); scrollUnassignedPatient.setMinimumSize(new Dimension(300, 200)); scrollUnassignedPatient.setPreferredSize(new Dimension(300, 300)); scrollUnassignedPatient.setOpaque(false); diff --git a/MekHQ/src/mekhq/gui/InterstellarMapPanel.java b/MekHQ/src/mekhq/gui/InterstellarMapPanel.java index 60a62996e7..7f1d9089a4 100644 --- a/MekHQ/src/mekhq/gui/InterstellarMapPanel.java +++ b/MekHQ/src/mekhq/gui/InterstellarMapPanel.java @@ -18,37 +18,6 @@ */ package mekhq.gui; -import java.awt.*; -import java.awt.MultipleGradientPaint.CycleMethod; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseWheelEvent; -import java.awt.geom.AffineTransform; -import java.awt.geom.Arc2D; -import java.awt.geom.GeneralPath; -import java.awt.geom.Line2D; -import java.awt.geom.Point2D; -import java.awt.image.BufferedImage; -import java.io.File; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.imageio.ImageIO; -import javax.swing.*; -import javax.vecmath.Vector2d; - import megamek.codeUtilities.MathUtility; import megamek.codeUtilities.ObjectUtility; import megamek.common.EquipmentType; @@ -58,13 +27,24 @@ import mekhq.MekHQ; import mekhq.campaign.Campaign; import mekhq.campaign.JumpPath; -import mekhq.campaign.universe.Faction; +import mekhq.campaign.universe.*; import mekhq.campaign.universe.Faction.Tag; -import mekhq.campaign.universe.Factions; -import mekhq.campaign.universe.PlanetarySystem; -import mekhq.campaign.universe.SocioIndustrialData; -import mekhq.campaign.universe.Systems; import mekhq.campaign.universe.Systems.HPGLink; +import mekhq.campaign.universe.enums.HiringHallLevel; + +import javax.imageio.ImageIO; +import javax.swing.Timer; +import javax.swing.*; +import javax.vecmath.Vector2d; +import java.awt.*; +import java.awt.MultipleGradientPaint.CycleMethod; +import java.awt.event.*; +import java.awt.geom.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.time.LocalDate; +import java.util.List; +import java.util.*; /** * This is not functional yet. Just testing things out. @@ -104,7 +84,7 @@ public class InterstellarMapPanel extends JPanel { private JCheckBox optEmptySystems; private JCheckBox optHPGNetwork; - private JCheckBox optISWAreas; + private JCheckBox optTerritory; private Timer optionPanelTimer; private boolean optionPanelHidden; @@ -424,6 +404,8 @@ protected void paintComponent(Graphics g) { final Stroke thin = new BasicStroke(1.2f); final Stroke dashed = new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 3 }, 0); + final Stroke dashedThick = new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, + new float[] { 3 }, 0); final Stroke dotted = new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 2, 5 }, 0); final Color darkCyan = new Color(0, 100, 50); @@ -444,11 +426,12 @@ protected void paintComponent(Graphics g) { if (!campaign.getCampaignOptions().getContractMarketMethod().isNone() && MekHQ.getMHQOptions().getInterstellarMapShowContractSearchRadius()) { final double z = map2scrX(selectedSystem.getX() - + campaign.getCampaignOptions().getContractSearchRadius()); + + campaign.getCampaignOptions().getContractSearchRadius()); final double contractSearchRadius = z - x; g2.setPaint(MekHQ.getMHQOptions().getInterstellarMapContractSearchRadiusColour()); + g2.setStroke(dashedThick); arc.setArcByCenter(x, y, contractSearchRadius, 0, 360, Arc2D.OPEN); - g2.fill(arc); + g2.draw(arc); } // Acquisition Search Radius Aura @@ -459,10 +442,11 @@ protected void paintComponent(Graphics g) { final double z = map2scrX(selectedSystem.getX() + (MHQConstants.MAX_JUMP_RADIUS * campaign.getCampaignOptions().getMaxJumpsPlanetaryAcquisition())); - final double contractSearchRadius = z - x; + final double acquisitionRadius = z - x; g2.setPaint(MekHQ.getMHQOptions().getInterstellarMapPlanetaryAcquisitionRadiusColour()); - arc.setArcByCenter(x, y, contractSearchRadius, 0, 360, Arc2D.OPEN); - g2.fill(arc); + g2.setStroke(dashedThick); + arc.setArcByCenter(x, y, acquisitionRadius, 0, 360, Arc2D.OPEN); + g2.draw(arc); } // Jump Radius Aura @@ -471,8 +455,9 @@ protected void paintComponent(Graphics g) { final double z = map2scrX(selectedSystem.getX() + MHQConstants.MAX_JUMP_RADIUS); final double jumpRadius = z - x; g2.setPaint(MekHQ.getMHQOptions().getInterstellarMapJumpRadiusColour()); + g2.setStroke(dashedThick); arc.setArcByCenter(x, y, jumpRadius, 0, 360, Arc2D.OPEN); - g2.fill(arc); + g2.draw(arc); } // Don't override HPG Network drawing @@ -486,30 +471,52 @@ protected void paintComponent(Graphics g) { } } - if ((conf.scale > 1.0) && optISWAreas.isSelected()) { - // IDEA: Allow for different hex sizes later on. - final double HEX_SIZE = 30.0; + if ((conf.scale > 1.0) && optTerritory.isSelected()) { + final double HEX_SIZE = 30; final double SPACING_X = HEX_SIZE * Math.sqrt(3) / 2.0; + AffineTransform transform = getMap2ScrTransform(); + Paint defaultFactionPaint = new Color(0.0f, 0.0f, 0.0f, 0.25f); + int minX = (int) Math.floor(scr2mapX(0.0) / SPACING_X); int maxX = (int) Math.ceil(scr2mapX(getWidth()) / SPACING_X); int minY = (int) Math.floor(scr2mapY(getHeight()) / HEX_SIZE); int maxY = (int) Math.ceil(scr2mapY(0.0) / HEX_SIZE); - GeneralPath path = new GeneralPath(); + + Faction indFaction = Factions.getInstance().getFaction("IND"); + for (int x = minX; x <= maxX; ++x) { for (int y = minY; y <= maxY; ++y) { double coordX = x * SPACING_X; double coordY = y * HEX_SIZE + (x % 2) * HEX_SIZE / 2.0; + GeneralPath path = new GeneralPath(); setupHexPath(path, coordX, coordY, HEX_SIZE / 2.0); - Paint factionPaint = new Color(0.0f, 0.0f, 0.0f, 0.25f); - Paint linePaint = new Color(1.0f, 1.0f, 1.0f, 0.25f); - Set hexFactions = Systems.getInstance() - .getNearbySystems(coordX, coordY, (int) Math.round(HEX_SIZE * 1.3)).stream() - .filter(system -> !isSystemEmpty(system) - && path.contains(system.getX(), system.getY())) - .flatMap(system -> system.getFactionSet(now).stream()) - .collect(Collectors.toSet()); + Paint factionPaint = defaultFactionPaint; + Set hexFactions = new HashSet<>(); + + List nearbySystems = Systems.getInstance().getNearbySystems(coordX, coordY, (int) Math.round(HEX_SIZE * 1.3)); + + for (PlanetarySystem system : nearbySystems) { + if (!isSystemEmpty(system) && path.contains(system.getX(), system.getY())) { + Set factions = system.getFactionSet(now); + factions.remove(indFaction); + hexFactions.addAll(factions); + } + } + + if (hexFactions.isEmpty()) { + for (PlanetarySystem system : nearbySystems) { + if (!isSystemEmpty(system)) { + Set factions = system.getFactionSet(now); + hexFactions.addAll(factions); + } + } + } + + if (hexFactions.size() > 1) { + hexFactions.remove(indFaction); + } path.transform(transform); @@ -519,11 +526,7 @@ protected void paintComponent(Graphics g) { float[] colorComponents = new float[4]; factionColor.getComponents(colorComponents); factionPaint = new Color(colorComponents[0], colorComponents[1], colorComponents[2], - 0.25f); - Color lineColor = factionColor.brighter(); - lineColor.getComponents(colorComponents); - linePaint = new Color(colorComponents[0], colorComponents[1], colorComponents[2], - 0.25f); + 0.25f); } else if (hexFactions.size() > 1) { // Create the painted stripes data int factionSize = hexFactions.size(); @@ -537,7 +540,7 @@ protected void paintComponent(Graphics g) { Color factionColor = factionIterator.next().getColor(); factionColor.getComponents(colorComponents); factionColor = new Color(colorComponents[0], colorComponents[1], colorComponents[2], - 0.25f); + 0.25f); paintColors[i * 2] = factionColor; paintColors[i * 2 + 1] = factionColor; } @@ -546,21 +549,15 @@ protected void paintComponent(Graphics g) { // Determine where to anchor the stripes Point2D firstPoint = new Point2D.Double(map2scrX(coordX), map2scrY(coordY)); Point2D secondPoint = new Point2D.Double( - firstPoint.getX() + 6 * conf.scale, - firstPoint.getY() + 6 * conf.scale); + firstPoint.getX() + 6 * conf.scale, + firstPoint.getY() + 6 * conf.scale); factionPaint = new LinearGradientPaint( - firstPoint, secondPoint, paintFractions, paintColors, - CycleMethod.REPEAT); - linePaint = new Color(1.0f, 0.2f, 0.0f, 0.5f); + firstPoint, secondPoint, paintFractions, paintColors, + CycleMethod.REPEAT); } + g2.setPaint(factionPaint); g2.fill(path); - g2.setPaint(linePaint); - Shape clip = g2.getClip(); - g2.clip(path); - g2.setStroke(new BasicStroke(4.0f)); - g2.draw(path); - g2.setClip(clip); } } } @@ -726,18 +723,28 @@ protected void paintComponent(Graphics g) { int i = 0; for (Faction faction : factions) { if (capitals.get(faction).equals(system.getId())) { - g2.setPaint(new Color(255, 228, 181)); - arc.setArcByCenter(x, y, size + 3, 0, - 360.0 * (1 - ((double) i) / factions.size()), Arc2D.PIE); + g2.setPaint(faction.getColor()); + arc.setArcByCenter(x, y, size + 5, 0, + 360.0 * (1 - ((double) i) / factions.size()), Arc2D.OPEN); g2.fill(arc); - } - if (campaign.getCampaignOptions().isUseAtB() - && system.isHiringHall(campaign.getLocalDate())) { - g2.setPaint(new Color(176, 196, 222)); - arc.setArcByCenter(x, y, size + 4, 0, - 360.0 * (1 - ((double) i) / factions.size()), Arc2D.PIE); + g2.setPaint(new Color(0.0f, 0.0f, 0.0f, 0.5f)); + arc.setArcByCenter(x, y, size + 3, 0, + 360.0 * (1 - ((double) i) / factions.size()), Arc2D.OPEN); g2.fill(arc); + } else { + if (campaign.getCampaignOptions().isUseAtB() + && (system.getHiringHallLevel(campaign.getLocalDate()) == HiringHallLevel.GREAT)) { + g2.setPaint(new Color(176, 196, 222)); + arc.setArcByCenter(x, y, size + 5, 0, + 360.0 * (1 - ((double) i) / factions.size()), Arc2D.OPEN); + g2.fill(arc); + g2.setPaint(new Color(0.0f, 0.0f, 0.0f, 0.5f)); + arc.setArcByCenter(x, y, size + 3, 0, + 360.0 * (1 - ((double) i) / factions.size()), Arc2D.OPEN); + g2.fill(arc); + } } + g2.setPaint(faction.getColor()); arc.setArcByCenter(x, y, size, 0, 360.0 * (1 - ((double) i) / factions.size()), Arc2D.PIE); @@ -745,8 +752,8 @@ protected void paintComponent(Graphics g) { ++i; } } else { - // Just a black circle then - g2.setPaint(new Color(0.0f, 0.0f, 0.0f, 0.5f)); + // Just a dark grey circle then + g2.setPaint(Color.DARK_GRAY); arc.setArcByCenter(x, y, size, 0, 360.0, Arc2D.PIE); g2.fill(arc); } @@ -838,8 +845,9 @@ protected void paintComponent(Graphics g) { optEmptySystems = createOptionCheckBox("Empty systems", checkboxIcon, checkboxSelectedIcon); optEmptySystems.setSelected(true); optionPanel.add(optEmptySystems); - optISWAreas = createOptionCheckBox("ISW Areas", checkboxIcon, checkboxSelectedIcon); - optionPanel.add(optISWAreas); + optTerritory = createOptionCheckBox("Territory", checkboxIcon, checkboxSelectedIcon); + optTerritory.setSelected(true); + optionPanel.add(optTerritory); optHPGNetwork = createOptionCheckBox("HPG Network", checkboxIcon, checkboxSelectedIcon); optionPanel.add(optHPGNetwork); diff --git a/MekHQ/src/mekhq/gui/MapTab.java b/MekHQ/src/mekhq/gui/MapTab.java index 36a4f8d25e..03466a8596 100644 --- a/MekHQ/src/mekhq/gui/MapTab.java +++ b/MekHQ/src/mekhq/gui/MapTab.java @@ -27,6 +27,7 @@ import mekhq.campaign.universe.Planet; import mekhq.campaign.universe.PlanetarySystem; import mekhq.gui.enums.MHQTabType; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.JSuggestField; import mekhq.gui.view.JumpPathViewPanel; import mekhq.gui.view.PlanetViewPanel; @@ -136,7 +137,7 @@ public void initTab() { mapView.setMinimumSize(new Dimension(600,600)); mapView.setView(panMapView); - scrollPlanetView = new JScrollPane(); + scrollPlanetView = new JScrollPaneWithSpeed(); scrollPlanetView.setMinimumSize(new Dimension(400, 600)); scrollPlanetView.setPreferredSize(new Dimension(400, 600)); scrollPlanetView.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); diff --git a/MekHQ/src/mekhq/gui/MekLabTab.java b/MekHQ/src/mekhq/gui/MekLabTab.java index d9c060f3bd..8e9ced42b4 100644 --- a/MekHQ/src/mekhq/gui/MekLabTab.java +++ b/MekHQ/src/mekhq/gui/MekLabTab.java @@ -77,6 +77,7 @@ import mekhq.campaign.parts.Refit; import mekhq.campaign.unit.Unit; import mekhq.gui.enums.MHQTabType; +import mekhq.gui.utilities.JScrollPaneWithSpeed; public class MekLabTab extends CampaignGuiTab { private static final MMLogger logger = MMLogger.create(MekLabTab.class); @@ -535,11 +536,11 @@ public void reloadTabs() { buildTab.addRefreshedListener(this); fluffTab.setRefreshedListener(this); - addTab("Structure/Armor", new JScrollPane(structureTab)); - addTab("Equipment", new JScrollPane(equipmentTab)); - addTab("Assign Criticals", new JScrollPane(buildTab)); - addTab("Fluff", new JScrollPane(fluffTab)); - addTab("Preview", new JScrollPane(previewTab)); + addTab("Structure/Armor", new JScrollPaneWithSpeed(structureTab)); + addTab("Equipment", new JScrollPaneWithSpeed(equipmentTab)); + addTab("Assign Criticals", new JScrollPaneWithSpeed(buildTab)); + addTab("Fluff", new JScrollPaneWithSpeed(fluffTab)); + addTab("Preview", new JScrollPaneWithSpeed(previewTab)); this.repaint(); } @@ -664,12 +665,12 @@ public void reloadTabs() { transportTab.addRefreshedListener(this); fluffTab.setRefreshedListener(this); - addTab("Structure/Armor", new JScrollPane(structureTab)); - addTab("Equipment", new JScrollPane(equipmentTab)); - addTab("Assign Criticals", new JScrollPane(buildTab)); - addTab("Transport Bays", new JScrollPane(transportTab)); - addTab("Fluff", new JScrollPane(fluffTab)); - addTab("Preview", new JScrollPane(previewTab)); + addTab("Structure/Armor", new JScrollPaneWithSpeed(structureTab)); + addTab("Equipment", new JScrollPaneWithSpeed(equipmentTab)); + addTab("Assign Criticals", new JScrollPaneWithSpeed(buildTab)); + addTab("Transport Bays", new JScrollPaneWithSpeed(transportTab)); + addTab("Fluff", new JScrollPaneWithSpeed(fluffTab)); + addTab("Preview", new JScrollPaneWithSpeed(previewTab)); this.repaint(); } @@ -792,11 +793,11 @@ public void reloadTabs() { buildTab.addRefreshedListener(this); fluffTab.setRefreshedListener(this); - addTab("Structure/Armor", new JScrollPane(structureTab)); - addTab("Equipment", new JScrollPane(equipmentTab)); - addTab("Assign Critical", new JScrollPane(buildTab)); - addTab("Fluff", new JScrollPane(fluffTab)); - addTab("Preview", new JScrollPane(previewTab)); + addTab("Structure/Armor", new JScrollPaneWithSpeed(structureTab)); + addTab("Equipment", new JScrollPaneWithSpeed(equipmentTab)); + addTab("Assign Critical", new JScrollPaneWithSpeed(buildTab)); + addTab("Fluff", new JScrollPaneWithSpeed(fluffTab)); + addTab("Preview", new JScrollPaneWithSpeed(previewTab)); this.repaint(); } @@ -916,11 +917,11 @@ public void reloadTabs() { buildTab.addRefreshedListener(this); fluffTab.setRefreshedListener(this); - addTab("Structure", new JScrollPane(structureTab)); - addTab("Equipment", new JScrollPane(equipmentTab)); - addTab("Build", new JScrollPane(buildTab)); - addTab("Fluff", new JScrollPane(fluffTab)); - addTab("Preview", new JScrollPane(previewTab)); + addTab("Structure", new JScrollPaneWithSpeed(structureTab)); + addTab("Equipment", new JScrollPaneWithSpeed(equipmentTab)); + addTab("Build", new JScrollPaneWithSpeed(buildTab)); + addTab("Fluff", new JScrollPaneWithSpeed(fluffTab)); + addTab("Preview", new JScrollPaneWithSpeed(previewTab)); this.repaint(); } @@ -1046,13 +1047,13 @@ void reloadTabs() { transportTab.addRefreshedListener(this); fluffTab.setRefreshedListener(this); - addTab("Structure", new JScrollPane(structureTab)); - addTab("Armor", new JScrollPane(armorTab)); - addTab("Equipment", new JScrollPane(equipmentTab)); - addTab("Build", new JScrollPane(buildTab)); - addTab("Transport", new JScrollPane(transportTab)); - addTab("Fluff", new JScrollPane(fluffTab)); - addTab("Preview", new JScrollPane(previewTab)); + addTab("Structure", new JScrollPaneWithSpeed(structureTab)); + addTab("Armor", new JScrollPaneWithSpeed(armorTab)); + addTab("Equipment", new JScrollPaneWithSpeed(equipmentTab)); + addTab("Build", new JScrollPaneWithSpeed(buildTab)); + addTab("Transport", new JScrollPaneWithSpeed(transportTab)); + addTab("Fluff", new JScrollPaneWithSpeed(fluffTab)); + addTab("Preview", new JScrollPaneWithSpeed(previewTab)); this.repaint(); } @@ -1174,10 +1175,10 @@ public void reloadTabs() { buildTab.addRefreshedListener(this); fluffTab.setRefreshedListener(this); - addTab("Structure", new JScrollPane(structureTab)); - addTab("Equipment", new JScrollPane(equipmentTab)); - addTab("Assign Criticals", new JScrollPane(buildTab)); - addTab("Fluff", new JScrollPane(fluffTab)); + addTab("Structure", new JScrollPaneWithSpeed(structureTab)); + addTab("Equipment", new JScrollPaneWithSpeed(equipmentTab)); + addTab("Assign Criticals", new JScrollPaneWithSpeed(buildTab)); + addTab("Fluff", new JScrollPaneWithSpeed(fluffTab)); this.repaint(); } @@ -1290,9 +1291,9 @@ public void reloadTabs() { FluffTab fluffTab = new FluffTab(this); fluffTab.setRefreshedListener(this); - addTab("Build", new JScrollPane(structureTab)); - addTab("Fluff", new JScrollPane(fluffTab)); - addTab("Preview", new JScrollPane(previewTab)); + addTab("Build", new JScrollPaneWithSpeed(structureTab)); + addTab("Fluff", new JScrollPaneWithSpeed(fluffTab)); + addTab("Preview", new JScrollPaneWithSpeed(previewTab)); this.repaint(); } @@ -1408,11 +1409,11 @@ void reloadTabs() { buildTab.addRefreshedListener(this); fluffTab.setRefreshedListener(this); - addTab("Structure/Armor", new JScrollPane(structureTab)); - addTab("Equipment", new JScrollPane(equipmentTab)); - addTab("Assign Critical", new JScrollPane(buildTab)); - addTab("FluffTab", new JScrollPane(fluffTab)); - addTab("Preview", new JScrollPane(previewTab)); + addTab("Structure/Armor", new JScrollPaneWithSpeed(structureTab)); + addTab("Equipment", new JScrollPaneWithSpeed(equipmentTab)); + addTab("Assign Critical", new JScrollPaneWithSpeed(buildTab)); + addTab("FluffTab", new JScrollPaneWithSpeed(fluffTab)); + addTab("Preview", new JScrollPaneWithSpeed(previewTab)); this.repaint(); } @@ -1538,12 +1539,12 @@ void reloadTabs() { transportTab.addRefreshedListener(this); fluffTab.setRefreshedListener(this); - addTab("Structure/Armor", new JScrollPane(structureTab)); - addTab("Equipment", new JScrollPane(equipmentTab)); - addTab("Assign Criticals", new JScrollPane(buildTab)); - addTab("Transport Bays", new JScrollPane(transportTab)); - addTab("FluffTab", new JScrollPane(fluffTab)); - addTab("Preview", new JScrollPane(previewTab)); + addTab("Structure/Armor", new JScrollPaneWithSpeed(structureTab)); + addTab("Equipment", new JScrollPaneWithSpeed(equipmentTab)); + addTab("Assign Criticals", new JScrollPaneWithSpeed(buildTab)); + addTab("Transport Bays", new JScrollPaneWithSpeed(transportTab)); + addTab("FluffTab", new JScrollPaneWithSpeed(fluffTab)); + addTab("Preview", new JScrollPaneWithSpeed(previewTab)); this.repaint(); } diff --git a/MekHQ/src/mekhq/gui/PersonnelTab.java b/MekHQ/src/mekhq/gui/PersonnelTab.java index bc167eb3ba..3034c170b7 100644 --- a/MekHQ/src/mekhq/gui/PersonnelTab.java +++ b/MekHQ/src/mekhq/gui/PersonnelTab.java @@ -54,6 +54,7 @@ import mekhq.gui.enums.PersonnelTabView; import mekhq.gui.enums.PersonnelTableModelColumn; import mekhq.gui.model.PersonnelTableModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.view.PersonViewPanel; /** @@ -210,13 +211,13 @@ public Component getListCellRendererComponent(final JList list, final Object changePersonnelView(); personnelTable.getSelectionModel().addListSelectionListener(ev -> refreshPersonnelView()); - scrollPersonnelView = new JScrollPane(); + scrollPersonnelView = new JScrollPaneWithSpeed(); scrollPersonnelView.setMinimumSize(new Dimension(PERSONNEL_VIEW_WIDTH, 600)); scrollPersonnelView.setPreferredSize(new Dimension(PERSONNEL_VIEW_WIDTH, 600)); scrollPersonnelView.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPersonnelView.setViewportView(null); - JScrollPane scrollPersonnelTable = new JScrollPane(personnelTable); + JScrollPane scrollPersonnelTable = new JScrollPaneWithSpeed(personnelTable); splitPersonnel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, scrollPersonnelTable, scrollPersonnelView); splitPersonnel.setOneTouchExpandable(true); diff --git a/MekHQ/src/mekhq/gui/RepairTab.java b/MekHQ/src/mekhq/gui/RepairTab.java index 6150faf858..0efdd07092 100644 --- a/MekHQ/src/mekhq/gui/RepairTab.java +++ b/MekHQ/src/mekhq/gui/RepairTab.java @@ -71,6 +71,7 @@ import mekhq.gui.sorter.TechSorter; import mekhq.gui.sorter.UnitStatusSorter; import mekhq.gui.sorter.UnitTypeSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.service.PartsAcquisitionService; import mekhq.service.enums.MRMSMode; import mekhq.service.mrms.MRMSService; @@ -239,14 +240,14 @@ public void initTab() { servicedUnitTable.setShowGrid(false); servicedUnitTable.getSelectionModel().addListSelectionListener(this::servicedUnitTableValueChanged); ServicedUnitsTableMouseAdapter.connect(getCampaignGui(), servicedUnitTable, servicedUnitModel); - JScrollPane scrollServicedUnitTable = new JScrollPane(servicedUnitTable); + JScrollPane scrollServicedUnitTable = new JScrollPaneWithSpeed(servicedUnitTable); scrollServicedUnitTable.setMinimumSize(new Dimension(350, 200)); scrollServicedUnitTable.setPreferredSize(new Dimension(350, 200)); txtServicedUnitView = new JTextPane(); txtServicedUnitView.setEditable(false); txtServicedUnitView.setContentType("text/html"); - scrollServicedUnitView = new JScrollPane(txtServicedUnitView); + scrollServicedUnitView = new JScrollPaneWithSpeed(txtServicedUnitView); scrollServicedUnitView.setMinimumSize(new Dimension(350, 400)); scrollServicedUnitView.setPreferredSize(new Dimension(350, 400)); @@ -275,7 +276,7 @@ public void initTab() { sortKeys = new ArrayList<>(); sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING)); techSorter.setSortKeys(sortKeys); - JScrollPane scrollTechTable = new JScrollPane(techTable); + JScrollPane scrollTechTable = new JScrollPaneWithSpeed(techTable); scrollTechTable.setMinimumSize(new Dimension(200, 200)); scrollTechTable.setPreferredSize(new Dimension(300, 300)); @@ -340,7 +341,7 @@ public void initTab() { textTarget.setWrapStyleWord(true); textTarget.setBorder(null); textTarget.setName("textTarget"); - scrTextTarget = new JScrollPane(textTarget); + scrTextTarget = new JScrollPaneWithSpeed(textTarget); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 1; @@ -393,7 +394,7 @@ public void initTab() { sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING)); taskSorter.setSortKeys(sortKeys); TaskTableMouseAdapter.connect(getCampaignGui(), taskTable, taskModel); - JScrollPane scrollTaskTable = new JScrollPane(taskTable); + JScrollPane scrollTaskTable = new JScrollPaneWithSpeed(taskTable); scrollTaskTable.setMinimumSize(new Dimension(200, 200)); scrollTaskTable.setPreferredSize(new Dimension(300, 300)); diff --git a/MekHQ/src/mekhq/gui/StratconTab.java b/MekHQ/src/mekhq/gui/StratconTab.java index 0fdaf6da9d..66fb5db9d6 100644 --- a/MekHQ/src/mekhq/gui/StratconTab.java +++ b/MekHQ/src/mekhq/gui/StratconTab.java @@ -26,6 +26,7 @@ import mekhq.campaign.stratcon.StratconTrackState; import mekhq.gui.enums.MHQTabType; import mekhq.gui.stratcon.CampaignManagementDialog; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import java.awt.Dialog.ModalityType; @@ -105,7 +106,7 @@ public void mousePressed(MouseEvent me) { initializeInfoPanel(); cmd = new CampaignManagementDialog(this); - JScrollPane infoScrollPane = new JScrollPane(infoPanel); + JScrollPane infoScrollPane = new JScrollPaneWithSpeed(infoPanel); this.add(infoScrollPane); MekHQ.registerHandler(this); @@ -127,7 +128,7 @@ private void initializeInfoPanel() { btnManageCampaignState.addActionListener(this::showCampaignStateManagement); infoPanel.add(btnManageCampaignState); - expandedObjectivePanel = new JScrollPane(objectiveStatusText); + expandedObjectivePanel = new JScrollPaneWithSpeed(objectiveStatusText); expandedObjectivePanel.setMaximumSize(new Dimension(400, 300)); expandedObjectivePanel.setAlignmentX(LEFT_ALIGNMENT); infoPanel.add(expandedObjectivePanel); diff --git a/MekHQ/src/mekhq/gui/TOETab.java b/MekHQ/src/mekhq/gui/TOETab.java index 596566f180..6d2332aa1c 100644 --- a/MekHQ/src/mekhq/gui/TOETab.java +++ b/MekHQ/src/mekhq/gui/TOETab.java @@ -29,6 +29,7 @@ import mekhq.gui.handler.TOETransferHandler; import mekhq.gui.model.CrewListModel; import mekhq.gui.model.OrgTreeModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.view.ForceViewPanel; import mekhq.gui.view.PersonViewPanel; import mekhq.gui.view.UnitViewPanel; @@ -84,7 +85,7 @@ public void initTab() { panForceView.setPreferredSize(new Dimension(550, 600)); panForceView.setLayout(new BorderLayout()); - JScrollPane scrollOrg = new JScrollPane(orgTree); + JScrollPane scrollOrg = new JScrollPaneWithSpeed(orgTree); splitOrg = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, scrollOrg, panForceView); splitOrg.setOneTouchExpandable(true); splitOrg.setResizeWeight(1.0); @@ -132,7 +133,7 @@ public void refreshForceView() { if (crewSize > 0) { JPanel crewPanel = new JPanel(new BorderLayout()); crewPanel.getAccessibleContext().setAccessibleName("Crew for " + u.getName()); - final JScrollPane scrollPerson = new JScrollPane(); + final JScrollPane scrollPerson = new JScrollPaneWithSpeed(); crewPanel.add(scrollPerson, BorderLayout.CENTER); CrewListModel model = new CrewListModel(); model.setData(u); @@ -160,7 +161,7 @@ public Dimension getPreferredScrollableViewportSize() { }); crewList.setSelectedIndex(0); if (crewSize > 1) { - crewPanel.add(new JScrollPane(crewList), BorderLayout.NORTH); + crewPanel.add(new JScrollPaneWithSpeed(crewList), BorderLayout.NORTH); } String name = "Crew"; if (u.usesSoloPilot()) { @@ -170,14 +171,14 @@ public Dimension getPreferredScrollableViewportSize() { tabUnit.add(name, crewPanel); SwingUtilities.invokeLater(() -> scrollPerson.getVerticalScrollBar().setValue(0)); } - final JScrollPane scrollUnit = new JScrollPane(new UnitViewPanel(u, getCampaign())); + final JScrollPane scrollUnit = new JScrollPaneWithSpeed(new UnitViewPanel(u, getCampaign())); tabUnit.add("Unit", scrollUnit); panForceView.add(tabUnit, BorderLayout.CENTER); SwingUtilities.invokeLater(() -> scrollUnit.getVerticalScrollBar().setValue(0)); tabUnit.setSelectedIndex(tabUnitLastSelectedIndex); tabUnit.addChangeListener(evt -> forceViewTabChange()); // added late so it won't overwrite } else if (node instanceof Force) { - final JScrollPane scrollForce = new JScrollPane(new ForceViewPanel((Force) node, getCampaign())); + final JScrollPane scrollForce = new JScrollPaneWithSpeed(new ForceViewPanel((Force) node, getCampaign())); panForceView.add(scrollForce, BorderLayout.CENTER); SwingUtilities.invokeLater(() -> scrollForce.getVerticalScrollBar().setValue(0)); } diff --git a/MekHQ/src/mekhq/gui/WarehouseTab.java b/MekHQ/src/mekhq/gui/WarehouseTab.java index e01c40ac9b..10b6ea407f 100644 --- a/MekHQ/src/mekhq/gui/WarehouseTab.java +++ b/MekHQ/src/mekhq/gui/WarehouseTab.java @@ -55,6 +55,7 @@ import mekhq.gui.sorter.FormattedNumberSorter; import mekhq.gui.sorter.PartsDetailSorter; import mekhq.gui.sorter.TechSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * Displays all spare parts in stock, parts on order, and permits repair of @@ -200,7 +201,7 @@ public void initTab() { }); PartsTableMouseAdapter.connect(getCampaignGui(), partsTable, partsModel); - JScrollPane scrollPartsTable = new JScrollPane(partsTable); + JScrollPane scrollPartsTable = new JScrollPaneWithSpeed(partsTable); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; @@ -245,7 +246,7 @@ public void initTab() { textTargetWarehouse.setText(""); textTargetWarehouse.setWrapStyleWord(true); textTargetWarehouse.setBorder(null); - JScrollPane scrTargetWarehouse = new JScrollPane(textTargetWarehouse); + JScrollPane scrTargetWarehouse = new JScrollPaneWithSpeed(textTargetWarehouse); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 1; @@ -283,7 +284,7 @@ public void initTab() { ArrayList sortKeys = new ArrayList<>(); sortKeys.add(new SortKey(0, SortOrder.ASCENDING)); techSorter.setSortKeys(sortKeys); - JScrollPane scrollTechTable = new JScrollPane(techTable); + JScrollPane scrollTechTable = new JScrollPaneWithSpeed(techTable); scrollTechTable.setMinimumSize(new Dimension(200, 200)); scrollTechTable.setPreferredSize(new Dimension(300, 300)); gridBagConstraints = new GridBagConstraints(); diff --git a/MekHQ/src/mekhq/gui/control/EditKillLogControl.java b/MekHQ/src/mekhq/gui/control/EditKillLogControl.java index bccb345494..4882041028 100644 --- a/MekHQ/src/mekhq/gui/control/EditKillLogControl.java +++ b/MekHQ/src/mekhq/gui/control/EditKillLogControl.java @@ -24,6 +24,7 @@ import mekhq.campaign.personnel.Person; import mekhq.gui.dialog.AddOrEditKillEntryDialog; import mekhq.gui.model.KillTableModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.event.ListSelectionEvent; @@ -96,7 +97,7 @@ private void initComponents() { killTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); killTable.getSelectionModel().addListSelectionListener(this::killTableValueChanged); - scrollKillTable = new JScrollPane(); + scrollKillTable = new JScrollPaneWithSpeed(); scrollKillTable.setName("scrollPartsTable"); scrollKillTable.setViewportView(killTable); this.add(scrollKillTable, BorderLayout.CENTER); diff --git a/MekHQ/src/mekhq/gui/control/EditPersonnelLogControl.java b/MekHQ/src/mekhq/gui/control/EditPersonnelLogControl.java index b9b7298ae8..bc64e56919 100644 --- a/MekHQ/src/mekhq/gui/control/EditPersonnelLogControl.java +++ b/MekHQ/src/mekhq/gui/control/EditPersonnelLogControl.java @@ -24,6 +24,7 @@ import mekhq.campaign.personnel.Person; import mekhq.gui.dialog.AddOrEditPersonnelEntryDialog; import mekhq.gui.model.LogTableModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.event.ListSelectionEvent; @@ -96,7 +97,7 @@ private void initComponents() { logsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); logsTable.getSelectionModel().addListSelectionListener(this::logTableValueChanged); - scrollLogsTable = new JScrollPane(); + scrollLogsTable = new JScrollPaneWithSpeed(); scrollLogsTable.setName(resourceMap.getString("scrollLogsTable.name")); scrollLogsTable.setViewportView(logsTable); this.add(scrollLogsTable, BorderLayout.CENTER); diff --git a/MekHQ/src/mekhq/gui/control/EditScenarioLogControl.java b/MekHQ/src/mekhq/gui/control/EditScenarioLogControl.java index d8e7cd6a89..dc1cdf8fac 100644 --- a/MekHQ/src/mekhq/gui/control/EditScenarioLogControl.java +++ b/MekHQ/src/mekhq/gui/control/EditScenarioLogControl.java @@ -24,6 +24,7 @@ import mekhq.campaign.personnel.Person; import mekhq.gui.dialog.AddOrEditScenarioEntryDialog; import mekhq.gui.model.LogTableModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.event.ListSelectionEvent; @@ -96,7 +97,7 @@ private void initComponents() { logsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); logsTable.getSelectionModel().addListSelectionListener(this::logTableValueChanged); - scrollLogsTable = new JScrollPane(); + scrollLogsTable = new JScrollPaneWithSpeed(); scrollLogsTable.setName(resourceMap.getString("scrollLogsTable.name")); scrollLogsTable.setViewportView(logsTable); this.add(scrollLogsTable, BorderLayout.CENTER); diff --git a/MekHQ/src/mekhq/gui/dialog/AcquisitionsDialog.java b/MekHQ/src/mekhq/gui/dialog/AcquisitionsDialog.java index f650acdf9a..85f83b0de1 100644 --- a/MekHQ/src/mekhq/gui/dialog/AcquisitionsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/AcquisitionsDialog.java @@ -55,6 +55,7 @@ import mekhq.gui.CampaignGUI; import mekhq.gui.RepairTab; import mekhq.gui.enums.MHQTabType; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.service.PartsAcquisitionService; import mekhq.service.PartsAcquisitionService.PartCountInfo; @@ -121,7 +122,7 @@ private void initComponents() { pnlSummary.firePropertyChange("counts", -1, 0); - JScrollPane scrollMain = new JScrollPane(pnlMain); + JScrollPane scrollMain = new JScrollPaneWithSpeed(pnlMain); scrollMain.setPreferredSize(new Dimension(700, 500)); content.add(scrollMain, BorderLayout.CENTER); diff --git a/MekHQ/src/mekhq/gui/dialog/AutoAwardsDialog.java b/MekHQ/src/mekhq/gui/dialog/AutoAwardsDialog.java index 8f75f61030..29a5327663 100644 --- a/MekHQ/src/mekhq/gui/dialog/AutoAwardsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/AutoAwardsDialog.java @@ -28,6 +28,7 @@ import mekhq.gui.enums.PersonnelFilter; import mekhq.gui.model.AutoAwardsTableModel; import mekhq.gui.sorter.PersonRankStringSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.RowSorter.SortKey; @@ -165,7 +166,7 @@ private void initComponents() { JCheckBox cbxAward = (JCheckBox) cellEditor.getComponent(); cbxAward.addMouseListener(checkboxListener); - JScrollPane scrollPane = new JScrollPane(); + JScrollPane scrollPane = new JScrollPaneWithSpeed(); scrollPane.setViewportView(personnelTable); scrollPane.setPreferredSize(new Dimension(500, 500)); autoAwardsPanel.add(scrollPane, BorderLayout.CENTER); diff --git a/MekHQ/src/mekhq/gui/dialog/BatchXPDialog.java b/MekHQ/src/mekhq/gui/dialog/BatchXPDialog.java index 8de0fc3b66..7bca413ffa 100644 --- a/MekHQ/src/mekhq/gui/dialog/BatchXPDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/BatchXPDialog.java @@ -53,6 +53,7 @@ import mekhq.campaign.personnel.ranks.Rank; import mekhq.gui.enums.PersonnelTableModelColumn; import mekhq.gui.model.PersonnelTableModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.MekHqTableCellRenderer; public final class BatchXPDialog extends JDialog { @@ -184,7 +185,7 @@ private JComponent getPersonnelTable() { personnelSorter.setRowFilter(personnelFilter); personnelTable.setRowSorter(personnelSorter); - final JScrollPane pane = new JScrollPane(personnelTable); + final JScrollPane pane = new JScrollPaneWithSpeed(personnelTable); pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); return pane; } diff --git a/MekHQ/src/mekhq/gui/dialog/BombsDialog.java b/MekHQ/src/mekhq/gui/dialog/BombsDialog.java index 79c7fca08a..d6843faa65 100644 --- a/MekHQ/src/mekhq/gui/dialog/BombsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/BombsDialog.java @@ -44,6 +44,7 @@ import mekhq.campaign.Campaign; import mekhq.campaign.parts.AmmoStorage; import mekhq.campaign.parts.equipment.EquipmentPart; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * @author Deric Page (dericpage@users.sourceforge.net) @@ -103,7 +104,7 @@ private void initGUI() { true, typeMax); // Set up the display of this dialog. - JScrollPane scroller = new JScrollPane(bombPanel); + JScrollPane scroller = new JScrollPaneWithSpeed(bombPanel); scroller.setPreferredSize(new Dimension(300, 200)); setLayout(new BorderLayout()); add(scroller, BorderLayout.CENTER); diff --git a/MekHQ/src/mekhq/gui/dialog/CampaignExportWizard.java b/MekHQ/src/mekhq/gui/dialog/CampaignExportWizard.java index 98d5460ada..d3e4c5db45 100644 --- a/MekHQ/src/mekhq/gui/dialog/CampaignExportWizard.java +++ b/MekHQ/src/mekhq/gui/dialog/CampaignExportWizard.java @@ -60,6 +60,7 @@ import mekhq.campaign.unit.Unit; import mekhq.gui.CampaignGUI; import mekhq.gui.FileDialogs; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * This class manages the GUI and logic for the campaign subset export wizard. @@ -137,7 +138,7 @@ public void display(CampaignExportWizardState state) { gbc.gridy++; - JScrollPane scrollPane = new JScrollPane(); + JScrollPane scrollPane = new JScrollPaneWithSpeed(); switch (state) { case ForceSelection: lblInstructions.setText(resourceMap.getString("lblInstructions.ForceSelection.text")); diff --git a/MekHQ/src/mekhq/gui/dialog/ChooseFactionsDialog.java b/MekHQ/src/mekhq/gui/dialog/ChooseFactionsDialog.java index 570223c59b..66c868bfb3 100644 --- a/MekHQ/src/mekhq/gui/dialog/ChooseFactionsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/ChooseFactionsDialog.java @@ -47,6 +47,7 @@ import mekhq.MekHQ; import mekhq.campaign.universe.Faction; import mekhq.campaign.universe.Factions; +import mekhq.gui.utilities.JScrollPaneWithSpeed; public class ChooseFactionsDialog extends JDialog { private static final MMLogger logger = MMLogger.create(ChooseFactionsDialog.class); @@ -92,7 +93,7 @@ protected void initComponents() { gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; - JScrollPane scrollPane = new JScrollPane(); + JScrollPane scrollPane = new JScrollPaneWithSpeed(); factionList = new JList<>(new FactionListModel(date)); factionList.setCellRenderer(new DefaultListCellRenderer() { @Override diff --git a/MekHQ/src/mekhq/gui/dialog/ChooseRefitDialog.java b/MekHQ/src/mekhq/gui/dialog/ChooseRefitDialog.java index 89c9466322..9da7979302 100644 --- a/MekHQ/src/mekhq/gui/dialog/ChooseRefitDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/ChooseRefitDialog.java @@ -54,6 +54,7 @@ import mekhq.campaign.Campaign; import mekhq.campaign.parts.Refit; import mekhq.campaign.unit.Unit; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * @author Taharqa @@ -120,7 +121,7 @@ private void initComponents() { refitSorter.setComparator(RefitTableModel.COL_CLASS, new ClassSorter()); refitSorter.setComparator(RefitTableModel.COL_COST, new FormattedNumberSorter()); refitTable.setRowSorter(refitSorter); - scrRefitTable = new JScrollPane(); + scrRefitTable = new JScrollPaneWithSpeed(); scrRefitTable.setViewportView(refitTable); scrRefitTable.setBorder(BorderFactory.createTitledBorder(resourceMap.getString("refitTable.title"))); GridBagConstraints gridBagConstraints = new GridBagConstraints(); @@ -133,7 +134,7 @@ private void initComponents() { gridBagConstraints.insets = new Insets(5, 5, 5, 5); getContentPane().add(scrRefitTable, gridBagConstraints); - scrShoppingList = new JScrollPane(); + scrShoppingList = new JScrollPaneWithSpeed(); scrShoppingList.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(resourceMap.getString("shoppingList.title")), BorderFactory.createEmptyBorder(5, 5, 5, 5))); @@ -157,7 +158,7 @@ private void initComponents() { BorderFactory.createEmptyBorder(5, 5, 5, 5))); MekView mv = new MekView(unit.getEntity(), false, true, true, ViewFormatting.HTML); txtOldUnit.setText("
" + mv.getMekReadout() + "
"); - scrOldUnit = new JScrollPane(txtOldUnit); + scrOldUnit = new JScrollPaneWithSpeed(txtOldUnit); scrOldUnit.setMinimumSize(new Dimension(300, 400)); scrOldUnit.setPreferredSize(new Dimension(300, 400)); SwingUtilities.invokeLater(() -> scrOldUnit.getVerticalScrollBar().setValue(0)); @@ -178,7 +179,7 @@ private void initComponents() { txtNewUnit.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(resourceMap.getString("txtNewUnit.title")), BorderFactory.createEmptyBorder(5, 5, 5, 5))); - scrNewUnit = new JScrollPane(txtNewUnit); + scrNewUnit = new JScrollPaneWithSpeed(txtNewUnit); scrNewUnit.setMinimumSize(new Dimension(300, 400)); scrNewUnit.setPreferredSize(new Dimension(300, 400)); gridBagConstraints.gridx = 2; diff --git a/MekHQ/src/mekhq/gui/dialog/CompanyGenerationDialog.java b/MekHQ/src/mekhq/gui/dialog/CompanyGenerationDialog.java index 8e6f801a6e..062f81dd1f 100644 --- a/MekHQ/src/mekhq/gui/dialog/CompanyGenerationDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CompanyGenerationDialog.java @@ -37,6 +37,7 @@ import mekhq.campaign.universe.generators.companyGenerators.AbstractCompanyGenerator; import mekhq.gui.baseComponents.AbstractMHQValidationButtonDialog; import mekhq.gui.panels.CompanyGenerationOptionsPanel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import java.awt.*; @@ -94,7 +95,7 @@ public void setCompanyGenerationOptionsPanel(final CompanyGenerationOptionsPanel protected Container createCenterPane() { setCompanyGenerationOptionsPanel(new CompanyGenerationOptionsPanel(getFrame(), getCampaign(), getCompanyGenerationOptions())); - return new JScrollPane(getCompanyGenerationOptionsPanel()); + return new JScrollPaneWithSpeed(getCompanyGenerationOptionsPanel()); } @Override diff --git a/MekHQ/src/mekhq/gui/dialog/ContractMarketDialog.java b/MekHQ/src/mekhq/gui/dialog/ContractMarketDialog.java index 7efcdb7864..29a9fba0c4 100644 --- a/MekHQ/src/mekhq/gui/dialog/ContractMarketDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/ContractMarketDialog.java @@ -35,6 +35,7 @@ import mekhq.gui.FactionComboBox; import mekhq.gui.sorter.FormattedNumberSorter; import mekhq.gui.sorter.IntegerStringSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.view.ContractSummaryPanel; import javax.swing.*; @@ -123,8 +124,8 @@ private void countSuccessfulContracts() { } private void initComponents() { - JScrollPane scrollTableContracts = new JScrollPane(); - scrollContractView = new JScrollPane(); + JScrollPane scrollTableContracts = new JScrollPaneWithSpeed(); + scrollContractView = new JScrollPaneWithSpeed(); JPanel panelTable = new JPanel(); JPanel panelFees = new JPanel(); JPanel panelRetainer = new JPanel(); @@ -511,17 +512,18 @@ private boolean triggerConfirmationDialog() { ImageIcon icon = getFactionLogo(campaign, ((AtBContract) selectedContract).getEmployerCode(), true); - // Define resource keys for each difficulty level - Map difficultyMessages = Map.of( - -99, "messageChallengeUnknown.text", - 1, "messageChallengeVeryEasy.text", - 2, "messageChallengeEasy.text", - 9, "messageChallengeHard.text", - 10, "messageChallengeVeryHard.text" - ); - - // Extract the resource mapping and get the resource string - String resourceKey = difficultyMessages.getOrDefault(difficulty, ""); + // Get the resource string + String resourceKey = ""; + + if (difficulty == -99) { + resourceKey = "messageChallengeUnknown.text"; + } else if (difficulty <= 2) { + resourceKey = "messageChallengeVeryEasy.text"; + } else if (difficulty > 8) { + resourceKey = "messageChallengeVeryHard.text"; + } else if (difficulty > 6) { + resourceKey = "messageChallengeHard.text"; + } // If resourceKey is not found, just return true, acting as if the player had accepted the mission if (resourceKey.isEmpty()) { diff --git a/MekHQ/src/mekhq/gui/dialog/CreateCharacterDialog.java b/MekHQ/src/mekhq/gui/dialog/CreateCharacterDialog.java index b966ec467e..e8cde0c6bf 100644 --- a/MekHQ/src/mekhq/gui/dialog/CreateCharacterDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CreateCharacterDialog.java @@ -46,6 +46,7 @@ import mekhq.campaign.universe.Factions; import mekhq.campaign.universe.Planet; import mekhq.campaign.universe.PlanetarySystem; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.MarkdownEditorPanel; import mekhq.gui.utilities.MarkdownRenderer; @@ -865,9 +866,9 @@ private JPanel getRightPanel() { rightPanel.add(topPanel, BorderLayout.PAGE_START); - JScrollPane scrOptions = new JScrollPane(); + JScrollPane scrOptions = new JScrollPaneWithSpeed(); panOptions = new JPanel(); - JScrollPane scrSkills = new JScrollPane(); + JScrollPane scrSkills = new JScrollPaneWithSpeed(); panSkills = new JPanel(); JTabbedPane tabStats = new JTabbedPane(); diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index 490a457d8f..9d7f691d10 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -60,6 +60,7 @@ import mekhq.gui.FileDialogs; import mekhq.gui.baseComponents.DefaultMHQScrollablePanel; import mekhq.gui.displayWrappers.FactionDisplay; +import mekhq.gui.utilities.JScrollPaneWithSpeed; public class CustomizeBotForceDialog extends JDialog { private static final MMLogger logger = MMLogger.create(CustomizeBotForceDialog.class); @@ -256,7 +257,7 @@ private void initComponents() { panFixedUnits = new DefaultMHQScrollablePanel(frame, "panFixedEntity", new GridBagLayout()); refreshFixedEntityPanel(); - JScrollPane scrollFixedUnits = new JScrollPane(panFixedUnits); + JScrollPane scrollFixedUnits = new JScrollPaneWithSpeed(panFixedUnits); scrollFixedUnits.setMinimumSize(new Dimension(400, 200)); scrollFixedUnits.setPreferredSize(new Dimension(400, 200)); scrollFixedUnits.setBorder(BorderFactory.createCompoundBorder( diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizePersonDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizePersonDialog.java index 413261071a..7dc5d07e4f 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizePersonDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizePersonDialog.java @@ -52,6 +52,7 @@ import mekhq.gui.control.EditKillLogControl; import mekhq.gui.control.EditPersonnelLogControl; import mekhq.gui.control.EditScenarioLogControl; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.MarkdownEditorPanel; import javax.swing.*; @@ -187,8 +188,8 @@ private void initComponents() { JLabel lblToughness = new JLabel(); textEducationLevel = new JComboBox<>(); JLabel lblEducationLevel = new JLabel(); - JScrollPane scrOptions = new JScrollPane(); - JScrollPane scrSkills = new JScrollPane(); + JScrollPane scrOptions = new JScrollPaneWithSpeed(); + JScrollPane scrSkills = new JScrollPaneWithSpeed(); JPanel panButtons = new JPanel(); JButton btnOk = new JButton(); diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 5d35aeb1ea..7a7b2377e4 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -58,6 +58,7 @@ import mekhq.gui.model.BotForceTableModel; import mekhq.gui.model.LootTableModel; import mekhq.gui.model.ObjectiveTableModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.MarkdownEditorPanel; /** @@ -910,7 +911,7 @@ private void initObjectivesPanel(ResourceBundle resourceMap) { objectiveTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); objectiveTable.getSelectionModel().addListSelectionListener(this::objectiveTableValueChanged); - panObjectives.add(new JScrollPane(objectiveTable), BorderLayout.CENTER); + panObjectives.add(new JScrollPaneWithSpeed(objectiveTable), BorderLayout.CENTER); } @@ -998,7 +999,7 @@ private void initLootPanel(ResourceBundle resourceMap) { lootTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); lootTable.getSelectionModel().addListSelectionListener(this::lootTableValueChanged); - panLoot.add(new JScrollPane(lootTable), BorderLayout.CENTER); + panLoot.add(new JScrollPaneWithSpeed(lootTable), BorderLayout.CENTER); } private void lootTableValueChanged(ListSelectionEvent evt) { @@ -1081,7 +1082,7 @@ private void initOtherForcesPanel(ResourceBundle resourceMap) { forcesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); forcesTable.getSelectionModel().addListSelectionListener(this::forcesTableValueChanged); - panOtherForces.add(new JScrollPane(forcesTable), BorderLayout.CENTER); + panOtherForces.add(new JScrollPaneWithSpeed(forcesTable), BorderLayout.CENTER); } private void forcesTableValueChanged(ListSelectionEvent evt) { diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index 1dffa3d5ad..5723c29dfe 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -41,6 +41,7 @@ import mekhq.campaign.mission.ScenarioObjective.ObjectiveAmountType; import mekhq.campaign.mission.ScenarioObjective.ObjectiveCriterion; import mekhq.campaign.mission.ScenarioObjective.TimeLimitType; +import mekhq.gui.utilities.JScrollPaneWithSpeed; public class CustomizeScenarioObjectiveDialog extends JDialog { @@ -182,7 +183,7 @@ private void initialize() { lstDetails.addListSelectionListener( e -> btnRemoveDetail.setEnabled(!lstDetails.getSelectedValuesList().isEmpty())); lstDetails.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - JScrollPane scrDetails = new JScrollPane(lstDetails); + JScrollPane scrDetails = new JScrollPaneWithSpeed(lstDetails); scrDetails.setMinimumSize(new Dimension(200, 100)); scrDetails.setPreferredSize(new Dimension(200, 100)); gbc.gridx = 1; @@ -336,7 +337,7 @@ private void initForcePanel(ResourceBundle resourceMap) { localGbc.gridx++; panForce.add(btnAdd, localGbc); localGbc.gridx++; - JScrollPane scrForceNames = new JScrollPane(forceNames); + JScrollPane scrForceNames = new JScrollPaneWithSpeed(forceNames); scrForceNames.setMinimumSize(new Dimension(250, 100)); scrForceNames.setPreferredSize(new Dimension(250, 100)); panForce.add(scrForceNames, localGbc); @@ -436,14 +437,14 @@ private void initObjectiveEffectPanel(ResourceBundle resourceMap) { gbc.gridx = 0; gbc.gridy++; gbc.anchor = GridBagConstraints.NORTHWEST; - JScrollPane scrSuccessEffects = new JScrollPane(successEffects); + JScrollPane scrSuccessEffects = new JScrollPaneWithSpeed(successEffects); scrSuccessEffects.setMinimumSize(new Dimension(300, 100)); scrSuccessEffects.setPreferredSize(new Dimension(300, 100)); panBottom.add(scrSuccessEffects, gbc); gbc.gridx++; panBottom.add(btnRemoveSuccess, gbc); gbc.gridx++; - JScrollPane scrFailureEffects = new JScrollPane(failureEffects); + JScrollPane scrFailureEffects = new JScrollPaneWithSpeed(failureEffects); scrFailureEffects.setMinimumSize(new Dimension(300, 100)); scrFailureEffects.setPreferredSize(new Dimension(300, 100)); panBottom.add(scrFailureEffects, gbc); diff --git a/MekHQ/src/mekhq/gui/dialog/DataLoadingDialog.java b/MekHQ/src/mekhq/gui/dialog/DataLoadingDialog.java index db6a62606b..d48946b4a2 100644 --- a/MekHQ/src/mekhq/gui/dialog/DataLoadingDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/DataLoadingDialog.java @@ -320,9 +320,6 @@ public Campaign doInBackground() throws Exception { if ((preset != null) && (preset.getGameOptions() != null)) { campaign.setGameOptions(preset.getGameOptions()); } - campaign.setLocalDate(dc.getDate()); - campaign.getGameOptions().getOption(OptionsConstants.ALLOWED_YEAR).setValue(campaign.getGameYear()); - campaign.setStartingSystem((preset == null) ? null : preset.getPlanet()); // This must be after the date chooser to enable correct functionality. setVisible(false); @@ -330,7 +327,17 @@ public Campaign doInBackground() throws Exception { // Campaign Options if (isSelect && preset != null) { preset.applyContinuousToCampaign(campaign); + + // This needs to be after we've applied the preset + campaign.setLocalDate(dc.getDate()); + campaign.getGameOptions().getOption(OptionsConstants.ALLOWED_YEAR).setValue(campaign.getGameYear()); + campaign.setStartingSystem(preset.getPlanet()); } else { + // This needs to be before we trigger the customize preset dialog + campaign.setLocalDate(dc.getDate()); + campaign.getGameOptions().getOption(OptionsConstants.ALLOWED_YEAR).setValue(campaign.getGameYear()); + campaign.setStartingSystem((preset == null) ? null : preset.getPlanet()); + CampaignOptionsDialog optionsDialog = new CampaignOptionsDialog(dialog, getFrame(), campaign, true); optionsDialog.setLocationRelativeTo(getFrame()); optionsDialog.applyPreset(preset); diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index 63cd10c7d8..3a505e07cd 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -56,6 +56,7 @@ import megamek.server.totalwarfare.TWGameManager; import mekhq.MekHQ; import mekhq.campaign.mission.Scenario; +import mekhq.gui.utilities.JScrollPaneWithSpeed; public class EditMapSettingsDialog extends JDialog { private static final MMLogger logger = MMLogger.create(EditMapSettingsDialog.class); @@ -133,7 +134,7 @@ private void initComponents() { panSizeFixed = new JPanel(new BorderLayout()); JPanel panButtons = new JPanel(new FlowLayout()); - scrChooseMap = new JScrollPane(); + scrChooseMap = new JScrollPaneWithSpeed(); scrChooseMap.setMinimumSize(new Dimension(600, 800)); scrChooseMap.setPreferredSize(new Dimension(600, 800)); diff --git a/MekHQ/src/mekhq/gui/dialog/EditPersonnelInjuriesDialog.java b/MekHQ/src/mekhq/gui/dialog/EditPersonnelInjuriesDialog.java index 72d530ceb9..d5035e265f 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditPersonnelInjuriesDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditPersonnelInjuriesDialog.java @@ -48,6 +48,7 @@ import mekhq.campaign.Campaign; import mekhq.campaign.personnel.Injury; import mekhq.campaign.personnel.Person; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * @author Ralgith @@ -122,7 +123,7 @@ private void initComponents() { injuriesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); injuriesTable.getSelectionModel().addListSelectionListener(this::injuriesTableValueChanged); - JScrollPane scrollInjuryTable = new JScrollPane(); + JScrollPane scrollInjuryTable = new JScrollPaneWithSpeed(); scrollInjuryTable.setName("scrollInjuryTable"); scrollInjuryTable.setViewportView(injuriesTable); getContentPane().add(scrollInjuryTable, BorderLayout.CENTER); diff --git a/MekHQ/src/mekhq/gui/dialog/EditSkillPerquisiteDialog.java b/MekHQ/src/mekhq/gui/dialog/EditSkillPerquisiteDialog.java index 12f0ec5d91..4d082e55a7 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditSkillPerquisiteDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditSkillPerquisiteDialog.java @@ -42,6 +42,7 @@ import mekhq.MekHQ; import mekhq.campaign.personnel.SkillPerquisite; import mekhq.campaign.personnel.SkillType; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * @author Taharqa @@ -113,7 +114,7 @@ private void initComponents() { setTitle("Select Abilities"); getContentPane().setLayout(new BorderLayout()); - getContentPane().add(new JScrollPane(panMain), BorderLayout.CENTER); + getContentPane().add(new JScrollPaneWithSpeed(panMain), BorderLayout.CENTER); getContentPane().add(panButtons, BorderLayout.SOUTH); this.setPreferredSize(new Dimension(400, 700)); diff --git a/MekHQ/src/mekhq/gui/dialog/ForceTemplateAssignmentDialog.java b/MekHQ/src/mekhq/gui/dialog/ForceTemplateAssignmentDialog.java index 49c4db64e6..0f109889be 100644 --- a/MekHQ/src/mekhq/gui/dialog/ForceTemplateAssignmentDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/ForceTemplateAssignmentDialog.java @@ -27,6 +27,7 @@ import mekhq.campaign.mission.ScenarioForceTemplate.ForceGenerationMethod; import mekhq.campaign.unit.Unit; import mekhq.gui.CampaignGUI; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import java.awt.*; @@ -87,7 +88,7 @@ private void display(boolean individualUnits) { gbc.gridwidth = 1; gbc.gridy++; - JScrollPane itemListPane = new JScrollPane(); + JScrollPane itemListPane = new JScrollPaneWithSpeed(); if (individualUnits) { itemListPane.setViewportView(unitList); refreshUnitList(); @@ -98,7 +99,7 @@ private void display(boolean individualUnits) { getContentPane().add(itemListPane, gbc); gbc.gridx++; - JScrollPane templateListPane = new JScrollPane(); + JScrollPane templateListPane = new JScrollPaneWithSpeed(); templateListPane.setViewportView(templateList); itemListPane.setPreferredSize( new Dimension((int) itemListPane.getPreferredSize().getWidth() + (int) templateListPane.getPreferredSize().getWidth(), diff --git a/MekHQ/src/mekhq/gui/dialog/GMToolsDialog.java b/MekHQ/src/mekhq/gui/dialog/GMToolsDialog.java index a0a88bff35..e08903f31b 100644 --- a/MekHQ/src/mekhq/gui/dialog/GMToolsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/GMToolsDialog.java @@ -49,6 +49,7 @@ import mekhq.gui.displayWrappers.ClanDisplay; import mekhq.gui.displayWrappers.FactionDisplay; import mekhq.gui.panels.LayeredForceIconCreationPanel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.GroupLayout.Alignment; @@ -558,7 +559,7 @@ private JScrollPane createGeneralTab() { .addComponent(dicePanel) .addComponent(ratPanel)); - return new JScrollPane(panel); + return new JScrollPaneWithSpeed(panel); } private JPanel createDicePanel() { @@ -788,7 +789,7 @@ private JScrollPane createNamesTab() { .addComponent(companyNamePanel) .addComponent(bloodnamePanel)); - return new JScrollPane(namesPanel); + return new JScrollPaneWithSpeed(namesPanel); } private JPanel createNamePanel() { @@ -1270,7 +1271,7 @@ private JScrollPane createPersonnelModuleTab() { layout.createParallelGroup(Alignment.LEADING) .addComponent(procreationPanel)); - return new JScrollPane(personnelModulePanel); + return new JScrollPaneWithSpeed(personnelModulePanel); } private JPanel createProcreationPanel() { diff --git a/MekHQ/src/mekhq/gui/dialog/LargeCraftAmmoSwapDialog.java b/MekHQ/src/mekhq/gui/dialog/LargeCraftAmmoSwapDialog.java index 0b249c03c2..fa5533fb1e 100644 --- a/MekHQ/src/mekhq/gui/dialog/LargeCraftAmmoSwapDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/LargeCraftAmmoSwapDialog.java @@ -38,6 +38,7 @@ import mekhq.campaign.parts.equipment.LargeCraftAmmoBin; import mekhq.campaign.unit.Unit; import mekhq.campaign.unit.actions.AdjustLargeCraftAmmoAction; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * @author Neoancient @@ -55,7 +56,7 @@ public LargeCraftAmmoSwapDialog(final JFrame frame, final Unit unit) { getContentPane().setLayout(new BorderLayout()); mainPanel = new BayMunitionsChoicePanel(unit.getEntity(), unit.getCampaign().getGame()); - getContentPane().add(new JScrollPane(mainPanel), BorderLayout.CENTER); + getContentPane().add(new JScrollPaneWithSpeed(mainPanel), BorderLayout.CENTER); JPanel panButtons = new JPanel(); JButton button = new JButton("OK"); button.addActionListener(ev -> apply()); diff --git a/MekHQ/src/mekhq/gui/dialog/LootDialog.java b/MekHQ/src/mekhq/gui/dialog/LootDialog.java index 028f4f4168..fdc84a453b 100644 --- a/MekHQ/src/mekhq/gui/dialog/LootDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/LootDialog.java @@ -40,6 +40,7 @@ import mekhq.campaign.finances.Money; import mekhq.campaign.mission.Loot; import mekhq.campaign.parts.Part; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * @author Taharqa @@ -183,7 +184,7 @@ private void initComponents() { gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.insets = new Insets(5, 5, 5, 5); - scrUnits = new JScrollPane(listUnits); + scrUnits = new JScrollPaneWithSpeed(listUnits); listUnits.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); listUnits.getSelectionModel().addListSelectionListener(evt -> listUnitsValueChanged()); refreshUnitList(); @@ -226,7 +227,7 @@ private void initComponents() { gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.insets = new Insets(5, 5, 5, 5); - scrParts = new JScrollPane(listParts); + scrParts = new JScrollPaneWithSpeed(listParts); listParts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); listParts.getSelectionModel().addListSelectionListener(evt -> listPartsValueChanged()); refreshPartList(); diff --git a/MekHQ/src/mekhq/gui/dialog/MHQOptionsDialog.java b/MekHQ/src/mekhq/gui/dialog/MHQOptionsDialog.java index 7c610b600a..5e54ad82c7 100644 --- a/MekHQ/src/mekhq/gui/dialog/MHQOptionsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/MHQOptionsDialog.java @@ -36,6 +36,7 @@ import mekhq.gui.baseComponents.AbstractMHQButtonDialog; import mekhq.gui.enums.ForceIconOperationalStatusStyle; import mekhq.gui.enums.PersonnelFilterStyle; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.GroupLayout.Alignment; @@ -222,16 +223,22 @@ public MHQOptionsDialog(final JFrame frame) { protected Container createCenterPane() { JTabbedPane optionsTabbedPane = new JTabbedPane(); optionsTabbedPane.setName("optionsTabbedPane"); - optionsTabbedPane.add(resources.getString("displayTab.title"), new JScrollPane(createDisplayTab())); - optionsTabbedPane.add(resources.getString("coloursTab.title"), new JScrollPane(createColoursTab())); - optionsTabbedPane.add(resources.getString("fontsTab.title"), new JScrollPane(createFontsTab())); - optionsTabbedPane.add(resources.getString("autosaveTab.title"), new JScrollPane(createAutosaveTab())); - optionsTabbedPane.add(resources.getString("newDayTab.title"), new JScrollPane(createNewDayTab())); + optionsTabbedPane.add(resources.getString("displayTab.title"), + new JScrollPaneWithSpeed(createDisplayTab())); + optionsTabbedPane.add(resources.getString("coloursTab.title"), + new JScrollPaneWithSpeed(createColoursTab())); + optionsTabbedPane.add(resources.getString("fontsTab.title"), + new JScrollPaneWithSpeed(createFontsTab())); + optionsTabbedPane.add(resources.getString("autosaveTab.title"), + new JScrollPaneWithSpeed(createAutosaveTab())); + optionsTabbedPane.add(resources.getString("newDayTab.title"), + new JScrollPaneWithSpeed(createNewDayTab())); optionsTabbedPane.add(resources.getString("campaignXMLSaveTab.title"), - new JScrollPane(createCampaignXMLSaveTab())); - optionsTabbedPane.add(resources.getString("nagTab.title"), new JScrollPane(createNagTab())); + new JScrollPaneWithSpeed(createCampaignXMLSaveTab())); + optionsTabbedPane.add(resources.getString("nagTab.title"), + new JScrollPaneWithSpeed(createNagTab())); optionsTabbedPane.add(resources.getString("miscellaneousTab.title"), - new JScrollPane(createMiscellaneousTab())); + new JScrollPaneWithSpeed(createMiscellaneousTab())); return optionsTabbedPane; } diff --git a/MekHQ/src/mekhq/gui/dialog/MRMSDialog.java b/MekHQ/src/mekhq/gui/dialog/MRMSDialog.java index c7e5a1a60b..fc82ce557e 100644 --- a/MekHQ/src/mekhq/gui/dialog/MRMSDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/MRMSDialog.java @@ -39,6 +39,7 @@ import mekhq.gui.sorter.PartsDetailSorter; import mekhq.gui.sorter.UnitStatusSorter; import mekhq.gui.sorter.UnitTypeSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.service.enums.MRMSMode; import mekhq.service.mrms.MRMSConfiguredOptions; import mekhq.service.mrms.MRMSOption; @@ -287,7 +288,7 @@ private void initComponents() { pnlMain.add(createOptionsPanel(), createBaseConstraints(2)); - content.add(new JScrollPane(pnlMain), BorderLayout.CENTER); + content.add(new JScrollPaneWithSpeed(pnlMain), BorderLayout.CENTER); content.add(createActionButtons(), BorderLayout.SOUTH); pack(); @@ -345,7 +346,7 @@ private JPanel createUnitsPanel() { unitTable.setIntercellSpacing(new Dimension(0, 0)); unitTable.setShowGrid(false); - scrollUnitList = new JScrollPane(unitTable); + scrollUnitList = new JScrollPaneWithSpeed(unitTable); scrollUnitList.setMinimumSize(new Dimension(350, 200)); scrollUnitList.setPreferredSize(new Dimension(350, 200)); @@ -394,7 +395,7 @@ private JPanel createPartsPanel() { partsTable.setIntercellSpacing(new Dimension(0, 0)); partsTable.setShowGrid(false); - scrollPartsTable = new JScrollPane(partsTable); + scrollPartsTable = new JScrollPaneWithSpeed(partsTable); scrollPartsTable.setMinimumSize(new Dimension(350, 200)); scrollPartsTable.setPreferredSize(new Dimension(350, 200)); diff --git a/MekHQ/src/mekhq/gui/dialog/ManageAssetsDialog.java b/MekHQ/src/mekhq/gui/dialog/ManageAssetsDialog.java index 875a414408..3feaf47d7e 100644 --- a/MekHQ/src/mekhq/gui/dialog/ManageAssetsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/ManageAssetsDialog.java @@ -51,6 +51,7 @@ import mekhq.campaign.event.AssetRemovedEvent; import mekhq.campaign.finances.Asset; import mekhq.gui.model.DataTableModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * @author Taharqa @@ -117,7 +118,7 @@ private void initComponents() { assetTable.setShowGrid(false); assetTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); assetTable.getSelectionModel().addListSelectionListener(this::assetTableValueChanged); - scrollAssetTable = new JScrollPane(assetTable); + scrollAssetTable = new JScrollPaneWithSpeed(assetTable); getContentPane().add(scrollAssetTable, BorderLayout.CENTER); btnOK.setText(resourceMap.getString("btnOK.text")); diff --git a/MekHQ/src/mekhq/gui/dialog/MassMothballDialog.java b/MekHQ/src/mekhq/gui/dialog/MassMothballDialog.java index 4233af0057..b8604ff9d8 100644 --- a/MekHQ/src/mekhq/gui/dialog/MassMothballDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/MassMothballDialog.java @@ -49,6 +49,7 @@ import mekhq.campaign.personnel.Person; import mekhq.campaign.unit.Unit; import mekhq.gui.adapter.UnitTableMouseAdapter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * This class handles the display of the Mass Mothball/Reactivate dialog @@ -115,7 +116,7 @@ public MassMothballDialog(final JFrame frame, final Unit[] units, final Campaign gbc.gridy++; addExecuteButton(activating, gbc); - JScrollPane scrollPane = new JScrollPane(); + JScrollPane scrollPane = new JScrollPaneWithSpeed(); scrollPane.setViewportView(contentPanel); scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.setMaximumSize(new Dimension(600, 600)); @@ -196,7 +197,7 @@ private void addUnitTypePanel(int unitType, GridBagConstraints gbc) { techList.setBorder(new LineBorder(Color.GRAY, 1)); techList.setCellRenderer(new TechListCellRenderer()); - JScrollPane techListPane = new JScrollPane(); + JScrollPane techListPane = new JScrollPaneWithSpeed(); techListPane.setViewportView(techList); techListPane.setMaximumSize(new Dimension(200, 100)); techListPane.setPreferredSize(new Dimension(200, 50)); diff --git a/MekHQ/src/mekhq/gui/dialog/MedicalViewDialog.java b/MekHQ/src/mekhq/gui/dialog/MedicalViewDialog.java index 75e916c7ef..b4a8582c1a 100644 --- a/MekHQ/src/mekhq/gui/dialog/MedicalViewDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/MedicalViewDialog.java @@ -34,6 +34,7 @@ import mekhq.campaign.personnel.InjuryType; import mekhq.campaign.personnel.Person; import mekhq.campaign.personnel.enums.InjuryLevel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.view.Paperdoll; import javax.swing.*; @@ -167,7 +168,7 @@ public MedicalViewDialog(Window parent, Campaign c, Person p) { getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); Container scrollPanel = new JPanel(); - getContentPane().add(new JScrollPane(scrollPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + getContentPane().add(new JScrollPaneWithSpeed(scrollPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); initComponents(scrollPanel); diff --git a/MekHQ/src/mekhq/gui/dialog/MekViewDialog.java b/MekHQ/src/mekhq/gui/dialog/MekViewDialog.java index 2f6abc24eb..9ad4de2d84 100644 --- a/MekHQ/src/mekhq/gui/dialog/MekViewDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/MekViewDialog.java @@ -35,6 +35,7 @@ import megamek.common.MekView; import megamek.logging.MMLogger; import mekhq.MekHQ; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * @author Jay Lawson (jaylawson39 at yahoo.com) @@ -58,7 +59,7 @@ public MekViewDialog(JFrame parent, boolean modal, MekView mv) { private void initComponents() { - jScrollPane2 = new JScrollPane(); + jScrollPane2 = new JScrollPaneWithSpeed(); txtMek = new JTextPane(); btnOkay = new JButton(); diff --git a/MekHQ/src/mekhq/gui/dialog/NewContractDialog.java b/MekHQ/src/mekhq/gui/dialog/NewContractDialog.java index a3de37ef32..8ed053fe05 100644 --- a/MekHQ/src/mekhq/gui/dialog/NewContractDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/NewContractDialog.java @@ -49,6 +49,7 @@ import mekhq.campaign.personnel.SkillType; import mekhq.campaign.universe.PlanetarySystem; import mekhq.campaign.universe.Systems; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.JSuggestField; import mekhq.gui.utilities.MarkdownEditorPanel; import mekhq.gui.view.ContractPaymentBreakdown; @@ -185,7 +186,7 @@ protected void initComponents() { gridBagConstraints.insets = new Insets(5, 5, 5, 5); newContractPanel.add(btnClose, gridBagConstraints); - JScrollPane scrollPane = new JScrollPane(newContractPanel); + JScrollPane scrollPane = new JScrollPaneWithSpeed(newContractPanel); getContentPane().add(scrollPane); diff --git a/MekHQ/src/mekhq/gui/dialog/NewLoanDialog.java b/MekHQ/src/mekhq/gui/dialog/NewLoanDialog.java index 8540ba1e2b..0af6093b80 100644 --- a/MekHQ/src/mekhq/gui/dialog/NewLoanDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/NewLoanDialog.java @@ -20,24 +20,6 @@ */ package mekhq.gui.dialog; -import java.awt.BorderLayout; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.GridLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.text.NumberFormat; -import java.util.ResourceBundle; - -import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.text.DefaultFormatterFactory; -import javax.swing.text.NumberFormatter; - import megamek.client.ui.baseComponents.MMComboBox; import megamek.client.ui.preferences.JWindowPreference; import megamek.client.ui.preferences.PreferencesNode; @@ -48,6 +30,20 @@ import mekhq.campaign.finances.Money; import mekhq.campaign.finances.enums.FinancialTerm; +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.DefaultFormatterFactory; +import javax.swing.text.NumberFormatter; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.NumberFormat; +import java.util.Objects; +import java.util.ResourceBundle; + /** * @author Taharqa */ @@ -627,11 +623,11 @@ public void actionPerformed(ActionEvent e) { @Override public void stateChanged(ChangeEvent e) { if (campaign.getCampaignOptions().isUseLoanLimits()) { - if (e.getSource() == sldInterest) { + if (Objects.equals(e.getSource(), sldInterest)) { sldCollateral.removeChangeListener(this); sldCollateral.setValue(Loan.recalculateCollateralFromInterest(rating, sldInterest.getValue())); sldCollateral.addChangeListener(this); - } else if (e.getSource() == sldCollateral) { + } else if (Objects.equals(e.getSource(), sldCollateral)) { sldInterest.removeChangeListener(this); sldInterest.setValue(Loan.recalculateInterestFromCollateral(rating, sldCollateral.getValue())); sldInterest.addChangeListener(this); diff --git a/MekHQ/src/mekhq/gui/dialog/NewRecruitDialog.java b/MekHQ/src/mekhq/gui/dialog/NewRecruitDialog.java index 6f8bbd91c0..309974609a 100644 --- a/MekHQ/src/mekhq/gui/dialog/NewRecruitDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/NewRecruitDialog.java @@ -48,6 +48,7 @@ import mekhq.campaign.personnel.randomEvents.PersonalityController; import mekhq.gui.CampaignGUI; import mekhq.gui.displayWrappers.RankDisplay; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.view.PersonViewPanel; /** @@ -82,7 +83,7 @@ private void refreshView() { } private void initComponents() { - scrollView = new JScrollPane(); + scrollView = new JScrollPaneWithSpeed(); choiceRanks = new JComboBox<>(); final ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.NewRecruitDialog", diff --git a/MekHQ/src/mekhq/gui/dialog/ObjectiveEditPanel.java b/MekHQ/src/mekhq/gui/dialog/ObjectiveEditPanel.java index 63873cb8aa..7174361363 100644 --- a/MekHQ/src/mekhq/gui/dialog/ObjectiveEditPanel.java +++ b/MekHQ/src/mekhq/gui/dialog/ObjectiveEditPanel.java @@ -27,6 +27,7 @@ import mekhq.campaign.mission.ScenarioObjective; import mekhq.campaign.mission.ScenarioObjective.ObjectiveCriterion; import mekhq.campaign.mission.ScenarioObjective.TimeLimitType; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.campaign.mission.ScenarioTemplate; import javax.swing.*; @@ -185,7 +186,7 @@ private void addSaveCloseButtons(GridBagConstraints gbc) { private void addDescriptionUI(GridBagConstraints gbc) { lblShortDescription = new JLabel("Short Description:"); - JScrollPane txtScroll = new JScrollPane(); + JScrollPane txtScroll = new JScrollPaneWithSpeed(); txtShortDescription = new JTextArea(); txtShortDescription.setColumns(40); txtShortDescription.setRows(5); diff --git a/MekHQ/src/mekhq/gui/dialog/PartsReportDialog.java b/MekHQ/src/mekhq/gui/dialog/PartsReportDialog.java index 19f1f1fcdb..b1cf0f1e5a 100644 --- a/MekHQ/src/mekhq/gui/dialog/PartsReportDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/PartsReportDialog.java @@ -57,6 +57,7 @@ import mekhq.gui.model.PartsInUseTableModel; import mekhq.gui.sorter.FormattedNumberSorter; import mekhq.gui.sorter.TwoNumbersSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * A dialog to show parts in use, ordered, in transit with actionable buttons for buying or adding more @@ -260,7 +261,7 @@ public void actionPerformed(ActionEvent e) { PartsInUseTableModel.COL_BUTTON_GMADD_BULK); - JScrollPane tableScroll = new JScrollPane(overviewPartsInUseTable); + JScrollPane tableScroll = new JScrollPaneWithSpeed(overviewPartsInUseTable); ignoreMothballedCheck = new JCheckBox(resourceMap.getString("chkIgnoreMothballed.text")); ignoreMothballedCheck.addActionListener(evt -> refreshOverviewPartsInUse()); diff --git a/MekHQ/src/mekhq/gui/dialog/PartsStoreDialog.java b/MekHQ/src/mekhq/gui/dialog/PartsStoreDialog.java index 0cd896a886..eeba1f1e6e 100644 --- a/MekHQ/src/mekhq/gui/dialog/PartsStoreDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/PartsStoreDialog.java @@ -58,6 +58,7 @@ import mekhq.gui.CampaignGUI; import mekhq.gui.dialog.PartsStoreDialog.PartsTableModel.PartProxy; import mekhq.gui.sorter.PartsDetailSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * @author Taharqa @@ -140,7 +141,7 @@ private void initComponents() { } partsTable.setIntercellSpacing(new Dimension(0, 0)); partsTable.setShowGrid(false); - JScrollPane scrollPartsTable = new JScrollPane(); + JScrollPane scrollPartsTable = new JScrollPaneWithSpeed(); scrollPartsTable.setName("scrollPartsTable"); scrollPartsTable.setViewportView(partsTable); getContentPane().add(scrollPartsTable, BorderLayout.CENTER); diff --git a/MekHQ/src/mekhq/gui/dialog/PayCollateralDialog.java b/MekHQ/src/mekhq/gui/dialog/PayCollateralDialog.java index d8b52dd32c..62b5a6c577 100644 --- a/MekHQ/src/mekhq/gui/dialog/PayCollateralDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/PayCollateralDialog.java @@ -47,6 +47,7 @@ import mekhq.campaign.parts.AmmoStorage; import mekhq.campaign.parts.Part; import mekhq.campaign.unit.Unit; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * A dialog to decide how you want to pay off collateral when you @@ -134,7 +135,7 @@ private void initComponents() { pnlUnits.add(box, gridBagConstraints); i++; } - JScrollPane scrUnits = new JScrollPane(); + JScrollPane scrUnits = new JScrollPaneWithSpeed(); scrUnits.setViewportView(pnlUnits); scrUnits.setMinimumSize(new Dimension(400, 300)); scrUnits.setPreferredSize(new Dimension(400, 300)); @@ -181,7 +182,7 @@ private void initComponents() { + p.getActualValue().toAmountAndSymbolString() + ""), gridBagConstraints); i++; } - JScrollPane scrParts = new JScrollPane(); + JScrollPane scrParts = new JScrollPaneWithSpeed(); scrParts.setViewportView(pnlParts); scrParts.setMinimumSize(new Dimension(400, 300)); scrParts.setPreferredSize(new Dimension(400, 300)); @@ -228,7 +229,7 @@ private void initComponents() { pnlAssets.add(box, gridBagConstraints); i++; } - JScrollPane scrAssets = new JScrollPane(pnlAssets); + JScrollPane scrAssets = new JScrollPaneWithSpeed(pnlAssets); scrAssets.setMinimumSize(new Dimension(400, 300)); scrAssets.setPreferredSize(new Dimension(400, 300)); diff --git a/MekHQ/src/mekhq/gui/dialog/PersonnelMarketDialog.java b/MekHQ/src/mekhq/gui/dialog/PersonnelMarketDialog.java index e9be5763fd..ab93be87a6 100644 --- a/MekHQ/src/mekhq/gui/dialog/PersonnelMarketDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/PersonnelMarketDialog.java @@ -70,6 +70,7 @@ import mekhq.gui.enums.PersonnelFilter; import mekhq.gui.enums.PersonnelTableModelColumn; import mekhq.gui.model.PersonnelTableModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.view.PersonViewPanel; /** @@ -131,8 +132,8 @@ public PersonnelMarketDialog(final JFrame frame, final CampaignGUI view, final C } private void initComponents() { - scrollTablePersonnel = new JScrollPane(); - scrollPersonnelView = new JScrollPane(); + scrollTablePersonnel = new JScrollPaneWithSpeed(); + scrollPersonnelView = new JScrollPaneWithSpeed(); tablePersonnel = new JTable(); panelMain = new JPanel(); panelFilterBtns = new JPanel(); diff --git a/MekHQ/src/mekhq/gui/dialog/QuirksDialog.java b/MekHQ/src/mekhq/gui/dialog/QuirksDialog.java index 000705ea81..289d746914 100644 --- a/MekHQ/src/mekhq/gui/dialog/QuirksDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/QuirksDialog.java @@ -44,6 +44,7 @@ import megamek.common.options.WeaponQuirks; import megamek.logging.MMLogger; import mekhq.MekHQ; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * @author Deric Page (dericpage@users.sourceforge.net) @@ -86,7 +87,7 @@ private void initGUI() { qpanel.refreshQuirks(); // Set up the display of this dialog. - JScrollPane scroller = new JScrollPane(qpanel); + JScrollPane scroller = new JScrollPaneWithSpeed(qpanel); scroller.setPreferredSize(new Dimension(300, 200)); setLayout(new BorderLayout()); add(scroller, BorderLayout.CENTER); diff --git a/MekHQ/src/mekhq/gui/dialog/ResolveScenarioWizardDialog.java b/MekHQ/src/mekhq/gui/dialog/ResolveScenarioWizardDialog.java index d7629a9033..6df2520bd3 100644 --- a/MekHQ/src/mekhq/gui/dialog/ResolveScenarioWizardDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/ResolveScenarioWizardDialog.java @@ -26,6 +26,7 @@ import megamek.client.ui.preferences.JWindowPreference; import megamek.client.ui.preferences.PreferencesNode; import megamek.client.ui.swing.UnitEditorDialog; +import megamek.client.ui.swing.util.UIUtil; import megamek.common.GunEmplacement; import megamek.common.options.OptionsConstants; import megamek.logging.MMLogger; @@ -47,6 +48,7 @@ import mekhq.campaign.stratcon.StratconRulesManager; import mekhq.campaign.unit.TestUnit; import mekhq.campaign.unit.Unit; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.MarkdownEditorPanel; import mekhq.gui.view.PersonViewPanel; @@ -125,6 +127,7 @@ public class ResolveScenarioWizardDialog extends JDialog { /* * Prisoner status panel components */ + private JButton prisonerRansomAllButton; private final List prisonerCapturedBtns = new ArrayList<>(); private final List prisonerRansomedBtns = new ArrayList<>(); private final List prisonerKiaBtns = new ArrayList<>(); @@ -242,8 +245,6 @@ private void initComponents() { txtInstructions.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(resourceMap.getString("txtInstructions.title")), BorderFactory.createEmptyBorder(5,5,5,5))); - txtInstructions.setMinimumSize(new Dimension(590,120)); - txtInstructions.setPreferredSize(new Dimension(590,120)); getContentPane().add(txtInstructions, BorderLayout.PAGE_START); /* @@ -419,6 +420,19 @@ private void initComponents() { gridx = 1; + prisonerRansomAllButton = new JButton(resourceMap.getString("prisonerRansomAllButton.text")); + + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx=2; + gridBagConstraints.gridy=0; + gridBagConstraints.gridwidth=3; + gridBagConstraints.anchor = GridBagConstraints.CENTER; + gridBagConstraints.insets = new Insets(5, 5, 0, 0); + pnlPrisonerStatus.add(prisonerRansomAllButton, gridBagConstraints); + + prisonerRansomAllButton.addActionListener(evt -> prisonerRansomAll()); + + gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = gridx++; gridBagConstraints.gridy = 1; @@ -790,12 +804,12 @@ private void initComponents() { */ pnlPreview = new JPanel(); choiceStatus = new JComboBox<>(); - JScrollPane scrRecoveredUnits = new JScrollPane(); - JScrollPane scrRecoveredPilots = new JScrollPane(); - JScrollPane scrMissingUnits = new JScrollPane(); - JScrollPane scrMissingPilots = new JScrollPane(); - JScrollPane scrDeadPilots = new JScrollPane(); - JScrollPane scrSalvage = new JScrollPane(); + JScrollPane scrRecoveredUnits = new JScrollPaneWithSpeed(); + JScrollPane scrRecoveredPilots = new JScrollPaneWithSpeed(); + JScrollPane scrMissingUnits = new JScrollPaneWithSpeed(); + JScrollPane scrMissingPilots = new JScrollPaneWithSpeed(); + JScrollPane scrDeadPilots = new JScrollPaneWithSpeed(); + JScrollPane scrSalvage = new JScrollPaneWithSpeed(); txtInstructions = new JTextArea(); txtReport = new MarkdownEditorPanel("After-Action Report"); txtRecoveredUnits = new JTextArea(); @@ -852,11 +866,11 @@ private void initComponents() { gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new Insets(5, 5, 0, 0); - pnlPreview.add(new JScrollPane(txtRewards), gridBagConstraints); + pnlPreview.add(new JScrollPaneWithSpeed(txtRewards), gridBagConstraints); txtReport.setText(""); - txtReport.setPreferredSize(new Dimension(500, 300)); - txtReport.setMinimumSize(new Dimension(500, 300)); + txtReport.setPreferredSize(UIUtil.scaleForGUI(500, 300)); + txtReport.setMinimumSize(UIUtil.scaleForGUI(500, 300)); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; @@ -990,9 +1004,9 @@ private void initComponents() { pnlMain.add(pnlPreview, PREVIEWPANEL); - scrMain = new JScrollPane(pnlMain); - scrMain.setMinimumSize(new Dimension(600, 500)); - scrMain.setPreferredSize(new Dimension(600, 500)); + scrMain = new JScrollPaneWithSpeed(pnlMain); + scrMain.setMinimumSize(UIUtil.scaleForGUI(600, 500)); + scrMain.setPreferredSize(UIUtil.scaleForGUI(900, 500)); getContentPane().add(scrMain, BorderLayout.CENTER); @@ -1053,6 +1067,19 @@ private void initComponents() { pack(); } + private void prisonerRansomAll() { + Iterator capturedBoxes = prisonerCapturedBtns.iterator(); + Iterator ransomedBoxes = prisonerRansomedBtns.iterator(); + while (capturedBoxes.hasNext() && ransomedBoxes.hasNext()) { + JCheckBox capturedBox = capturedBoxes.next(); + JCheckBox ransomedBox = ransomedBoxes.next(); + if (capturedBox.isSelected()) { + ransomedBox.setSelected(true); + } + } + } + + /** * Rolls the dice to determine if the opposition personnel is captured. * @@ -1168,34 +1195,6 @@ private void switchPanel(String name) { cardLayout.show(pnlMain, currentPanel); switchInstructions(); - switch (name) { - case PILOTPANEL: - pnlMain.setPreferredSize(pnlPilotStatus.getLayout().preferredLayoutSize(pnlMain)); - break; - case UNITSPANEL: - pnlMain.setPreferredSize(pnlUnitStatus.getLayout().preferredLayoutSize(pnlMain)); - break; - case SALVAGEPANEL: - pnlMain.setPreferredSize(pnlSalvage.getLayout().preferredLayoutSize(pnlMain)); - break; - case KILLPANEL: - pnlMain.setPreferredSize(pnlKills.getLayout().preferredLayoutSize(pnlMain)); - break; - case REWARDPANEL: - pnlMain.setPreferredSize(pnlRewards.getLayout().preferredLayoutSize(pnlMain)); - break; - case PREVIEWPANEL: - pnlMain.setPreferredSize(pnlPreview.getLayout().preferredLayoutSize(pnlMain)); - break; - case OBJECTIVEPANEL: - pnlMain.setPreferredSize(pnlObjectiveStatus.getLayout().preferredLayoutSize(pnlMain)); - break; - case PRISONERPANEL: - pnlMain.setPreferredSize(pnlPrisonerStatus.getLayout().preferredLayoutSize(pnlMain)); - break; - } - - SwingUtilities.invokeLater(() -> scrMain.getVerticalScrollBar().setValue(0)); pack(); } @@ -1236,8 +1235,6 @@ private void switchInstructions() { txtInstructions.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(resourceMap.getString("txtInstructions.title")), BorderFactory.createEmptyBorder(5, 5, 5, 5))); - txtInstructions.setMinimumSize(new Dimension(590, 150)); - txtInstructions.setPreferredSize(new Dimension(590, 150)); getContentPane().add(txtInstructions, BorderLayout.PAGE_START); } @@ -1754,7 +1751,7 @@ private void showPerson(PersonStatus status, boolean isPrisoner) { gridBagConstraints.weighty = 1.0; //scroll panel - JScrollPane scrollPersonnelView = new JScrollPane(); + JScrollPane scrollPersonnelView = new JScrollPaneWithSpeed(); scrollPersonnelView.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPersonnelView.setViewportView(personViewPanel); dialog.getContentPane().add(scrollPersonnelView, gridBagConstraints); @@ -1768,8 +1765,8 @@ private void showPerson(PersonStatus status, boolean isPrisoner) { gridBagConstraints.fill = GridBagConstraints.NONE; dialog.getContentPane().add(btn, gridBagConstraints); - dialog.setMinimumSize(new Dimension(600, 300)); - dialog.setPreferredSize(new Dimension(600, 300)); + dialog.setMinimumSize(UIUtil.scaleForGUI(450, 700)); + dialog.setPreferredSize(UIUtil.scaleForGUI(450, 700)); dialog.validate(); dialog.setLocationRelativeTo(frame); dialog.setVisible(true); diff --git a/MekHQ/src/mekhq/gui/dialog/RetirementDefectionDialog.java b/MekHQ/src/mekhq/gui/dialog/RetirementDefectionDialog.java index 2587831b00..f6b90d0c17 100644 --- a/MekHQ/src/mekhq/gui/dialog/RetirementDefectionDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/RetirementDefectionDialog.java @@ -45,6 +45,7 @@ import mekhq.gui.sorter.FormattedNumberSorter; import mekhq.gui.sorter.PersonRankStringSorter; import mekhq.gui.sorter.WeightClassSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.JSpinner.DefaultEditor; @@ -280,7 +281,7 @@ private void initComponents(boolean doRetirement) { }); setBonusAndShareTotals(getTotalBonus()); - JScrollPane scroll = new JScrollPane(); + JScrollPane scroll = new JScrollPaneWithSpeed(); scroll.setViewportView(personnelTable); scroll.setPreferredSize(new Dimension(500, 500)); panOverview.add(scroll, BorderLayout.CENTER); @@ -394,7 +395,7 @@ private void initComponents(boolean doRetirement) { JPanel panResults = new JPanel(); panResults.setLayout(new BoxLayout(panResults, BoxLayout.X_AXIS)); - JScrollPane scroll = new JScrollPane(); + JScrollPane scroll = new JScrollPaneWithSpeed(); scroll.setViewportView(retireeTable); panResults.add(scroll); JPanel panAddRemoveBtns = new JPanel(); @@ -409,7 +410,7 @@ private void initComponents(boolean doRetirement) { panAddRemoveBtns.add(btnRemoveUnit); panResults.add(panAddRemoveBtns); - scroll = new JScrollPane(); + scroll = new JScrollPaneWithSpeed(); scroll.setViewportView(unitAssignmentTable); panResults.add(scroll); diff --git a/MekHQ/src/mekhq/gui/dialog/ScenarioTemplateEditorDialog.java b/MekHQ/src/mekhq/gui/dialog/ScenarioTemplateEditorDialog.java index dfd3239cd0..3aecc2fdc1 100644 --- a/MekHQ/src/mekhq/gui/dialog/ScenarioTemplateEditorDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/ScenarioTemplateEditorDialog.java @@ -61,6 +61,7 @@ import mekhq.campaign.stratcon.StratconBiomeManifest; import mekhq.gui.FileDialogs; import mekhq.gui.baseComponents.DefaultMHQScrollablePanel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; /** * Handles editing, saving and loading of scenario template definitions. @@ -175,7 +176,7 @@ protected void initComponents() { globalPanel = new DefaultMHQScrollablePanel(frame, "globalPanel", new GridBagLayout()); - JScrollPane globalScrollPane = new JScrollPane(globalPanel); + JScrollPane globalScrollPane = new JScrollPaneWithSpeed(globalPanel); globalScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); globalScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); getContentPane().add(globalScrollPane); @@ -233,7 +234,7 @@ private void setupTopFluff(GridBagConstraints gbc) { txtScenarioBriefing.setEditable(true); txtScenarioBriefing.setLineWrap(true); txtScenarioBriefing.setText(scenarioTemplate.shortBriefing); - JScrollPane scrScenarioBriefing = new JScrollPane(txtScenarioBriefing); + JScrollPane scrScenarioBriefing = new JScrollPaneWithSpeed(txtScenarioBriefing); gbc.gridy++; globalPanel.add(scrScenarioBriefing, gbc); @@ -245,7 +246,7 @@ private void setupTopFluff(GridBagConstraints gbc) { txtLongBriefing.setEditable(true); txtLongBriefing.setLineWrap(true); txtLongBriefing.setText(scenarioTemplate.detailedBriefing); - JScrollPane scrLongBriefing = new JScrollPane(txtLongBriefing); + JScrollPane scrLongBriefing = new JScrollPaneWithSpeed(txtLongBriefing); gbc.gridy++; globalPanel.add(scrLongBriefing, gbc); } @@ -281,7 +282,7 @@ private void setupObjectiveEditUI(GridBagConstraints gbc) { objectiveList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); objectiveList.setVisibleRowCount(5); objectiveList.setFixedCellWidth(400); - objectiveScrollPane = new JScrollPane(); + objectiveScrollPane = new JScrollPaneWithSpeed(); objectiveScrollPane.setViewportView(objectiveList); btnRemoveObjective = new JButton("Remove"); @@ -471,7 +472,7 @@ private void setupForceEditor(GridBagConstraints externalGBC) { lstMuls = new JList<>(); DefaultListModel mulModel = new DefaultListModel<>(); - JScrollPane scrMulList = new JScrollPane(lstMuls); + JScrollPane scrMulList = new JScrollPaneWithSpeed(lstMuls); File mulDir = new File(MHQConstants.STRATCON_MUL_FILES_DIRECTORY); if (mulDir.exists() && mulDir.isDirectory()) { @@ -706,7 +707,7 @@ private void initializeForceList(GridBagConstraints gbc) { renderForceList(); - forceScrollPane = new JScrollPane(panForceList); + forceScrollPane = new JScrollPaneWithSpeed(panForceList); forceScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); forceScrollPane.setVisible(false); @@ -898,7 +899,7 @@ private void setupMapParameters(GridBagConstraints gbc) { selectedModifiersList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); reloadSelectedModifiers(); - JScrollPane modifierScrollPane = new JScrollPane(selectedModifiersList); + JScrollPane modifierScrollPane = new JScrollPaneWithSpeed(selectedModifiersList); modifierScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); pnlMapParameters.add(modifierScrollPane, localGbc); diff --git a/MekHQ/src/mekhq/gui/dialog/StoryArcSelectionDialog.java b/MekHQ/src/mekhq/gui/dialog/StoryArcSelectionDialog.java index dc54e265ca..bddb96bd46 100644 --- a/MekHQ/src/mekhq/gui/dialog/StoryArcSelectionDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/StoryArcSelectionDialog.java @@ -22,6 +22,7 @@ import mekhq.campaign.storyarc.StoryArcStub; import mekhq.gui.baseComponents.AbstractMHQButtonDialog; import mekhq.gui.panes.StoryArcSelectionPane; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.MarkdownRenderer; import javax.swing.*; @@ -86,7 +87,7 @@ protected Container createCenterPane() { descriptionPane.setMinimumSize(new Dimension(400, 400)); descriptionPane.setPreferredSize(new Dimension(400, 400)); descriptionPane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); - mainPanel.add(new JScrollPane(descriptionPane)); + mainPanel.add(new JScrollPaneWithSpeed(descriptionPane)); return mainPanel; } diff --git a/MekHQ/src/mekhq/gui/dialog/StoryChoiceDialog.java b/MekHQ/src/mekhq/gui/dialog/StoryChoiceDialog.java index df6d24b335..b9492ca2a6 100644 --- a/MekHQ/src/mekhq/gui/dialog/StoryChoiceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/StoryChoiceDialog.java @@ -22,6 +22,7 @@ import mekhq.campaign.storyarc.storypoint.ChoiceStoryPoint; import mekhq.gui.baseComponents.DefaultMHQScrollablePanel; import mekhq.gui.panels.StoryChoicePanel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.MarkdownRenderer; import javax.swing.*; @@ -116,7 +117,7 @@ protected Container getMainPanel() { gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; - JScrollPane scrollPane = new JScrollPane(rightPanel); + JScrollPane scrollPane = new JScrollPaneWithSpeed(rightPanel); scrollPane.setMinimumSize(new Dimension(200, 150)); scrollPane.setPreferredSize(new Dimension(200, 150)); mainPanel.add(scrollPane, gbc); diff --git a/MekHQ/src/mekhq/gui/dialog/StoryNarrativeDialog.java b/MekHQ/src/mekhq/gui/dialog/StoryNarrativeDialog.java index b282e0c044..d040c1477d 100644 --- a/MekHQ/src/mekhq/gui/dialog/StoryNarrativeDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/StoryNarrativeDialog.java @@ -20,6 +20,7 @@ import mekhq.campaign.storyarc.StoryArc; import mekhq.campaign.storyarc.storypoint.NarrativeStoryPoint; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.MarkdownRenderer; import javax.swing.*; @@ -60,7 +61,7 @@ protected Container getMainPanel() { String text = StoryArc.replaceTokens(((NarrativeStoryPoint) getStoryPoint()).getNarrative(), getStoryPoint().getCampaign()); txtDesc.setText(MarkdownRenderer.getRenderedHtml(text)); txtDesc.setCaretPosition(0); - JScrollPane scrollPane = new JScrollPane(txtDesc); + JScrollPane scrollPane = new JScrollPaneWithSpeed(txtDesc); mainPanel.add(scrollPane, gbc); return mainPanel; diff --git a/MekHQ/src/mekhq/gui/dialog/reportDialogs/AbstractReportDialog.java b/MekHQ/src/mekhq/gui/dialog/reportDialogs/AbstractReportDialog.java index a119fc2585..42205a8a90 100644 --- a/MekHQ/src/mekhq/gui/dialog/reportDialogs/AbstractReportDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/reportDialogs/AbstractReportDialog.java @@ -19,6 +19,7 @@ package mekhq.gui.dialog.reportDialogs; import mekhq.gui.baseComponents.AbstractMHQDialog; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.border.EmptyBorder; @@ -39,7 +40,7 @@ protected AbstractReportDialog(final JFrame frame, final String name, final Stri //region Initialization @Override protected Container createCenterPane() { - final JScrollPane scrollPane = new JScrollPane(createTxtReport()); + final JScrollPane scrollPane = new JScrollPaneWithSpeed(createTxtReport()); scrollPane.setBorder(new EmptyBorder(2, 10, 2, 2)); scrollPane.setName("reportPane"); diff --git a/MekHQ/src/mekhq/gui/model/TechTableModel.java b/MekHQ/src/mekhq/gui/model/TechTableModel.java index ca1869162e..dc0e018618 100644 --- a/MekHQ/src/mekhq/gui/model/TechTableModel.java +++ b/MekHQ/src/mekhq/gui/model/TechTableModel.java @@ -136,7 +136,9 @@ public String getTechDesc(Person tech, boolean overtimeAllowed, IPartWork part) } toReturn.append("
"); - toReturn.append(String.format("%d minutes left", tech.getMinutesLeft())); + toReturn.append(String.format("%d/%d minutes left", tech.getMinutesLeft(), + tech.getDailyAvailableTechTime())); + if (overtimeAllowed) { toReturn.append(String.format(" + (%d overtime)", tech.getOvertimeLeft())); } diff --git a/MekHQ/src/mekhq/gui/model/UnitTableModel.java b/MekHQ/src/mekhq/gui/model/UnitTableModel.java index 274f537894..616880dc8f 100644 --- a/MekHQ/src/mekhq/gui/model/UnitTableModel.java +++ b/MekHQ/src/mekhq/gui/model/UnitTableModel.java @@ -227,37 +227,37 @@ public Object getValueAt(int row, int col) { return ""; } - Unit u = getUnit(row); - Entity e = u.getEntity(); - if (e == null) { + Unit unit = getUnit(row); + Entity entity = unit.getEntity(); + if (entity == null) { return "?"; } return switch (col) { - case COL_NAME -> u.getName(); - case COL_TYPE -> UnitType.getTypeDisplayableName(e.getUnitType()); - case COL_WCLASS -> e.getWeightClassName(); - case COL_TECH -> TechConstants.getLevelDisplayableName(e.getTechLevel()); - case COL_WEIGHT -> e.getWeight(); - case COL_COST -> u.getSellValue().toAmountAndSymbolString(); - case COL_STATUS -> u.getStatus(); - case COL_CONDITION -> u.getCondition(); - case COL_CREW_STATE -> u.getCrewState(); - case COL_QUALITY -> u.getQualityName(); - case COL_PILOT -> (u.getCommander() != null) ? u.getCommander().getHTMLTitle() : "-"; + case COL_NAME -> unit.getName(); + case COL_TYPE -> unit.getTypeDisplayableNameWithOmni(); + case COL_WCLASS -> entity.getWeightClassName(); + case COL_TECH -> TechConstants.getLevelDisplayableName(entity.getTechLevel()); + case COL_WEIGHT -> entity.getWeight(); + case COL_COST -> unit.getSellValue().toAmountAndSymbolString(); + case COL_STATUS -> unit.getStatus(); + case COL_CONDITION -> unit.getCondition(); + case COL_CREW_STATE -> unit.getCrewState(); + case COL_QUALITY -> unit.getQualityName(); + case COL_PILOT -> (unit.getCommander() != null) ? unit.getCommander().getHTMLTitle() : "-"; case COL_FORCE -> { - Force force = u.getCampaign().getForce(u.getForceId()); + Force force = unit.getCampaign().getForce(unit.getForceId()); yield (force != null) ? force.getFullName() : "-"; } - case COL_CREW -> u.getActiveCrew().size() + "/" + u.getFullCrewSize(); - case COL_TECH_CRW -> (u.getTech() != null) ? u.getTech().getHTMLTitle() : "-"; - case COL_MAINTAIN -> u.getMaintenanceCost().toAmountAndSymbolString(); - case COL_BV -> e.calculateBattleValue(true, u.getEntity().getCrew() == null); - case COL_REPAIR -> u.getPartsNeedingFixing().size(); - case COL_PARTS -> u.getPartsNeeded().size(); - case COL_SITE -> Unit.getSiteName(u.getSite()); - case COL_QUIRKS -> e.countQuirks(); - case COL_RSTATUS -> u.isSalvage() ? "Strip" : "Repair"; + case COL_CREW -> unit.getActiveCrew().size() + "/" + unit.getFullCrewSize(); + case COL_TECH_CRW -> (unit.getTech() != null) ? unit.getTech().getHTMLTitle() : "-"; + case COL_MAINTAIN -> unit.getMaintenanceCost().toAmountAndSymbolString(); + case COL_BV -> entity.calculateBattleValue(true, unit.getEntity().getCrew() == null); + case COL_REPAIR -> unit.getPartsNeedingFixing().size(); + case COL_PARTS -> unit.getPartsNeeded().size(); + case COL_SITE -> Unit.getSiteName(unit.getSite()); + case COL_QUIRKS -> entity.countQuirks(); + case COL_RSTATUS -> unit.isSalvage() ? "Strip" : "Repair"; default -> "?"; }; } diff --git a/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java b/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java index 4f8d17f232..220086d9a5 100644 --- a/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java +++ b/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java @@ -73,6 +73,7 @@ import mekhq.gui.dialog.iconDialogs.UnitIconDialog; import mekhq.gui.displayWrappers.FactionDisplay; import mekhq.gui.panels.RandomOriginOptionsPanel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.module.PersonnelMarketServiceManager; import mekhq.module.api.PersonnelMarketMethod; @@ -888,7 +889,7 @@ private JScrollPane createGeneralTab() { gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; panGeneral.add(btnIcon, gridBagConstraints); - return new JScrollPane(panGeneral); + return new JScrollPaneWithSpeed(panGeneral); } private JScrollPane createRepairAndMaintenanceTab() { @@ -1170,7 +1171,7 @@ private JScrollPane createRepairAndMaintenanceTab() { gridBagConstraints.weighty = 1.0; panSubMaintenance.add(logMaintenance, gridBagConstraints); - return new JScrollPane(panRepair); + return new JScrollPaneWithSpeed(panRepair); } private JScrollPane createSuppliesAndAcquisitionsTab() { @@ -1542,7 +1543,7 @@ private JScrollPane createSuppliesAndAcquisitionsTab() { gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; panSubPlanetAcquire.add(panSocioIndustrialBonus, gridBagConstraints); - return new JScrollPane(panSupplies); + return new JScrollPaneWithSpeed(panSupplies); } private JScrollPane createTechLimitsTab() { @@ -1675,7 +1676,7 @@ private JScrollPane createTechLimitsTab() { gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; panTech.add(useAmmoByTypeBox, gridBagConstraints); - return new JScrollPane(panTech); + return new JScrollPaneWithSpeed(panTech); } private JScrollPane createFinancesTab(boolean reverseQualities) { @@ -1905,7 +1906,7 @@ public Component getListCellRendererComponent(JList list, Object value, int i gridBagConstraints.gridheight = 20; panFinances.add(createSharesPanel(), gridBagConstraints); - return new JScrollPane(panFinances); + return new JScrollPaneWithSpeed(panFinances); } private JScrollPane createMercenaryTab() { @@ -2036,7 +2037,7 @@ private JScrollPane createMercenaryTab() { groupContract.add(btnContractEquipment); groupContract.add(btnContractPersonnel); - return new JScrollPane(panMercenary); + return new JScrollPaneWithSpeed(panMercenary); } private JScrollPane createExperienceTab() { @@ -2395,7 +2396,7 @@ private JScrollPane createExperienceTab() { tableXP.setColumnSelectionAllowed(false); tableXP.setCellSelectionEnabled(true); tableXP.setShowGrid(true); - final JScrollPane scrXP = new JScrollPane(tableXP); + final JScrollPane scrXP = new JScrollPaneWithSpeed(tableXP); scrXP.setMinimumSize(new Dimension(500, ((tableXP.getRowCount() * 25) + 50))); scrXP.setPreferredSize(new Dimension(500, ((tableXP.getRowCount() * 25) + 50))); JTable rowTable = new RowNamesTable(tableXP); @@ -2415,7 +2416,7 @@ private JScrollPane createExperienceTab() { gridBagConstraints.insets = new Insets(5, 5, 5, 5); panXP.add(scrXP, gridBagConstraints); - return new JScrollPane(panXP); + return new JScrollPaneWithSpeed(panXP); } private JScrollPane createSkillsTab() { @@ -2498,7 +2499,7 @@ private JScrollPane createSkillsTab() { gridBagConstraints.gridy++; } - final JScrollPane scrSkill = new JScrollPane(panSkill); + final JScrollPane scrSkill = new JScrollPaneWithSpeed(panSkill); scrSkill.setPreferredSize(new Dimension(500, 400)); return scrSkill; } @@ -2521,7 +2522,7 @@ private JScrollPane createSpecialAbilitiesTab() { recreateSPAPanel(!getUnusedSPA().isEmpty()); - JScrollPane scrSPA = new JScrollPane(panSpecialAbilities); + JScrollPane scrSPA = new JScrollPaneWithSpeed(panSpecialAbilities); scrSPA.setPreferredSize(new Dimension(500, 400)); return scrSPA; } @@ -2791,7 +2792,7 @@ private JScrollPane createSkillRandomizationTab() { gridBagConstraints.insets = new Insets(5, 5, 5, 5); panRandomSkill.add(panOtherBonuses, gridBagConstraints); - JScrollPane scrRandomSkill = new JScrollPane(panRandomSkill); + JScrollPane scrRandomSkill = new JScrollPaneWithSpeed(panRandomSkill); scrRandomSkill.setPreferredSize(new Dimension(500, 400)); return scrRandomSkill; } @@ -2940,7 +2941,7 @@ private JScrollPane createNameAndPortraitGenerationTab() { gridBagConstraints.anchor = GridBagConstraints.WEST; panNameGen.add(chkAssignPortraitOnRoleChange, gridBagConstraints); - return new JScrollPane(panNameGen); + return new JScrollPaneWithSpeed(panNameGen); } private JScrollPane createAgainstTheBotTab() { @@ -3470,7 +3471,7 @@ private JScrollPane createAgainstTheBotTab() { gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; panSubAtBScenario.add(panScenarioMod, gridBagConstraints); - JScrollPane scrAtB = new JScrollPane(panAtB); + JScrollPane scrAtB = new JScrollPaneWithSpeed(panAtB); scrAtB.setPreferredSize(new Dimension(500, 410)); return scrAtB; } @@ -3534,7 +3535,7 @@ private JScrollPane createPersonnelTab() { gbc.gridwidth = 2; personnelPanel.add(createSalaryPanel(), gbc); - final JScrollPane scrollPersonnel = new JScrollPane(personnelPanel); + final JScrollPane scrollPersonnel = new JScrollPaneWithSpeed(personnelPanel); scrollPersonnel.setPreferredSize(new Dimension(500, 400)); return scrollPersonnel; @@ -3570,7 +3571,7 @@ private JScrollPane createTurnoverAndRetentionTab() { gbc.gridx++; turnoverAndRetentionPanel.add(createTurnoverAndRetentionUnitCohesionPanel(), gbc); - final JScrollPane scrollPersonnel = new JScrollPane(turnoverAndRetentionPanel); + final JScrollPane scrollPersonnel = new JScrollPaneWithSpeed(turnoverAndRetentionPanel); scrollPersonnel.setPreferredSize(new Dimension(500, 400)); return scrollPersonnel; @@ -3627,7 +3628,7 @@ private JScrollPane createLifePathsPanel() { gbc.gridwidth = 2; lifePathsPanel.add(createDeathPanel(), gbc); - final JScrollPane scrollLifePaths = new JScrollPane(lifePathsPanel); + final JScrollPane scrollLifePaths = new JScrollPaneWithSpeed(lifePathsPanel); scrollLifePaths.setPreferredSize(new Dimension(400, 400)); return scrollLifePaths; @@ -4039,7 +4040,7 @@ public Component getListCellRendererComponent(final JList list, final Object txtAwardSetFilterList.setName("txtAwardSetFilterList"); txtAwardSetFilterList.setText(""); - JScrollPane scrollAwardSetFilterList = new JScrollPane(txtAwardSetFilterList); + JScrollPane scrollAwardSetFilterList = new JScrollPaneWithSpeed(txtAwardSetFilterList); scrollAwardSetFilterList.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollAwardSetFilterList.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); @@ -7734,7 +7735,7 @@ private JScrollPane createMarketsTab() { gbc.gridy++; marketsPanel.add(createUnitMarketPanel(), gbc); - JScrollPane scrollMarkets = new JScrollPane(marketsPanel); + JScrollPane scrollMarkets = new JScrollPaneWithSpeed(marketsPanel); scrollMarkets.setPreferredSize(new Dimension(500, 400)); return scrollMarkets; @@ -8161,7 +8162,7 @@ private JScrollPane createRATTab() { btnUseStaticRATs.setSelected(true); btnUseStaticRATs.doClick(); - return new JScrollPane(panel); + return new JScrollPaneWithSpeed(panel); } private void createTraditionalRATPanel(final JDisableablePanel panel) { diff --git a/MekHQ/src/mekhq/gui/panes/RankSystemsPane.java b/MekHQ/src/mekhq/gui/panes/RankSystemsPane.java index 130375b69d..0ce95b83f0 100644 --- a/MekHQ/src/mekhq/gui/panes/RankSystemsPane.java +++ b/MekHQ/src/mekhq/gui/panes/RankSystemsPane.java @@ -37,6 +37,7 @@ import mekhq.gui.baseComponents.SortedComboBoxModel; import mekhq.gui.dialog.CustomRankSystemCreationDialog; import mekhq.gui.model.RankTableModel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.GroupLayout.Alignment; @@ -311,7 +312,7 @@ private JScrollPane createRanksTablePane() { } // Create the Scroll Pane - final JScrollPane pane = new JScrollPane(getRanksTable()); + final JScrollPane pane = new JScrollPaneWithSpeed(getRanksTable()); pane.setName("ranksTableScrollPane"); pane.setMinimumSize(new Dimension(1200, 400)); pane.setPreferredSize(new Dimension(1200, 500)); diff --git a/MekHQ/src/mekhq/gui/panes/UnitMarketPane.java b/MekHQ/src/mekhq/gui/panes/UnitMarketPane.java index 7856fb8b68..bacf267f7e 100644 --- a/MekHQ/src/mekhq/gui/panes/UnitMarketPane.java +++ b/MekHQ/src/mekhq/gui/panes/UnitMarketPane.java @@ -54,6 +54,7 @@ import mekhq.gui.baseComponents.AbstractMHQSplitPane; import mekhq.gui.model.UnitMarketTableModel; import mekhq.gui.sorter.WeightClassSorter; +import mekhq.gui.utilities.JScrollPaneWithSpeed; public class UnitMarketPane extends AbstractMHQSplitPane { private static final MMLogger logger = MMLogger.create(UnitMarketPane.class); @@ -347,7 +348,7 @@ private JScrollPane createMarketTablePane() { !getCampaign().getCampaignOptions().isInstantUnitMarketDelivery()); getMarketTable().getSelectionModel().addListSelectionListener(evt -> updateDisplay()); - final JScrollPane marketTableScrollPane = new JScrollPane(getMarketTable(), + final JScrollPane marketTableScrollPane = new JScrollPaneWithSpeed(getMarketTable(), ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); marketTableScrollPane.setName("marketTableScrollPane"); marketTableScrollPane.setMinimumSize(new Dimension(500, 400)); diff --git a/MekHQ/src/mekhq/gui/sorter/UnitTypeSorter.java b/MekHQ/src/mekhq/gui/sorter/UnitTypeSorter.java index a40a2004f8..6cc8c7022f 100644 --- a/MekHQ/src/mekhq/gui/sorter/UnitTypeSorter.java +++ b/MekHQ/src/mekhq/gui/sorter/UnitTypeSorter.java @@ -29,18 +29,47 @@ */ public class UnitTypeSorter implements Comparator { @Override - public int compare(String s0, String s1) { + public int compare(String compare0, String compare1) { // lets find the weight class integer for each name - int l0 = 0; - int l1 = 0; + int sort0 = 0; + int sort1 = 0; + + // We ONLY get the strings so sorting Omni units (in this case to be after the same + // unit type but otherwise in the same order as this) is going to be a little silly + + boolean omni0 = false; + boolean omni1 = false; + + if (compare0.startsWith("Omni ")) { + omni0 = true; + compare0 = compare0.substring(5); + } else if (compare0.startsWith("Omni")) { + omni0 = true; + compare0 = compare0.substring(4); + } + + if (compare1.startsWith("Omni ")) { + omni1 = true; + compare1 = compare1.substring(5); + } else if (compare1.startsWith("Omni")) { + omni1 = true; + compare1 = compare1.substring(4); + } + for (int i = 0; i <= UnitType.SPACE_STATION; i++) { - if (UnitType.getTypeDisplayableName(i).equals(s0)) { - l0 = i; + if (UnitType.getTypeDisplayableName(i).equals(compare0)) { + sort0 = i * 2; + if (omni0) { + sort0++; + } } - if (UnitType.getTypeDisplayableName(i).equals(s1)) { - l1 = i; + if (UnitType.getTypeDisplayableName(i).equals(compare1)) { + sort1 = i * 2; + if (omni1) { + sort1++; + } } } - return ((Comparable) l1).compareTo(l0); + return ((Comparable) sort1).compareTo(sort0); } } diff --git a/MekHQ/src/mekhq/gui/stratcon/StratconScenarioWizard.java b/MekHQ/src/mekhq/gui/stratcon/StratconScenarioWizard.java index de1869a70b..acfa670d95 100644 --- a/MekHQ/src/mekhq/gui/stratcon/StratconScenarioWizard.java +++ b/MekHQ/src/mekhq/gui/stratcon/StratconScenarioWizard.java @@ -32,6 +32,7 @@ import mekhq.campaign.stratcon.StratconScenario.ScenarioState; import mekhq.campaign.stratcon.StratconTrackState; import mekhq.campaign.unit.Unit; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import javax.swing.event.ListSelectionEvent; @@ -270,7 +271,7 @@ private void setLeadershipUI(GridBagConstraints gbc, List eligibleUnits, i */ private JList addAvailableForceList(JPanel parent, GridBagConstraints gbc, ScenarioForceTemplate forceTemplate) { - JScrollPane forceListContainer = new JScrollPane(); + JScrollPane forceListContainer = new JScrollPaneWithSpeed(); ScenarioWizardLanceModel lanceModel; @@ -332,7 +333,7 @@ private JList addIndividualUnitSelector(List units, GridBagConstrain availableUnits.addListSelectionListener( e -> availableUnitSelectorChanged(e, unitSelectionLabel, unitStatusLabel, maxSelectionSize)); - JScrollPane infantryContainer = new JScrollPane(); + JScrollPane infantryContainer = new JScrollPaneWithSpeed(); infantryContainer.setViewportView(availableUnits); localGridBagConstraints.gridy++; unitPanel.add(infantryContainer, localGridBagConstraints); diff --git a/MekHQ/src/mekhq/gui/stratcon/TrackForceAssignmentUI.java b/MekHQ/src/mekhq/gui/stratcon/TrackForceAssignmentUI.java index f0f95fecb9..55bf38c547 100644 --- a/MekHQ/src/mekhq/gui/stratcon/TrackForceAssignmentUI.java +++ b/MekHQ/src/mekhq/gui/stratcon/TrackForceAssignmentUI.java @@ -21,6 +21,7 @@ import mekhq.campaign.stratcon.StratconCoords; import mekhq.campaign.stratcon.StratconRulesManager; import mekhq.gui.StratconPanel; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import javax.swing.*; import java.awt.*; @@ -69,7 +70,7 @@ private void initializeUI() { getContentPane().add(forceAssignmentInstructions, gbc); gbc.gridy++; - JScrollPane forceListContainer = new JScrollPane(); + JScrollPane forceListContainer = new JScrollPaneWithSpeed(); ScenarioWizardLanceModel lanceModel; diff --git a/MekHQ/src/mekhq/gui/utilities/JScrollPaneWithSpeed.java b/MekHQ/src/mekhq/gui/utilities/JScrollPaneWithSpeed.java new file mode 100644 index 0000000000..ee591abc66 --- /dev/null +++ b/MekHQ/src/mekhq/gui/utilities/JScrollPaneWithSpeed.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MekHQ. + * + * MekHQ 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 3 of the License, or + * (at your option) any later version. + * + * MekHQ 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 MekHQ. If not, see . + */ +package mekhq.gui.utilities; + +import java.awt.*; + +import javax.swing.*; + +import megamek.client.ui.swing.GUIPreferences; + +/** + * It's a JScrollPane that manages its scrollspeed based on the UI scale + */ +public class JScrollPaneWithSpeed extends JScrollPane { + final static int BASE_INCREMENT = 16; + + /** + * @see JPanel#JPanel() + */ + public JScrollPaneWithSpeed() { + super(); + setScaleIncrement(); + } + + /** + * @see JPanel#JPanel() + */ + public JScrollPaneWithSpeed(Component view) { + super(view); + setScaleIncrement(); + } + + /** + * @see JPanel#JPanel() + */ + public JScrollPaneWithSpeed(Component view, int vsbPolicy, int hsbPolicy) { + super(view, vsbPolicy, hsbPolicy); + setScaleIncrement(); + } + + /** + * Set the panel's scroll increments based on the UI scale + */ + private void setScaleIncrement() { + float scale = GUIPreferences.getInstance().getGUIScale(); + + int increment = (int) (scale * BASE_INCREMENT); + + getVerticalScrollBar().setUnitIncrement(increment); + getHorizontalScrollBar().setUnitIncrement(increment); + } +} diff --git a/MekHQ/src/mekhq/gui/utilities/JSuggestField.java b/MekHQ/src/mekhq/gui/utilities/JSuggestField.java index 54c4692adb..1e95513219 100644 --- a/MekHQ/src/mekhq/gui/utilities/JSuggestField.java +++ b/MekHQ/src/mekhq/gui/utilities/JSuggestField.java @@ -205,7 +205,7 @@ public void mouseEntered(MouseEvent e) { public void mouseClicked(MouseEvent e) { } }); - d.add(new JScrollPane(list, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + d.add(new JScrollPaneWithSpeed(list, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); d.pack(); addKeyListener(new KeyListener() { diff --git a/MekHQ/src/mekhq/gui/utilities/MarkdownEditorPanel.java b/MekHQ/src/mekhq/gui/utilities/MarkdownEditorPanel.java index 280dba3a01..2e6c617bcd 100644 --- a/MekHQ/src/mekhq/gui/utilities/MarkdownEditorPanel.java +++ b/MekHQ/src/mekhq/gui/utilities/MarkdownEditorPanel.java @@ -19,6 +19,7 @@ package mekhq.gui.utilities; import javax.swing.*; + import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; @@ -65,7 +66,7 @@ public MarkdownEditorPanel(String title) { editor.setEditable(true); editor.setLineWrap(true); editor.setWrapStyleWord(true); - scrollEditor = new JScrollPane(editor); + scrollEditor = new JScrollPaneWithSpeed(editor); scrollEditor.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); //set up buttons @@ -133,7 +134,7 @@ public MarkdownEditorPanel(String title) { viewer = new JTextPane(); viewer.setEditable(false); viewer.setContentType("text/html"); - scrollViewer = new JScrollPane(viewer); + scrollViewer = new JScrollPaneWithSpeed(viewer); scrollViewer.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); tabPane.add("Preview", scrollViewer); diff --git a/MekHQ/src/mekhq/gui/view/MissionViewPanel.java b/MekHQ/src/mekhq/gui/view/MissionViewPanel.java index e74c496aca..a457385ed6 100644 --- a/MekHQ/src/mekhq/gui/view/MissionViewPanel.java +++ b/MekHQ/src/mekhq/gui/view/MissionViewPanel.java @@ -26,6 +26,7 @@ import mekhq.gui.CampaignGUI; import mekhq.gui.baseComponents.JScrollablePanel; import mekhq.gui.enums.MHQTabType; +import mekhq.gui.utilities.JScrollPaneWithSpeed; import mekhq.gui.utilities.MarkdownRenderer; import javax.swing.*; @@ -128,7 +129,7 @@ private void initComponents() { gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; add(pnlStats, gridBagConstraints); - JScrollPane scrollScenarioTable = new JScrollPane(scenarioTable); + JScrollPane scrollScenarioTable = new JScrollPaneWithSpeed(scenarioTable); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; diff --git a/MekHQ/src/mekhq/gui/view/UnitViewPanel.java b/MekHQ/src/mekhq/gui/view/UnitViewPanel.java index 7de9a09f14..4957bcf93d 100644 --- a/MekHQ/src/mekhq/gui/view/UnitViewPanel.java +++ b/MekHQ/src/mekhq/gui/view/UnitViewPanel.java @@ -22,11 +22,9 @@ import megamek.common.Entity; import megamek.common.MekView; import megamek.common.TechConstants; -import megamek.common.UnitType; import mekhq.MekHQ; import mekhq.campaign.Campaign; import mekhq.campaign.unit.Unit; -import mekhq.gui.baseComponents.JScrollablePanel; import mekhq.gui.utilities.ImgLabel; import mekhq.gui.utilities.MarkdownRenderer; @@ -38,7 +36,7 @@ * A custom panel that gets filled in with goodies from a unit record * @author Jay Lawson (jaylawson39 at yahoo.com) */ -public class UnitViewPanel extends JScrollablePanel { +public class UnitViewPanel extends JPanel { private Unit unit; private Entity entity; private Campaign campaign; @@ -184,7 +182,7 @@ private void fillStats(ResourceBundle resourceMap) { pnlStats.setLayout(new GridBagLayout()); lblType.setName("lblType"); - lblType.setText("" + UnitType.getTypeDisplayableName(entity.getUnitType()) + ""); + lblType.setText("" + unit.getTypeDisplayableNameWithOmni() + ""); GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0;