diff --git a/1.0.4 Changelog.txt b/1.0.4 Changelog.txt new file mode 100644 index 0000000..2a40267 --- /dev/null +++ b/1.0.4 Changelog.txt @@ -0,0 +1,27 @@ +1. Fixed NullPointerException in mission refit screens where mousing over forge hullmods caused crash. + +2. Civilian grade check now allows Archean Order Civilian-grade hullmod. + +3. Added a setting to disable civilian-grade requirement. + +4. Corrected hullmod descriptions with regards to "available" carge space requirement, + while in code it was base cargo space stat derived from ShipHullSpecAPI. + + (Changing code to check for modified cargo space is unfeasible due to the nature of refit screen, + which clones ship instances, therefore leading to hard-to-fix wonky behaviour.) + +5. Added a setting to disable cargo space requirement. + + (Adding a setting for disabling hullsize requirement requires extensive rewrite, not something I'm willing to do.) + +6. Enabled Fuel Centrifuge installation on Prometheus-class hulls. + +7. Moved campaign burn abilities incompatibility from tags to code and added a setting to disable it. + Move slowly restriction and sensor profile penalty settings are split and toggled off separately. + +8. Added status lines in ability tooltip that tell whether conversion is working or halted due to insufficient inputs. + + *** + + Important: I do NOT guarantee that your save will be compatible with this update or that there will be no crashes. + It is working fine on my end, but no promises. \ No newline at end of file diff --git a/data/campaign/abilities.csv b/data/campaign/abilities.csv index ec77a18..8ab6e62 100644 --- a/data/campaign/abilities.csv +++ b/data/campaign/abilities.csv @@ -1,2 +1,2 @@ -name,id,type,tags,activationDays,activationCooldown,durationDays,deactivationDays,deactivationCooldown,unlockedAtStart,defaultForAIFleet,musicSuppression,uiOn,uiOff,uiLoop,worldOn,worldOff,worldLoop,icon,plugin,ai,desc,sortOrder -"Forge Production",forge_production,TOGGLE,"burn-, stealth-,sensors+",0.5,,,0.25,1,TRUE,,,ui_neutrino_detector_on,ui_neutrino_detector_off,,system_temporalshell_off,,system_temporalshell_loop,graphics/icons/abilities/forge_production.png,data.forge.abilities.ForgeProduction,,"Control forge production of your fleet.",868 +name,id,type,tags,activationDays,activationCooldown,durationDays,deactivationDays,deactivationCooldown,unlockedAtStart,defaultForAIFleet,musicSuppression,uiOn,uiOff,uiLoop,worldOn,worldOff,worldLoop,icon,plugin,ai,desc,sortOrder +"Forge Production",forge_production,TOGGLE,,0.5,,,0.25,1,TRUE,,,ui_neutrino_detector_on,ui_neutrino_detector_off,,system_temporalshell_off,,system_temporalshell_loop,graphics/icons/abilities/forge_production.png,data.forge.abilities.ForgeProduction,,"Control forge production of your fleet.",868 diff --git a/data/config/settings.json b/data/config/settings.json new file mode 100644 index 0000000..509b294 --- /dev/null +++ b/data/config/settings.json @@ -0,0 +1,27 @@ +{ + "designTypeColors": { + + "Forge":[161, 152, 146, 255] + + }, + + "graphics": { + + "intel": { + + "forge_production_report": "graphics/icons/intel/forge_production_report.png", + + }, + + "hullmods": { + + "ore_refinery_module": "graphics/hullmods/ore_refinery_module.png", + "fuel_centrifuge_module": "graphics/hullmods/fuel_centrifuge_module.png", + "supply_manufacture_module": "graphics/hullmods/supply_manufacture_module.png", + "machinery_assembly_module": "graphics/hullmods/machinery_assembly_module.png", + + } + + } + +} \ No newline at end of file diff --git a/data/hullmods/hull_mods.csv b/data/hullmods/hull_mods.csv index a082297..b7ed766 100644 --- a/data/hullmods/hull_mods.csv +++ b/data/hullmods/hull_mods.csv @@ -1,17 +1,9 @@ -name,id,tier,rarity,tech/manufacturer,tags,uiTags,"base value",unlocked,hidden,hiddenEverywhere,cost_frigate,cost_dest,cost_cruiser,cost_capital,script,desc,short,sprite +name,id,tier,rarity,tech/manufacturer,tags,uiTags,"base value",unlocked,hidden,hiddenEverywhere,cost_frigate,cost_dest,cost_cruiser,cost_capital,script,desc,short,sprite "Ore Refinery",forge_refinery_module,2,"0.8 -",Forge,"req_spaceport, special","Special, Requires Dock",120000,FALSE,FALSE,FALSE,25,25,25,30,data.forge.hullmods.ForgeRefineryModule,"Refits %s/%s available cargo space, depending on hull size, into ore refinery, allowing for production of metal and transplutonics from their raw ores. It requires additional %s/%s crew and %s/%s supplies per month, depending on hull size. - -Installable only on cruisers or capital ships with civilian-grade hull.","Allows refining of ore.",graphics/hullmods/ore_refinery_module.png +",Forge,"req_spaceport, special","Special, Requires Dock",120000,FALSE,FALSE,FALSE,25,25,25,30,data.forge.hullmods.ForgeRefineryModule,"Refits %s/%s base cargo space, depending on hull size, into ore refinery, allowing for production of metal and transplutonics from their raw ores. It requires additional %s/%s crew and %s/%s supplies per month, depending on hull size.","Allows refining of ore.",graphics/hullmods/ore_refinery_module.png "Fuel Centrifuge",forge_centrifuge_module,2,"0.6 -",Forge,"req_spaceport, special","Special, Requires Dock",140000,FALSE,FALSE,FALSE,25,25,25,30,data.forge.hullmods.ForgeCentrifugeModule,"Refits %s/%s available cargo space, depending on hull size, into fuel centrifuge, allowing for production of fuel from volatiles. It requires additional %s/%s crew and %s/%s supplies per month, depending on hull size. - -Installable only on cruisers or capital ships with civilian-grade hull.","Allows centrifuging of volatiles.",graphics/hullmods/fuel_centrifuge_module.png +",Forge,"req_spaceport, special","Special, Requires Dock",140000,FALSE,FALSE,FALSE,25,25,25,30,data.forge.hullmods.ForgeCentrifugeModule,"Refits %s/%s base cargo space, depending on hull size, into fuel centrifuge, allowing for production of fuel from volatiles. It requires additional %s/%s crew and %s/%s supplies per month, depending on hull size.","Allows centrifuging of volatiles.",graphics/hullmods/fuel_centrifuge_module.png "Supply Manufacture",forge_manufacture_module,3,"0.4 -",Forge,"req_spaceport, special","Special, Requires Dock",160000,FALSE,FALSE,FALSE,25,25,25,30,data.forge.hullmods.ForgeManufactureModule,"Refits %s/%s available cargo space, depending on hull size, into supply manufacture, allowing for production of supplies from metal and transplutonics. It requires additional %s/%s crew and %s/%s supplies per month, depending on hull size. - -Installable only on cruisers or capital ships with civilian-grade hull.","Allows manufacturing of supplies",graphics/hullmods/supply_manufacture_module.png +",Forge,"req_spaceport, special","Special, Requires Dock",160000,FALSE,FALSE,FALSE,25,25,25,30,data.forge.hullmods.ForgeManufactureModule,"Refits %s/%s base cargo space, depending on hull size, into supply manufacture, allowing for production of supplies from metal and transplutonics. It requires additional %s/%s crew and %s/%s supplies per month, depending on hull size.","Allows manufacturing of supplies",graphics/hullmods/supply_manufacture_module.png "Machinery Assembly",forge_assembly_module,3,"0.2 -",Forge,"req_spaceport, special","Special, Requires Dock",180000,FALSE,FALSE,FALSE,25,25,25,30,data.forge.hullmods.ForgeAssemblyModule,"Refits %s/%s available cargo space, depending on hull size, into machinery assembly, allowing for production of heavy machinery from metal and transplutonics. It requires additional %s/%s crew and %s/%s supplies per month, depending on hull size. - -Installable only on cruisers or capital ships with civilian-grade hull.","Allows assembling of heavy machinery",graphics/hullmods/machinery_assembly_module.png +",Forge,"req_spaceport, special","Special, Requires Dock",180000,FALSE,FALSE,FALSE,25,25,25,30,data.forge.hullmods.ForgeAssemblyModule,"Refits %s/%s base cargo space, depending on hull size, into machinery assembly, allowing for production of heavy machinery from metal and transplutonics. It requires additional %s/%s crew and %s/%s supplies per month, depending on hull size.","Allows assembling of heavy machinery",graphics/hullmods/machinery_assembly_module.png diff --git a/data/world/factions/hegemony.faction b/data/world/factions/hegemony.faction new file mode 100644 index 0000000..cf2e4f1 --- /dev/null +++ b/data/world/factions/hegemony.faction @@ -0,0 +1,10 @@ +{ + "knownHullMods":{ + "hullMods":[ + "forge_refinery_module", + "forge_centrifuge_module", + "forge_manufacture_module", + "forge_assembly_module" + ], + }, +}, \ No newline at end of file diff --git a/data/world/factions/independent.faction b/data/world/factions/independent.faction new file mode 100644 index 0000000..cf2e4f1 --- /dev/null +++ b/data/world/factions/independent.faction @@ -0,0 +1,10 @@ +{ + "knownHullMods":{ + "hullMods":[ + "forge_refinery_module", + "forge_centrifuge_module", + "forge_manufacture_module", + "forge_assembly_module" + ], + }, +}, \ No newline at end of file diff --git a/data/world/factions/persean_league.faction b/data/world/factions/persean_league.faction new file mode 100644 index 0000000..cf2e4f1 --- /dev/null +++ b/data/world/factions/persean_league.faction @@ -0,0 +1,10 @@ +{ + "knownHullMods":{ + "hullMods":[ + "forge_refinery_module", + "forge_centrifuge_module", + "forge_manufacture_module", + "forge_assembly_module" + ], + }, +}, \ No newline at end of file diff --git a/data/world/factions/pirates.faction b/data/world/factions/pirates.faction new file mode 100644 index 0000000..cf2e4f1 --- /dev/null +++ b/data/world/factions/pirates.faction @@ -0,0 +1,10 @@ +{ + "knownHullMods":{ + "hullMods":[ + "forge_refinery_module", + "forge_centrifuge_module", + "forge_manufacture_module", + "forge_assembly_module" + ], + }, +}, \ No newline at end of file diff --git a/data/world/factions/sindrian_diktat.faction b/data/world/factions/sindrian_diktat.faction new file mode 100644 index 0000000..cf2e4f1 --- /dev/null +++ b/data/world/factions/sindrian_diktat.faction @@ -0,0 +1,10 @@ +{ + "knownHullMods":{ + "hullMods":[ + "forge_refinery_module", + "forge_centrifuge_module", + "forge_manufacture_module", + "forge_assembly_module" + ], + }, +}, \ No newline at end of file diff --git a/data/world/factions/tritachyon.faction b/data/world/factions/tritachyon.faction new file mode 100644 index 0000000..cf2e4f1 --- /dev/null +++ b/data/world/factions/tritachyon.faction @@ -0,0 +1,10 @@ +{ + "knownHullMods":{ + "hullMods":[ + "forge_refinery_module", + "forge_centrifuge_module", + "forge_manufacture_module", + "forge_assembly_module" + ], + }, +}, \ No newline at end of file diff --git a/forge_production_settings.ini b/forge_production_settings.ini index 830064d..5c78b1c 100644 --- a/forge_production_settings.ini +++ b/forge_production_settings.ini @@ -1,12 +1,23 @@ { - # Exercise caution when modifying settings variables: balance is fragile. + ####### Installation Settings ####### + + "forge_enable_cargo_requirement": true, + "forge_enable_civgrade_requirement": true, ####### Miscellaneous Settings ####### - # Slow-moving and detected-at-range penalties when forge production is on. + # Slow-moving penalty when forge production is on. + + "forge_enable_slow_move_penalty": true, + + # Detected-at-range penalty when forge production is on. + + "forge_enable_sensor_penalty": true, - "forge_enable_ability_penalties": true, + # Burn abilities are Sustained Burn and Emergency Burn. + + "forge_enable_burn_abilities_incompatibility": true, # Percentage. @@ -21,11 +32,16 @@ "forge_play_sound_notification": true, "forge_show_notification": true, + # Determines style of production report. + # True is inverted grid, while false is basic grid. Default is false. + + "forge_inverted_grid_notification": false, + # In days. Production is still calculated daily. # Results are gathered and cleared when intel is created. # Recommended to set only to values >= 1, default = 3. - "forge_notification_interval": 1, # (Integer) + "forge_notification_interval": 3, # (Integer) ####### Ship Capacity Settings ####### diff --git a/graphics/hullmods/fuel_centrifuge_module.png b/graphics/hullmods/fuel_centrifuge_module.png new file mode 100644 index 0000000..2b7961b Binary files /dev/null and b/graphics/hullmods/fuel_centrifuge_module.png differ diff --git a/graphics/hullmods/machinery_assembly_module.png b/graphics/hullmods/machinery_assembly_module.png new file mode 100644 index 0000000..658d349 Binary files /dev/null and b/graphics/hullmods/machinery_assembly_module.png differ diff --git a/graphics/hullmods/ore_refinery_module.png b/graphics/hullmods/ore_refinery_module.png new file mode 100644 index 0000000..d43ec91 Binary files /dev/null and b/graphics/hullmods/ore_refinery_module.png differ diff --git a/graphics/hullmods/supply_manufacture_module.png b/graphics/hullmods/supply_manufacture_module.png new file mode 100644 index 0000000..7a70372 Binary files /dev/null and b/graphics/hullmods/supply_manufacture_module.png differ diff --git a/graphics/icons/abilities/forge_production.png b/graphics/icons/abilities/forge_production.png new file mode 100644 index 0000000..976e498 Binary files /dev/null and b/graphics/icons/abilities/forge_production.png differ diff --git a/graphics/icons/intel/forge_production_report.png b/graphics/icons/intel/forge_production_report.png new file mode 100644 index 0000000..cf3ee67 Binary files /dev/null and b/graphics/icons/intel/forge_production_report.png differ diff --git a/jars/forge_production.jar b/jars/forge_production.jar new file mode 100644 index 0000000..0c70c53 Binary files /dev/null and b/jars/forge_production.jar differ diff --git a/mod_info.json b/mod_info.json index 5cadb40..a8ebe1e 100644 --- a/mod_info.json +++ b/mod_info.json @@ -1,10 +1,12 @@ -{ - "id":"forge_production", - "name":"Forge Production", - "author":"Ontheheavens", - "version":"1.0.1", - "description":"Hullmods that allow ships to produce commodities with ability toggle.", - "gameVersion":"0.95a-RC15", - "jars":["jars/forge_production.jar"], - "modPlugin":"data.forge.plugins.ForgeModPlugin", +{ + "id":"forge_production", + "name":"Forge Production", + "author":"Ontheheavens", + "version":"1.0.4", + "description":"Hullmods that allow ships to produce commodities with ability toggle.", + "gameVersion": "0.95.1a-RC6", + "jars":["jars/forge_production.jar"], + "modPlugin":"data.forge.plugins.ForgeModPlugin", + "totalConversion": "false", + "utility": "false", } \ No newline at end of file diff --git a/source/data/forge/abilities/ForgeProduction.java b/source/data/forge/abilities/ForgeProduction.java new file mode 100644 index 0000000..54ca523 --- /dev/null +++ b/source/data/forge/abilities/ForgeProduction.java @@ -0,0 +1,271 @@ +package data.forge.abilities; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import com.fs.starfarer.api.characters.AbilityPlugin; +import com.fs.starfarer.api.impl.campaign.ids.Commodities; +import data.forge.abilities.conversion.*; +import data.forge.abilities.conversion.support.ForgeConversionGeneral; +import data.forge.abilities.tooltip.ForgeProductionTooltip; +import data.forge.campaign.ForgeConditionChecker; +import data.forge.plugins.ForgeSettings; +import org.lwjgl.util.vector.Vector2f; +import com.fs.starfarer.api.Global; +import com.fs.starfarer.api.util.Misc; +import com.fs.starfarer.api.util.IntervalUtil; +import com.fs.starfarer.api.ui.LabelAPI; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.campaign.CampaignFleetAPI; +import com.fs.starfarer.api.impl.campaign.abilities.BaseToggleAbility; + +import data.forge.campaign.ForgeProductionReport; + +import static data.forge.campaign.ForgeConditionChecker.*; +import static data.forge.plugins.ForgeSettings.*; +import static data.forge.abilities.conversion.support.ForgeConversionVariables.*; + +public class ForgeProduction extends BaseToggleAbility { + + private static final Vector2f ZERO = new Vector2f(); + + private int notificationCounter = 0; + + private final IntervalUtil productionInterval = new IntervalUtil(1f,1f); + + protected void activateImpl() { + interruptIncompatible(); + } + + @Override + protected String getActivationText() { + return "Commencing forge production"; + } + + protected void applyEffect(float amount, float level) { + + CampaignFleetAPI fleet = getFleet(); + + if (fleet == null) return; + if (!isActive()) return; + + if (ENABLE_DETECT_AT_RANGE_PENALTY) { + fleet.getStats().getDetectedRangeMod().modifyPercent(getModId(), ForgeSettings.SENSOR_PROFILE_INCREASE, "Forge production"); + } + + if (ENABLE_SLOW_MOVE_PENALTY) { + fleet.goSlowOneFrame(); + } + + float days = Global.getSector().getClock().convertToDays(amount); + + productionInterval.advance(days); + + if (productionInterval.intervalElapsed()) { + + ForgeRefiningLogic.startRefining(fleet); + + ForgeCentrifugingLogic.startCentrifuging(fleet); + + ForgeManufacturingLogic.startManufacturing(fleet); + + ForgeAssemblingLogic.startAssembling(fleet); + + if (goodsWereForged()) { + + fleet.addFloatingText("Forged goods", Misc.setAlpha(Misc.getTextColor(), 255), 0.5f); + + if(PLAY_SOUND_NOTIFICATION) { + Global.getSoundPlayer().playSound("ui_cargo_raremetals", 1f, 1f, fleet.getLocation(), ZERO); + } + + clearGoodsStatus(); + } + + if (SHOW_NOTIFICATION && goodsProducedReport()) { + notificationCounter += 1; + } + + boolean notificationCounterElapsed = (notificationCounter >= NOTIFICATION_INTERVAL); + + if (SHOW_NOTIFICATION && (notificationCounterElapsed)) { + ForgeProductionReport intel = new ForgeProductionReport(); + Global.getSector().getIntelManager().addIntel(intel); + notificationCounter = 0; + } + + } + + if (!checkUsableForMachinery()) { + deactivate(); + } + disableIncompatible(); + } + + protected void deactivateImpl() { cleanupImpl(); } + + @Override + protected void cleanupImpl() { + CampaignFleetAPI fleet = getFleet(); + if (fleet == null) return; + + if (ENABLE_DETECT_AT_RANGE_PENALTY) { + fleet.getStats().getDetectedRangeMod().unmodify(getModId()); + } + } + + private boolean checkUsableForMachinery() { + boolean hasMachinery = ForgeConditionChecker.getPlayerCargo(Commodities.HEAVY_MACHINERY) > 0; + return (hasActiveForgeShips() && hasMachinery); + } + + @Override + public boolean isUsable() { + if (!isActivateCooldown && + getProgressFraction() > 0 && getProgressFraction() < 1 && + getDeactivationDays() > 0) return false; + + if (!checkUsableForMachinery()) + return false; + + return super.isUsable(); + } + + @Override + public boolean showActiveIndicator() { return isActive(); } + + @Override + public boolean hasTooltip() { return true; } + + @Override + public float getTooltipWidth() { + return 390f; + } + + @Override + public void createTooltip(TooltipMakerAPI tooltip, boolean expanded) { + + Color gray = Misc.getGrayColor(); + Color highlight = Misc.getHighlightColor(); + + String status = " (off)"; + if (turnedOn) { + status = " (on)"; + } + + LabelAPI title = tooltip.addTitle(this.spec.getName() + status); + title.highlightLast(status); + title.setHighlightColor(highlight); + + String percentageCR = "10%"; + String percentageMachinery = "10%"; + + float pad = 6f; + tooltip.addPara("Control forge production of your fleet and monitor fleet forging capacity.", pad); + if (!expanded) { + tooltip.addPara("Your fleet must have ships with active forge modules to produce goods. " + + "Ships that are mothballed, do not receive repairs or have less than %s CR are unable to use their forge modules. " + + "Production also uses heavy machinery, which must be present but is not consumed, and can break accidentally. " + + "At least %s of total needed machinery must be available to produce goods.", pad, highlight, percentageCR, percentageMachinery); + } + + if (!hasActiveForgeShips() && expanded) { + ForgeProductionTooltip.addCannotForgeNoActiveShips(tooltip); + } + + if (hasActiveForgeShips() && ForgeConversionGeneral.getMachineryAvailability() < 0.1f && expanded) { + ForgeProductionTooltip.addCannotForgeNoMachinery(tooltip); + } + + if (expanded) { + ForgeProductionTooltip.addExpandedInfo(tooltip, this.isActive()); + } + + if (ENABLE_DETECT_AT_RANGE_PENALTY && !expanded) { + tooltip.addPara("Increases the range at which the fleet can be detected by %s.", + pad, highlight, (int) ForgeSettings.SENSOR_PROFILE_INCREASE + "%"); + } + + if (ENABLE_SLOW_MOVE_PENALTY && !expanded) { + tooltip.addPara("Causes the fleet to %s.", + pad, highlight, "move slowly"); + + tooltip.addPara("*A fleet is considered slow-moving at a burn level of half that of its slowest ship.", gray, pad); + } + + if (!hasActiveForgeShips() && !expanded) { + ForgeProductionTooltip.addCannotForgeNoActiveShips(tooltip); + } + + if (hasActiveForgeShips() && ForgeConversionGeneral.getMachineryAvailability() < 0.1f && !expanded) { + ForgeProductionTooltip.addCannotForgeNoMachinery(tooltip); + } + + addIncompatibleToTooltip(tooltip, expanded); + } + + @Override + protected void addIncompatibleToTooltip(TooltipMakerAPI tooltip, boolean expanded) { + addIncompatibleToTooltip(tooltip, "Incompatible with the following abilities:", + "Expand tooltip to view production specifics and conflicting abilities", + expanded); + } + + @Override + protected boolean isCompatible(AbilityPlugin other) { + if(!ENABLE_BURN_ABILITIES_INCOMPATIBILITY) + return true; + if (other.getId().equals("sustained_burn") || other.getId().equals("emergency_burn")) { + return false; + } + return true; + } + + @Override + public List getInterruptedList() { + List result = new ArrayList<>(); + CampaignFleetAPI fleet = getFleet(); + if (fleet == null) return result; + for (AbilityPlugin curr : fleet.getAbilities().values()) { + if (curr == this) continue; + if (!isCompatible(curr)) { + result.add(curr); + } + } + Collections.sort(result, new Comparator() { + public int compare(AbilityPlugin o1, AbilityPlugin o2) { + + return o1.getSpec().getSortOrder() - o2.getSpec().getSortOrder(); + } + }); + return result; + } + + @Override + protected void interruptIncompatible() { + CampaignFleetAPI fleet = getFleet(); + if (fleet == null) return; + for (AbilityPlugin curr : fleet.getAbilities().values()) { + if (curr == this) continue; + if (!isCompatible(curr) && curr.isActive()) { + curr.deactivate(); + } + } + } + + @Override + protected void disableIncompatible() { + CampaignFleetAPI fleet = getFleet(); + if (fleet == null) return; + for (AbilityPlugin curr : fleet.getAbilities().values()) { + if (curr == this) continue; + if (!isCompatible(curr)) { + curr.forceDisable(); + } + } + } + +} \ No newline at end of file diff --git a/source/data/forge/abilities/conversion/ForgeAssemblingLogic.java b/source/data/forge/abilities/conversion/ForgeAssemblingLogic.java new file mode 100644 index 0000000..6b2425c --- /dev/null +++ b/source/data/forge/abilities/conversion/ForgeAssemblingLogic.java @@ -0,0 +1,79 @@ +package data.forge.abilities.conversion; + +import com.fs.starfarer.api.campaign.CampaignFleetAPI; +import com.fs.starfarer.api.impl.campaign.ids.Commodities; +import data.forge.abilities.conversion.support.ForgeConversionGeneral; +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; + +import static data.forge.abilities.conversion.support.ForgeConversionVariables.*; +import static data.forge.plugins.ForgeSettings.*; + +public class ForgeAssemblingLogic { + + public static void startAssembling(CampaignFleetAPI fleet) { + + if (ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.ASSEMBLY) <= 1) return; + if (!ForgeConditionChecker.hasMinimumMachinery()) return; + + if (ForgeConditionChecker.getPlayerCargo(Commodities.METALS) > METAL_TO_ASSEMBLE && + ForgeConditionChecker.getPlayerCargo(Commodities.RARE_METALS) > TRANSPLUTONICS_TO_ASSEMBLE) { + assembleMachinery(fleet); + } + + if (heavyMachineryWasAssembled) { + ForgeConversionGeneral.applyForgingCRMalus(fleet, ForgeTypes.ASSEMBLY); + } + + } + + public static void assembleMachinery(CampaignFleetAPI fleet) { + + int machineryAssemblingCycles = ForgeConversionGeneral.getMachineryUsageCycles(ForgeTypes.Conversion.ASSEMBLING, ForgeTypes.ASSEMBLY); + + int assemblingCapacity = ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.ASSEMBLY); + + int metalAssemblingCycles = (int) Math.floor(ForgeConditionChecker.getPlayerCargo(Commodities.METALS) / METAL_TO_ASSEMBLE); + int transplutonicsAssemblingCycles = (int) Math.floor(ForgeConditionChecker.getPlayerCargo(Commodities.RARE_METALS) / TRANSPLUTONICS_TO_ASSEMBLE); + + int assemblingCycles = (int) Math.floor(Math.min(assemblingCapacity, + Math.min(machineryAssemblingCycles, Math.min(metalAssemblingCycles, transplutonicsAssemblingCycles)))); + + boolean willHeavyMachineryBreakdown = ForgeConditionChecker.getMachineryBreakdownChance(); + int MachineryInAssembling = (int) Math.ceil((assemblingCapacity * HEAVY_MACHINERY_ASSEMBLING_USAGE)); + int machineryBroken = 0; + + for (int machineryInCheck = 0; machineryInCheck < MachineryInAssembling; machineryInCheck++) { + if (Math.random() < (BREAKDOWN_SEVERITY * ForgeConditionChecker.getForgingQuality())) + machineryBroken++; + } + + int dailyMetalSpent = (int) Math.ceil(METAL_TO_ASSEMBLE * assemblingCycles); + int dailyTransplutonicsSpent = (int) Math.ceil(TRANSPLUTONICS_TO_ASSEMBLE * assemblingCycles); + int dailyHeavyMachineryProduced = (int) Math.floor((HEAVY_MACHINERY_PRODUCED + ForgeConditionChecker.getNanoforgeAssemblingBonus()) * assemblingCycles); + int dailyHeavyMachineryBroken = machineryBroken; + + fleet.getCargo().removeCommodity(Commodities.METALS, dailyMetalSpent); + fleet.getCargo().removeCommodity(Commodities.RARE_METALS, dailyTransplutonicsSpent); + fleet.getCargo().addCommodity(Commodities.HEAVY_MACHINERY, dailyHeavyMachineryProduced); + if (willHeavyMachineryBreakdown) { + fleet.getCargo().removeCommodity(Commodities.HEAVY_MACHINERY, dailyHeavyMachineryBroken); + } + + totalHeavyMachineryProduction += dailyHeavyMachineryProduced; + if (willHeavyMachineryBreakdown) { + totalMachineryBreakage += dailyHeavyMachineryBroken; + } + + if (willHeavyMachineryBreakdown && dailyHeavyMachineryBroken > 0) { + breakdownReport = true; + } + + if (dailyHeavyMachineryProduced > 0) { + heavyMachineryWasAssembled = true; + heavyMachineryAssemblingReport = true; + } + + } + +} diff --git a/source/data/forge/abilities/conversion/ForgeCentrifugingLogic.java b/source/data/forge/abilities/conversion/ForgeCentrifugingLogic.java new file mode 100644 index 0000000..3d04e48 --- /dev/null +++ b/source/data/forge/abilities/conversion/ForgeCentrifugingLogic.java @@ -0,0 +1,83 @@ +package data.forge.abilities.conversion; + +import com.fs.starfarer.api.campaign.CampaignFleetAPI; +import com.fs.starfarer.api.impl.campaign.ids.Commodities; + +import data.forge.abilities.conversion.support.ForgeConversionGeneral; +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; + +import static data.forge.plugins.ForgeSettings.*; +import static data.forge.abilities.conversion.support.ForgeConversionVariables.*; + +public class ForgeCentrifugingLogic { + + public static void startCentrifuging(CampaignFleetAPI fleet) { + + if (ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.CENTRIFUGE) <= 1) return; + if (!ForgeConditionChecker.hasMinimumMachinery()) return; + if (getPossibleCentrifugingCycles(fleet) < 1) return; + + if (ForgeConditionChecker.getPlayerCargo(Commodities.VOLATILES) > VOLATILES_TO_CENTRIFUGE) { + centrifugeFuel(fleet); + } + + if (fuelWasCentrifuged) { + ForgeConversionGeneral.applyForgingCRMalus(fleet, ForgeTypes.CENTRIFUGE); + } + + } + + public static int getPossibleCentrifugingCycles(CampaignFleetAPI fleet) { + + return (int) Math.floor(fleet.getCargo().getFreeFuelSpace() / (FUEL_PRODUCED + ForgeConditionChecker.getSynchrotronCoreBonus())); + + } + + public static void centrifugeFuel(CampaignFleetAPI fleet) { + + int machineryCentrifugingCycles = ForgeConversionGeneral.getMachineryUsageCycles(ForgeTypes.Conversion.CENTRIFUGING, ForgeTypes.CENTRIFUGE); + + int centrifugingCapacity = ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.CENTRIFUGE); + + int volatilesCentrifugingCycles = (int) Math.floor(ForgeConditionChecker.getPlayerCargo(Commodities.VOLATILES) / VOLATILES_TO_CENTRIFUGE); + + int initialCentrifugingCycles = Math.min(centrifugingCapacity, Math.min(machineryCentrifugingCycles, volatilesCentrifugingCycles)); + + int centrifugingCycles = (int) Math.floor(Math.min(initialCentrifugingCycles, getPossibleCentrifugingCycles(fleet))); + + boolean willHeavyMachineryBreakdown = ForgeConditionChecker.getMachineryBreakdownChance(); + int machineryInCentrifuging = (int) Math.ceil((centrifugingCycles * HEAVY_MACHINERY_CENTRIFUGING_USAGE)); + int machineryBroken = 0; + + for (int machineryInCheck = 0; machineryInCheck < machineryInCentrifuging; machineryInCheck++) { + if (Math.random()<(BREAKDOWN_SEVERITY * ForgeConditionChecker.getForgingQuality())) machineryBroken++; + } + + int dailyVolatilesSpent = (int) Math.ceil(VOLATILES_TO_CENTRIFUGE * centrifugingCycles); + int dailyFuelProduced = (int) Math.floor((FUEL_PRODUCED + ForgeConditionChecker.getSynchrotronCoreBonus()) * centrifugingCycles); + int dailyHeavyMachineryBroken = machineryBroken; + + fleet.getCargo().removeCommodity(Commodities.VOLATILES, dailyVolatilesSpent); + fleet.getCargo().addCommodity(Commodities.FUEL, dailyFuelProduced); + if(willHeavyMachineryBreakdown) { + fleet.getCargo().removeCommodity(Commodities.HEAVY_MACHINERY, dailyHeavyMachineryBroken); + } + + totalFuelProduction += dailyFuelProduced; + if(willHeavyMachineryBreakdown) { + totalMachineryBreakage += dailyHeavyMachineryBroken; + } + + if (willHeavyMachineryBreakdown && dailyHeavyMachineryBroken > 0) { + breakdownReport = true; + } + + if (centrifugingCycles >= 1 && dailyFuelProduced > 0) { + fuelWasCentrifuged = true; + fuelCentrifugingReport = true; + } + + } + +} diff --git a/source/data/forge/abilities/conversion/ForgeManufacturingLogic.java b/source/data/forge/abilities/conversion/ForgeManufacturingLogic.java new file mode 100644 index 0000000..498a4d0 --- /dev/null +++ b/source/data/forge/abilities/conversion/ForgeManufacturingLogic.java @@ -0,0 +1,79 @@ +package data.forge.abilities.conversion; + +import com.fs.starfarer.api.campaign.CampaignFleetAPI; +import com.fs.starfarer.api.impl.campaign.ids.Commodities; +import data.forge.abilities.conversion.support.ForgeConversionGeneral; +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; + +import static data.forge.abilities.conversion.support.ForgeConversionVariables.*; +import static data.forge.plugins.ForgeSettings.*; + +public class ForgeManufacturingLogic { + + public static void startManufacturing(CampaignFleetAPI fleet) { + + if (ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.MANUFACTURE) <= 1) return; + if (!ForgeConditionChecker.hasMinimumMachinery()) return; + + if (ForgeConditionChecker.getPlayerCargo(Commodities.METALS) > METAL_TO_MANUFACTURE && + ForgeConditionChecker.getPlayerCargo(Commodities.RARE_METALS) > TRANSPLUTONICS_TO_MANUFACTURE) { + manufactureSupplies(fleet); + } + + if (suppliesWereManufactured) { + ForgeConversionGeneral.applyForgingCRMalus(fleet, ForgeTypes.MANUFACTURE); + } + + } + + public static void manufactureSupplies(CampaignFleetAPI fleet) { + + int machineryManufacturingCycles = ForgeConversionGeneral.getMachineryUsageCycles(ForgeTypes.Conversion.MANUFACTURING, ForgeTypes.MANUFACTURE); + + int manufacturingCapacity = ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.MANUFACTURE); + + int metalManufacturingCycles = (int) Math.floor(ForgeConditionChecker.getPlayerCargo(Commodities.METALS) / METAL_TO_MANUFACTURE); + int transplutonicsManufacturingCycles = (int) Math.floor(ForgeConditionChecker.getPlayerCargo(Commodities.RARE_METALS) / TRANSPLUTONICS_TO_MANUFACTURE); + + int manufacturingCycles = (int) Math.floor(Math.min(manufacturingCapacity, + Math.min(machineryManufacturingCycles, Math.min(metalManufacturingCycles, transplutonicsManufacturingCycles)))); + + boolean willHeavyMachineryBreakdown = ForgeConditionChecker.getMachineryBreakdownChance(); + int MachineryInManufacturing = (int) Math.ceil((manufacturingCycles * HEAVY_MACHINERY_MANUFACTURING_USAGE)); + int machineryBroken = 0; + + for (int machineryInCheck = 0; machineryInCheck < MachineryInManufacturing; machineryInCheck++) { + if (Math.random() < (BREAKDOWN_SEVERITY * ForgeConditionChecker.getForgingQuality())) + machineryBroken++; + } + + int dailyMetalSpent = (int) Math.ceil(METAL_TO_MANUFACTURE * manufacturingCycles); + int dailyTransplutonicsSpent = (int) Math.ceil(TRANSPLUTONICS_TO_MANUFACTURE * manufacturingCycles); + int dailySuppliesProduced = (int) Math.floor((SUPPLIES_PRODUCED + ForgeConditionChecker.getNanoforgeManufacturingBonus()) * manufacturingCycles); + int dailyHeavyMachineryBroken = machineryBroken; + + fleet.getCargo().removeCommodity(Commodities.METALS, dailyMetalSpent); + fleet.getCargo().removeCommodity(Commodities.RARE_METALS, dailyTransplutonicsSpent); + fleet.getCargo().addCommodity(Commodities.SUPPLIES, dailySuppliesProduced); + if (willHeavyMachineryBreakdown) { + fleet.getCargo().removeCommodity(Commodities.HEAVY_MACHINERY, dailyHeavyMachineryBroken); + } + + totalSuppliesProduction += dailySuppliesProduced; + if (willHeavyMachineryBreakdown) { + totalMachineryBreakage += dailyHeavyMachineryBroken; + } + + if (willHeavyMachineryBreakdown && dailyHeavyMachineryBroken > 0) { + breakdownReport = true; + } + + if (dailySuppliesProduced > 0) { + suppliesWereManufactured = true; + suppliesManufacturingReport = true; + } + + } + +} diff --git a/source/data/forge/abilities/conversion/ForgeRefiningLogic.java b/source/data/forge/abilities/conversion/ForgeRefiningLogic.java new file mode 100644 index 0000000..8b1972c --- /dev/null +++ b/source/data/forge/abilities/conversion/ForgeRefiningLogic.java @@ -0,0 +1,120 @@ +package data.forge.abilities.conversion; + +import com.fs.starfarer.api.campaign.CampaignFleetAPI; +import com.fs.starfarer.api.impl.campaign.ids.Commodities; + +import data.forge.abilities.conversion.support.ForgeConversionGeneral; +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; +import static data.forge.plugins.ForgeSettings.*; +import static data.forge.abilities.conversion.support.ForgeConversionVariables.*; + +public class ForgeRefiningLogic { + + public static void startRefining(CampaignFleetAPI fleet) { + + if (ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.REFINERY) <= 1) return; + if (!ForgeConditionChecker.hasMinimumMachinery()) return; + + if (ForgeConditionChecker.getPlayerCargo(Commodities.ORE) > ORE_TO_REFINE) { + refineOre(fleet); + } + + if (ForgeConditionChecker.getPlayerCargo(Commodities.RARE_ORE) > TRANSPLUTONIC_ORE_TO_REFINE) { + refineTransplutonicOre(fleet); + } + + if (oreWasRefined || transplutonicsWereRefined) { + ForgeConversionGeneral.applyForgingCRMalus(fleet, ForgeTypes.REFINERY); + } + + } + + public static void refineOre(CampaignFleetAPI fleet) { + + int machineryRefiningCycles = ForgeConversionGeneral.getMachineryUsageCycles(ForgeTypes.Conversion.REFINING, ForgeTypes.REFINERY); + + int refiningCapacity = ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.REFINERY); + + int oreRefiningCycles = (int) Math.floor(ForgeConditionChecker.getPlayerCargo(Commodities.ORE)/ ORE_TO_REFINE); + + int refiningCycles = (int) Math.floor(Math.min(refiningCapacity, Math.min(machineryRefiningCycles, oreRefiningCycles))); + + boolean willHeavyMachineryBreakdown = ForgeConditionChecker.getMachineryBreakdownChance(); + int MachineryInRefining = (int) Math.ceil((refiningCycles * HEAVY_MACHINERY_REFINING_USAGE)); + int machineryBroken = 0; + + for (int machineryInCheck = 0; machineryInCheck < MachineryInRefining; machineryInCheck++) { + if (Math.random()<(BREAKDOWN_SEVERITY * ForgeConditionChecker.getForgingQuality())) machineryBroken++; + } + + int dailyOreSpent = (int) Math.ceil(ORE_TO_REFINE * refiningCycles); + int dailyMetalProduced = (int) Math.floor((METAL_PRODUCED + ForgeConditionChecker.getCatalyticCoreBonus()) * refiningCycles); + int dailyHeavyMachineryBroken = machineryBroken; + + fleet.getCargo().removeCommodity(Commodities.ORE, dailyOreSpent); + fleet.getCargo().addCommodity(Commodities.METALS, dailyMetalProduced); + if(willHeavyMachineryBreakdown) { + fleet.getCargo().removeCommodity(Commodities.HEAVY_MACHINERY, dailyHeavyMachineryBroken); + } + + totalMetalProduction += dailyMetalProduced; + if(willHeavyMachineryBreakdown) { + totalMachineryBreakage += dailyHeavyMachineryBroken; + } + + if (willHeavyMachineryBreakdown && dailyHeavyMachineryBroken > 0) { + breakdownReport = true; + } + + if (dailyMetalProduced > 0) { + oreWasRefined = true; + oreRefiningReport = true; + } + + } + + public static void refineTransplutonicOre(CampaignFleetAPI fleet) { + + int machineryRefiningCycles = ForgeConversionGeneral.getMachineryUsageCycles(ForgeTypes.Conversion.REFINING, ForgeTypes.REFINERY); + + int refiningCapacity = ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.REFINERY); + + int transplutonicOreRefiningCycles = (int) Math.floor(ForgeConditionChecker.getPlayerCargo(Commodities.RARE_ORE) / TRANSPLUTONIC_ORE_TO_REFINE); + + int refiningCycles = (int) Math.floor(Math.min(refiningCapacity, Math.min(machineryRefiningCycles, transplutonicOreRefiningCycles))); + + boolean willHeavyMachineryBreakdown = ForgeConditionChecker.getMachineryBreakdownChance(); + int machineryInRefining = (int) Math.ceil((refiningCycles * HEAVY_MACHINERY_REFINING_USAGE)); + int machineryBroken = 0; + + for (int machineryInCheck = 0; machineryInCheck < machineryInRefining; machineryInCheck++) { + if (Math.random()<(BREAKDOWN_SEVERITY * ForgeConditionChecker.getForgingQuality())) machineryBroken++; + } + + int dailyTransplutonicOreSpent = (int) Math.ceil(TRANSPLUTONIC_ORE_TO_REFINE * refiningCycles); + int dailyTransplutonicsProduced = (int) Math.floor((TRANSPLUTONICS_PRODUCED + ForgeConditionChecker.getCatalyticCoreBonus()) * refiningCycles); + int dailyHeavyMachineryBroken = machineryBroken; + + fleet.getCargo().removeCommodity(Commodities.RARE_ORE, dailyTransplutonicOreSpent); + fleet.getCargo().addCommodity(Commodities.RARE_METALS, dailyTransplutonicsProduced); + if(willHeavyMachineryBreakdown) { + fleet.getCargo().removeCommodity(Commodities.HEAVY_MACHINERY, dailyHeavyMachineryBroken); + } + + totalTransplutonicsProduction += dailyTransplutonicsProduced; + if(willHeavyMachineryBreakdown) { + totalMachineryBreakage += dailyHeavyMachineryBroken; + } + + if (willHeavyMachineryBreakdown && dailyHeavyMachineryBroken > 0) { + breakdownReport = true; + } + + if (dailyTransplutonicsProduced > 0) { + transplutonicsWereRefined = true; + transplutonicsRefiningReport = true; + } + } + +} diff --git a/source/data/forge/abilities/conversion/support/ForgeConversionGeneral.java b/source/data/forge/abilities/conversion/support/ForgeConversionGeneral.java new file mode 100644 index 0000000..6b28e01 --- /dev/null +++ b/source/data/forge/abilities/conversion/support/ForgeConversionGeneral.java @@ -0,0 +1,87 @@ +package data.forge.abilities.conversion.support; + +import com.fs.starfarer.api.Global; +import com.fs.starfarer.api.campaign.CampaignFleetAPI; +import com.fs.starfarer.api.fleet.FleetMemberAPI; +import com.fs.starfarer.api.impl.campaign.ids.Commodities; +import data.forge.campaign.ForgeConditionChecker; +import data.forge.plugins.ForgeSettings; + +import static data.forge.hullmods.support.ForgeHullmodsGeneral.shipSizeEffect; +import static data.forge.plugins.ForgeSettings.CR_PRODUCTION_DECAY; + +public class ForgeConversionGeneral { + + public static int getForgingCapacityWithCR(CampaignFleetAPI fleet, String forgeType) { + if (Global.getSector().getPlayerFleet() == null) { return 0; } + int totalForgingCapacity = 0; + for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { + if (!ForgeConditionChecker.isOperational(member)) + continue; + int shipBaseCapacity = shipSizeEffect.get(member.getVariant().getHullSize()); + if (member.getVariant().hasHullMod(forgeType)) + totalForgingCapacity += (int) Math.floor(shipBaseCapacity * + (member.getRepairTracker().getCR() / 0.7f)); + + } + return totalForgingCapacity; + } + + public static void applyForgingCRMalus(CampaignFleetAPI fleet, String forgeType) { + for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { + if ((!ForgeConditionChecker.isOperational(member))) + continue; + if (member.getVariant().hasHullMod(forgeType)) + member.getRepairTracker().applyCREvent(-((CR_PRODUCTION_DECAY * ForgeConditionChecker.getForgingQuality()) * + (member.getRepairTracker().getCR() / 0.7f)), "Forged goods"); + } + } + + public static float getTotalFleetMachineryRequirement(CampaignFleetAPI fleet) { + + float requirementRefining = (ForgeSettings.HEAVY_MACHINERY_REFINING_USAGE * getForgingCapacityWithCR(fleet, ForgeTypes.REFINERY)); + float requirementCentrifuging = (ForgeSettings.HEAVY_MACHINERY_CENTRIFUGING_USAGE * getForgingCapacityWithCR(fleet, ForgeTypes.CENTRIFUGE)); + float requirementManufacturing = (ForgeSettings.HEAVY_MACHINERY_MANUFACTURING_USAGE * getForgingCapacityWithCR(fleet, ForgeTypes.MANUFACTURE)); + float requirementAssembling = (ForgeSettings.HEAVY_MACHINERY_ASSEMBLING_USAGE * getForgingCapacityWithCR(fleet, ForgeTypes.ASSEMBLY)); + + return (requirementRefining + requirementCentrifuging + requirementManufacturing + requirementAssembling); + } + + public static float getMachineryAvailability() { + + if (Global.getSector().getPlayerFleet() == null) { + return 0f; + } + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + + int machineryInCargo = (int) Math.floor(ForgeConditionChecker.getPlayerCargo(Commodities.HEAVY_MACHINERY)); + float machineryRequiredTotal = getTotalFleetMachineryRequirement(fleet); + + float machineryAvailability = machineryInCargo / machineryRequiredTotal; + + if (machineryAvailability > 1f) { + machineryAvailability = 1f; + } + + return machineryAvailability; + } + + public static float getConversionMachineryUsageTotal(CampaignFleetAPI fleet, ForgeTypes.Conversion type, String forgeType) { + + float requirementForConversion = (ForgeTypes.MACHINERY_USAGE.get(type) * getForgingCapacityWithCR(fleet, forgeType)); + float machineryAvailableTotal = getTotalFleetMachineryRequirement(fleet) * getMachineryAvailability(); + float machineryAvailableForOtherConversions = machineryAvailableTotal - (requirementForConversion * getMachineryAvailability()); + + return machineryAvailableTotal - machineryAvailableForOtherConversions; + } + + public static int getMachineryUsageCycles(ForgeTypes.Conversion type, String forgeType) { + + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + + float machineryAvailable = ForgeConversionGeneral.getConversionMachineryUsageTotal(fleet, type, forgeType); + + return (int) Math.floor(machineryAvailable / ForgeTypes.MACHINERY_USAGE.get(type)); + } + +} diff --git a/source/data/forge/abilities/conversion/support/ForgeConversionVariables.java b/source/data/forge/abilities/conversion/support/ForgeConversionVariables.java new file mode 100644 index 0000000..eaf0bc0 --- /dev/null +++ b/source/data/forge/abilities/conversion/support/ForgeConversionVariables.java @@ -0,0 +1,57 @@ +package data.forge.abilities.conversion.support; + +public class ForgeConversionVariables { + + // Here: Production report variables + + public static float totalMetalProduction = 0f; + public static float totalTransplutonicsProduction = 0f; + public static float totalFuelProduction = 0f; + public static float totalSuppliesProduction = 0f; + public static float totalHeavyMachineryProduction = 0f; + + public static float totalMachineryBreakage = 0f; + + public static boolean breakdownReport = false; + + // Here: Daily floating/sound notification variables + + public static boolean oreWasRefined = false; + public static boolean transplutonicsWereRefined = false; + public static boolean fuelWasCentrifuged = false; + public static boolean suppliesWereManufactured = false; + public static boolean heavyMachineryWasAssembled = false; + + public static boolean goodsWereForged () { + return oreWasRefined || + transplutonicsWereRefined || + fuelWasCentrifuged || + suppliesWereManufactured || + heavyMachineryWasAssembled; + } + + public static void clearGoodsStatus () { + oreWasRefined = false; + transplutonicsWereRefined = false; + fuelWasCentrifuged = false; + suppliesWereManufactured = false; + heavyMachineryWasAssembled = false; + } + + // Here: Detailed intel report variables + + public static boolean oreRefiningReport = false; + public static boolean transplutonicsRefiningReport = false; + public static boolean fuelCentrifugingReport = false; + public static boolean suppliesManufacturingReport = false; + public static boolean heavyMachineryAssemblingReport = false; + + public static boolean goodsProducedReport () { + return oreRefiningReport || + transplutonicsRefiningReport || + fuelCentrifugingReport || + suppliesManufacturingReport || + heavyMachineryAssemblingReport; + } + +} diff --git a/source/data/forge/abilities/conversion/support/ForgeTypes.java b/source/data/forge/abilities/conversion/support/ForgeTypes.java new file mode 100644 index 0000000..b2117e2 --- /dev/null +++ b/source/data/forge/abilities/conversion/support/ForgeTypes.java @@ -0,0 +1,30 @@ +package data.forge.abilities.conversion.support; + +import data.forge.plugins.ForgeSettings; + +import java.util.HashMap; +import java.util.Map; + +public class ForgeTypes { + + public static final String REFINERY = "forge_refinery_module"; + public static final String CENTRIFUGE = "forge_centrifuge_module"; + public static final String MANUFACTURE = "forge_manufacture_module"; + public static final String ASSEMBLY = "forge_assembly_module"; + + public enum Conversion { + REFINING, + CENTRIFUGING, + MANUFACTURING, + ASSEMBLING, + } + + public static final Map MACHINERY_USAGE = new HashMap<>(); + static { + MACHINERY_USAGE.put(Conversion.REFINING, ForgeSettings.HEAVY_MACHINERY_REFINING_USAGE); + MACHINERY_USAGE.put(Conversion.CENTRIFUGING, ForgeSettings.HEAVY_MACHINERY_CENTRIFUGING_USAGE); + MACHINERY_USAGE.put(Conversion.MANUFACTURING, ForgeSettings.HEAVY_MACHINERY_MANUFACTURING_USAGE); + MACHINERY_USAGE.put(Conversion.ASSEMBLING, ForgeSettings.HEAVY_MACHINERY_ASSEMBLING_USAGE); + } + +} diff --git a/source/data/forge/abilities/tooltip/ForgeProductionTooltip.java b/source/data/forge/abilities/tooltip/ForgeProductionTooltip.java new file mode 100644 index 0000000..5df75d4 --- /dev/null +++ b/source/data/forge/abilities/tooltip/ForgeProductionTooltip.java @@ -0,0 +1,132 @@ +package data.forge.abilities.tooltip; + +import java.awt.*; +import java.util.List; +import java.util.LinkedList; +import java.util.ArrayList; +import java.util.Collections; + +import com.fs.starfarer.api.Global; +import com.fs.starfarer.api.campaign.CampaignFleetAPI; +import com.fs.starfarer.api.fleet.FleetMemberAPI; +import com.fs.starfarer.api.impl.campaign.ids.Commodities; +import com.fs.starfarer.api.impl.campaign.ids.Items; +import com.fs.starfarer.api.ui.Alignment; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.util.Misc; + +import data.forge.campaign.ForgeConditionChecker; + +import static data.forge.campaign.ForgeConditionChecker.*; + +public class ForgeProductionTooltip { + + public static void addCannotForgeNoActiveShips(TooltipMakerAPI tooltip) { + float pad = 6f; + Color negativeHighlight = Misc.getNegativeHighlightColor(); + tooltip.addPara("Your fleet currently cannot conduct forging operations: no active forge ships.", negativeHighlight, pad); + } + + public static void addCannotForgeNoMachinery(TooltipMakerAPI tooltip) { + float pad = 6f; + Color negativeHighlight = Misc.getNegativeHighlightColor(); + if (ForgeConditionChecker.getPlayerCargo(Commodities.HEAVY_MACHINERY) > 0) { + tooltip.addPara("Production halted: insufficient machinery.", negativeHighlight, pad); + } else { + tooltip.addPara("Your fleet currently cannot conduct forging operations: no machinery available.", negativeHighlight, pad); + } + } + + public static void addExpandedInfo(TooltipMakerAPI tooltip, boolean isActive) { + + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + + if (hasActiveForgeShips()) { + ForgeTooltipShips.addOperationalShipsBreakdown(tooltip); + } + + if (hasInactiveForgeShips()) { + ForgeTooltipShips.addInactiveShipsBreakdown(tooltip); + } + + if (ForgeConditionChecker.hasAnyForgingCapacity(fleet) && ForgeConditionChecker.getPlayerCargo(Commodities.HEAVY_MACHINERY) >= 1) { + ForgeTooltipBreakdown.addProductionBreakdown(tooltip, isActive); + } + + if (ForgeConditionChecker.hasAnySpecialItem()) { + ForgeProductionTooltip.addSpecialItemsBreakdown(tooltip); + } + + } + + public static void addSpecialItemsBreakdown(TooltipMakerAPI tooltip) { + + float pad = 10f; + tooltip.addSectionHeading("Special effects", Alignment.MID, pad); + tooltip.addSpacer(4f); + + if (ForgeConditionChecker.hasSpecialItem(Items.CORRUPTED_NANOFORGE)) { + ForgeTooltipItems.addCorruptedNanoforgeNote(tooltip); + } + + if (ForgeConditionChecker.hasSpecialItem(Items.PRISTINE_NANOFORGE)) { + ForgeTooltipItems.addPristineNanoforgeNote(tooltip); + } + + if (ForgeConditionChecker.hasSpecialItem(Items.CATALYTIC_CORE)) { + ForgeTooltipItems.addCatalyticCoreNote(tooltip); + } + + if (ForgeConditionChecker.hasSpecialItem(Items.SYNCHROTRON)) { + ForgeTooltipItems.addSynchrotronCoreNote(tooltip); + } + + } + + protected static List getOperationalForgeShipsList() { + return getForgeShipsWithActivity(true); + } + + protected static List getInactiveForgeShipsList() { + return getForgeShipsWithActivity(false); + } + + protected static List getForgeShipsWithActivity(boolean isActiveCheck) { + List forgeHullMods = new ArrayList<>();{ + forgeHullMods.add("forge_refinery_module"); + forgeHullMods.add("forge_centrifuge_module"); + forgeHullMods.add("forge_manufacture_module"); + forgeHullMods.add("forge_assembly_module");} + List membersWithHullMod = new LinkedList<>(); + CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet(); + for (FleetMemberAPI forgeShip : playerFleet.getFleetData().getMembersListCopy()) { + if (isActiveCheck ^ isOperational(forgeShip)) { + continue;} + if (!Collections.disjoint(forgeShip.getVariant().getHullMods(), forgeHullMods)) + membersWithHullMod.add(forgeShip); + } + return membersWithHullMod; + } + + protected static String getForgeHullmodOfForgeShip(FleetMemberAPI member) { + + if (member.getVariant().hasHullMod("forge_refinery_module")) { + return "Refinery"; + } + + if (member.getVariant().hasHullMod("forge_centrifuge_module")) { + return "Centrifuge"; + } + + if (member.getVariant().hasHullMod("forge_manufacture_module")) { + return "Manufacture"; + } + + if (member.getVariant().hasHullMod("forge_assembly_module")) { + return "Assembly"; + } + + return null; + } + +} diff --git a/source/data/forge/abilities/tooltip/ForgeTooltipBreakdown.java b/source/data/forge/abilities/tooltip/ForgeTooltipBreakdown.java new file mode 100644 index 0000000..bf3828e --- /dev/null +++ b/source/data/forge/abilities/tooltip/ForgeTooltipBreakdown.java @@ -0,0 +1,296 @@ +package data.forge.abilities.tooltip; + +import com.fs.starfarer.api.Global; +import com.fs.starfarer.api.campaign.CampaignFleetAPI; +import com.fs.starfarer.api.impl.campaign.ids.Commodities; +import com.fs.starfarer.api.ui.Alignment; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.util.Misc; +import data.forge.abilities.conversion.support.ForgeConversionGeneral; +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; + +import java.awt.*; + +import static data.forge.abilities.conversion.support.ForgeConversionGeneral.getForgingCapacityWithCR; +import static data.forge.abilities.conversion.support.ForgeTypes.*; +import static data.forge.plugins.ForgeSettings.*; + +public class ForgeTooltipBreakdown { + + public static void addProductionBreakdown(TooltipMakerAPI tooltip, boolean isActive) { + + float pad = 10f; + + tooltip.addSectionHeading("Production details", Alignment.MID, pad); + tooltip.addSpacer(3f); + + if (ForgeConditionChecker.hasMinimumMachinery()) { + addMachineryRequirementLine(tooltip, isActive); + + tooltip.addSpacer(3f); + + addProductionValues(tooltip, isActive); + } + + if (!ForgeConditionChecker.hasMinimumMachinery()) { + addInsufficientMachineryLine(tooltip); + } + + } + + private static void addProductionValues(TooltipMakerAPI tooltip, boolean isActive) { + + Color textColor = Misc.getTextColor(); + Color highlightColor = Misc.getHighlightColor(); + Color negativeHighlight = Misc.getNegativeHighlightColor(); + + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + + float pad = 10f; + + int gridSize = 0; + float gridWidth = 185f; + tooltip.beginGridFlipped(gridWidth, 2, 45f, pad); + + String tanksAreFullFormat = " Halted: tanks full"; + if (!isActive) { + tanksAreFullFormat = " Standby: tanks full"; + } + + String noInputsFormat = " Halted: no inputs"; + if (!isActive) { + noInputsFormat = " Standby: no inputs"; + } + String lowInputsFormat = " Working: low inputs"; + if (!isActive) { + lowInputsFormat = "Standby: low inputs"; + } + String workingFormat = " Working"; + if (!isActive) { + workingFormat = " Standby"; + } + + if (getForgingCapacityWithCR(fleet, REFINERY) >= 1) { + + int machineryAvailable = (int) Math.floor(ForgeConversionGeneral.getMachineryUsageCycles(ForgeTypes.Conversion.REFINING, ForgeTypes.REFINERY)); + + int maxMetalProductionCapacity = ((int) Math.floor(Math.min(getForgingCapacityWithCR(fleet, REFINERY), machineryAvailable) * + (METAL_PRODUCED + ForgeConditionChecker.getCatalyticCoreBonus()))); + String metalLabel = "Metal / day"; + + tooltip.addToGrid(0, gridSize++, metalLabel, "+" + Misc.getWithDGS(maxMetalProductionCapacity), highlightColor); + + boolean noOre = ForgeConditionChecker.getPlayerCargo(Commodities.ORE) < ORE_TO_REFINE; + + if (noOre) { + tooltip.setGridLabelColor(negativeHighlight); + tooltip.addToGrid(1, 0, noInputsFormat, "", negativeHighlight); + } else { + tooltip.setGridLabelColor(highlightColor); + tooltip.addToGrid(1, 0, workingFormat, "", highlightColor); + } + tooltip.setGridLabelColor(textColor); + + int maxTransplutonicsProductionCapacity = (int) Math.floor(Math.min(getForgingCapacityWithCR(fleet, REFINERY), machineryAvailable) * + (TRANSPLUTONICS_PRODUCED + ForgeConditionChecker.getCatalyticCoreBonus())); + String transplutonicsLabel = "Transplutonics / day"; + + tooltip.addToGrid(0, gridSize++, transplutonicsLabel, "+" + Misc.getWithDGS(maxTransplutonicsProductionCapacity), highlightColor); + + boolean noTransplutonicOre = ForgeConditionChecker.getPlayerCargo(Commodities.RARE_ORE) < TRANSPLUTONIC_ORE_TO_REFINE; + + if (noTransplutonicOre) { + tooltip.setGridLabelColor(negativeHighlight); + tooltip.addToGrid(1, gridSize - 1, noInputsFormat, "", negativeHighlight); + } else { + tooltip.setGridLabelColor(highlightColor); + tooltip.addToGrid(1, gridSize - 1, workingFormat, "", highlightColor); + } + tooltip.setGridLabelColor(textColor); + + } + + if (getForgingCapacityWithCR(fleet, CENTRIFUGE) >= 1) { + + int machineryAvailable = (int) Math.floor(ForgeConversionGeneral.getMachineryUsageCycles(ForgeTypes.Conversion.CENTRIFUGING, ForgeTypes.CENTRIFUGE)); + + int maxFuelProductionCapacity = (int) Math.floor(Math.min(getForgingCapacityWithCR(fleet, CENTRIFUGE), machineryAvailable) * + (FUEL_PRODUCED + ForgeConditionChecker.getSynchrotronCoreBonus())); + + String fuelLabel = "Fuel / day"; + + tooltip.addToGrid(0, gridSize++, fuelLabel, "+" + Misc.getWithDGS(maxFuelProductionCapacity), highlightColor); + + if (ForgeConditionChecker.areFuelTanksFull(fleet)) { + tooltip.setGridLabelColor(negativeHighlight); + tooltip.addToGrid(1, gridSize - 1, tanksAreFullFormat, "", negativeHighlight); + tooltip.setGridLabelColor(textColor); + } else if (ForgeConditionChecker.getPlayerCargo(Commodities.VOLATILES) < VOLATILES_TO_CENTRIFUGE) { + tooltip.setGridLabelColor(negativeHighlight); + tooltip.addToGrid(1, gridSize - 1, noInputsFormat, "", negativeHighlight); + tooltip.setGridLabelColor(textColor); + } else { + tooltip.setGridLabelColor(highlightColor); + tooltip.addToGrid(1, gridSize - 1, workingFormat, "", highlightColor); + tooltip.setGridLabelColor(textColor); + } + + } + + if (getForgingCapacityWithCR(fleet, MANUFACTURE) >= 1) { + + int machineryAvailable = (int) Math.floor(ForgeConversionGeneral.getMachineryUsageCycles(ForgeTypes.Conversion.MANUFACTURING, ForgeTypes.MANUFACTURE)); + + int maxSuppliesProductionCapacity = (int) Math.floor(Math.min(getForgingCapacityWithCR(fleet, MANUFACTURE), machineryAvailable) * + (SUPPLIES_PRODUCED + ForgeConditionChecker.getNanoforgeManufacturingBonus())); + String suppliesLabel = "Supplies / day"; + + tooltip.addToGrid(0, gridSize++, suppliesLabel, "+" + Misc.getWithDGS(maxSuppliesProductionCapacity), highlightColor); + + boolean noMetal = ForgeConditionChecker.getPlayerCargo(Commodities.METALS) < METAL_TO_MANUFACTURE; + boolean noTransplutonics = ForgeConditionChecker.getPlayerCargo(Commodities.RARE_METALS) < TRANSPLUTONICS_TO_MANUFACTURE; + boolean noInputs = noMetal || noTransplutonics; + + boolean hasRefining = getForgingCapacityWithCR(fleet, REFINERY) >= 1; + boolean hasOre = ForgeConditionChecker.getPlayerCargo(Commodities.ORE) > ORE_TO_REFINE; + boolean hasTransplutonicOre = ForgeConditionChecker.getPlayerCargo(Commodities.RARE_ORE) > TRANSPLUTONIC_ORE_TO_REFINE; + boolean hasRawOres = hasOre && hasTransplutonicOre; + boolean hasOresAndRefining = hasRefining && hasRawOres; + boolean refiningOreOperational = hasRefining && hasOre; + boolean refiningTransplutonicsOperational = hasRefining && hasTransplutonicOre; + boolean hasOneRawAndOneProcessed = (!noMetal && refiningTransplutonicsOperational) + || (!noTransplutonics && refiningOreOperational); + + if (noInputs && !hasOresAndRefining && !hasOneRawAndOneProcessed) { + tooltip.setGridLabelColor(negativeHighlight); + tooltip.addToGrid(1, gridSize - 1, noInputsFormat, "", negativeHighlight); + } else if (noInputs || hasOneRawAndOneProcessed) { + tooltip.setGridLabelColor(highlightColor); + tooltip.addToGrid(1, gridSize - 1, lowInputsFormat, "", highlightColor); + } else { + tooltip.setGridLabelColor(highlightColor); + tooltip.addToGrid(1, gridSize - 1, workingFormat, "", highlightColor); + } + tooltip.setGridLabelColor(textColor); + + } + + if (getForgingCapacityWithCR(fleet, ASSEMBLY) > 0) { + + int machineryAvailable = (int) Math.floor(ForgeConversionGeneral.getMachineryUsageCycles(ForgeTypes.Conversion.ASSEMBLING, ForgeTypes.ASSEMBLY)); + + int maxHeavyMachineryProductionCapacity = (int) Math.floor(Math.min(getForgingCapacityWithCR(fleet, ASSEMBLY), machineryAvailable) * + (HEAVY_MACHINERY_PRODUCED + ForgeConditionChecker.getNanoforgeAssemblingBonus())); + String machineryLabel = "Machinery / day"; + + tooltip.addToGrid(0, gridSize++, machineryLabel, "+" + Misc.getWithDGS(maxHeavyMachineryProductionCapacity), highlightColor); + + boolean noMetal = ForgeConditionChecker.getPlayerCargo(Commodities.METALS) < METAL_TO_ASSEMBLE; + boolean noTransplutonics = ForgeConditionChecker.getPlayerCargo(Commodities.RARE_METALS) < TRANSPLUTONICS_TO_ASSEMBLE; + boolean noInputs = noMetal || noTransplutonics; + + boolean hasRefining = getForgingCapacityWithCR(fleet, REFINERY) >= 1; + boolean hasOre = ForgeConditionChecker.getPlayerCargo(Commodities.ORE) > ORE_TO_REFINE; + boolean hasTransplutonicOre = ForgeConditionChecker.getPlayerCargo(Commodities.RARE_ORE) > TRANSPLUTONIC_ORE_TO_REFINE; + boolean hasRawOres = hasOre && hasTransplutonicOre; + boolean hasOresAndRefining = hasRefining && hasRawOres; + boolean refiningOreOperational = hasRefining && hasOre; + boolean refiningTransplutonicsOperational = hasRefining && hasTransplutonicOre; + boolean hasOneRawAndOneProcessed = (!noMetal && refiningTransplutonicsOperational) + || (!noTransplutonics && refiningOreOperational); + + if (noInputs && !hasOresAndRefining && !hasOneRawAndOneProcessed) { + tooltip.setGridLabelColor(negativeHighlight); + tooltip.addToGrid(1, gridSize - 1, noInputsFormat, "", negativeHighlight); + } else if (noInputs || hasOneRawAndOneProcessed) { + tooltip.setGridLabelColor(highlightColor); + tooltip.addToGrid(1, gridSize - 1, lowInputsFormat, "", highlightColor); + } else { + tooltip.setGridLabelColor(highlightColor); + tooltip.addToGrid(1, gridSize - 1, workingFormat, "", highlightColor); + } + tooltip.setGridLabelColor(textColor); + + } + + tooltip.addGrid(0); + + } + + public static void addMachineryRequirementLine(TooltipMakerAPI tooltip, boolean isActive) { + + Color highlightColor = Misc.getHighlightColor(); + Color negativeHighlight = Misc.getNegativeHighlightColor(); + + float pad = 5f; + + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + + Color [] positiveHighlights = {highlightColor}; + Color [] negativeHighlights = {negativeHighlight, highlightColor, highlightColor}; + + int maxMachineryNeededFinal = (int) Math.ceil(ForgeConversionGeneral.getTotalFleetMachineryRequirement(fleet)); + int heavyMachineryAvailable = (int) fleet.getCargo().getCommodityQuantity(Commodities.HEAVY_MACHINERY); + + int machineryPercentage = (int) (ForgeConversionGeneral.getMachineryAvailability() * 100f); + String machineryUsagePercentage = machineryPercentage + "%"; + + String machineryNeeded = Misc.getWithDGS(maxMachineryNeededFinal); + String machineryAvailable = Misc.getWithDGS(heavyMachineryAvailable); + + String usingOrCanUse = "Using"; + if (!isActive) { + usingOrCanUse = "Can use"; + } + + String demandMetFormat = " all %s needed heavy machinery:"; + String demandNotMetFormat = " %s (out of %s needed, %s ratio) machinery:"; + + tooltip.setBulletedListMode(" "); + + if (heavyMachineryAvailable >= maxMachineryNeededFinal ) { + tooltip.addPara(usingOrCanUse + demandMetFormat, pad, positiveHighlights, machineryNeeded); + } + else { + tooltip.addPara(usingOrCanUse + demandNotMetFormat, pad, negativeHighlights, machineryAvailable, machineryNeeded, machineryUsagePercentage); + } + + tooltip.setBulletedListMode(null); + + } + + public static void addInsufficientMachineryLine(TooltipMakerAPI tooltip) { + + Color highlightColor = Misc.getHighlightColor(); + Color negativeHighlight = Misc.getNegativeHighlightColor(); + + float pad = 5f; + + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + + Color [] tooFewMachineryHighlights = {negativeHighlight, negativeHighlight, highlightColor, negativeHighlight}; + + int maxMachineryNeededFinal = (int) Math.ceil(ForgeConversionGeneral.getTotalFleetMachineryRequirement(fleet)); + int heavyMachineryAvailable = (int) fleet.getCargo().getCommodityQuantity(Commodities.HEAVY_MACHINERY); + + int machineryPercentage = (int) (ForgeConversionGeneral.getMachineryAvailability() * 100f); + String machineryUsagePercentage = machineryPercentage + "%"; + + String machineryNeeded = Misc.getWithDGS(maxMachineryNeededFinal); + String machineryAvailable = Misc.getWithDGS(heavyMachineryAvailable); + String tooFewMachinery = "Production halted:"; + + String tooFewMachineryFormat = "%s only %s (out of %s needed, %s ratio) machinery is available."; + + tooltip.setBulletedListMode(" "); + + if (ForgeConversionGeneral.getMachineryAvailability() > 0 && ForgeConditionChecker.getPlayerCargo(Commodities.HEAVY_MACHINERY) >= 1 ) { + tooltip.addPara(tooFewMachineryFormat, pad, tooFewMachineryHighlights, tooFewMachinery, machineryAvailable, machineryNeeded, machineryUsagePercentage); + } + + tooltip.setBulletedListMode(null); + + } + +} diff --git a/source/data/forge/abilities/tooltip/ForgeTooltipItems.java b/source/data/forge/abilities/tooltip/ForgeTooltipItems.java new file mode 100644 index 0000000..de1d749 --- /dev/null +++ b/source/data/forge/abilities/tooltip/ForgeTooltipItems.java @@ -0,0 +1,138 @@ +package data.forge.abilities.tooltip; + +import com.fs.starfarer.api.Global; +import com.fs.starfarer.api.campaign.CampaignFleetAPI; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.util.Misc; + +import java.awt.*; + +import static data.forge.abilities.conversion.support.ForgeConversionGeneral.getForgingCapacityWithCR; +import static data.forge.abilities.conversion.support.ForgeTypes.*; +import static data.forge.abilities.conversion.support.ForgeTypes.CENTRIFUGE; +import static data.forge.plugins.ForgeSettings.*; +import static data.forge.plugins.ForgeSettings.CATALYTIC_CORE_REFINING_BONUS; + +public class ForgeTooltipItems { + + public static void addCorruptedNanoforgeNote(TooltipMakerAPI tooltip) { + + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + + Color textColor = Misc.getTextColor(); + Color highlightColor = Misc.getHighlightColor(); + float pad = 5f; + + int manufacturingCapacity = (int) Math.ceil(getForgingCapacityWithCR(fleet, MANUFACTURE)); + int assemblingCapacity = (int) Math.ceil(getForgingCapacityWithCR(fleet, ASSEMBLY)); + String manufacturingBonus = Misc.getWithDGS((int) Math.ceil(CORRUPTED_NANOFORGE_MANUFACTURING_BONUS * manufacturingCapacity)); + String assemblingBonus = Misc.getWithDGS((int) Math.ceil(CORRUPTED_NANOFORGE_ASSEMBLING_BONUS * assemblingCapacity)); + String qualityBonus = ((int)(100-(CORRUPTED_NANOFORGE_QUALITY_BONUS*100)) + "%"); + String nanoforge = "Corrupted Nanoforge"; + String formatNoCapacity = "%s increases output of supplies, increases output of heavy machinery, and reduces " + + "breakdowns and CR loss by %s."; + String formatManufacturingCapacity = "%s increases output of supplies by %s, increases output of heavy machinery, and reduces " + + "breakdowns and CR loss by %s."; + String formatAssemblingCapacity = "%s increases output of supplies, increases output of heavy machinery by %s, and reduces " + + "breakdowns and CR loss by %s."; + String formatFullCapacity = "%s increases output of supplies by %s, increases output of heavy machinery by %s, and reduces " + + "breakdowns and CR loss by %s."; + + if (manufacturingCapacity >= 1 && assemblingCapacity < 1) { + tooltip.addPara(formatManufacturingCapacity, pad, textColor, highlightColor, + nanoforge, manufacturingBonus, qualityBonus);} + if (assemblingCapacity >= 1 && manufacturingCapacity < 1) { + tooltip.addPara(formatAssemblingCapacity, pad, textColor, highlightColor, + nanoforge, assemblingBonus, qualityBonus);} + if (manufacturingCapacity >= 1 && assemblingCapacity >= 1) { + tooltip.addPara(formatFullCapacity, pad, textColor, highlightColor, + nanoforge, manufacturingBonus, assemblingBonus, qualityBonus);} + if (manufacturingCapacity < 1 && assemblingCapacity < 1) { + tooltip.addPara(formatNoCapacity, pad, textColor, highlightColor, + nanoforge, qualityBonus);} + + } + + public static void addPristineNanoforgeNote(TooltipMakerAPI tooltip) { + + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + + Color textColor = Misc.getTextColor(); + Color highlightColor = Misc.getHighlightColor(); + float pad = 5f; + + int manufacturingCapacity = (int) Math.ceil(getForgingCapacityWithCR(fleet, MANUFACTURE)); + int assemblingCapacity = (int) Math.ceil(getForgingCapacityWithCR(fleet, ASSEMBLY)); + String manufacturingBonus = Misc.getWithDGS((int) Math.ceil(PRISTINE_NANOFORGE_MANUFACTURING_BONUS * manufacturingCapacity)); + String assemblingBonus = Misc.getWithDGS((int) Math.ceil(PRISTINE_NANOFORGE_ASSEMBLING_BONUS * assemblingCapacity)); + String qualityBonus = ((int)(100-(PRISTINE_NANOFORGE_QUALITY_BONUS*100)) + "%"); + String nanoforge = "Pristine Nanoforge"; + String formatNoCapacity = "%s increases output of supplies, increases output of heavy machinery, and reduces " + + "breakdowns and CR loss by %s."; + String formatManufacturingCapacity = "%s increases output of supplies by %s, increases output of heavy machinery, and reduces " + + "breakdowns and CR loss by %s."; + String formatAssemblingCapacity = "%s increases output of supplies, increases output of heavy machinery by %s, and reduces " + + "breakdowns and CR loss by %s."; + String formatFullCapacity = "%s increases output of supplies by %s, increases output of heavy machinery by %s, and reduces " + + "breakdowns and CR loss by %s."; + + if (manufacturingCapacity >= 1 && assemblingCapacity < 1) { + tooltip.addPara(formatManufacturingCapacity, pad, textColor, highlightColor, + nanoforge, manufacturingBonus, qualityBonus);} + if (assemblingCapacity >= 1 && manufacturingCapacity < 1) { + tooltip.addPara(formatAssemblingCapacity, pad, textColor, highlightColor, + nanoforge, assemblingBonus, qualityBonus);} + if (manufacturingCapacity >= 1 && assemblingCapacity >= 1) { + tooltip.addPara(formatFullCapacity, pad, textColor, highlightColor, + nanoforge, manufacturingBonus, assemblingBonus, qualityBonus);} + if (manufacturingCapacity < 1 && assemblingCapacity < 1) { + tooltip.addPara(formatNoCapacity, pad, textColor, highlightColor, + nanoforge, qualityBonus);} + + } + + public static void addCatalyticCoreNote(TooltipMakerAPI tooltip) { + + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + + Color textColor = Misc.getTextColor(); + Color highlightColor = Misc.getHighlightColor(); + float pad = 5f; + + int fleetCapacity = (int) Math.ceil(getForgingCapacityWithCR(fleet, REFINERY)); + String refiningBonus = Misc.getWithDGS((int) Math.ceil(CATALYTIC_CORE_REFINING_BONUS * fleetCapacity)); + String specialItem = "Catalytic Core"; + + String formatNoCapacity = specialItem + " increases output of metals and transplutonics."; + String formatCapacity = specialItem + " increases output of metals and transplutonics by " + refiningBonus + "."; + + if (fleetCapacity > 0 ) { + tooltip.addPara(formatCapacity, pad, textColor, highlightColor, specialItem, refiningBonus);} + else { + tooltip.addPara(formatNoCapacity, pad, textColor, highlightColor, specialItem);} + + } + + public static void addSynchrotronCoreNote(TooltipMakerAPI tooltip) { + + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + + Color textColor = Misc.getTextColor(); + Color highlightColor = Misc.getHighlightColor(); + float pad = 5f; + + int fleetCapacity = (int) Math.ceil(getForgingCapacityWithCR(fleet, CENTRIFUGE)); + String centrifugingBonus = Misc.getWithDGS((int) Math.ceil(CATALYTIC_CORE_REFINING_BONUS * fleetCapacity)); + String specialItem = "Synchrotron Core"; + + String formatNoCapacity = specialItem + " increases output of fuel."; + String formatCapacity = specialItem + " increases output of fuel by " + centrifugingBonus + "."; + + if (fleetCapacity > 0 ) { + tooltip.addPara(formatCapacity, pad, textColor, highlightColor, specialItem, centrifugingBonus);} + else { + tooltip.addPara(formatNoCapacity, pad, textColor, highlightColor, specialItem);} + + } + +} diff --git a/source/data/forge/abilities/tooltip/ForgeTooltipShips.java b/source/data/forge/abilities/tooltip/ForgeTooltipShips.java new file mode 100644 index 0000000..121322b --- /dev/null +++ b/source/data/forge/abilities/tooltip/ForgeTooltipShips.java @@ -0,0 +1,115 @@ +package data.forge.abilities.tooltip; + +import data.forge.abilities.ForgeProduction; +import data.forge.plugins.ForgeSettings; + +import com.fs.starfarer.api.fleet.FleetMemberAPI; +import com.fs.starfarer.api.ui.Alignment; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.util.Misc; + +import java.awt.*; +import java.util.List; + +import static data.forge.plugins.ForgeSettings.SHIP_LIST_SIZE; + +public class ForgeTooltipShips { + public static void addOperationalShipsBreakdown(TooltipMakerAPI tooltip) { + + Color textColor = Misc.getTextColor(); + Color highlightColor = Misc.getHighlightColor(); + + String indent = " "; + float pad = 10f; + + tooltip.addSectionHeading("Operational ships", Alignment.MID, pad); + tooltip.addSpacer(6f); + + java.util.List forgeShips = ForgeProductionTooltip.getOperationalForgeShipsList(); + + int counter = 1; + int rowNumber = 0; + int displayThatMany = SHIP_LIST_SIZE; + int shipsOverTooltipCap = forgeShips.size() - displayThatMany; + + tooltip.beginGrid(380f, 1, textColor); + + for (FleetMemberAPI member : forgeShips) { + + if (counter > displayThatMany) { + break; + } + + String shipName = member.getShipName(); + String shipNameShort = tooltip.shortenString(shipName, 175); + String shipClass = member.getHullSpec().getHullNameWithDashClass(); + String forgeModule = ForgeProductionTooltip.getForgeHullmodOfForgeShip(member); + + String label = indent + shipNameShort + ", " + shipClass; + + tooltip.addToGrid(0, rowNumber++, label, forgeModule, highlightColor); + + counter++; + + } + + tooltip.addGrid(1); + + if ((counter > displayThatMany) && !(shipsOverTooltipCap == 0)) { + String shipsOverCapString = String.valueOf(shipsOverTooltipCap); + String format = " ...and %s more."; + tooltip.addPara(format, 3, textColor, highlightColor, shipsOverCapString); + } + + } + + + public static void addInactiveShipsBreakdown(TooltipMakerAPI tooltip) { + + Color negativeHighlightColor = Misc.getNegativeHighlightColor(); + Color grayColor = Misc.getGrayColor(); + Color highlightColor = Misc.getHighlightColor(); + + String indent = " "; + float pad = 10f; + + tooltip.addSectionHeading("Inactive ships", Alignment.MID, pad); + tooltip.addSpacer(6f); + + List forgeShips = ForgeProductionTooltip.getInactiveForgeShipsList(); + + int counter = 1; + int rowNumber = 0; + int displayThatMany = SHIP_LIST_SIZE; + int shipsOverTooltipCap = forgeShips.size() - displayThatMany; + + tooltip.beginGrid(380f, 1, grayColor); + + for (FleetMemberAPI member : forgeShips) { + + if (counter > displayThatMany) { + break; + } + + String shipName = member.getShipName(); + String shipNameShort = tooltip.shortenString(shipName, 175); + String shipClass = member.getHullSpec().getHullNameWithDashClass(); + String forgeModule = ForgeProductionTooltip.getForgeHullmodOfForgeShip(member); + + String label = indent + shipNameShort + ", " + shipClass; + + tooltip.addToGrid(0, rowNumber++, label, forgeModule, negativeHighlightColor); + counter++; + + } + + tooltip.addGrid(3); + + if ((counter > displayThatMany) && !(shipsOverTooltipCap == 0)) { + String shipsOverCapString = String.valueOf(shipsOverTooltipCap); + String format = " ...and %s more."; + tooltip.addPara(format, 3, grayColor, highlightColor, shipsOverCapString); + } + } + +} diff --git a/source/data/forge/campaign/ForgeConditionChecker.java b/source/data/forge/campaign/ForgeConditionChecker.java new file mode 100644 index 0000000..18dc288 --- /dev/null +++ b/source/data/forge/campaign/ForgeConditionChecker.java @@ -0,0 +1,194 @@ +package data.forge.campaign; + +import java.util.List; +import java.util.ArrayList; + +import com.fs.starfarer.api.Global; +import com.fs.starfarer.api.campaign.CampaignFleetAPI; +import com.fs.starfarer.api.campaign.CargoAPI; +import com.fs.starfarer.api.campaign.SpecialItemData; +import com.fs.starfarer.api.combat.ShipAPI; +import com.fs.starfarer.api.fleet.FleetMemberAPI; +import com.fs.starfarer.api.impl.campaign.ids.Items; + +import data.forge.abilities.conversion.support.ForgeConversionGeneral; +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.hullmods.support.ForgeHullmodsGeneral; +import data.forge.plugins.ForgeSettings; + +import static data.forge.plugins.ForgeSettings.BASE_BREAKDOWN_CHANCE; +import static data.forge.plugins.ForgeSettings.FUEL_PRODUCED; + +public class ForgeConditionChecker { + + public static boolean getMachineryBreakdownChance() { + return (Math.random()<(BASE_BREAKDOWN_CHANCE * ForgeConditionChecker.getForgingQuality())); + } + + public static boolean areFuelTanksFull(CampaignFleetAPI fleet) { + return fleet.getCargo().getFreeFuelSpace() < (FUEL_PRODUCED + ForgeConditionChecker.getSynchrotronCoreBonus()); + } + + public static boolean hasMinimumMachinery() { + return ForgeConversionGeneral.getMachineryAvailability() >= 0.1f; + } + + public static int getPlayerCargo(String commodity) { + if (Global.getSector().getPlayerFleet() == null) { + return 0; + } + CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); + return Math.round(fleet.getCargo().getCommodityQuantity(commodity)); + } + + public static boolean hasSpecialItem(String specialItemType) { + SpecialItemData specialItem = new SpecialItemData(specialItemType, null); + CargoAPI cargo = Global.getSector().getPlayerFleet().getCargo(); + int specialItemQuantity = (int) Math.ceil(cargo.getQuantity(CargoAPI.CargoItemType.SPECIAL, specialItem)); + return specialItemQuantity > 0; + } + + public static boolean hasAnySpecialItem() { + List specialItems = new ArrayList<>(); + { + specialItems.add(Items.CORRUPTED_NANOFORGE); + specialItems.add(Items.PRISTINE_NANOFORGE); + specialItems.add(Items.CATALYTIC_CORE); + specialItems.add(Items.SYNCHROTRON); + } + for(String specialItem : specialItems) { + if(hasSpecialItem(specialItem)) { + return true; + } + } + return false; + } + + public static float getForgingQuality() { + if (hasSpecialItem(Items.PRISTINE_NANOFORGE)) { + return ForgeSettings.PRISTINE_NANOFORGE_QUALITY_BONUS; + } + if (hasSpecialItem(Items.CORRUPTED_NANOFORGE)) { + return ForgeSettings.CORRUPTED_NANOFORGE_QUALITY_BONUS; + } + return 1f; + } + + public static float getCatalyticCoreBonus() { + if (hasSpecialItem(Items.CATALYTIC_CORE)) { + return ForgeSettings.CATALYTIC_CORE_REFINING_BONUS; + } + return 0f; + } + + public static float getSynchrotronCoreBonus() { + if (hasSpecialItem(Items.SYNCHROTRON)) { + return ForgeSettings.SYNCHROTRON_CORE_CENTRIFUGING_BONUS; + } + return 0f; + } + + public static float getNanoforgeManufacturingBonus() { + if (hasSpecialItem(Items.PRISTINE_NANOFORGE)) { + return ForgeSettings.PRISTINE_NANOFORGE_MANUFACTURING_BONUS; + } + if (hasSpecialItem(Items.CORRUPTED_NANOFORGE)) { + return ForgeSettings.CORRUPTED_NANOFORGE_MANUFACTURING_BONUS; + } + return 0f; + } + + public static float getNanoforgeAssemblingBonus() { + if (hasSpecialItem(Items.PRISTINE_NANOFORGE)) { + return ForgeSettings.PRISTINE_NANOFORGE_ASSEMBLING_BONUS; + } + if (hasSpecialItem(Items.CORRUPTED_NANOFORGE)) { + return ForgeSettings.CORRUPTED_NANOFORGE_ASSEMBLING_BONUS; + } + return 0f; + } + + public static boolean hasAnyForgingCapacity (CampaignFleetAPI fleet) { + return ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.REFINERY) >= 1 || + ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.CENTRIFUGE) >= 1 || + ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.MANUFACTURE) >= 1 || + ForgeConversionGeneral.getForgingCapacityWithCR(fleet, ForgeTypes.ASSEMBLY) >= 1; + } + + + public static boolean hasActiveForgeShips() { + CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet(); + if (playerFleet == null) { + return false; + } + for (FleetMemberAPI member : playerFleet.getMembersWithFightersCopy()) { + if (!isValidHullsize(member) || !isOperational(member)) { + continue; + } + if (isForgeShip(member)) { + return true; + } + } + return false; + } + + public static boolean hasInactiveForgeShips() { + CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet(); + if (playerFleet == null) { + return false; + } + for (FleetMemberAPI member : playerFleet.getMembersWithFightersCopy()) { + if (!isValidHullsize(member)) { + continue; + } + if (isForgeShip(member) && !isOperational(member)) { + return true; + } + } + return false; + } + + public static boolean isOperational(FleetMemberAPI member) { + return !member.getRepairTracker().isMothballed() && + !member.getRepairTracker().isSuspendRepairs() && + hasMinimumCR(member); + } + + public static boolean isOperational(ShipAPI ship) { + return !ship.getFleetMember().getRepairTracker().isMothballed() && + !ship.getFleetMember().getRepairTracker().isSuspendRepairs() && + hasMinimumCR(ship); + } + + public static boolean hasMinimumCR(FleetMemberAPI member) { + return member.getRepairTracker().getCR() > 0.1f; + } + + public static boolean hasMinimumCR(ShipAPI ship) { + return ship.getFleetMember().getRepairTracker().getCR() > 0.1f; + } + + public static boolean isValidHullsize(FleetMemberAPI member) { + return isSize(member, ShipAPI.HullSize.CRUISER) || + isSize(member, ShipAPI.HullSize.CAPITAL_SHIP); + } + + public static boolean isValidHullsize(ShipAPI ship) { + return (ship.getHullSize() == ShipAPI.HullSize.CRUISER || + ship.getHullSize() == ShipAPI.HullSize.CAPITAL_SHIP); + } + + public static boolean isForgeShip(FleetMemberAPI member) { + for (String forgeHullmod : ForgeHullmodsGeneral.ALL_FORGE_HULLMODS) { + if (member.getVariant().getHullMods().contains(forgeHullmod)) { + return true; + } + } + return false; + } + + public static boolean isSize(FleetMemberAPI member, ShipAPI.HullSize hullSize) { + return member.getHullSpec().getHullSize().equals(hullSize); + } + +} diff --git a/source/data/forge/campaign/ForgeProductionReport.java b/source/data/forge/campaign/ForgeProductionReport.java new file mode 100644 index 0000000..5a26657 --- /dev/null +++ b/source/data/forge/campaign/ForgeProductionReport.java @@ -0,0 +1,138 @@ +package data.forge.campaign; + +import java.awt.*; + +import com.fs.starfarer.api.Global; +import com.fs.starfarer.api.util.Misc; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin; + +import data.forge.abilities.conversion.support.ForgeConversionVariables; +import data.forge.plugins.ForgeSettings; + +import static data.forge.plugins.ForgeSettings.NOTIFICATION_INTERVAL; + +public class ForgeProductionReport extends BaseIntelPlugin { + + @Override + public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) { + + Color titleColor = getTitleColor(mode); + + if (NOTIFICATION_INTERVAL > 1) { + info.addPara("Forge Production - " + NOTIFICATION_INTERVAL + " Days Report", titleColor, 0f); + } else if (NOTIFICATION_INTERVAL == 1) { + info.addPara("Forge Production - Daily Report", titleColor, 0f); + } + else { + info.addPara("Forge Production - Report", titleColor, 0f); + } + + info.addSpacer(2.5f); + + addBulletPoints(info, mode); + + clearTemporaryVariables(); + + Global.getSector().getIntelManager().removeIntel(this); + + } + + @Override public String getIcon() { + + return Global.getSettings().getSpriteName("intel", "forge_production_report"); + + } + + protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) { + + Color highlightColor = Misc.getHighlightColor(); + Color negativeHighlight = Misc.getNegativeHighlightColor(); + + float pad = 10f; + int gridSize = 0; + float gridWidth = 190f; + + String metalValue = "+" + Misc.getWithDGS((int) (ForgeConversionVariables.totalMetalProduction)); + String transplutonicsValue = "+" + Misc.getWithDGS((int) (ForgeConversionVariables.totalTransplutonicsProduction)); + String fuelValue = "+" + Misc.getWithDGS((int) (ForgeConversionVariables.totalFuelProduction)); + String suppliesValue = "+" + Misc.getWithDGS((int) (ForgeConversionVariables.totalSuppliesProduction)); + String heavyMachineryValue = "+" + Misc.getWithDGS((int) (ForgeConversionVariables.totalHeavyMachineryProduction)); + + String machineryBreakdownsValue = "-" + Misc.getWithDGS((int) (ForgeConversionVariables.totalMachineryBreakage)); + + String indent = " - "; + + String metalProductionLine = indent + "Metal:"; + String transplutonicsProductionLine = indent + "Transplutonics:"; + String fuelProductionLine = indent + "Fuel:"; + String suppliesProductionLine = indent + "Supplies:"; + String heavyMachineryProductionLine = indent + "Machinery:"; + String machineryBreakdownsLine = indent + "Breakdowns:"; + + if (ForgeSettings.INVERTED_GRID_NOTIFICATION) { + gridWidth = 220f; + metalProductionLine = "Metal produced"; + transplutonicsProductionLine = "Transplutonics produced"; + fuelProductionLine = "Fuel produced"; + suppliesProductionLine = "Supplies produced"; + heavyMachineryProductionLine = "Machinery produced"; + machineryBreakdownsLine = "Machinery broken"; + } + + info.setGridRowHeight(12.5f); + + if (!ForgeSettings.INVERTED_GRID_NOTIFICATION) { + info.beginGrid(gridWidth, 1); + } + + if (ForgeSettings.INVERTED_GRID_NOTIFICATION) { + info.beginGridFlipped(gridWidth, 1, 40f, pad); + } + + if (ForgeConversionVariables.oreRefiningReport) { + info.addToGrid(0, gridSize++, metalProductionLine, metalValue, highlightColor); + } + + if (ForgeConversionVariables.transplutonicsRefiningReport) { + info.addToGrid(0, gridSize++, transplutonicsProductionLine, transplutonicsValue, highlightColor); + } + + if (ForgeConversionVariables.fuelCentrifugingReport) { + info.addToGrid(0, gridSize++, fuelProductionLine, fuelValue, highlightColor); + } + + if (ForgeConversionVariables.suppliesManufacturingReport) { + info.addToGrid(0, gridSize++, suppliesProductionLine, suppliesValue, highlightColor); + } + + if (ForgeConversionVariables.heavyMachineryAssemblingReport) { + info.addToGrid(0, gridSize++, heavyMachineryProductionLine, heavyMachineryValue, highlightColor); + } + + if (ForgeConversionVariables.breakdownReport) { + info.addToGrid(0, gridSize++, machineryBreakdownsLine, machineryBreakdownsValue, negativeHighlight); + } + info.addGrid(2f); + info.resetGridRowHeight(); + } + + public void clearTemporaryVariables() { + + ForgeConversionVariables.totalMetalProduction = 0f; + ForgeConversionVariables.totalTransplutonicsProduction = 0f; + ForgeConversionVariables.totalFuelProduction = 0f; + ForgeConversionVariables.totalSuppliesProduction = 0f; + ForgeConversionVariables.totalHeavyMachineryProduction = 0f; + ForgeConversionVariables.totalMachineryBreakage = 0f; + + ForgeConversionVariables.oreRefiningReport = false; + ForgeConversionVariables.transplutonicsRefiningReport = false; + ForgeConversionVariables.fuelCentrifugingReport = false; + ForgeConversionVariables.suppliesManufacturingReport = false; + ForgeConversionVariables.heavyMachineryAssemblingReport = false; + ForgeConversionVariables.breakdownReport = false; + + } + +} diff --git a/source/data/forge/hullmods/ForgeAssemblyModule.java b/source/data/forge/hullmods/ForgeAssemblyModule.java new file mode 100644 index 0000000..0e92126 --- /dev/null +++ b/source/data/forge/hullmods/ForgeAssemblyModule.java @@ -0,0 +1,186 @@ +package data.forge.hullmods; + +import java.awt.*; +import java.util.HashSet; +import java.util.Set; + +import com.fs.starfarer.api.combat.BaseHullMod; +import com.fs.starfarer.api.combat.MutableShipStatsAPI; +import com.fs.starfarer.api.combat.ShipAPI; +import com.fs.starfarer.api.ui.Alignment; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.util.Misc; + +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; +import data.forge.hullmods.support.ForgeHullmodsTooltip; +import data.forge.plugins.ForgeSettings; + +import static data.forge.hullmods.support.ForgeHullmodsGeneral.*; + +public class ForgeAssemblyModule extends BaseHullMod { + + private static final Set OTHER_FORGE_HULLMODS = new HashSet<>(); + static + { + OTHER_FORGE_HULLMODS.add("forge_refinery_module"); + OTHER_FORGE_HULLMODS.add("forge_centrifuge_module"); + OTHER_FORGE_HULLMODS.add("forge_manufacture_module"); + } + + @Override + public void applyEffectsBeforeShipCreation(ShipAPI.HullSize hullSize, MutableShipStatsAPI stats, String id) { + + if (stats.getVariant().getSMods().contains("forge_assembly_module") || + stats.getVariant().getHullSpec().isBuiltInMod("forge_assembly_module")) { + + float cargoMalus = shipCargoMalus.get(hullSize); + stats.getCargoMod().modifyFlat(id, -cargoMalus); + + float nullifiedMalus = 0f; + stats.getSuppliesPerMonth().modifyFlat(id, nullifiedMalus); + stats.getMinCrewMod().modifyFlat(id, nullifiedMalus); + + } + else { + + float cargoMalus = shipCargoMalus.get(hullSize); + stats.getCargoMod().modifyFlat(id, -cargoMalus); + + float maintenanceIncrease = shipMaintenanceIncrease.get(hullSize); + stats.getSuppliesPerMonth().modifyFlat(id, maintenanceIncrease); + + float skeletonCrew = skeletonCrewRequirement.get(hullSize); + stats.getMinCrewMod().modifyFlat(id, skeletonCrew); + + } + } + + public String getDescriptionParam(int index, ShipAPI.HullSize hullSize) { + if (index == 0) return "" + (shipCargoMalus.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 1) return "" + (shipCargoMalus.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + if (index == 2) return "" + (skeletonCrewRequirement.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 3) return "" + (skeletonCrewRequirement.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + if (index == 4) return "" + (shipMaintenanceIncrease.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 5) return "" + (shipMaintenanceIncrease.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + return null; + } + + + public void addPostDescriptionSection(TooltipMakerAPI tooltip, ShipAPI.HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec) { + + ForgeHullmodsTooltip.addRequirementsLines(tooltip); + + if (ship != null) + { + float pad = 10f; + tooltip.addSectionHeading("Details", Alignment.MID, pad); + + Color highlightColor = Misc.getHighlightColor(); + + boolean isOperational = ForgeConditionChecker.isOperational(ship); + boolean hasMachinery = ForgeConditionChecker.hasMinimumMachinery(); + boolean isInstalled = ship.getVariant().hasHullMod(ForgeTypes.ASSEMBLY); + boolean hasCapacity = getShipCapacityWithCR(ship, hullSize) >= 1; + + int shipModifier = getShipCapacityMod(ship,hullSize, ForgeTypes.Conversion.ASSEMBLING); + + if (!isOperational || !isInstalled) { + shipModifier = shipSizeEffect.get(hullSize); + } + + ForgeHullmodsTooltip.addShipStateNote(tooltip, ship, hullSize, ForgeTypes.ASSEMBLY); + + tooltip.setBulletedListMode(" • "); + + //Here: First line + + Color [] firstLineHighlights = { + highlightColor, highlightColor, highlightColor + }; + + float heavyMachineryValue = ForgeSettings.HEAVY_MACHINERY_PRODUCED * shipModifier; + String heavyMachinery = String.valueOf((int)Math.floor(heavyMachineryValue)); + if (heavyMachineryValue < 1) { + heavyMachinery = String.valueOf((int)Math.ceil(heavyMachineryValue)); + } + + String metal = String.valueOf((int)Math.ceil(ForgeSettings.METAL_TO_ASSEMBLE * shipModifier)); + String transplutonics = String.valueOf((int)Math.ceil(ForgeSettings.TRANSPLUTONICS_TO_ASSEMBLE * shipModifier)); + + String firstLine = "Assembles %s heavy machinery from %s metal and %s transplutonics."; + String firstLineNoCapacity = "Assembles heavy machinery from metal and transplutonics."; + + if (!isOperational) { + tooltip.addPara(firstLine, 4f, firstLineHighlights, heavyMachinery, metal, transplutonics); + } + if (isOperational && hasCapacity && hasMachinery) { + tooltip.addPara(firstLine, 4f, firstLineHighlights, heavyMachinery, metal, transplutonics); + } + if (isOperational && (!hasCapacity || !hasMachinery)) { + tooltip.addPara(firstLineNoCapacity, 4f); + } + + //Here: Second line + + ForgeHullmodsTooltip.addMachineryLine(tooltip, hullSize, ship, ForgeTypes.Conversion.ASSEMBLING, ForgeTypes.ASSEMBLY); + + //Here: Third line + + ForgeHullmodsTooltip.addCRNoteLine(tooltip); + + //Here: Fourth line + + ForgeHullmodsTooltip.addInactiveLine(tooltip); + + tooltip.setBulletedListMode(null); + + //Here: S-Mod lines + + ForgeHullmodsTooltip.addSModLine(tooltip, ship, isForModSpec, ForgeTypes.ASSEMBLY) ; + + } + + } + + @Override + public boolean isApplicableToShip(ShipAPI ship) { + + boolean hasForgeModule = false; + + for (String forgeHullmod : OTHER_FORGE_HULLMODS) { + if(ship.getVariant().getHullMods().contains(forgeHullmod)) { + hasForgeModule = true; + } + } + + return (isForgeHullmodInstallValid(ship) && !hasForgeModule); + + } + + public String getUnapplicableReason(ShipAPI ship) { + if (ship != null && !ForgeConditionChecker.isValidHullsize(ship)) { + return REASON_WRONG_HULLSIZE; + } + if (ship != null && !isCivGrade(ship) && ForgeSettings.ENABLE_CIVGRADE_REQUIREMENT) { + return REASON_NOT_CIVGRADE; + } + if (ship != null && !isNotModule(ship)) { + return REASON_IS_MODULE; + } + if (ship != null && !hasCargoCapacity(ship) && ForgeSettings.ENABLE_CARGO_REQUIREMENT) { + return REASON_NO_CARGO_SPACE; + } + boolean hasForgeModule = false; + for (String forgeHullmod : OTHER_FORGE_HULLMODS) { + if (ship != null && ship.getVariant().getHullMods().contains(forgeHullmod)) { + hasForgeModule = true; + } + } + if (hasForgeModule) { + return REASON_ALREADY_HAS; + } + return null; + } + +} diff --git a/source/data/forge/hullmods/ForgeCentrifugeModule.java b/source/data/forge/hullmods/ForgeCentrifugeModule.java new file mode 100644 index 0000000..2e10113 --- /dev/null +++ b/source/data/forge/hullmods/ForgeCentrifugeModule.java @@ -0,0 +1,191 @@ +package data.forge.hullmods; + +import java.awt.*; +import java.util.Set; +import java.util.HashSet; + +import com.fs.starfarer.api.combat.BaseHullMod; +import com.fs.starfarer.api.combat.MutableShipStatsAPI; +import com.fs.starfarer.api.combat.ShipAPI; +import com.fs.starfarer.api.ui.Alignment; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.util.Misc; + +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; +import data.forge.hullmods.support.ForgeHullmodsTooltip; +import data.forge.plugins.ForgeSettings; + +import static data.forge.hullmods.support.ForgeHullmodsGeneral.*; + +public class ForgeCentrifugeModule extends BaseHullMod { + + private static final Set OTHER_FORGE_HULLMODS = new HashSet<>(); + static + { + OTHER_FORGE_HULLMODS.add("forge_refinery_module"); + OTHER_FORGE_HULLMODS.add("forge_manufacture_module"); + OTHER_FORGE_HULLMODS.add("forge_assembly_module"); + } + + @Override + public void applyEffectsBeforeShipCreation(ShipAPI.HullSize hullSize, MutableShipStatsAPI stats, String id) { + + if (stats.getVariant().getSMods().contains("forge_centrifuge_module") || + stats.getVariant().getHullSpec().isBuiltInMod("forge_centrifuge_module")) { + + float cargoMalus = shipCargoMalus.get(hullSize); + stats.getCargoMod().modifyFlat(id, -cargoMalus); + + float nullifiedMalus = 0f; + stats.getSuppliesPerMonth().modifyFlat(id, nullifiedMalus); + stats.getMinCrewMod().modifyFlat(id, nullifiedMalus); + + } + else { + + float cargoMalus = shipCargoMalus.get(hullSize); + stats.getCargoMod().modifyFlat(id, -cargoMalus); + + float maintenanceIncrease = shipMaintenanceIncrease.get(hullSize); + stats.getSuppliesPerMonth().modifyFlat(id, maintenanceIncrease); + + float skeletonCrew = skeletonCrewRequirement.get(hullSize); + stats.getMinCrewMod().modifyFlat(id, skeletonCrew); + + } + } + + public String getDescriptionParam(int index, ShipAPI.HullSize hullSize) { + if (index == 0) return "" + (shipCargoMalus.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 1) return "" + (shipCargoMalus.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + if (index == 2) return "" + (skeletonCrewRequirement.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 3) return "" + (skeletonCrewRequirement.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + if (index == 4) return "" + (shipMaintenanceIncrease.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 5) return "" + (shipMaintenanceIncrease.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + return null; + } + + + public void addPostDescriptionSection(TooltipMakerAPI tooltip, ShipAPI.HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec) { + + ForgeHullmodsTooltip.addRequirementsLines(tooltip); + + if (ship != null) + { + float pad = 10f; + tooltip.addSectionHeading("Details", Alignment.MID, pad); + + Color highlightColor = Misc.getHighlightColor(); + + boolean isOperational = ForgeConditionChecker.isOperational(ship); + boolean hasMachinery = ForgeConditionChecker.hasMinimumMachinery(); + boolean isInstalled = ship.getVariant().hasHullMod(ForgeTypes.CENTRIFUGE); + boolean hasCapacity = getShipCapacityWithCR(ship, hullSize) >= 1; + + int shipModifier = getShipCapacityMod(ship,hullSize, ForgeTypes.Conversion.CENTRIFUGING); + + if (!isOperational || !isInstalled) { + shipModifier = shipSizeEffect.get(hullSize); + } + + ForgeHullmodsTooltip.addShipStateNote(tooltip, ship, hullSize, ForgeTypes.CENTRIFUGE); + + tooltip.setBulletedListMode(" • "); + + //Here: First line + + Color [] firstLineHighlights = { + highlightColor, highlightColor, highlightColor, highlightColor + }; + + String volatiles = String.valueOf((int)Math.ceil(ForgeSettings.VOLATILES_TO_CENTRIFUGE * shipModifier)); + String fuel = String.valueOf((int)Math.floor(ForgeSettings.FUEL_PRODUCED * shipModifier)); + + String firstLine = "Centrifuges %s fuel from %s volatiles."; + String firstLineNoCapacity = "Centrifuges fuel from volatiles."; + + if (!isOperational) { + tooltip.addPara(firstLine, 4f, firstLineHighlights, fuel, volatiles); + } + if (isOperational && hasCapacity && hasMachinery) { + tooltip.addPara(firstLine, 4f, firstLineHighlights, fuel, volatiles); + } + if (isOperational && (!hasCapacity || !hasMachinery)) { + tooltip.addPara(firstLineNoCapacity, 4f); + } + + //Here: Second line + + ForgeHullmodsTooltip.addMachineryLine(tooltip, hullSize, ship, ForgeTypes.Conversion.CENTRIFUGING, ForgeTypes.CENTRIFUGE); + + //Here: Third line + + ForgeHullmodsTooltip.addCRNoteLine(tooltip); + + //Here: Fourth line + + ForgeHullmodsTooltip.addInactiveLine(tooltip); + + tooltip.setBulletedListMode(null); + + //Here: S-Mod lines + + ForgeHullmodsTooltip.addSModLine(tooltip, ship, isForModSpec, ForgeTypes.CENTRIFUGE) ; + + //Here: Prometheus line + + if (isHullPrometheus(ship) && !isInstalled) { + String prometheusInstall = "Installable on Prometheus-class hulls due to existence of built-in facilities."; + tooltip.addPara(prometheusInstall, Misc.getPositiveHighlightColor(), 2f); + } + } + } + + private boolean isHullPrometheus(ShipAPI ship) { + return ship.getHullSpec().getBaseHullId().equals("prometheus"); + } + + @Override + public boolean isApplicableToShip(ShipAPI ship) { + + boolean hasForgeModule = false; + + for (String forgeHullmod : OTHER_FORGE_HULLMODS) { + if(ship.getVariant().getHullMods().contains(forgeHullmod)) { + hasForgeModule = true; + } + } + + if (isHullPrometheus(ship)) { + return !hasForgeModule; + } + return (isForgeHullmodInstallValid(ship) && !hasForgeModule); + } + + public String getUnapplicableReason(ShipAPI ship) { + if (ship != null && !ForgeConditionChecker.isValidHullsize(ship)) { + return REASON_WRONG_HULLSIZE; + } + if (ship != null && !isCivGrade(ship) && ForgeSettings.ENABLE_CIVGRADE_REQUIREMENT) { + return REASON_NOT_CIVGRADE; + } + if (ship != null && !isNotModule(ship)) { + return REASON_IS_MODULE; + } + if (ship != null && !hasCargoCapacity(ship) && ForgeSettings.ENABLE_CARGO_REQUIREMENT) { + return REASON_NO_CARGO_SPACE; + } + boolean hasForgeModule = false; + for (String forgeHullmod : OTHER_FORGE_HULLMODS) { + if (ship != null && ship.getVariant().getHullMods().contains(forgeHullmod)) { + hasForgeModule = true; + } + } + if (hasForgeModule) { + return REASON_ALREADY_HAS; + } + return null; + } + +} diff --git a/source/data/forge/hullmods/ForgeManufactureModule.java b/source/data/forge/hullmods/ForgeManufactureModule.java new file mode 100644 index 0000000..8002f05 --- /dev/null +++ b/source/data/forge/hullmods/ForgeManufactureModule.java @@ -0,0 +1,186 @@ +package data.forge.hullmods; + +import java.awt.*; +import java.util.HashSet; +import java.util.Set; + +import com.fs.starfarer.api.combat.BaseHullMod; +import com.fs.starfarer.api.combat.MutableShipStatsAPI; +import com.fs.starfarer.api.combat.ShipAPI; +import com.fs.starfarer.api.ui.Alignment; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.util.Misc; + +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; +import data.forge.hullmods.support.ForgeHullmodsTooltip; +import data.forge.plugins.ForgeSettings; + +import static data.forge.hullmods.support.ForgeHullmodsGeneral.*; + +public class ForgeManufactureModule extends BaseHullMod { + + private static final Set OTHER_FORGE_HULLMODS = new HashSet<>(); + static + { + OTHER_FORGE_HULLMODS.add("forge_refinery_module"); + OTHER_FORGE_HULLMODS.add("forge_centrifuge_module"); + OTHER_FORGE_HULLMODS.add("forge_assembly_module"); + } + + @Override + public void applyEffectsBeforeShipCreation(ShipAPI.HullSize hullSize, MutableShipStatsAPI stats, String id) { + + if (stats.getVariant().getSMods().contains("forge_manufacture_module") || + stats.getVariant().getHullSpec().isBuiltInMod("forge_manufacture_module")) { + + float cargoMalus = shipCargoMalus.get(hullSize); + stats.getCargoMod().modifyFlat(id, -cargoMalus); + + float nullifiedMalus = 0f; + stats.getSuppliesPerMonth().modifyFlat(id, -nullifiedMalus); + stats.getMinCrewMod().modifyFlat(id, -nullifiedMalus); + + } + else { + + float cargoMalus = shipCargoMalus.get(hullSize); + stats.getCargoMod().modifyFlat(id, -cargoMalus); + + float maintenanceIncrease = shipMaintenanceIncrease.get(hullSize); + stats.getSuppliesPerMonth().modifyFlat(id, maintenanceIncrease); + + float skeletonCrew = skeletonCrewRequirement.get(hullSize); + stats.getMinCrewMod().modifyFlat(id, skeletonCrew); + + } + } + + public String getDescriptionParam(int index, ShipAPI.HullSize hullSize) { + if (index == 0) return "" + (shipCargoMalus.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 1) return "" + (shipCargoMalus.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + if (index == 2) return "" + (skeletonCrewRequirement.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 3) return "" + (skeletonCrewRequirement.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + if (index == 4) return "" + (shipMaintenanceIncrease.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 5) return "" + (shipMaintenanceIncrease.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + return null; + } + + + public void addPostDescriptionSection(TooltipMakerAPI tooltip, ShipAPI.HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec) { + + ForgeHullmodsTooltip.addRequirementsLines(tooltip); + + if (ship != null) + { + float pad = 10f; + tooltip.addSectionHeading("Details", Alignment.MID, pad); + + Color highlightColor = Misc.getHighlightColor(); + + boolean isOperational = ForgeConditionChecker.isOperational(ship); + boolean hasMachinery = ForgeConditionChecker.hasMinimumMachinery(); + boolean isInstalled = ship.getVariant().hasHullMod(ForgeTypes.MANUFACTURE); + boolean hasCapacity = getShipCapacityWithCR(ship, hullSize) >= 1; + + int shipModifier = getShipCapacityMod(ship,hullSize, ForgeTypes.Conversion.MANUFACTURING); + + if (!isOperational || !isInstalled) { + shipModifier = shipSizeEffect.get(hullSize); + } + + ForgeHullmodsTooltip.addShipStateNote(tooltip, ship, hullSize, ForgeTypes.MANUFACTURE); + + tooltip.setBulletedListMode(" • "); + + //Here: First line + + Color [] firstLineHighlights = { + highlightColor, highlightColor, highlightColor + }; + + float suppliesValue = ForgeSettings.SUPPLIES_PRODUCED * shipModifier; + String supplies = String.valueOf((int)Math.floor(suppliesValue)); + if (suppliesValue < 1) { + supplies = String.valueOf((int)Math.ceil(suppliesValue)); + } + + String metal = String.valueOf((int)Math.ceil(ForgeSettings.METAL_TO_MANUFACTURE * shipModifier)); + String transplutonics = String.valueOf((int)Math.ceil(ForgeSettings.TRANSPLUTONICS_TO_MANUFACTURE * shipModifier)); + + String firstLine = "Manufactures %s supplies from %s metal and %s transplutonics."; + String firstLineNoCapacity = "Manufactures supplies from metal and transplutonics."; + + if (!isOperational) { + tooltip.addPara(firstLine, 4f, firstLineHighlights, supplies, metal, transplutonics); + } + if (isOperational && hasCapacity && hasMachinery) { + tooltip.addPara(firstLine, 4f, firstLineHighlights, supplies, metal, transplutonics); + } + if (isOperational && (!hasCapacity || !hasMachinery)) { + tooltip.addPara(firstLineNoCapacity, 4f); + } + + //Here: Second line + + ForgeHullmodsTooltip.addMachineryLine(tooltip, hullSize, ship, ForgeTypes.Conversion.MANUFACTURING, ForgeTypes.MANUFACTURE); + + //Here: Third line + + ForgeHullmodsTooltip.addCRNoteLine(tooltip); + + //Here: Fourth line + + ForgeHullmodsTooltip.addInactiveLine(tooltip); + + tooltip.setBulletedListMode(null); + + //Here: S-Mod lines + + ForgeHullmodsTooltip.addSModLine(tooltip, ship, isForModSpec, ForgeTypes.MANUFACTURE) ; + + } + + } + + @Override + public boolean isApplicableToShip(ShipAPI ship) { + + boolean hasForgeModule = false; + + for (String forgeHullmod : OTHER_FORGE_HULLMODS) { + if(ship.getVariant().getHullMods().contains(forgeHullmod)) { + hasForgeModule = true; + } + } + + return (isForgeHullmodInstallValid(ship) && !hasForgeModule); + + } + + public String getUnapplicableReason(ShipAPI ship) { + if (ship != null && !ForgeConditionChecker.isValidHullsize(ship)) { + return REASON_WRONG_HULLSIZE; + } + if (ship != null && !isCivGrade(ship) && ForgeSettings.ENABLE_CIVGRADE_REQUIREMENT) { + return REASON_NOT_CIVGRADE; + } + if (ship != null && !isNotModule(ship)) { + return REASON_IS_MODULE; + } + if (ship != null && !hasCargoCapacity(ship) && ForgeSettings.ENABLE_CARGO_REQUIREMENT) { + return REASON_NO_CARGO_SPACE; + } + boolean hasForgeModule = false; + for (String forgeHullmod : OTHER_FORGE_HULLMODS) { + if (ship != null && ship.getVariant().getHullMods().contains(forgeHullmod)) { + hasForgeModule = true; + } + } + if (hasForgeModule) { + return REASON_ALREADY_HAS; + } + return null; + } + +} diff --git a/source/data/forge/hullmods/ForgeRefineryModule.java b/source/data/forge/hullmods/ForgeRefineryModule.java new file mode 100644 index 0000000..6501232 --- /dev/null +++ b/source/data/forge/hullmods/ForgeRefineryModule.java @@ -0,0 +1,188 @@ +package data.forge.hullmods; + +import java.awt.*; +import java.util.Set; +import java.util.HashSet; + +import com.fs.starfarer.api.combat.BaseHullMod; +import com.fs.starfarer.api.combat.MutableShipStatsAPI; +import com.fs.starfarer.api.combat.ShipAPI; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.ui.Alignment; +import com.fs.starfarer.api.util.Misc; + +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; +import data.forge.hullmods.support.ForgeHullmodsTooltip; +import data.forge.plugins.ForgeSettings; + +import static data.forge.hullmods.support.ForgeHullmodsGeneral.*; + +public class ForgeRefineryModule extends BaseHullMod { + + private static final Set OTHER_FORGE_HULLMODS = new HashSet<>(); + static + { + OTHER_FORGE_HULLMODS.add("forge_centrifuge_module"); + OTHER_FORGE_HULLMODS.add("forge_manufacture_module"); + OTHER_FORGE_HULLMODS.add("forge_assembly_module"); + } + + @Override + public void applyEffectsBeforeShipCreation(ShipAPI.HullSize hullSize, MutableShipStatsAPI stats, String id) { + + if (stats.getVariant().getSMods().contains("forge_refinery_module") || + stats.getVariant().getHullSpec().isBuiltInMod("forge_refinery_module")) { + + float cargoMalus = shipCargoMalus.get(hullSize); + stats.getCargoMod().modifyFlat(id, -cargoMalus); + + float nullifiedMalus = 0f; + stats.getSuppliesPerMonth().modifyFlat(id, -nullifiedMalus); + stats.getMinCrewMod().modifyFlat(id, -nullifiedMalus); + + } + else { + + float cargoMalus = shipCargoMalus.get(hullSize); + stats.getCargoMod().modifyFlat(id, -cargoMalus); + + float maintenanceIncrease = shipMaintenanceIncrease.get(hullSize); + stats.getSuppliesPerMonth().modifyFlat(id, maintenanceIncrease); + + float skeletonCrew = skeletonCrewRequirement.get(hullSize); + stats.getMinCrewMod().modifyFlat(id, skeletonCrew); + + } + } + + public String getDescriptionParam(int index, ShipAPI.HullSize hullSize) { + if (index == 0) return "" + (shipCargoMalus.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 1) return "" + (shipCargoMalus.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + if (index == 2) return "" + (skeletonCrewRequirement.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 3) return "" + (skeletonCrewRequirement.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + if (index == 4) return "" + (shipMaintenanceIncrease.get(ShipAPI.HullSize.CRUISER)).intValue(); + if (index == 5) return "" + (shipMaintenanceIncrease.get(ShipAPI.HullSize.CAPITAL_SHIP)).intValue(); + return null; + } + + public void addPostDescriptionSection(TooltipMakerAPI tooltip, ShipAPI.HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec) { + + ForgeHullmodsTooltip.addRequirementsLines(tooltip); + + if (ship != null) + { + float pad = 10f; + tooltip.addSectionHeading("Details", Alignment.MID, pad); + + Color highlightColor = Misc.getHighlightColor(); + + boolean isOperational = ForgeConditionChecker.isOperational(ship); + boolean hasMachinery = ForgeConditionChecker.hasMinimumMachinery(); + boolean isInstalled = ship.getVariant().hasHullMod(ForgeTypes.REFINERY); + boolean hasCapacity = getShipCapacityWithCR(ship, hullSize) >= 1; + + int shipModifier = getShipCapacityMod(ship,hullSize, ForgeTypes.Conversion.REFINING); + + if (!isOperational || !isInstalled) { + shipModifier = shipSizeEffect.get(hullSize); + } + + ForgeHullmodsTooltip.addShipStateNote(tooltip, ship, hullSize, ForgeTypes.REFINERY); + + tooltip.setBulletedListMode(" • "); + + // Here: First line + + Color [] firstLineHighlights = { + highlightColor, highlightColor, highlightColor, highlightColor + }; + + String ore = String.valueOf((int)Math.ceil(ForgeSettings.ORE_TO_REFINE * shipModifier)); + String metal = String.valueOf((int)Math.floor(ForgeSettings.METAL_PRODUCED * shipModifier)); + String transplutonicOre = String.valueOf((int)Math.ceil(ForgeSettings.TRANSPLUTONIC_ORE_TO_REFINE * shipModifier)); + + float transplutonicsValue = ForgeSettings.TRANSPLUTONICS_PRODUCED * shipModifier; + String transplutonics = String.valueOf((int)Math.floor(transplutonicsValue)); + if (transplutonicsValue < 1) { + transplutonics = String.valueOf((int)Math.ceil(transplutonicsValue)); + } + + String firstLine = "Refines %s metal from %s ore and %s transplutonics from %s transplutonic ore."; + String firstLineNoCapacity = "Refines metal from ore and transplutonics from transplutonic ore."; + + if (!isOperational) { + tooltip.addPara(firstLine, 4f, firstLineHighlights, + metal, ore, transplutonics, transplutonicOre); + } + if (isOperational && hasCapacity && hasMachinery) { + tooltip.addPara(firstLine, 4f, firstLineHighlights, + metal, ore, transplutonics, transplutonicOre); + } + if (isOperational && (!hasCapacity || !hasMachinery)) { + tooltip.addPara(firstLineNoCapacity, 4f); + } + + // Here: Second line + + ForgeHullmodsTooltip.addMachineryLine(tooltip, hullSize, ship, ForgeTypes.Conversion.REFINING, ForgeTypes.REFINERY); + + // Here: Third line + + ForgeHullmodsTooltip.addCRNoteLine(tooltip); + + // Here: Fourth line + + ForgeHullmodsTooltip.addInactiveLine(tooltip); + + tooltip.setBulletedListMode(null); + + // Here: S-Mod lines + + ForgeHullmodsTooltip.addSModLine(tooltip, ship, isForModSpec, ForgeTypes.REFINERY) ; + + } + + } + + @Override + public boolean isApplicableToShip(ShipAPI ship) { + + boolean hasForgeModule = false; + + for (String forgeHullmod : OTHER_FORGE_HULLMODS) { + if(ship.getVariant().getHullMods().contains(forgeHullmod)) { + hasForgeModule = true; + } + } + + return (isForgeHullmodInstallValid(ship) && !hasForgeModule); + + } + + public String getUnapplicableReason(ShipAPI ship) { + if (ship != null && !ForgeConditionChecker.isValidHullsize(ship)) { + return REASON_WRONG_HULLSIZE; + } + if (ship != null && !isCivGrade(ship) && ForgeSettings.ENABLE_CIVGRADE_REQUIREMENT) { + return REASON_NOT_CIVGRADE; + } + if (ship != null && !isNotModule(ship)) { + return REASON_IS_MODULE; + } + if (ship != null && !hasCargoCapacity(ship) && ForgeSettings.ENABLE_CARGO_REQUIREMENT) { + return REASON_NO_CARGO_SPACE; + } + boolean hasForgeModule = false; + for (String forgeHullmod : OTHER_FORGE_HULLMODS) { + if (ship != null && ship.getVariant().getHullMods().contains(forgeHullmod)) { + hasForgeModule = true; + } + } + if (hasForgeModule) { + return REASON_ALREADY_HAS; + } + return null; + } + +} diff --git a/source/data/forge/hullmods/support/ForgeHullmodsGeneral.java b/source/data/forge/hullmods/support/ForgeHullmodsGeneral.java new file mode 100644 index 0000000..de5272c --- /dev/null +++ b/source/data/forge/hullmods/support/ForgeHullmodsGeneral.java @@ -0,0 +1,129 @@ +package data.forge.hullmods.support; + +import java.util.HashSet; +import java.util.Map; +import java.util.HashMap; +import java.util.Set; + +import com.fs.starfarer.api.combat.ShipAPI; +import com.fs.starfarer.api.impl.campaign.ids.HullMods; + +import data.forge.abilities.conversion.support.ForgeConversionGeneral; +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; +import data.forge.plugins.ForgeSettings; + +public class ForgeHullmodsGeneral { + + public static final String REASON_WRONG_HULLSIZE = "Can only be installed on cruisers and capital ships"; + public static final String REASON_NOT_CIVGRADE = "Can only be installed on civilian-grade hulls"; + public static final String REASON_IS_MODULE = "Can not be installed on modules"; + public static final String REASON_NO_CARGO_SPACE = "Can not be installed on ships with insufficient cargo space"; + public static final String REASON_ALREADY_HAS = "Can only install one Forge module per ship"; + + public static final Set ALL_FORGE_HULLMODS = new HashSet<>(); + static + { + ALL_FORGE_HULLMODS.add("forge_refinery_module"); + ALL_FORGE_HULLMODS.add("forge_centrifuge_module"); + ALL_FORGE_HULLMODS.add("forge_manufacture_module"); + ALL_FORGE_HULLMODS.add("forge_assembly_module"); + } + + public static Map shipSizeEffect = new HashMap<>(); + static { + + shipSizeEffect.put(ShipAPI.HullSize.DEFAULT, 0); + shipSizeEffect.put(ShipAPI.HullSize.FIGHTER, 0); + shipSizeEffect.put(ShipAPI.HullSize.FRIGATE, 0); + shipSizeEffect.put(ShipAPI.HullSize.DESTROYER, 0); + shipSizeEffect.put(ShipAPI.HullSize.CRUISER, ForgeSettings.CAPACITY_CRUISER); + shipSizeEffect.put(ShipAPI.HullSize.CAPITAL_SHIP, ForgeSettings.CAPACITY_CAPITAL); + + } + + public static final Map shipCargoMalus = new HashMap<>(); + static { + shipCargoMalus.put(ShipAPI.HullSize.DEFAULT, 0f); + shipCargoMalus.put(ShipAPI.HullSize.FIGHTER, 0f); + shipCargoMalus.put(ShipAPI.HullSize.FRIGATE, 0f); + shipCargoMalus.put(ShipAPI.HullSize.DESTROYER, 0f); + shipCargoMalus.put(ShipAPI.HullSize.CRUISER, 200f); + shipCargoMalus.put(ShipAPI.HullSize.CAPITAL_SHIP, 400f); + } + + public static final Map shipMaintenanceIncrease = new HashMap<>(); + static { + shipMaintenanceIncrease.put(ShipAPI.HullSize.DEFAULT, 0f); + shipMaintenanceIncrease.put(ShipAPI.HullSize.FIGHTER, 0f); + shipMaintenanceIncrease.put(ShipAPI.HullSize.FRIGATE, 0f); + shipMaintenanceIncrease.put(ShipAPI.HullSize.DESTROYER, 0f); + shipMaintenanceIncrease.put(ShipAPI.HullSize.CRUISER, 2f); + shipMaintenanceIncrease.put(ShipAPI.HullSize.CAPITAL_SHIP, 4f); + } + + public static final Map skeletonCrewRequirement = new HashMap<>(); + static { + skeletonCrewRequirement.put(ShipAPI.HullSize.DEFAULT, 0f); + skeletonCrewRequirement.put(ShipAPI.HullSize.FIGHTER, 0f); + skeletonCrewRequirement.put(ShipAPI.HullSize.FRIGATE, 0f); + skeletonCrewRequirement.put(ShipAPI.HullSize.DESTROYER, 0f); + skeletonCrewRequirement.put(ShipAPI.HullSize.CRUISER, 20f); + skeletonCrewRequirement.put(ShipAPI.HullSize.CAPITAL_SHIP, 40f); + } + + public static boolean isForgeHullmodInstallValid(ShipAPI ship) { + return (ForgeConditionChecker.isValidHullsize(ship) && + isCivGrade(ship) && + isNotModule(ship) && + hasCargoCapacity(ship)); + } + + public static boolean isCivGrade(ShipAPI ship) { + if (!ForgeSettings.ENABLE_CIVGRADE_REQUIREMENT) { + return true; + } + boolean hasCivHullmod = ship.getVariant().hasHullMod(HullMods.CIVGRADE); + boolean hasArcheanCivHullmod = ship.getVariant().hasHullMod("archeus_civgrade"); + return (hasCivHullmod || hasArcheanCivHullmod); + } + + public static boolean isNotModule(ShipAPI ship) { + return !ship.isStationModule(); + } + + public static boolean hasCargoCapacity(ShipAPI ship) { + if (!ForgeSettings.ENABLE_CARGO_REQUIREMENT) { + return true; + } + return (ship.getVariant().getHullSpec().getCargo() > shipCargoMalus.get(ship.getHullSize())); + } + + public static int getShipCapacityMod (ShipAPI ship, ShipAPI.HullSize hullSize, ForgeTypes.Conversion type) { + int shipSize = shipSizeEffect.get(hullSize); + float getCurrentCR = (ship.getFleetMember().getRepairTracker().getCR() / 0.7f); + return (int) Math.floor(Math.min((int) Math.floor(shipSize * getCurrentCR), getShipMachineryCycles(ship, hullSize, type))); + } + + public static int getShipCapacityWithCR (ShipAPI ship, ShipAPI.HullSize hullSize) { + int shipSize = shipSizeEffect.get(hullSize); + float getCurrentCR = (ship.getFleetMember().getRepairTracker().getCR() / 0.7f); + return (int) Math.floor(shipSize * getCurrentCR); + } + + public static int getShipMachineryMod (ShipAPI ship, ShipAPI.HullSize hullSize) { + int shipSize = shipSizeEffect.get(hullSize); + float getCurrentCR = (ship.getFleetMember().getRepairTracker().getCR() / 0.7f); + return (int) Math.ceil((int) Math.floor(shipSize * getCurrentCR) * ForgeConversionGeneral.getMachineryAvailability()); + } + + public static int getShipMachineryCycles (ShipAPI ship, ShipAPI.HullSize hullSize, ForgeTypes.Conversion type) { + int shipSize = shipSizeEffect.get(hullSize); + float getCurrentCR = (ship.getFleetMember().getRepairTracker().getCR() / 0.7f); + int shipCapacity = (int) Math.floor(shipSize * getCurrentCR); + float machineryAvailable = (shipCapacity * ForgeTypes.MACHINERY_USAGE.get(type)) * ForgeConversionGeneral.getMachineryAvailability(); + float machineryCycles = machineryAvailable / ForgeTypes.MACHINERY_USAGE.get(type); + return (int) Math.floor(machineryCycles); + } + +} diff --git a/source/data/forge/hullmods/support/ForgeHullmodsTooltip.java b/source/data/forge/hullmods/support/ForgeHullmodsTooltip.java new file mode 100644 index 0000000..b65f699 --- /dev/null +++ b/source/data/forge/hullmods/support/ForgeHullmodsTooltip.java @@ -0,0 +1,156 @@ +package data.forge.hullmods.support; + +import java.awt.*; + +import com.fs.starfarer.api.combat.ShipAPI; +import com.fs.starfarer.api.ui.TooltipMakerAPI; +import com.fs.starfarer.api.util.Misc; + +import data.forge.abilities.conversion.support.ForgeTypes; +import data.forge.campaign.ForgeConditionChecker; +import data.forge.plugins.ForgeSettings; + +import static data.forge.hullmods.support.ForgeHullmodsGeneral.getShipCapacityWithCR; + +public class ForgeHullmodsTooltip { + + public static void addRequirementsLines(TooltipMakerAPI tooltip) { + String hullsizeRequirement; + if (ForgeSettings.ENABLE_CIVGRADE_REQUIREMENT) { + hullsizeRequirement = "Installable only on cruisers or capital ships with civilian-grade hull."; + } else { + hullsizeRequirement = "Installable only on cruisers or capital ships."; + } + tooltip.addPara(hullsizeRequirement, 6f); + + if (!ForgeSettings.ENABLE_CARGO_REQUIREMENT) { + String cargoRequirementNullified = "Cargo requirements nullified."; + tooltip.addPara(cargoRequirementNullified, Misc.getPositiveHighlightColor(), 2f); + } + } + + public static void addShipStateNote(TooltipMakerAPI tooltip, ShipAPI ship, ShipAPI.HullSize hullSize, String forgeType) { + + boolean isInstalled = ship.getVariant().hasHullMod(forgeType); + boolean isOperational = ForgeConditionChecker.isOperational(ship); + boolean hasMachinery = ForgeConditionChecker.hasMinimumMachinery(); + boolean hasCapacity = getShipCapacityWithCR(ship, hullSize) >= 1; + + String indent = " "; + + Color stateHighlightColor = Misc.getHighlightColor(); + Color stateTextColor = Misc.getTextColor(); + + String stateHighlight = "Not installed:" ; + if (isInstalled && !isOperational) { + stateHighlight = "Module inactive:" ; + } + if (isInstalled && isOperational) { + stateHighlight = "Module active:" ; + } + + String shipStateLine = "%s showing default values." ; + if (isInstalled && !isOperational) { + shipStateLine = "%s showing default values." ; + } + if (isInstalled && isOperational) { + shipStateLine = "%s showing current values." ; + } + if (isInstalled && isOperational && !hasMachinery && hasCapacity) { + stateTextColor = Misc.getNegativeHighlightColor(); + shipStateLine = "%s insufficient machinery." ; + } + if (isInstalled && isOperational && hasMachinery && !hasCapacity) { + stateTextColor = Misc.getNegativeHighlightColor(); + shipStateLine = "%s low CR." ; + } + if (isInstalled && isOperational && !hasMachinery && !hasCapacity) { + stateTextColor = Misc.getNegativeHighlightColor(); + shipStateLine = "%s low CR." ; + } + + tooltip.setBulletedListMode(indent); + tooltip.addPara(shipStateLine, 10f, stateTextColor, stateHighlightColor, stateHighlight); + tooltip.setBulletedListMode(null); + + } + + public static void addMachineryLine(TooltipMakerAPI tooltip, ShipAPI.HullSize hullSize, ShipAPI ship, + ForgeTypes.Conversion type, String forgeType) { + + Color highlightColor = Misc.getHighlightColor(); + + Color [] secondLineHighlights = { + highlightColor, highlightColor + }; + + boolean isOperational = ForgeConditionChecker.isOperational(ship); + boolean hasMachinery = ForgeConditionChecker.hasMinimumMachinery(); + boolean isInstalled = ship.getVariant().hasHullMod(forgeType); + boolean hasCapacity = ForgeHullmodsGeneral.getShipCapacityMod(ship, hullSize, type) >= 1; + + int shipMachineryModifier = ForgeHullmodsGeneral.getShipMachineryMod(ship,hullSize); + + if (!isOperational || !isInstalled) { + shipMachineryModifier = ForgeHullmodsGeneral.shipSizeEffect.get(hullSize); + } + + float heavyMachineryUsageValue = ForgeTypes.MACHINERY_USAGE.get(type) * shipMachineryModifier; + String heavyMachineryUsage = String.valueOf((int)Math.floor(heavyMachineryUsageValue)); + if (heavyMachineryUsageValue < 1) { + heavyMachineryUsage = String.valueOf((int)Math.ceil(heavyMachineryUsageValue)); + } + + String breakdownChance = ((int)(ForgeSettings.BASE_BREAKDOWN_CHANCE * 100) + "%"); + + String secondLine = "Uses %s heavy machinery, with %s chance of breakdown." ; + String secondLineNoCapacity = "Uses heavy machinery, with %s chance of breakdown." ; + + if (!isOperational) { + tooltip.addPara(secondLine, 2f, secondLineHighlights, heavyMachineryUsage, breakdownChance); + } + if (isOperational && hasCapacity && hasMachinery) { + tooltip.addPara(secondLine, 2f, secondLineHighlights, heavyMachineryUsage, breakdownChance); + } + if (isOperational && (!hasCapacity || !hasMachinery)) { + tooltip.addPara(secondLineNoCapacity, 2f, highlightColor, breakdownChance); + } + + } + + public static void addCRNoteLine(TooltipMakerAPI tooltip) { + + Color [] thirdLineHighlights = {Misc.getHighlightColor()}; + + String crDecrease = ((int)(( ForgeSettings.CR_PRODUCTION_DECAY)*100) + "%"); + String CRNoteLine = "Refining drains %s CR per day. Ships with low CR have lowered output and lose less CR." ; + + tooltip.addPara(CRNoteLine, 2f, thirdLineHighlights, crDecrease); + + } + + public static void addInactiveLine(TooltipMakerAPI tooltip) { + + Color [] fourthLineHighlights = {Misc.getHighlightColor()}; + String CR = "10%"; + String InactiveLine = "Forge module cannot be activated if ship is mothballed, does not receive repairs or has less than %s CR."; + + tooltip.addPara(InactiveLine, 2f, fourthLineHighlights, CR); + + } + + public static void addSModLine(TooltipMakerAPI tooltip, ShipAPI ship, boolean isForModSpec, String forgeType) { + + if (isForModSpec) { + tooltip.addPara("If this hullmod is built in, additional crew requirement and maintenance cost increase are nullified.", Misc.getGrayColor(), 10f); + } else if (ship.getVariant().getSMods().contains(forgeType)) { + tooltip.addPara("S-mod Bonus: Additional crew requirement and maintenance cost increase are nullified.", Misc.getPositiveHighlightColor(), 10f); + } else if (ship.getHullSpec().isBuiltInMod(forgeType)) { + tooltip.addPara("Built-in Bonus: Additional crew requirement and maintenance cost increase are nullified.", Misc.getPositiveHighlightColor(), 10f); + } else { + tooltip.addPara("If this hullmod is built in, additional crew requirement and maintenance cost increase are nullified.", Misc.getGrayColor(), 10f); + } + + } + +} diff --git a/source/data/forge/plugins/ForgeDataSupplier.java b/source/data/forge/plugins/ForgeDataSupplier.java new file mode 100644 index 0000000..7cf14c9 --- /dev/null +++ b/source/data/forge/plugins/ForgeDataSupplier.java @@ -0,0 +1,81 @@ +package data.forge.plugins; + +import java.io.IOException; + +import org.json.JSONException; +import org.json.JSONObject; + +import com.fs.starfarer.api.Global; + +public class ForgeDataSupplier { + + public static void loadSettings(String fileName) throws IOException, JSONException { + + JSONObject settings = Global.getSettings().loadJSON(fileName); + + ForgeSettings.ENABLE_CARGO_REQUIREMENT = settings.getBoolean("forge_enable_cargo_requirement"); + ForgeSettings.ENABLE_CIVGRADE_REQUIREMENT = settings.getBoolean("forge_enable_civgrade_requirement"); + + // Here: Miscellaneous Settings + ForgeSettings.ENABLE_SLOW_MOVE_PENALTY = settings.getBoolean("forge_enable_slow_move_penalty"); + ForgeSettings.ENABLE_DETECT_AT_RANGE_PENALTY = settings.getBoolean("forge_enable_sensor_penalty"); + + ForgeSettings.ENABLE_BURN_ABILITIES_INCOMPATIBILITY = settings.getBoolean("forge_enable_burn_abilities_incompatibility"); + + ForgeSettings.SENSOR_PROFILE_INCREASE = settings.getInt("forge_sensor_profile_increase"); + ForgeSettings.SHIP_LIST_SIZE = settings.getInt("forge_ship_list_size"); + + // Here: Notification Settings + ForgeSettings.PLAY_SOUND_NOTIFICATION = settings.getBoolean("forge_play_sound_notification"); + ForgeSettings.SHOW_NOTIFICATION = settings.getBoolean("forge_show_notification"); + ForgeSettings.INVERTED_GRID_NOTIFICATION = settings.getBoolean("forge_inverted_grid_notification"); + ForgeSettings.NOTIFICATION_INTERVAL = settings.getInt("forge_notification_interval"); + + // Here: Capacity Settings + ForgeSettings.CAPACITY_CRUISER = settings.getInt("forge_capacity_cruiser"); + ForgeSettings.CAPACITY_CAPITAL = settings.getInt("forge_capacity_capital"); + + // Here: Refining Settings + ForgeSettings.ORE_TO_REFINE = Float.parseFloat(settings.getString("forge_ore_to_refine")); + ForgeSettings.METAL_PRODUCED = Float.parseFloat(settings.getString("forge_metal_produced")); + ForgeSettings.TRANSPLUTONIC_ORE_TO_REFINE = Float.parseFloat(settings.getString("forge_transplutonic_ore_to_refine")); + ForgeSettings.TRANSPLUTONICS_PRODUCED = Float.parseFloat(settings.getString("forge_transplutonics_produced")); + ForgeSettings.HEAVY_MACHINERY_REFINING_USAGE = Float.parseFloat(settings.getString("forge_heavy_machinery_refining_usage")); + + // Here: Centrifuging Settings + ForgeSettings.VOLATILES_TO_CENTRIFUGE = Float.parseFloat(settings.getString("forge_volatiles_to_centrifuge")); + ForgeSettings.FUEL_PRODUCED = Float.parseFloat(settings.getString("forge_fuel_produced")); + ForgeSettings.HEAVY_MACHINERY_CENTRIFUGING_USAGE = Float.parseFloat(settings.getString("forge_heavy_machinery_centrifuging_usage")); + + // Here: Manufacturing Settings + ForgeSettings.METAL_TO_MANUFACTURE = Float.parseFloat(settings.getString("forge_metal_to_manufacture")); + ForgeSettings.TRANSPLUTONICS_TO_MANUFACTURE = Float.parseFloat(settings.getString("forge_transplutonics_to_manufacture")); + ForgeSettings.SUPPLIES_PRODUCED = Float.parseFloat(settings.getString("forge_supplies_produced")); + ForgeSettings.HEAVY_MACHINERY_MANUFACTURING_USAGE = Float.parseFloat(settings.getString("forge_heavy_machinery_manufacturing_usage")); + + // Here: Assembling Settings + ForgeSettings.METAL_TO_ASSEMBLE = Float.parseFloat(settings.getString("forge_metal_to_assemble")); + ForgeSettings.TRANSPLUTONICS_TO_ASSEMBLE = Float.parseFloat(settings.getString("forge_transplutonics_to_assemble")); + ForgeSettings.HEAVY_MACHINERY_PRODUCED = Float.parseFloat(settings.getString("forge_heavy_machinery_produced")); + ForgeSettings.HEAVY_MACHINERY_ASSEMBLING_USAGE = Float.parseFloat(settings.getString("forge_heavy_machinery_assembling_usage")); + + // Here: Machinery Breakdown Settings + ForgeSettings.BASE_BREAKDOWN_CHANCE = Float.parseFloat(settings.getString("forge_base_heavy_machinery_breakdown_chance")); + ForgeSettings.BREAKDOWN_SEVERITY = Float.parseFloat(settings.getString("forge_heavy_machinery_breakdown_severity")); + + // Here: CR Settings + ForgeSettings.CR_PRODUCTION_DECAY = Float.parseFloat(settings.getString("forge_combat_readiness_decay_when_producing")); + + // Here: Special Item Settings + ForgeSettings.CORRUPTED_NANOFORGE_QUALITY_BONUS = Float.parseFloat(settings.getString("forge_corrupted_nanoforge_quality_bonus")); + ForgeSettings.PRISTINE_NANOFORGE_QUALITY_BONUS = Float.parseFloat(settings.getString("forge_pristine_nanoforge_quality_bonus")); + ForgeSettings.CATALYTIC_CORE_REFINING_BONUS = Float.parseFloat(settings.getString("forge_catalytic_core_refining_bonus")); + ForgeSettings.SYNCHROTRON_CORE_CENTRIFUGING_BONUS = Float.parseFloat(settings.getString("forge_synchrotron_core_centrifuging_bonus")); + ForgeSettings.CORRUPTED_NANOFORGE_MANUFACTURING_BONUS = Float.parseFloat(settings.getString("forge_corrupted_nanoforge_manufacturing_bonus")); + ForgeSettings.PRISTINE_NANOFORGE_MANUFACTURING_BONUS = Float.parseFloat(settings.getString("forge_pristine_nanoforge_manufacturing_bonus")); + ForgeSettings.CORRUPTED_NANOFORGE_ASSEMBLING_BONUS = Float.parseFloat(settings.getString("forge_corrupted_nanoforge_assembling_bonus")); + ForgeSettings.PRISTINE_NANOFORGE_ASSEMBLING_BONUS = Float.parseFloat(settings.getString("forge_pristine_nanoforge_assembling_bonus")); + + } + +} diff --git a/source/data/forge/plugins/ForgeModPlugin.java b/source/data/forge/plugins/ForgeModPlugin.java new file mode 100644 index 0000000..f21d55f --- /dev/null +++ b/source/data/forge/plugins/ForgeModPlugin.java @@ -0,0 +1,27 @@ +package data.forge.plugins; + +import java.io.IOException; +import org.json.JSONException; + +import com.fs.starfarer.api.BaseModPlugin; +import com.fs.starfarer.api.Global; + +public class ForgeModPlugin extends BaseModPlugin { + + public static final String FORGE_SETTINGS = "forge_production_settings.ini"; + public static final String FORGE_PRODUCTION_ABILITY = "forge_production"; + + @Override + public void onApplicationLoad() throws JSONException, IOException { + ForgeDataSupplier.loadSettings(FORGE_SETTINGS); + } + + @Override + public void onGameLoad(boolean newGame) { + + if(!Global.getSector().getPlayerFleet().hasAbility(FORGE_PRODUCTION_ABILITY)) { + Global.getSector().getCharacterData().addAbility(FORGE_PRODUCTION_ABILITY); + } + } + +} diff --git a/source/data/forge/plugins/ForgeSettings.java b/source/data/forge/plugins/ForgeSettings.java new file mode 100644 index 0000000..46543a5 --- /dev/null +++ b/source/data/forge/plugins/ForgeSettings.java @@ -0,0 +1,66 @@ +package data.forge.plugins; + +public class ForgeSettings { + public static boolean ENABLE_CARGO_REQUIREMENT = true; + public static boolean ENABLE_CIVGRADE_REQUIREMENT = true; + + // Here: Miscellaneous Settings + + public static boolean ENABLE_SLOW_MOVE_PENALTY = true; + public static boolean ENABLE_DETECT_AT_RANGE_PENALTY = true; + public static boolean ENABLE_BURN_ABILITIES_INCOMPATIBILITY = true; + public static float SENSOR_PROFILE_INCREASE = 100; + public static int SHIP_LIST_SIZE = 5; + + // Here: Notification Settings + public static boolean PLAY_SOUND_NOTIFICATION = true; + public static boolean SHOW_NOTIFICATION = true; + public static boolean INVERTED_GRID_NOTIFICATION = false; + public static int NOTIFICATION_INTERVAL = 3; + + // Here: Capacity Settings + public static int CAPACITY_CRUISER = 40; + public static int CAPACITY_CAPITAL = 60; + + // Here: Refining Settings + public static float ORE_TO_REFINE = 2f; + public static float METAL_PRODUCED = 1.2f; + public static float TRANSPLUTONIC_ORE_TO_REFINE = 1f; + public static float TRANSPLUTONICS_PRODUCED = 0.6f; + public static float HEAVY_MACHINERY_REFINING_USAGE = 0.6f; + + // Here: Centrifuging Settings + public static float VOLATILES_TO_CENTRIFUGE = 0.1f; + public static float FUEL_PRODUCED = 1.2f; + public static float HEAVY_MACHINERY_CENTRIFUGING_USAGE = 0.8f; + + // Here: Manufacturing Settings + public static float METAL_TO_MANUFACTURE = 0.8f; + public static float TRANSPLUTONICS_TO_MANUFACTURE = 0.2f; + public static float SUPPLIES_PRODUCED = 0.4f; + public static float HEAVY_MACHINERY_MANUFACTURING_USAGE = 1f; + + // Here: Assembling Settings + public static float METAL_TO_ASSEMBLE = 1.2f; + public static float TRANSPLUTONICS_TO_ASSEMBLE = 0.1f; + public static float HEAVY_MACHINERY_PRODUCED = 0.2f; + public static float HEAVY_MACHINERY_ASSEMBLING_USAGE = 1.6f; + + // Here: Machinery Breakdown Settings + public static float BASE_BREAKDOWN_CHANCE = 0.3f; + public static float BREAKDOWN_SEVERITY = 0.05f; + + // Here: CR Settings + public static float CR_PRODUCTION_DECAY = 0.02f; + + // Here: Special Item Settings + public static float CORRUPTED_NANOFORGE_QUALITY_BONUS = 0.8f; + public static float PRISTINE_NANOFORGE_QUALITY_BONUS = 0.5f; + public static float CATALYTIC_CORE_REFINING_BONUS = 0.2f; + public static float SYNCHROTRON_CORE_CENTRIFUGING_BONUS = 0.4f; + public static float CORRUPTED_NANOFORGE_MANUFACTURING_BONUS = 0.1f; + public static float PRISTINE_NANOFORGE_MANUFACTURING_BONUS = 0.2f; + public static float CORRUPTED_NANOFORGE_ASSEMBLING_BONUS = 0.05f; + public static float PRISTINE_NANOFORGE_ASSEMBLING_BONUS = 0.1f; + +}