001package com.fs.starfarer.api.impl.campaign.submarkets; 002 003import java.util.HashSet; 004import java.util.Random; 005import java.util.Set; 006 007import com.fs.starfarer.api.Global; 008import com.fs.starfarer.api.campaign.CampaignUIAPI.CoreUITradeMode; 009import com.fs.starfarer.api.campaign.CoreUIAPI; 010import com.fs.starfarer.api.campaign.FactionAPI.ShipPickMode; 011import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI; 012import com.fs.starfarer.api.campaign.econ.SubmarketAPI; 013import com.fs.starfarer.api.impl.campaign.ids.Commodities; 014import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 015import com.fs.starfarer.api.impl.campaign.ids.Submarkets; 016import com.fs.starfarer.api.util.Highlights; 017import com.fs.starfarer.api.util.Misc; 018 019public class OpenMarketPlugin extends BaseSubmarketPlugin { 020 021 public void init(SubmarketAPI submarket) { 022 super.init(submarket); 023 } 024 025 026 public void updateCargoPrePlayerInteraction() { 027 float seconds = Global.getSector().getClock().convertToSeconds(sinceLastCargoUpdate); 028 addAndRemoveStockpiledResources(seconds, false, true, true); 029 sinceLastCargoUpdate = 0f; 030 031 if (okToUpdateShipsAndWeapons()) { 032 sinceSWUpdate = 0f; 033 034 boolean military = Misc.isMilitary(market); 035 boolean hiddenBase = market.getMemoryWithoutUpdate().getBoolean(MemFlags.HIDDEN_BASE_MEM_FLAG); 036 037 float extraShips = 0f; 038 //int extraShipSize = 0; 039 if (military && hiddenBase && !market.hasSubmarket(Submarkets.GENERIC_MILITARY)) { 040 extraShips = 150f; 041 //extraShipSize = 1; 042 } 043 044 pruneWeapons(0f); 045 046 int weapons = 5 + Math.max(0, market.getSize() - 1) + (Misc.isMilitary(market) ? 5 : 0); 047 int fighters = 1 + Math.max(0, (market.getSize() - 3) / 2) + (Misc.isMilitary(market) ? 2 : 0); 048 049 addWeapons(weapons, weapons + 2, 0, market.getFactionId()); 050 addFighters(fighters, fighters + 2, 0, market.getFactionId()); 051 052 053 getCargo().getMothballedShips().clear(); 054 055 float freighters = 10f; 056 CommodityOnMarketAPI com = market.getCommodityData(Commodities.SHIPS); 057 freighters += com.getMaxSupply() * 2f; 058 if (freighters > 30) freighters = 30; 059 060 addShips(market.getFactionId(), 061 10f + extraShips, // combat 062 freighters, // freighter 063 0f, // tanker 064 10f, // transport 065 10f, // liner 066 5f, // utilityPts 067 null, // qualityOverride 068 0f, // qualityMod 069 ShipPickMode.PRIORITY_THEN_ALL, 070 null); 071 072 addShips(market.getFactionId(), 073 40f, // combat 074 0f, // freighter 075 0f, // tanker 076 0f, // transport 077 0f, // liner 078 0f, // utilityPts 079 null, // qualityOverride 080 -1f, // qualityMod 081 null, 082 null, 083 4); 084 085 float tankers = 20f; 086 com = market.getCommodityData(Commodities.FUEL); 087 tankers += com.getMaxSupply() * 3f; 088 if (tankers > 40) tankers = 40; 089 //tankers = 40; 090 addShips(market.getFactionId(), 091 0f, // combat 092 0f, // freighter 093 tankers, // tanker 094 0, // transport 095 0f, // liner 096 0f, // utilityPts 097 null, // qualityOverride 098 0f, // qualityMod 099 ShipPickMode.PRIORITY_THEN_ALL, 100 null); 101 102 103 addHullMods(1, 1 + itemGenRandom.nextInt(3), market.getFactionId()); 104 } 105 106 getCargo().sort(); 107 } 108 109 protected Object writeReplace() { 110 if (okToUpdateShipsAndWeapons()) { 111 pruneWeapons(0f); 112 getCargo().getMothballedShips().clear(); 113 } 114 return this; 115 } 116 117 118 public boolean shouldHaveCommodity(CommodityOnMarketAPI com) { 119 return !market.isIllegal(com); 120 } 121 122 @Override 123 public int getStockpileLimit(CommodityOnMarketAPI com) { 124// int demand = com.getMaxDemand(); 125// int available = com.getAvailable(); 126// 127// float limit = BaseIndustry.getSizeMult(available) - BaseIndustry.getSizeMult(Math.max(0, demand - 2)); 128// limit *= com.getCommodity().getEconUnit(); 129 130 //limit *= com.getMarket().getStockpileMult().getModifiedValue(); 131 132 float limit = OpenMarketPlugin.getBaseStockpileLimit(com); 133 134 Random random = new Random(market.getId().hashCode() + submarket.getSpecId().hashCode() + Global.getSector().getClock().getMonth() * 170000); 135 limit *= 0.9f + 0.2f * random.nextFloat(); 136 137 float sm = market.getStabilityValue() / 10f; 138 limit *= (0.25f + 0.75f * sm); 139 140 if (limit < 0) limit = 0; 141 142 return (int) limit; 143 } 144 145 public static float ECON_UNIT_MULT_EXTRA = 1f; 146 public static float ECON_UNIT_MULT_PRODUCTION = 0.4f; 147 public static float ECON_UNIT_MULT_IMPORTS = 0.1f; 148 public static float ECON_UNIT_MULT_DEFICIT = -0.2f; 149 150 public static Set<String> SPECIAL_COMMODITIES = new HashSet<String>(); 151 static { 152 SPECIAL_COMMODITIES.add(Commodities.SUPPLIES); 153 SPECIAL_COMMODITIES.add(Commodities.FUEL); 154 SPECIAL_COMMODITIES.add(Commodities.CREW); 155 SPECIAL_COMMODITIES.add(Commodities.MARINES); 156 SPECIAL_COMMODITIES.add(Commodities.HEAVY_MACHINERY); 157 } 158 159 public static float getBaseStockpileLimit(CommodityOnMarketAPI com) { 160// if (com.getCommodity().getId().equals(Commodities.LUXURY_GOODS)) { 161// System.out.println("wefwefwef"); 162// } 163 int shippingGlobal = Global.getSettings().getShippingCapacity(com.getMarket(), false); 164 int available = com.getAvailable(); 165 int production = com.getMaxSupply(); 166 production = Math.min(production, available); 167 168 int demand = com.getMaxDemand(); 169 int export = (int) Math.min(production, shippingGlobal); 170 171 int extra = available - Math.max(export, demand); 172 if (extra < 0) extra = 0; 173 174 //int inDemand = Math.min(available, demand); 175 //int normal = Math.max(0, available - inDemand - extra); 176 int deficit = Math.max(0, demand - available); 177 178 float unit = com.getCommodity().getEconUnit(); 179 180 int imports = available - production; 181 if (imports < 0) imports = 0; 182 183 float limit = 0f; 184 limit += imports * unit * ECON_UNIT_MULT_IMPORTS; 185 limit += production * unit * ECON_UNIT_MULT_PRODUCTION; 186 limit += extra * unit * ECON_UNIT_MULT_EXTRA; 187 limit -= deficit * unit * ECON_UNIT_MULT_DEFICIT; 188 189 190 //limit += inDemand * unit * ECON_UNIT_MULT_IN_DEMAND; 191 //limit += normal * unit * ECON_UNIT_MULT_NORMAL; 192 193 if (limit < 0) limit = 0; 194 return (int) limit; 195 } 196 197 198 public static int getApproximateStockpileLimit(CommodityOnMarketAPI com) { 199// int demand = com.getMaxDemand(); 200// int available = com.getAvailable(); 201// 202// float limit = BaseIndustry.getSizeMult(available) - BaseIndustry.getSizeMult(Math.max(0, demand - 2)); 203// limit *= com.getCommodity().getEconUnit(); 204// //limit *= 0.5f; 205// 206// if (limit < 0) limit = 0; 207// return (int) limit; 208 209 float limit = OpenMarketPlugin.getBaseStockpileLimit(com); 210 return (int) limit; 211 } 212 213 214 215 216 @Override 217 public PlayerEconomyImpactMode getPlayerEconomyImpactMode() { 218 return PlayerEconomyImpactMode.PLAYER_SELL_ONLY; 219 } 220 221 222 @Override 223 public boolean isOpenMarket() { 224 return true; 225 } 226 227 228 @Override 229 public String getTooltipAppendix(CoreUIAPI ui) { 230 if (ui.getTradeMode() == CoreUITradeMode.SNEAK) { 231 return "Requires: proper docking authorization (transponder on)"; 232 } 233 return super.getTooltipAppendix(ui); 234 } 235 236 237 @Override 238 public Highlights getTooltipAppendixHighlights(CoreUIAPI ui) { 239 if (ui.getTradeMode() == CoreUITradeMode.SNEAK) { 240 String appendix = getTooltipAppendix(ui); 241 if (appendix == null) return null; 242 243 Highlights h = new Highlights(); 244 h.setText(appendix); 245 h.setColors(Misc.getNegativeHighlightColor()); 246 return h; 247 } 248 return super.getTooltipAppendixHighlights(ui); 249 } 250 251 252}