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}