001package com.fs.starfarer.api.impl.campaign.econ;
002
003import com.fs.starfarer.api.Global;
004import com.fs.starfarer.api.campaign.econ.MarketAPI;
005import com.fs.starfarer.api.campaign.econ.MarketConditionAPI;
006import com.fs.starfarer.api.campaign.econ.MarketImmigrationModifier;
007import com.fs.starfarer.api.impl.campaign.ids.Conditions;
008import com.fs.starfarer.api.impl.campaign.ids.Factions;
009import com.fs.starfarer.api.impl.campaign.ids.Stats;
010import com.fs.starfarer.api.impl.campaign.population.PopulationComposition;
011import com.fs.starfarer.api.ui.TooltipMakerAPI;
012import com.fs.starfarer.api.util.Misc;
013
014
015
016public class FreeMarket extends BaseMarketConditionPlugin implements MarketImmigrationModifier {
017
018        public static float OFFICER_MERC_PROB_MOD = 0.25f;
019        
020        public static float MIN_STABILITY_PENALTY = 1f;
021        public static float MAX_STABILITY_PENALTY = 3f;
022        //public static float STABILITY_PENALTY = 3f;
023        
024        public static float MIN_ACCESS_BONUS = 0.05f;
025        public static float MAX_ACCESS_BONUS = 0.25f;
026        
027        public static float MIN_GROWTH = 3f;
028        public static float MAX_GROWTH = 10f;
029        public static float MAX_DAYS = 365f;
030
031        public static FreeMarket get(MarketAPI market) {
032                MarketConditionAPI mc = market.getCondition(Conditions.FREE_PORT);
033                if (mc != null && mc.getPlugin() instanceof FreeMarket) {
034                        return (FreeMarket) mc.getPlugin();
035                }
036                return null;
037        }
038        
039        private float daysActive = 0f;
040        @Override
041        public void advance(float amount) {
042                if (!market.hasSpaceport()) {
043                        market.removeSpecificCondition(condition.getIdForPluginModifications());
044                        market.setFreePort(false);
045                        return;
046                }
047                if (amount <= 0) return;
048                
049                super.advance(amount);
050                
051                float days = Global.getSector().getClock().convertToDays(amount);
052                daysActive += days;
053        }
054        
055        public boolean runWhilePaused() {
056                return true;
057        }
058        
059        public float getDaysActive() {
060                return daysActive;
061        }
062        
063        public void setDaysActive(float daysActive) {
064                this.daysActive = daysActive;
065        }
066
067        public void apply(String id) {
068                market.addTransientImmigrationModifier(this);
069                
070                market.getAccessibilityMod().modifyFlat(id, getAccessBonus(), "Free port");
071                market.getStability().modifyFlat(id, -getStabilityPenalty(), "Free port");
072                
073                market.getStats().getDynamic().getMod(Stats.OFFICER_IS_MERC_PROB_MOD).modifyFlat(id, OFFICER_MERC_PROB_MOD);
074        }
075        
076        @Override
077        public boolean isTransient() {
078                return false;
079        }
080
081        public void unapply(String id) {
082                market.removeTransientImmigrationModifier(this);
083                
084                market.getStability().unmodifyFlat(id);
085                market.getAccessibilityMod().unmodifyFlat(id);
086                
087                market.getStats().getDynamic().getMod(Stats.OFFICER_IS_MERC_PROB_MOD).unmodifyFlat(id);
088        }
089
090        public void modifyIncoming(MarketAPI market, PopulationComposition incoming) {
091                incoming.add(Factions.PIRATES, 5f);
092                incoming.add(Factions.POOR, 5f);
093                incoming.add(Factions.INDEPENDENT, 5f);
094                incoming.getWeight().modifyFlat(getModId(), getImmigrationBonus(), Misc.ucFirst(condition.getName().toLowerCase()));
095        }
096        
097        protected float getImmigrationBonus() {
098                //float growth = Math.min(1f, daysActive / 10f) * MAX_GROWTH;
099                float growth = MIN_GROWTH + daysActive / MAX_DAYS * (MAX_GROWTH - MIN_GROWTH);
100                growth = Math.round(growth);
101                if (growth > MAX_GROWTH) growth = MAX_GROWTH;
102                if (growth < 1) growth = 1;
103                return growth;
104        }
105        
106        protected float getAccessBonus() {
107                //float growth = Math.min(1f, daysActive / 10f) * MAX_GROWTH;
108                float access = MIN_ACCESS_BONUS + daysActive / MAX_DAYS * (MAX_ACCESS_BONUS - MIN_ACCESS_BONUS);
109                access = Math.round(access * 100f) / 100f;
110                if (access > MAX_ACCESS_BONUS) access = MAX_ACCESS_BONUS;
111                if (access < 0.01f) access = 0.01f;
112                return access;
113        }
114        
115        protected float getStabilityPenalty() {
116                //float growth = Math.min(1f, daysActive / 10f) * MAX_GROWTH;
117                float s = MIN_STABILITY_PENALTY + daysActive / MAX_DAYS * (MAX_STABILITY_PENALTY - MIN_STABILITY_PENALTY);
118                s = Math.round(s);
119                if (s > MAX_STABILITY_PENALTY) s = MAX_STABILITY_PENALTY;
120                if (s < 1f) s = 1f;
121                return s;
122        }
123        
124
125        protected void createTooltipAfterDescription(TooltipMakerAPI tooltip, boolean expanded) {
126                super.createTooltipAfterDescription(tooltip, expanded);
127                
128                if (!market.hasSpaceport() && !Global.CODEX_TOOLTIP_MODE) {
129                        tooltip.addPara("Requires a spaceport to have any effect", Misc.getNegativeHighlightColor(), 10f);
130                        return;
131                }
132                
133                if (Global.CODEX_TOOLTIP_MODE) {
134                        tooltip.addPara("Reduced stability (maximum of %s, reached after %s days)", 
135                                        10f, Misc.getHighlightColor(),
136                                        "-" + (int) (MAX_STABILITY_PENALTY),
137                                        "" + (int) MAX_DAYS);
138                        tooltip.addPara("Increased population growth (maximum of %s, reached after %s days)",
139                                        10f, Misc.getHighlightColor(), 
140                                        "+" + (int) (MAX_GROWTH),
141                                        "" + (int) MAX_DAYS);
142                        
143                        tooltip.addPara("Increased accessibility (maximum of %s, reached after %s days)", 
144                                        10f, Misc.getHighlightColor(), 
145                                        "+" + (int) Math.round(MAX_ACCESS_BONUS * 100f) + "%",
146                                        "" + (int) MAX_DAYS);
147                } else {
148                        tooltip.addPara("%s stability (maximum of %s, reached after %s days)", 
149                                        10f, Misc.getHighlightColor(),
150                                        "-" + (int)getStabilityPenalty(),
151                                        "-" + (int) (MAX_STABILITY_PENALTY),
152                                        "" + (int) MAX_DAYS);
153                        tooltip.addPara("%s population growth (maximum of %s, reached after %s days)",
154                                        
155                                        10f, Misc.getHighlightColor(), 
156                                        "+" + (int) getImmigrationBonus(),
157                                        "+" + (int) (MAX_GROWTH),
158                                        "" + (int) MAX_DAYS);
159                        
160                        tooltip.addPara("%s accessibility (maximum of %s, reached after %s days)", 
161                                        10f, Misc.getHighlightColor(), 
162                                        "+" + (int) Math.round(getAccessBonus() * 100f) + "%",
163                                        "+" + (int) Math.round(MAX_ACCESS_BONUS * 100f) + "%",
164                                        "" + (int) MAX_DAYS);
165                }
166                
167                tooltip.addPara("Colony does not require the transponder to be turned on for open trade. " +
168                                                "All commodities are legal to trade.", 10f);
169                
170                tooltip.addPara("Colony gets income from smuggled exports.", 10f);
171        }
172}
173
174
175
176
177