001package com.fs.starfarer.api.impl.campaign.rulecmd.salvage;
002
003import java.util.ArrayList;
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.CargoStackAPI;
011import com.fs.starfarer.api.campaign.FleetEncounterContextPlugin.DataForEncounterSide;
012import com.fs.starfarer.api.campaign.FleetEncounterContextPlugin.FleetMemberData;
013import com.fs.starfarer.api.campaign.InteractionDialogAPI;
014import com.fs.starfarer.api.campaign.InteractionDialogPlugin;
015import com.fs.starfarer.api.campaign.SectorEntityToken;
016import com.fs.starfarer.api.campaign.rules.MemoryAPI;
017import com.fs.starfarer.api.combat.BattleCreationContext;
018import com.fs.starfarer.api.fleet.FleetMemberAPI;
019import com.fs.starfarer.api.impl.campaign.FleetEncounterContext;
020import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl;
021import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.BaseFIDDelegate;
022import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.FIDConfig;
023import com.fs.starfarer.api.impl.campaign.ids.Drops;
024import com.fs.starfarer.api.impl.campaign.ids.Factions;
025import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
026import com.fs.starfarer.api.impl.campaign.ids.Stats;
027import com.fs.starfarer.api.impl.campaign.ids.Tags;
028import com.fs.starfarer.api.impl.campaign.procgen.SalvageEntityGenDataSpec.DropData;
029import com.fs.starfarer.api.impl.campaign.rulecmd.BaseCommandPlugin;
030import com.fs.starfarer.api.impl.campaign.rulecmd.FireBest;
031import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.SalvageGenFromSeed.SDMParams;
032import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.SalvageGenFromSeed.SalvageDefenderModificationPlugin;
033import com.fs.starfarer.api.loading.WeaponSpecAPI;
034import com.fs.starfarer.api.util.Misc;
035import com.fs.starfarer.api.util.Misc.Token;
036
037/**
038 *      SalvageDefenderInteraction
039 */
040public class SalvageDefenderInteraction extends BaseCommandPlugin {
041
042        public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, final Map<String, MemoryAPI> memoryMap) {
043                if (dialog == null) return false;
044                
045                final SectorEntityToken entity = dialog.getInteractionTarget();
046                final MemoryAPI memory = getEntityMemory(memoryMap);
047
048                final CampaignFleetAPI defenders = memory.getFleet("$defenderFleet");
049                if (defenders == null) return false;
050                
051                dialog.setInteractionTarget(defenders);
052                
053                final FIDConfig config = new FIDConfig();
054                config.leaveAlwaysAvailable = true;
055                config.showCommLinkOption = false;
056                config.showEngageText = false;
057                config.showFleetAttitude = false;
058                config.showTransponderStatus = false;
059                config.showWarningDialogWhenNotHostile = false;
060                config.alwaysAttackVsAttack = true;
061                config.impactsAllyReputation = true;
062                config.impactsEnemyReputation = false;
063                config.pullInAllies = false;
064                config.pullInEnemies = false;
065                config.pullInStations = false;
066                config.lootCredits = false;
067                
068                config.firstTimeEngageOptionText = "Engage the automated defenses";
069                config.afterFirstTimeEngageOptionText = "Re-engage the automated defenses";
070                config.noSalvageLeaveOptionText = "Continue";
071                
072                config.dismissOnLeave = false;
073                config.printXPToDialog = true;
074                
075                long seed = memory.getLong(MemFlags.SALVAGE_SEED);
076                config.salvageRandom = Misc.getRandom(seed, 75);
077                
078                
079                final FleetInteractionDialogPluginImpl plugin = new FleetInteractionDialogPluginImpl(config);
080                
081                final InteractionDialogPlugin originalPlugin = dialog.getPlugin();
082                config.delegate = new BaseFIDDelegate() {
083                        @Override
084                        public void notifyLeave(InteractionDialogAPI dialog) {
085                                // nothing in there we care about keeping; clearing to reduce savefile size
086                                defenders.getMemoryWithoutUpdate().clear();
087                                // there's a "standing down" assignment given after a battle is finished that we don't care about
088                                defenders.clearAssignments();
089                                defenders.deflate();
090                                
091                                dialog.setPlugin(originalPlugin);
092                                dialog.setInteractionTarget(entity);
093                                
094                                //Global.getSector().getCampaignUI().clearMessages();
095                                
096                                if (plugin.getContext() instanceof FleetEncounterContext) {
097                                        FleetEncounterContext context = (FleetEncounterContext) plugin.getContext();
098                                        if (context.didPlayerWinEncounterOutright()) {
099                                                
100                                                SDMParams p = new SDMParams();
101                                                p.entity = entity;
102                                                p.factionId = defenders.getFaction().getId();
103                                                
104                                                SalvageDefenderModificationPlugin plugin = Global.getSector().getGenericPlugins().pickPlugin(
105                                                                                                SalvageDefenderModificationPlugin.class, p);
106                                                if (plugin != null) {
107                                                        plugin.reportDefeated(p, entity, defenders);
108                                                }
109                                                
110                                                memory.unset("$hasDefenders");
111                                                memory.unset("$defenderFleet");
112                                                memory.set("$defenderFleetDefeated", true);
113                                                entity.removeScriptsOfClass(FleetAdvanceScript.class);
114                                                FireBest.fire(null, dialog, memoryMap, "BeatDefendersContinue");
115                                        } else {
116                                                boolean persistDefenders = false;
117                                                if (context.isEngagedInHostilities()) {
118                                                        persistDefenders |= !Misc.getSnapshotMembersLost(defenders).isEmpty();
119                                                        for (FleetMemberAPI member : defenders.getFleetData().getMembersListCopy()) {
120                                                                if (member.getStatus().needsRepairs()) {
121                                                                        persistDefenders = true;
122                                                                        break;
123                                                                }
124                                                        }
125                                                }
126                                                
127                                                if (persistDefenders) {
128                                                        if (!entity.hasScriptOfClass(FleetAdvanceScript.class)) {
129                                                                defenders.setDoNotAdvanceAI(true);
130                                                                defenders.setContainingLocation(entity.getContainingLocation());
131                                                                // somewhere far off where it's not going to be in terrain or whatever
132                                                                defenders.setLocation(1000000, 1000000);
133                                                                entity.addScript(new FleetAdvanceScript(defenders));
134                                                        }
135                                                        memory.expire("$defenderFleet", 10); // defenders may have gotten damaged; persist them for a bit
136                                                }
137                                                dialog.dismiss();
138                                        }
139                                } else {
140                                        dialog.dismiss();
141                                }
142                        }
143                        @Override
144                        public void battleContextCreated(InteractionDialogAPI dialog, BattleCreationContext bcc) {
145                                bcc.aiRetreatAllowed = false;
146                                bcc.objectivesAllowed = false;
147                                bcc.enemyDeployAll = true;
148                        }
149                        @Override
150                        public void postPlayerSalvageGeneration(InteractionDialogAPI dialog, FleetEncounterContext context, CargoAPI salvage) {
151                                DataForEncounterSide winner = context.getWinnerData();
152                                DataForEncounterSide loser = context.getLoserData();
153
154                                if (winner == null || loser == null) return;
155                                
156                                float playerContribMult = context.computePlayerContribFraction();
157                                
158                                List<DropData> dropRandom = new ArrayList<DropData>();
159                                List<DropData> dropValue = new ArrayList<DropData>();
160                                
161                                float valueMultFleet = Global.getSector().getPlayerFleet().getStats().getDynamic().getValue(Stats.BATTLE_SALVAGE_MULT_FLEET);
162                                float valueModShips = context.getSalvageValueModPlayerShips();
163                                
164                                for (FleetMemberData data : winner.getEnemyCasualties()) {
165                                        // add at least one of each weapon that was present on the OMEGA ships, since these
166                                        // are hard to get; don't want them to be too RNG
167                                        if (data.getMember() != null && context.getBattle() != null) {
168                                                CampaignFleetAPI fleet = context.getBattle().getSourceFleet(data.getMember());
169                                        
170                                                if (fleet != null && fleet.getFaction().getId().equals(Factions.OMEGA)) {
171                                                        for (String slotId : data.getMember().getVariant().getNonBuiltInWeaponSlots()) {
172                                                                String weaponId = data.getMember().getVariant().getWeaponId(slotId);
173                                                                if (weaponId == null) continue;
174                                                                if (salvage.getNumWeapons(weaponId) <= 0) {
175                                                                        WeaponSpecAPI spec = Global.getSettings().getWeaponSpec(weaponId);
176                                                                        if (spec.hasTag(Tags.NO_DROP)) continue;
177                                                                        
178                                                                        salvage.addWeapons(weaponId, 1);
179                                                                }
180                                                        }
181                                                }
182                                                
183                                                if (fleet != null && 
184                                                                fleet.getFaction().getCustomBoolean(Factions.CUSTOM_NO_AI_CORES_FROM_AUTOMATED_DEFENSES)) {
185                                                        continue;
186                                                }
187                                        }
188                                        if (config.salvageRandom.nextFloat() < playerContribMult) {
189                                                DropData drop = new DropData();
190                                                drop.chances = 1;
191                                                drop.value = -1;
192                                                switch (data.getMember().getHullSpec().getHullSize()) {
193                                                case CAPITAL_SHIP:
194                                                        drop.group = Drops.AI_CORES3;
195                                                        drop.chances = 2;
196                                                        break;
197                                                case CRUISER:
198                                                        drop.group = Drops.AI_CORES3;
199                                                        break;
200                                                case DESTROYER:
201                                                        drop.group = Drops.AI_CORES2;
202                                                        break;
203                                                case FIGHTER:
204                                                case FRIGATE:
205                                                        drop.group = Drops.AI_CORES1;
206                                                        break;
207                                                }
208                                                if (drop.group != null) {
209                                                        dropRandom.add(drop);
210                                                }
211                                        }
212                                }
213                                
214                                float fuelMult = Global.getSector().getPlayerFleet().getStats().getDynamic().getValue(Stats.FUEL_SALVAGE_VALUE_MULT_FLEET);
215                                //float fuel = salvage.getFuel();
216                                //salvage.addFuel((int) Math.round(fuel * fuelMult));
217                                
218                                CargoAPI extra = SalvageEntity.generateSalvage(config.salvageRandom, valueMultFleet + valueModShips, 1f, 1f, fuelMult, dropValue, dropRandom);
219                                for (CargoStackAPI stack : extra.getStacksCopy()) {
220                                        if (stack.isFuelStack()) {
221                                                stack.setSize((int)(stack.getSize() * fuelMult));
222                                        }
223                                        salvage.addFromStack(stack);
224                                }
225                                
226                        }
227                        
228                };
229                
230                
231                dialog.setPlugin(plugin);
232                plugin.init(dialog);
233        
234                return true;
235        }
236
237        
238}
239
240
241
242