001package com.fs.starfarer.api.impl.campaign.intel.bar.events;
002
003import java.util.Random;
004
005import org.lwjgl.util.vector.Vector2f;
006
007import com.fs.starfarer.api.EveryFrameScript;
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.campaign.BattleAPI;
010import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
011import com.fs.starfarer.api.campaign.CampaignFleetAPI;
012import com.fs.starfarer.api.campaign.FleetAssignment;
013import com.fs.starfarer.api.campaign.StarSystemAPI;
014import com.fs.starfarer.api.campaign.ai.CampaignFleetAIAPI.EncounterOption;
015import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
016import com.fs.starfarer.api.campaign.rules.MemoryAPI;
017import com.fs.starfarer.api.characters.AbilityPlugin;
018import com.fs.starfarer.api.characters.FullName.Gender;
019import com.fs.starfarer.api.impl.campaign.DebugFlags;
020import com.fs.starfarer.api.impl.campaign.fleets.AutoDespawnScript;
021import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
022import com.fs.starfarer.api.impl.campaign.fleets.FleetParamsV3;
023import com.fs.starfarer.api.impl.campaign.ids.Abilities;
024import com.fs.starfarer.api.impl.campaign.ids.Factions;
025import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
026import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
027import com.fs.starfarer.api.util.Misc;
028
029public class DeliveryFailureConsequences implements EveryFrameScript, FleetEventListener {
030
031        public static float RADIUS_FROM_CORE = 30000f; // may send fleet when within this radius from core
032        public static float DAYS_IN_SYSTEM = 7f;
033        
034        protected float delayDays;
035        protected boolean sentFleet;
036        protected String name;
037        protected String commodity;
038        protected Gender gender;
039        protected float reward;
040        protected long seed;
041        public DeliveryFailureConsequences(DeliveryMissionIntel intel) {
042                name = intel.getEvent().getPerson().getNameString();
043                gender = intel.getEvent().getPerson().getGender();
044                commodity = Global.getSettings().getCommoditySpec(intel.getEvent().getCommodityId()).getLowerCaseName();
045                
046                reward = intel.getEvent().getReward();
047                
048                seed = Misc.genRandomSeed();
049                
050                delayDays = 100f + (float) Math.random() * 200f;
051                
052                if (DebugFlags.BAR_DEBUG) {
053                        delayDays = 0f;
054                }
055        }
056        
057        protected StarSystemAPI systemPlayerIsIn = null;
058        protected float daysInSystem = 0f;
059        public void advance(float amount) {
060                if (sentFleet) return;
061                
062                float days = Misc.getDays(amount);
063                //days *= 1000f;
064                delayDays -= days;
065                if (delayDays > 0) return;
066                
067                
068                CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
069                float distFromCore = playerFleet.getLocationInHyperspace().length();
070                if (distFromCore > RADIUS_FROM_CORE) {
071                        daysInSystem = 0f;
072                        systemPlayerIsIn = null;
073                        return;
074                }
075                        
076                if (!(playerFleet.getContainingLocation() instanceof StarSystemAPI)) {
077                        if ((daysInSystem > DAYS_IN_SYSTEM || DebugFlags.BAR_DEBUG) && systemPlayerIsIn != null) {
078                                float dist = Misc.getDistance(systemPlayerIsIn.getLocation(), playerFleet.getLocationInHyperspace());
079                                if (dist < 3000f) {
080                                        sendFleet();
081                                }
082                        }
083                        daysInSystem = 0f;
084                        systemPlayerIsIn = null;
085                        return;
086                }
087                
088                systemPlayerIsIn = (StarSystemAPI)playerFleet.getContainingLocation();
089                daysInSystem += days;
090        }
091        
092        protected void sendFleet() {
093                if (sentFleet) return;
094                sentFleet = true;
095                CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
096                CampaignFleetAPI hunter = createBountyHunter();
097                if (hunter != null) {
098                        Global.getSector().getHyperspace().addEntity(hunter);
099                        Vector2f hunterLoc = Misc.getPointAtRadius(playerFleet.getLocationInHyperspace(), 500f);
100                        hunter.setLocation(hunterLoc.x, hunterLoc.y);
101                        hunter.getAI().addAssignmentAtStart(FleetAssignment.INTERCEPT, playerFleet, 1000f, null);
102                        Misc.giveStandardReturnToSourceAssignments(hunter, false);
103                }
104                
105        }
106
107        protected CampaignFleetAPI createBountyHunter() {
108                Random random = new Random(seed);
109                String faction = Factions.INDEPENDENT;
110                
111                float pts = reward / 400;
112                pts *= 0.8f + 0.4f * random.nextFloat();
113                if (pts < 30) pts = 30;
114                if (pts > 150) pts = 150; //maxes out at a 60k mission reward
115                
116                float qMod = reward / 100000f; // but the quality keeps going up
117                
118                String hunter = "bounty hunter";
119                
120                if (random.nextFloat() < 0.5f) {
121                        faction = Factions.PIRATES;
122                        pts *= 1.5f;
123                        hunter = "pirate";
124                }
125                
126                FleetParamsV3 params = new FleetParamsV3(
127                                null,
128                                Global.getSector().getPlayerFleet().getLocationInHyperspace(),
129                                faction,
130                                null,
131                                FleetTypes.MERC_BOUNTY_HUNTER,
132                                pts, // combatPts
133                                0f, // freighterPts 
134                                pts * 0.1f, // tankerPts
135                                0f, // transportPts
136                                0f, // linerPts
137                                0f, // utilityPts
138                                qMod // qualityMod
139                );
140                params.random = random;
141                
142                CampaignFleetAPI fleet = FleetFactoryV3.createFleet(params);
143                if (fleet.isEmpty()) fleet = null;
144                
145                if (fleet != null) {
146                        EncounterOption option = fleet.getAI().pickEncounterOption(null, Global.getSector().getPlayerFleet());
147                        if (option == EncounterOption.DISENGAGE) {
148                                fleet = null;
149                        }
150                }
151                
152                if (fleet != null) {
153                        //fleet.setFaction(Factions.INDEPENDENT, true);
154                        Misc.makeLowRepImpact(fleet, "dmi");
155
156                        fleet.addScript(new AutoDespawnScript(fleet));
157                        fleet.addEventListener(this);
158                        
159                        MemoryAPI memory = fleet.getMemoryWithoutUpdate();
160                        memory.set(MemFlags.MEMORY_KEY_MAKE_HOSTILE, true);
161                        memory.set(MemFlags.MEMORY_KEY_MAKE_AGGRESSIVE, true);
162                        memory.set(MemFlags.MEMORY_KEY_ALLOW_LONG_PURSUIT, true);
163                        
164                        String hisOrHer = "his";
165                        String himOrHer = "him";
166                        if (gender == Gender.FEMALE) {
167                                hisOrHer = "her";
168                                himOrHer = "her";
169                        }
170                        memory.set("$dmi_bountyHunter", true);
171                        memory.set("$dmi_hisOrHer", hisOrHer);
172                        memory.set("$dmi_himOrHer", himOrHer);
173                        memory.set("$dmi_name", name);
174                        memory.set("$dmi_commodity", commodity);
175                        memory.set("$dmi_hunter", hunter);
176
177                        if (reward >= 50000) {
178                                AbilityPlugin eb = fleet.getAbility(Abilities.EMERGENCY_BURN);
179                                if (eb != null) eb.activate();
180                        }
181                }
182                return fleet;
183        }
184        
185        
186
187        public boolean isDone() {
188                return sentFleet;
189        }
190
191        public boolean runWhilePaused() {
192                return false;
193        }
194
195        public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) {
196                MemoryAPI memory = fleet.getMemoryWithoutUpdate();
197                memory.unset(MemFlags.MEMORY_KEY_MAKE_AGGRESSIVE);
198        }
199
200        public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) {
201                
202        }
203
204}