001package com.fs.starfarer.api.impl.combat.threat; 002 003import com.fs.starfarer.api.EveryFrameScript; 004import com.fs.starfarer.api.Global; 005import com.fs.starfarer.api.campaign.CampaignFleetAPI; 006import com.fs.starfarer.api.campaign.FleetAssignment; 007import com.fs.starfarer.api.campaign.SectorEntityToken; 008import com.fs.starfarer.api.campaign.StarSystemAPI; 009import com.fs.starfarer.api.campaign.ai.ModularFleetAIAPI; 010import com.fs.starfarer.api.impl.campaign.fleets.DisposableFleetManager; 011import com.fs.starfarer.api.impl.campaign.ids.Abilities; 012import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 013import com.fs.starfarer.api.impl.campaign.ids.Stats; 014import com.fs.starfarer.api.util.Misc; 015 016public class ThreatFleetBehaviorScript implements EveryFrameScript { 017 018 public static float MIN_SECONDS_TO_PURSUE_AFTER_SEEN_BY_PLAYER = 30f; 019 public static float MAX_SECONDS_TO_PURSUE_AFTER_SEEN_BY_PLAYER = 120f; 020 protected StarSystemAPI system; 021 protected CampaignFleetAPI fleet; 022 protected DisposableFleetManager manager; 023 024 protected float seenByPlayerTimeout = 0f; 025 026 027 public ThreatFleetBehaviorScript(CampaignFleetAPI fleet, StarSystemAPI system) { 028 this.fleet = fleet; 029 this.system = system; 030 031 pickNext(); 032 } 033 034 protected void pickNext() { 035 float days = 1f + 1f * (float) Math.random(); 036 SectorEntityToken target = system.createToken(0, 0); 037 float distFromTarget = Misc.getDistance(fleet, target); 038 if (distFromTarget < 7000f) target = null; 039 040 CampaignFleetAPI player = Global.getSector().getPlayerFleet(); 041 if (player != null) { 042 float distFromPlayer = Misc.getDistance(fleet, player); 043 if (distFromPlayer < 4000f) target = null; 044 } 045 046 fleet.addAssignment(FleetAssignment.PATROL_SYSTEM, target, days, "cruising"); 047 } 048 049 public void advance(float amount) { 050 if (fleet.getCurrentAssignment() == null) { 051 pickNext(); 052 } 053 054 seenByPlayerTimeout -= amount; 055 056 CampaignFleetAPI player = Global.getSector().getPlayerFleet(); 057 if (player == null) return; 058 059 boolean playerHasSensorMods = Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean( 060 DisposableThreatFleetManager.SENSOR_MODS_KEY); 061 //playerHasSensorMods = true; 062 if (playerHasSensorMods) { 063 fleet.getStats().getDynamic().getStat(Stats.DETECTED_BY_PLAYER_RANGE_MULT).modifyMult( 064 DisposableThreatFleetManager.THREAT_DETECTED_RANGE_MULT_ID, 065 DisposableThreatFleetManager.ONSLAUGHT_MKI_SENSOR_MODIFICATIONS_RANGE_MULT); 066 } else { 067 fleet.getStats().getDynamic().getStat(Stats.DETECTED_BY_PLAYER_RANGE_MULT).unmodifyMult( 068 DisposableThreatFleetManager.THREAT_DETECTED_RANGE_MULT_ID); 069 } 070 071 072 boolean visibleToPlayer = fleet.isVisibleToPlayerFleet() && player.isVisibleToSensorsOf(fleet); 073 if (!Global.getSettings().isCampaignSensorsOn() && fleet.isInCurrentLocation()) { 074 float dist = Misc.getDistance(fleet, player); 075 dist -= fleet.getRadius() + player.getRadius(); 076 if (playerHasSensorMods) { 077 dist /= DisposableThreatFleetManager.ONSLAUGHT_MKI_SENSOR_MODIFICATIONS_RANGE_MULT; 078 } 079 boolean asb = player.getAbility(Abilities.SENSOR_BURST) != null && 080 player.getAbility(Abilities.SENSOR_BURST).isActive(); 081 visibleToPlayer = dist < 150f || asb && dist < 500f; 082 } 083 084 085 if (visibleToPlayer) { 086 setSeenByPlayer(); 087 } 088 if (seenByPlayerTimeout > 0f) { 089 visibleToPlayer = true; 090 } 091 //visibleToPlayer = false; 092 093 if (!visibleToPlayer) { 094 if (fleet.getAI() instanceof ModularFleetAIAPI) { 095 ModularFleetAIAPI ai = (ModularFleetAIAPI) fleet.getAI(); 096 for (int i = 0; i < 3; i++) { 097 ai.getNavModule().avoidEntity(player, 3000f, 5000f, 0.2f); 098 } 099 100 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_HOSTILE, false); 101 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_NON_HOSTILE, true); 102 } 103 } else { 104 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_HOSTILE, true); 105 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_NON_HOSTILE, false); 106 } 107 } 108 109 public void setSeenByPlayer() { 110 seenByPlayerTimeout = MIN_SECONDS_TO_PURSUE_AFTER_SEEN_BY_PLAYER + 111 (MAX_SECONDS_TO_PURSUE_AFTER_SEEN_BY_PLAYER - MIN_SECONDS_TO_PURSUE_AFTER_SEEN_BY_PLAYER) * (float) Math.random(); 112 } 113 114 public boolean isDone() { 115 return false; 116 } 117 118 public boolean runWhilePaused() { 119 return false; 120 } 121 122 123} 124 125 126 127 128 129 130 131 132 133