001package com.fs.starfarer.api.impl.campaign.rulecmd.salvage;
002
003import java.util.List;
004import java.util.Map;
005
006import org.lwjgl.util.vector.Vector2f;
007
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.campaign.CampaignFleetAPI;
010import com.fs.starfarer.api.campaign.CargoAPI;
011import com.fs.starfarer.api.campaign.FactionAPI;
012import com.fs.starfarer.api.campaign.InteractionDialogAPI;
013import com.fs.starfarer.api.campaign.OptionPanelAPI;
014import com.fs.starfarer.api.campaign.RepLevel;
015import com.fs.starfarer.api.campaign.SectorEntityToken;
016import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel;
017import com.fs.starfarer.api.campaign.TextPanelAPI;
018import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI;
019import com.fs.starfarer.api.campaign.rules.MemoryAPI;
020import com.fs.starfarer.api.characters.AbilityPlugin;
021import com.fs.starfarer.api.characters.PersonAPI;
022import com.fs.starfarer.api.fleet.FleetMemberAPI;
023import com.fs.starfarer.api.impl.campaign.abilities.DistressCallAbility;
024import com.fs.starfarer.api.impl.campaign.ids.Abilities;
025import com.fs.starfarer.api.impl.campaign.ids.Commodities;
026import com.fs.starfarer.api.impl.campaign.ids.Entities;
027import com.fs.starfarer.api.impl.campaign.ids.Strings;
028import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
029import com.fs.starfarer.api.impl.campaign.rulecmd.BaseCommandPlugin;
030import com.fs.starfarer.api.util.Misc;
031import com.fs.starfarer.api.util.Misc.Token;
032
033/**
034 * NotifyEvent $eventHandle <params> 
035 * 
036 */
037public class DistressResponse extends BaseCommandPlugin {
038        
039        //public static float REP_NORMAL = -0.05f;
040        public static float REP_PER_USE = -0.02f;
041        public static float REP_SCAM = -0.15f;
042        
043        protected CampaignFleetAPI playerFleet;
044        protected CampaignFleetAPI fleet;
045        protected SectorEntityToken entity;
046        protected FactionAPI playerFaction;
047        protected FactionAPI entityFaction;
048        protected TextPanelAPI text;
049        protected OptionPanelAPI options;
050        protected CargoAPI playerCargo;
051        protected MemoryAPI memory;
052        protected InteractionDialogAPI dialog;
053        protected Map<String, MemoryAPI> memoryMap;
054        protected PersonAPI person;
055        protected FactionAPI faction;
056
057        public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
058                
059                this.dialog = dialog;
060                this.memoryMap = memoryMap;
061                
062                String command = params.get(0).getString(memoryMap);
063                if (command == null) return false;
064                
065                memory = getEntityMemory(memoryMap);
066                
067                entity = dialog.getInteractionTarget();
068                text = dialog.getTextPanel();
069                options = dialog.getOptionPanel();
070                
071                playerFleet = Global.getSector().getPlayerFleet();
072                playerCargo = playerFleet.getCargo();
073                
074                playerFaction = Global.getSector().getPlayerFaction();
075                entityFaction = entity.getFaction();
076                
077                person = dialog.getInteractionTarget().getActivePerson();
078                faction = person.getFaction();
079
080                fleet = (CampaignFleetAPI) dialog.getInteractionTarget();
081
082                if (command.equals("playerNeedsHelp")) {
083                        return playerNeedsHelp();
084                } else if (command.equals("didNotNeedHelp")) {
085                        didNotNeedHelp();
086                }
087                else if (command.equals("acceptHelp")) {
088                        acceptAid();
089                }
090                else if (command.equals("neverMind")) {
091                        neverMind();
092                }
093                else if (command.equals("isCargoPodsScam")) {
094                        return isCargoPodsScam();
095                }
096                else if (command.equals("cargoPodsScam")) {
097                        cargoPodsScam();
098                }
099                else if (command.equals("unrespond")) {
100                        unrespond();
101                }
102                else if (command.equals("init")) {
103                        init();
104                }
105                else if (command.equals("pay")) {
106                        pay();
107                }
108                else if (command.equals("thank")) {
109                        thank();
110                }
111                
112                return true;
113        }
114        
115        protected void init() {
116                person.getMemoryWithoutUpdate().set("$distressUsesLastCycle", getNumUses(), 0);
117                
118                int fuel = getNeededFuel();
119                int supplies = getNeededSupplies();
120                int maxFuel = getMaxFuel();
121                int maxSupplies = getMaxSupplies();
122                
123                boolean adequate = fuel <= maxFuel * 1.5f && supplies <= maxSupplies * 1.5f;
124                person.getMemoryWithoutUpdate().set("$distressHelpAdequate", adequate, 0);
125                
126
127                int distressPayment = getPayment();
128                person.getMemoryWithoutUpdate().set("$distressPayment", Misc.getWithDGS(distressPayment), 0);
129                person.getMemoryWithoutUpdate().set("$distressPaymentC", Misc.getWithDGS(distressPayment) + Strings.C, 0);
130                person.getMemoryWithoutUpdate().set("$distressCanAfford", distressPayment <= playerCargo.getCredits().get(), 0);
131        }
132        
133        protected int getPayment() {
134                int fuel = getNeededFuel();
135                int supplies = getNeededSupplies();
136                int maxFuel = getMaxFuel();
137                int maxSupplies = getMaxSupplies();
138                if (fuel > maxFuel) fuel = maxFuel;
139                if (supplies > maxSupplies) supplies = maxSupplies;
140                
141                CommoditySpecAPI fuelComm = Global.getSettings().getCommoditySpec(Commodities.FUEL);
142                CommoditySpecAPI suppliesComm = Global.getSettings().getCommoditySpec(Commodities.FUEL);
143                
144                float distressPayment = fuel * fuelComm.getBasePrice() + supplies * suppliesComm.getBasePrice();
145                distressPayment = (float) Math.ceil(distressPayment / 10000f) * 10000f;
146                distressPayment *= 2f;
147                
148                return (int) distressPayment;
149        }
150        
151        protected int getNumUses() {
152                AbilityPlugin plugin = playerFleet.getAbility(Abilities.DISTRESS_CALL);
153                if (plugin != null) {
154                        int uses = ((DistressCallAbility) plugin).getNumUsesInLastPeriod();
155                        return uses;
156                }
157                return 0;
158        }
159
160        protected boolean playerNeedsHelp() {
161                return getNeededFuel() > 0 || getNeededSupplies() > 0;
162        }
163        
164        protected void cargoPodsScam() {
165                Misc.adjustRep(REP_SCAM, RepLevel.INHOSPITABLE, fleet.getFaction().getId(),
166                                           REP_SCAM, RepLevel.INHOSPITABLE, person, text);
167                
168                unrespond();    
169        }
170        
171        
172        protected boolean isCargoPodsScam () {
173                for (SectorEntityToken entity : fleet.getContainingLocation().getAllEntities()) {
174                        if (Entities.CARGO_PODS.equals(entity.getCustomEntityType())) {
175                                VisibilityLevel level = entity.getVisibilityLevelTo(fleet);
176                                if (level == VisibilityLevel.COMPOSITION_DETAILS ||
177                                                level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) {
178                                        if (entity.getCargo().getFuel() >= 10 || entity.getCargo().getSupplies() >= 10) {
179                                                return true;
180                                        }
181                                }
182                        }
183                }
184                return false;
185        }
186        
187        protected int getNeededFuel() {
188                return getNeededFuel(playerFleet);
189        }
190        
191        public static int getNeededFuel(CampaignFleetAPI playerFleet) {
192                float returnDistLY = Misc.getDistanceLY(new Vector2f(), playerFleet.getLocationInHyperspace());
193                int fuel = (int) (returnDistLY * Math.max(1, playerFleet.getLogistics().getFuelCostPerLightYear()));
194                fuel *= 0.75f;
195                if (fuel < 10) fuel = 10;
196                fuel -= playerFleet.getCargo().getFuel();
197                if (fuel < 0) fuel = 0;
198                
199                return fuel;
200        }
201        
202        protected int getNeededSupplies() {
203                //int supplies = (int) (playerCargo.getMaxCapacity() * 0.25f);
204                float supplies = 0f;
205                for (FleetMemberAPI member : playerFleet.getFleetData().getMembersListCopy()) {
206                        supplies += member.getStats().getSuppliesPerMonth().getModifiedValue();
207                }
208                //supplies *= 2;
209                
210                if (supplies < 5) supplies = 5;
211                supplies -= playerCargo.getSupplies();
212                if (supplies < 0) supplies = 0;
213                
214                return (int) supplies;
215        }
216
217        protected float getRepPenalty() {
218                float uses = getNumUses();
219                return REP_PER_USE * (uses + 1);
220        }
221        
222        protected void didNotNeedHelp() {
223                float penalty = getRepPenalty();
224                Misc.adjustRep(penalty, RepLevel.INHOSPITABLE, fleet.getFaction().getId(),
225                                           penalty * 2f, RepLevel.INHOSPITABLE, person, text);
226                
227                unrespond();
228        }
229
230        protected void neverMind() {
231                float penalty = getRepPenalty();
232                Misc.adjustRep(penalty * 0.5f, RepLevel.INHOSPITABLE, fleet.getFaction().getId(),
233                                           penalty, RepLevel.INHOSPITABLE, person, text);
234        }
235
236        protected int getMaxFuel() {
237                return (int) Math.max(10, (fleet.getCargo().getMaxFuel() * 0.25f));
238        }
239        protected int getMaxSupplies() {
240                return (int) Math.max(10, (fleet.getCargo().getMaxCapacity() * 0.1f));
241        }
242        
243        protected void pay() {
244                //int credits = getPayment();
245                int credits = (int) person.getMemoryWithoutUpdate().getFloat("$distressPayment");
246                playerCargo.getCredits().subtract(credits);
247                AddRemoveCommodity.addCreditsLossText(credits, text);
248                
249                float uses = getNumUses();
250                if (uses <= 4) {
251                        Misc.adjustRep(0.01f, RepLevel.WELCOMING, fleet.getFaction().getId(),
252                                                   0.02f, RepLevel.WELCOMING, person, text);
253                }
254        }
255        
256        protected void thank() {
257                float penalty = getRepPenalty();
258                Misc.adjustRep(penalty, RepLevel.INHOSPITABLE, fleet.getFaction().getId(),
259                                           penalty * 2f, RepLevel.INHOSPITABLE, person, text);
260        }
261        
262        protected void acceptAid() {
263                int fuel = getNeededFuel();
264                int supplies = getNeededSupplies();
265                
266                int maxFuel = getMaxFuel();
267                int maxSupplies = getMaxSupplies();
268                
269                if (fuel > maxFuel) fuel = maxFuel;
270                if (supplies > maxSupplies) supplies = maxSupplies;
271
272//              float penalty = getRepPenalty();
273//              Misc.adjustRep(penalty, RepLevel.INHOSPITABLE, fleet.getFaction().getId(),
274//                                         penalty * 2f, RepLevel.INHOSPITABLE, person, text);
275                
276                if (fuel > 0) {
277                        playerCargo.addFuel(fuel);
278                        AddRemoveCommodity.addCommodityGainText(Commodities.FUEL, fuel, text);
279                }
280                if (supplies > 0) {
281                        playerCargo.addSupplies(supplies);
282                        AddRemoveCommodity.addCommodityGainText(Commodities.SUPPLIES, supplies, text);
283                }
284
285                unrespond();
286        }
287        
288        protected void unrespond() {
289                Misc.clearTarget(fleet, true);
290                Misc.makeUnimportant(fleet, "distressResponse");
291                fleet.getMemoryWithoutUpdate().unset("$distressResponse");
292                Misc.giveStandardReturnToSourceAssignments(fleet);
293        }
294
295
296        
297}
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312