001package com.fs.starfarer.api.impl.campaign.missions.hub; 002 003import java.util.HashSet; 004import java.util.List; 005import java.util.Set; 006 007import com.fs.starfarer.api.EveryFrameScript; 008import com.fs.starfarer.api.Global; 009import com.fs.starfarer.api.campaign.CampaignFleetAPI; 010import com.fs.starfarer.api.campaign.FleetAssignment; 011import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel; 012import com.fs.starfarer.api.campaign.ai.CampaignFleetAIAPI.EncounterOption; 013import com.fs.starfarer.api.campaign.ai.FleetAssignmentDataAPI; 014import com.fs.starfarer.api.campaign.ai.ModularFleetAIAPI; 015import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 016import com.fs.starfarer.api.util.IntervalUtil; 017import com.fs.starfarer.api.util.Misc; 018 019public class MissionFleetInterceptPlayerIfNearby implements EveryFrameScript { 020 021 protected CampaignFleetAPI fleet; 022 protected BaseHubMission mission; 023 protected Set<Object> stages = new HashSet<Object>(); 024 protected boolean done = false; 025 protected float delay; 026 protected float delayRemaining; 027 protected float maxRange; 028 protected boolean repeatable; 029 protected boolean mustBeStrongEnoughToFight; 030 031 protected IntervalUtil interval = new IntervalUtil(0.05f, 0.1f); 032 033 public MissionFleetInterceptPlayerIfNearby(CampaignFleetAPI fleet, BaseHubMission mission, 034 boolean mustBeStrongEnoughToFight, float maxRange, boolean repeatable, float repeatDelay, List<Object> stages) { 035 this.delay = repeatDelay; 036 this.mission = mission; 037 this.fleet = fleet; 038 this.mustBeStrongEnoughToFight = mustBeStrongEnoughToFight; 039 this.maxRange = maxRange; 040 this.repeatable = repeatable; 041 this.stages.addAll(stages); 042 } 043 044 public void advance(float amount) { 045 if (done) return; 046 047 float days = Global.getSector().getClock().convertToDays(amount); 048 delayRemaining -= days; 049 if (delayRemaining < 0) delayRemaining = 0; 050 if (delayRemaining > 0) return; 051 052 interval.advance(days); 053 if (!interval.intervalElapsed()) return; 054 055 if (fleet.getMemoryWithoutUpdate().getBoolean("$turnOffAutoInterceptScript")) { 056 done = true; 057 return; 058 } 059 060 Object stage = mission.getCurrentStage(); 061 if (!stages.contains(stage)) { 062 done = true; 063 return; 064 } 065 066 if (fleet.getAI() instanceof ModularFleetAIAPI) { 067 ModularFleetAIAPI ai = (ModularFleetAIAPI) fleet.getAI(); 068 CampaignFleetAPI player = Global.getSector().getPlayerFleet(); 069 070 if (mustBeStrongEnoughToFight && ai.getTacticalModule() != null) { 071 EncounterOption option = ai.getTacticalModule().pickEncounterOption(null, player); 072 boolean recentlyBeaten = fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.MEMORY_KEY_RECENTLY_DEFEATED_BY_PLAYER); 073 if (recentlyBeaten) option = EncounterOption.DISENGAGE; 074 if (option == EncounterOption.DISENGAGE || option == EncounterOption.HOLD_VS_STRONGER) { 075 return; 076 } 077 } 078 079 if (ai.getAssignmentModule() != null) { 080 FleetAssignmentDataAPI curr = ai.getAssignmentModule().getCurrentAssignment(); 081 if (curr != null && curr.getTarget() == player && 082 (curr.getAssignment() == FleetAssignment.INTERCEPT || 083 curr.getAssignment() == FleetAssignment.FOLLOW)) { 084 return; 085 } else { 086 087 if (player.getContainingLocation() == fleet.getContainingLocation() && 088 Misc.getDistance(player, fleet) <= maxRange + player.getRadius() + fleet.getRadius() && 089 fleet.getVisibilityLevelOfPlayerFleet() != VisibilityLevel.NONE) { 090 ai.getAssignmentModule().addAssignmentAtStart(FleetAssignment.INTERCEPT, player, 3f, null); 091 delayRemaining = delay; 092 if (!repeatable) { 093 done = true; 094 } 095 } 096 } 097 } 098 } 099 } 100 101 public boolean isDone() { 102 return done; 103 } 104 105 public boolean runWhilePaused() { 106 return false; 107 } 108 109 110} 111 112 113 114 115 116 117 118 119 120