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}