001package com.fs.starfarer.api.impl.campaign.fleets.misc; 002 003import java.util.Random; 004 005import com.fs.starfarer.api.Global; 006import com.fs.starfarer.api.campaign.BattleAPI; 007import com.fs.starfarer.api.campaign.CampaignFleetAPI; 008import com.fs.starfarer.api.campaign.SectorEntityToken; 009import com.fs.starfarer.api.campaign.StarSystemAPI; 010import com.fs.starfarer.api.campaign.econ.MarketAPI; 011import com.fs.starfarer.api.impl.campaign.fleets.RouteManager; 012import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteData; 013import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteSegment; 014import com.fs.starfarer.api.impl.campaign.fleets.misc.MiscFleetRouteManager.MiscRouteData; 015import com.fs.starfarer.api.impl.campaign.ids.Factions; 016import com.fs.starfarer.api.impl.campaign.ids.FleetTypes; 017import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 018import com.fs.starfarer.api.impl.campaign.ids.Tags; 019import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission; 020import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetQuality; 021import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetSize; 022import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerNum; 023import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerQuality; 024import com.fs.starfarer.api.impl.campaign.missions.hub.MissionFleetAutoDespawn; 025import com.fs.starfarer.api.impl.campaign.shared.SharedData; 026import com.fs.starfarer.api.util.Misc; 027import com.fs.starfarer.api.util.WeightedRandomPicker; 028 029public class MiscAcademyFleetCreator extends BaseMiscFleetCreatorPlugin { 030 031 public static String ACADEMY_FLEET_TYPE = "$academyFleetType"; 032 033 @Override 034 public float getFrequency() { 035 return Global.getSettings().getFloat("miscFleetAcademyFrequency"); 036 } 037 038 @Override 039 public int getMaxFleetsForThisCreator() { 040 return Global.getSettings().getInt("miscFleetAcademyMaxFleets"); 041 } 042 043 public static SectorEntityToken getAcademy() { 044 StarSystemAPI system = Global.getSector().getStarSystem("Galatia"); 045 return system.getEntityById("station_galatia_academy"); 046 } 047 048 049 @Override 050 public MiscRouteData createRouteParams(MiscFleetRouteManager manager, Random random) { 051 MarketAPI from = pickSourceMarket(manager); 052 SectorEntityToken to = getAcademy(); 053 054 if (to == null || to.getContainingLocation().hasTag(Tags.SYSTEM_CUT_OFF_FROM_HYPER)) return null; 055 056 057// from = Global.getSector().getEconomy().getMarket("chalcedon"); 058// to = Global.getSector().getEconomy().getMarket("eochu_bres").getPrimaryEntity(); 059// to = Global.getSector().getEntityById("beholder_station"); 060 061 MiscRouteData result = createData(from, to); 062 063 return result; 064 } 065 066 067 @Override 068 public CampaignFleetAPI createFleet(MiscFleetRouteManager manager, RouteData route, Random random) { 069 MiscRouteData data = (MiscRouteData) route.getCustom(); 070 071 FleetCreatorMission m = new FleetCreatorMission(random); 072 m.beginFleet(); 073 074 075 m.triggerCreateFleet(FleetSize.MEDIUM, FleetQuality.LOWER, data.factionId, 076 FleetTypes.ACADEMY_FLEET, data.from.getLocationInHyperspace()); 077 m.triggerSetFleetOfficers(OfficerNum.FC_ONLY, OfficerQuality.LOWER); 078 m.triggerSetFleetSizeFraction(data.size * 0.5f * (0.5f + random.nextFloat() * 0.5f)); 079 m.triggerFleetSetNoFactionInName(); 080 m.triggerSetTraderFleet(); 081 m.triggerSetFleetComposition(0f, 0f, 0f, 1f, 0f); 082 m.triggerSetFleetMemoryValue(MemFlags.MEMORY_KEY_SOURCE_MARKET, data.from); 083 //m.triggerSetFleetMemoryValue("$destShrine", data.to.getId()); 084 m.triggerSetFleetMemoryValue(MemFlags.ACADEMY_FLEET, true); 085 086 WeightedRandomPicker<String> types = new WeightedRandomPicker<String>(random); 087 types.add("supplies"); 088 types.add("students"); 089 types.add("visitors"); 090 m.triggerSetFleetMemoryValue(ACADEMY_FLEET_TYPE, types.pick()); 091 092 093 CampaignFleetAPI fleet = m.createFleet(); 094 fleet.removeScriptsOfClass(MissionFleetAutoDespawn.class); 095 096 return fleet; 097 } 098 099 100 public MiscRouteData createData(MarketAPI from, SectorEntityToken to) { 101 MiscRouteData data = new MiscRouteData(getId()); 102 data.from = from; 103 data.to = to; 104 105 if (from.getFaction().isHostileTo(Factions.INDEPENDENT)) { 106 data.factionId = from.getFactionId(); 107 } else { 108 data.factionId = Factions.INDEPENDENT; 109 } 110 111 // in case the source colony is hostile to the Hegemony (which has Ancyra in the system) 112 data.smuggling = true; 113 114 float sizeBasis = from.getSize() / 8f; 115 sizeBasis *= 0.25f; 116 if (sizeBasis < 0.05f) sizeBasis = 0.05f; 117 if (sizeBasis > 0.25f) sizeBasis = 0.25f; 118 data.size = sizeBasis; 119 120 return data; 121 } 122 123 public MarketAPI pickSourceMarket(MiscFleetRouteManager manager) { 124 WeightedRandomPicker<MarketAPI> markets = new WeightedRandomPicker<MarketAPI>(manager.getRandom()); 125 for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) { 126 if (market.isHidden()) continue; 127 if (!market.hasSpaceport()) continue; // markets w/o spaceports don't launch fleets 128 if (market.getContainingLocation().hasTag(Tags.SYSTEM_CUT_OFF_FROM_HYPER)) continue; 129 130 if (manager.getTimeout(getId()).contains(market.getId())) continue; 131 132 // use this for academy fleets also 133 if (SharedData.getData().getMarketsWithoutTradeFleetSpawn().contains(market.getId())) continue; 134 135 float distLY = Misc.getDistanceToPlayerLY(market.getPrimaryEntity()); 136 float mult = 1f - Math.min(0.99f, distLY / 10f); 137 138 if (market.getFaction().isHostileTo(Factions.INDEPENDENT)) { 139 mult *= 0.2f; 140 } 141 142 markets.add(market, market.getSize() * mult); 143 } 144 return markets.pick(); 145 } 146 147 @Override 148 public void reportBattleOccurred(MiscFleetRouteManager manager, CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) { 149 RouteData route = RouteManager.getInstance().getRoute(manager.getRouteSourceId(), fleet); 150 if (route == null || !(route.getCustom() instanceof MiscRouteData)) return; 151 152 if (route.isExpired()) return; 153 if (!battle.isPlayerInvolved()) return; 154 155 // player was involved, no the opposite side of the pilgrim fleet 156 if (battle.getNonPlayerSideSnapshot().contains(fleet)) { 157 MiscRouteData data = (MiscRouteData) route.getCustom(); 158 159 // possible TODO: some kind of response, depending? 160 } 161 } 162 163 164 public String getStartingActionText(CampaignFleetAPI fleet, RouteSegment segment, MiscRouteData data) { 165 String type = fleet.getMemoryWithoutUpdate().getString(ACADEMY_FLEET_TYPE); 166 return "preparing for voyage to Galatia Academy"; 167 } 168 169 public String getEndingActionText(CampaignFleetAPI fleet, RouteSegment segment, MiscRouteData data) { 170 //return "orbiting " + data.from.getName(); 171 return "returned from voyage to Galatia Academy"; 172 } 173 174 public String getTravelToDestActionText(CampaignFleetAPI fleet, RouteSegment segment, MiscRouteData data) { 175 return "traveling to Galatia Academy"; 176 } 177 178 public String getTravelReturnActionText(CampaignFleetAPI fleet, RouteSegment segment, MiscRouteData data) { 179 return "traveling to " + data.from.getName(); 180 } 181 182 public String getAtDestUnloadActionText(CampaignFleetAPI fleet, RouteSegment segment, MiscRouteData data) { 183 return "orbiting Galatia Academy"; 184 } 185 186 public String getAtDestLoadActionText(CampaignFleetAPI fleet, RouteSegment segment, MiscRouteData data) { 187 return "orbiting Galatia Academy"; 188 } 189 190}