001package com.fs.starfarer.api.impl.campaign.rulecmd.missions;
002
003import java.awt.Color;
004import java.util.List;
005import java.util.Map;
006
007import com.fs.starfarer.api.Global;
008import com.fs.starfarer.api.campaign.CampaignFleetAPI;
009import com.fs.starfarer.api.campaign.CargoAPI;
010import com.fs.starfarer.api.campaign.FactionAPI;
011import com.fs.starfarer.api.campaign.InteractionDialogAPI;
012import com.fs.starfarer.api.campaign.OptionPanelAPI;
013import com.fs.starfarer.api.campaign.RepLevel;
014import com.fs.starfarer.api.campaign.SectorEntityToken;
015import com.fs.starfarer.api.campaign.TextPanelAPI;
016import com.fs.starfarer.api.campaign.econ.MarketAPI;
017import com.fs.starfarer.api.campaign.rules.MemoryAPI;
018import com.fs.starfarer.api.characters.PersonAPI;
019import com.fs.starfarer.api.fleet.FleetMemberAPI;
020import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin;
021import com.fs.starfarer.api.impl.campaign.ids.Entities;
022import com.fs.starfarer.api.impl.campaign.ids.Ranks;
023import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
024import com.fs.starfarer.api.impl.campaign.intel.BaseMissionIntel.MissionResult;
025import com.fs.starfarer.api.impl.campaign.intel.BaseMissionIntel.MissionState;
026import com.fs.starfarer.api.impl.campaign.intel.FactionCommissionIntel;
027import com.fs.starfarer.api.impl.campaign.rulecmd.BaseCommandPlugin;
028import com.fs.starfarer.api.ui.TooltipMakerAPI;
029import com.fs.starfarer.api.util.Misc;
030import com.fs.starfarer.api.util.Misc.Token;
031
032/**
033 * NotifyEvent $eventHandle <params> 
034 * 
035 */
036public class Commission extends BaseCommandPlugin {
037        
038        public static RepLevel COMMISSION_REQ = RepLevel.FAVORABLE;
039        
040        protected CampaignFleetAPI playerFleet;
041        protected SectorEntityToken entity;
042        protected FactionAPI playerFaction;
043        protected FactionAPI entityFaction;
044        protected TextPanelAPI text;
045        protected OptionPanelAPI options;
046        protected CargoAPI playerCargo;
047        protected MemoryAPI memory;
048        protected InteractionDialogAPI dialog;
049        protected Map<String, MemoryAPI> memoryMap;
050        protected PersonAPI person;
051        protected FactionAPI faction;
052
053        protected boolean offersCommissions;
054        
055        public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
056                
057                this.dialog = dialog;
058                this.memoryMap = memoryMap;
059                
060                String command = params.get(0).getString(memoryMap);
061                if (command == null) return false;
062                
063                memory = getEntityMemory(memoryMap);
064                
065                entity = dialog.getInteractionTarget();
066                text = dialog.getTextPanel();
067                options = dialog.getOptionPanel();
068                
069                playerFleet = Global.getSector().getPlayerFleet();
070                playerCargo = playerFleet.getCargo();
071                
072                playerFaction = Global.getSector().getPlayerFaction();
073                entityFaction = entity.getFaction();
074                
075                person = dialog.getInteractionTarget().getActivePerson();
076                faction = person.getFaction();
077                
078                offersCommissions = faction.getCustomBoolean("offersCommissions");
079                
080                
081                //printInfo
082                //accept
083                
084                if (command.equals("printRequirements")) {
085                        printRequirements();
086                } else if (command.equals("playerMeetsCriteria")) {
087                        return playerMeetsCriteria();
088                } else if (command.equals("printInfo")) {
089                        printInfo();
090                } else if (command.equals("hasFactionCommission")) {
091                        return hasFactionCommission();
092                } else if (command.equals("hasOtherCommission")) {
093                        if (hasOtherCommission()) {
094                                memory.set("$theOtherCommissionFaction", Misc.getCommissionFaction().getDisplayNameWithArticle(), 0);
095                                memory.set("$otherCommissionFaction", Misc.getCommissionFaction().getPersonNamePrefix(), 0);
096                                return true;
097                        }
098                        return false;
099                } else if (command.equals("accept")) {
100                        accept();
101                } else if (command.equals("resign")) {
102                        resign(true);
103                } else if (command.equals("resignNoPenalty")) {
104                        resign(false);
105                } else if (command.equals("personCanGiveCommission")) {
106                        return personCanGiveCommission();
107                }
108                else if (command.equals("commissionFactionIsAtWarWith")) {
109                        if (hasOtherCommission()) {
110                                if (params.size() >= 1) {
111                                        String target_faction_id = params.get(0).getString(memoryMap);
112                                        FactionAPI target_faction = Global.getSector().getFaction(target_faction_id);
113                                        if(target_faction != null )
114                                        {
115                                                return Misc.getCommissionFaction().isHostileTo(target_faction);
116                                        }
117                                }
118                        }
119                        return false;
120                }
121                else if (command.equals("isCargoPodsScam")) {
122                        MarketAPI market = dialog.getInteractionTarget().getMarket();
123                        if(market == null) 
124                                return false;
125                        //Misc.getStorage(market)
126                        for (SectorEntityToken entity : market.getContainingLocation().getAllEntities()) {
127                                if (Entities.CARGO_PODS.equals(entity.getCustomEntityType())) {
128                                        
129                                        // use player fleet 'cause it's in market range, right? And therefore scan range.
130                                        // market is otherwise attached to a station or planet entity (who knows!)
131                                        float dist = Misc.getDistance(entity.getLocation(), playerFleet.getLocation()); 
132                                        if( dist < 500f)
133                                                if (entity.getCargo().getSupplies() >= 10)
134                                                {
135                                                        return true;
136                                                }
137                                                        
138                                }
139                        }
140                        return false;
141                }
142                else if (command.equals("recalcFreeSupplyDaysRemaining")) {
143                        Object obj1 = person.getFaction().getMemoryWithoutUpdate().get("$playerReceivedCommissionResupplyOn");
144                        Object obj2 = Global.getSector().getMemoryWithoutUpdate().get("$daysSinceStart"); 
145                        if(obj1 == null) return false;
146                        if(obj2 == null) return false;
147
148                        float d1 = (Float) obj1;
149                        float d2 = (Float) obj2;
150                        
151                        faction.getMemoryWithoutUpdate().set("$daysLeft", (int)d1 + 365 - (int)d2 , 0);
152                }
153                else if (command.equals("doesPlayerFleetNeedRepairs")) {
154        
155                        
156                        float fleetCRcurrent = 0f;
157                        float fleetCRmax = 0f;
158                        float fleetHullDamage = 0f;
159
160                        //playerFleet.getFleetData().getMembersListCopy()
161                        for (FleetMemberAPI member : playerFleet.getMembersWithFightersCopy()) {
162                                if(member.isFighterWing()) continue; // no one cares about fighters.
163                                
164                                //if (member.canBeRepaired()) {
165                                fleetHullDamage += 1f - member.getStatus().getHullFraction();
166                                fleetCRcurrent += member.getRepairTracker().getCR();
167                                fleetCRmax += member.getRepairTracker().getMaxCR();
168
169                        }
170                        
171
172                        //System.out.println("doesPlayerFleetNeedRepairs results:");
173                        //System.out.println("fleetCRcurrent = " + fleetCRcurrent);
174                        //System.out.println("fleetCRmax = " + fleetCRmax);
175                        //System.out.println("fleetHullDamage = " + fleetHullDamage); // ever 1f is about 100% of a ship
176                        
177                        boolean needsSupplies = false;
178                        
179                        if(fleetHullDamage > 0.5) {
180                                needsSupplies = true;
181                                
182                                Global.getSector().getPlayerMemoryWithoutUpdate().set("$fleetDamaged", true , 0);
183                                //memory.set("$fleetDamaged", true , 0); // "Looks like you've taken some damage."
184                        }
185                        
186                        if(fleetHullDamage > 2.5) {
187                                needsSupplies = true;
188                                Global.getSector().getPlayerMemoryWithoutUpdate().set("$fleetDamagedLots", true , 0); // "Your fleet is in rough shape, captain."
189                        }
190                        
191
192                        // basically, if the CR percent is less than 60% (of max) for the fleet, acknowledge that supplies are needed.
193                        if(fleetCRcurrent == 0 || (fleetCRcurrent / fleetCRmax < 0.6f) ) {
194                                needsSupplies = true;
195                                Global.getSector().getPlayerMemoryWithoutUpdate().set("$fleetLowCR", true , 0);
196                        }
197                        
198                        //memory.set("$fleetLowCR", true , 0);
199                        //memory.set("$fleetDamaged", true , 0);
200                        //memory.set("$fleetDamagedLots", true , 0);
201                        
202                        return needsSupplies;
203                }
204                
205                return true;
206        }
207
208        protected boolean hasFactionCommission() {
209                return faction.getId().equals(Misc.getCommissionFactionId());
210        }
211        protected boolean hasOtherCommission() {
212                return Misc.getCommissionFactionId() != null && !hasFactionCommission();
213        }
214        
215        
216        protected boolean personCanGiveCommission() {
217                if (person == null || !offersCommissions) return false;
218                if (person.getFaction().isPlayerFaction()) return false;
219                
220                //if (Misc.getCommissionFactionId() != null) return false;
221                
222                return Ranks.POST_BASE_COMMANDER.equals(person.getPostId()) ||
223                           Ranks.POST_STATION_COMMANDER.equals(person.getPostId()) ||
224                           Ranks.POST_ADMINISTRATOR.equals(person.getPostId()) ||
225                           Ranks.POST_OUTPOST_COMMANDER.equals(person.getPostId());
226        }
227        
228        protected void resign(boolean withPenalty) {
229                FactionCommissionIntel intel = Misc.getCommissionIntel();
230                if (intel != null) {
231                        MissionResult result = intel.createResignedCommissionResult(withPenalty, true, dialog);
232                        intel.setMissionResult(result);
233                        intel.setMissionState(MissionState.ABANDONED);
234                        intel.endMission(dialog);
235                }
236        }
237        
238        protected void accept() {
239                if (Misc.getCommissionFactionId() == null) {
240                        FactionCommissionIntel intel = new FactionCommissionIntel(faction);
241                        intel.missionAccepted();
242                        intel.sendUpdate(FactionCommissionIntel.UPDATE_PARAM_ACCEPTED, dialog.getTextPanel());
243                        intel.makeRepChanges(dialog);
244                }
245        }
246        
247        protected void printInfo() {
248                TooltipMakerAPI info = dialog.getTextPanel().beginTooltip();
249                
250                FactionCommissionIntel temp = new FactionCommissionIntel(faction);
251                
252                Color h = Misc.getHighlightColor();
253                Color g = Misc.getGrayColor();
254                float pad = 3f;
255                float opad = 10f;
256                
257                info.setParaSmallInsignia();
258
259                int stipend = (int) temp.computeStipend();
260                
261                info.addPara("At your experience level, you would receive a %s monthly stipend, as well as a modest bounty for destroying enemy ships.",
262                                0f, h, Misc.getDGSCredits(stipend));
263                
264                List<FactionAPI> hostile = temp.getHostileFactions();
265                if (hostile.isEmpty()) {
266                        info.addPara(Misc.ucFirst(faction.getDisplayNameWithArticle()) + " is not currently hostile to any major factions.", 0f);
267                } else {
268                        info.addPara(Misc.ucFirst(faction.getDisplayNameWithArticle()) + " is currently hostile to:", opad);
269                        
270                        info.setParaFontDefault();
271                        
272                        info.setBulletedListMode(BaseIntelPlugin.INDENT);
273                        float initPad = opad;
274                        for (FactionAPI other : hostile) {
275                                info.addPara(Misc.ucFirst(other.getDisplayName()), other.getBaseUIColor(), initPad);
276                                initPad = 3f;
277                        }
278                        info.setBulletedListMode(null);
279                }
280                
281                
282                dialog.getTextPanel().addTooltip();
283        }
284        
285        
286        protected boolean playerMeetsCriteria() {
287                return faction.getRelToPlayer().isAtWorst(COMMISSION_REQ);
288        }
289        protected void printRequirements() {
290                CoreReputationPlugin.addRequiredStanding(entityFaction, COMMISSION_REQ, null, dialog.getTextPanel(), null, null, 0f, true);
291                CoreReputationPlugin.addCurrentStanding(entityFaction, null, dialog.getTextPanel(), null, null, 0f);
292        }
293        
294        
295        
296}
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311