001package com.fs.starfarer.api.impl.campaign.intel.misc; 002 003import java.util.ArrayList; 004import java.util.List; 005import java.util.Set; 006 007import java.awt.Color; 008 009import org.lwjgl.util.vector.Vector2f; 010 011import com.fs.starfarer.api.Global; 012import com.fs.starfarer.api.campaign.CampaignFleetAPI; 013import com.fs.starfarer.api.campaign.CampaignTerrainAPI; 014import com.fs.starfarer.api.campaign.FactionAPI; 015import com.fs.starfarer.api.campaign.PlanetAPI; 016import com.fs.starfarer.api.campaign.SectorEntityToken; 017import com.fs.starfarer.api.campaign.StarSystemAPI; 018import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin; 019import com.fs.starfarer.api.campaign.rules.MemoryAPI; 020import com.fs.starfarer.api.impl.campaign.entities.GateHaulerEntityPlugin; 021import com.fs.starfarer.api.impl.campaign.ids.Drops; 022import com.fs.starfarer.api.impl.campaign.ids.Entities; 023import com.fs.starfarer.api.impl.campaign.ids.Factions; 024import com.fs.starfarer.api.impl.campaign.ids.Tags; 025import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin; 026import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator; 027import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.AddedEntity; 028import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.EntityLocation; 029import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.OrbitGap; 030import com.fs.starfarer.api.impl.campaign.rulecmd.missions.GateHaulerCMD; 031import com.fs.starfarer.api.impl.campaign.terrain.DebrisFieldTerrainPlugin.DebrisFieldParams; 032import com.fs.starfarer.api.impl.campaign.terrain.DebrisFieldTerrainPlugin.DebrisFieldSource; 033import com.fs.starfarer.api.loading.Description; 034import com.fs.starfarer.api.loading.Description.Type; 035import com.fs.starfarer.api.ui.Alignment; 036import com.fs.starfarer.api.ui.SectorMapAPI; 037import com.fs.starfarer.api.ui.TooltipMakerAPI; 038import com.fs.starfarer.api.util.Misc; 039 040public class GateHaulerIntel extends BaseIntelPlugin { 041 042 public static float TRANSIT_DAYS_BASE = 100; 043 public static float TRANSIT_SPEED_LY_PER_CYCLE = 50; 044 045 046 public static Object UPDATE_WITNESSED_ARRIVAL = new Object(); 047 048 public static enum GateHaulerAction { 049 OUTBOUND, 050 DEEP_SPACE_TRANSIT, 051 INBOUND, 052 DEPLOYING, 053 } 054 055 public static GateHaulerIntel get(SectorEntityToken gateHauler) { 056 for (IntelInfoPlugin p : Global.getSector().getIntelManager().getIntel(GateHaulerIntel.class)) { 057 if (p instanceof GateHaulerIntel) { 058 GateHaulerIntel intel = (GateHaulerIntel) p; 059 if (intel.getGateHauler() == gateHauler) { 060 return intel; 061 } 062 } 063 } 064 return null; 065 } 066 067 protected SectorEntityToken gateHauler; 068 protected StarSystemAPI destination; 069 protected float departureAngle; 070 protected int transitDays; 071 protected float elapsedDaysInAction; 072 protected SectorEntityToken parkingOrbit; 073 protected SectorEntityToken stableLocation; 074 protected GateHaulerAction action = null; 075 076 //protected CampaignEntityMovementUtil movement; 077 078 public GateHaulerIntel(SectorEntityToken gateHauler) { 079 this.gateHauler = gateHauler; 080 Global.getSector().addScript(this); 081 082 //movement = new CampaignEntityMovementUtil(gateHauler, 0.5f, 3f, 5f, 2000f); 083 } 084 085 @Override 086 protected void notifyEnded() { 087 super.notifyEnded(); 088 Global.getSector().removeScript(this); 089 } 090 091 public void updateMemoryFlags() { 092// MemoryAPI mem = gateHauler.getMemoryWithoutUpdate(); 093// mem.set("$state", state.name()); 094// if (state == GateHaulerState.OUTBOUND || state == GateHaulerState.INBOUND) { 095// mem.set("$inTransit", true); 096// } else { 097// mem.unset("$inTransit"); 098// } 099 } 100 101 public void activate() { 102 // don't actually need to do anything; all handled in the entity plugin and rules 103 } 104 105 public int computeTransitDays(StarSystemAPI destination) { 106 //if (Global.getSettings().isDevMode()) return 1; 107 108 if (destination == null) return 0; 109 110 float dist = Misc.getDistanceLY(gateHauler, destination.getHyperspaceAnchor()); 111 float transitDays = TRANSIT_DAYS_BASE + dist / TRANSIT_SPEED_LY_PER_CYCLE * 365f; 112 return Math.round(transitDays); 113 } 114 115 public void initiateDeployment(SectorEntityToken stableLocation) { 116 if (stableLocation == null) return; 117 118 setAction(GateHaulerAction.DEPLOYING); 119 this.stableLocation = stableLocation; 120 121 getPlugin().getMovement().moveToLocation(stableLocation.getLocation()); 122 getPlugin().getMovement().setFaceInOppositeDirection(false); 123 getPlugin().getMovement().setTurnThenAccelerate(true); 124 getPlugin().setLongBurn(false); 125 126 gateHauler.getMemoryWithoutUpdate().set("$deploying", true); 127 128 129 gateHauler.fadeOutIndicator(); 130 gateHauler.addTag(Tags.NON_CLICKABLE); 131 //gateHauler.addTag(Tags.NO_ENTITY_TOOLTIP); 132 133 stableLocation.fadeOutIndicator(); 134 stableLocation.addTag(Tags.NON_CLICKABLE); 135 stableLocation.addTag(Tags.NO_ENTITY_TOOLTIP); 136 } 137 138 public void initiateDeparture(StarSystemAPI destination) { 139 if (destination == null || destination == gateHauler.getContainingLocation()) return; 140 141 setAction(GateHaulerAction.OUTBOUND); 142 if (parkingOrbit != null) { 143 gateHauler.getContainingLocation().removeEntity(parkingOrbit); 144 parkingOrbit = null; 145 } 146 147 transitDays = computeTransitDays(destination); 148 this.destination = destination; 149 150 departureAngle = Misc.getAngleInDegrees(gateHauler.getLocationInHyperspace(), destination.getLocation()); 151 152 gateHauler.fadeOutIndicator(); 153 getPlugin().getMovement().moveInDirection(departureAngle); 154 getPlugin().getMovement().setFaceInOppositeDirection(false); 155 getPlugin().getMovement().setTurnThenAccelerate(true); 156 getPlugin().setLongBurn(true); 157 158 gateHauler.getMemoryWithoutUpdate().set("$inTransit", true); 159 } 160 161 public void initiateArrival() { 162 if (destination == null) return; // something's badly wrong and the gate hauler is probably gone for good 163 164 setAction(GateHaulerAction.INBOUND); 165 166 findParkingOrbit(); 167 168 float brakeTime = GateHaulerEntityPlugin.MAX_SPEED / GateHaulerEntityPlugin.ACCELERATION; 169 float brakeDist = GateHaulerEntityPlugin.MAX_SPEED * 0.5f * brakeTime; 170 171 Vector2f spawnLoc = Misc.getUnitVectorAtDegreeAngle(departureAngle + 180f); 172 Vector2f spawnVel = new Vector2f(spawnLoc); 173 174 spawnVel.scale(GateHaulerEntityPlugin.MAX_SPEED); 175 spawnVel.negate(); 176 spawnLoc.scale(brakeDist * 1f + 4000f); 177 Vector2f.add(spawnLoc, parkingOrbit.getLocation(), spawnLoc); 178 179 gateHauler.setExpired(false); 180 gateHauler.removeTag(Tags.NON_CLICKABLE); 181 gateHauler.removeTag(Tags.FADING_OUT_AND_EXPIRING); 182 gateHauler.setAlwaysUseSensorFaderBrightness(null); 183 184 if (!destination.getAllEntities().contains(gateHauler)) { 185 destination.addEntity(gateHauler); 186 } 187 188 gateHauler.fadeOutIndicator(); 189 190 getPlugin().getMovement().setLocation(spawnLoc); 191 getPlugin().getMovement().setVelocity(spawnVel); 192 getPlugin().getMovement().setFacing(departureAngle + 180f); 193 194 getPlugin().getMovement().moveToLocation(parkingOrbit.getLocation()); 195 getPlugin().getMovement().setTurnThenAccelerate(true); 196 getPlugin().getMovement().setFaceInOppositeDirection(true); 197 getPlugin().setLongBurn(true); 198 } 199 200 protected void findParkingOrbit() { 201 float minDist = 4000f; 202 float maxDist = 8000f; 203 parkingOrbit = null; 204 SectorEntityToken found = null; 205 for (SectorEntityToken curr : destination.getEntitiesWithTag(Tags.STABLE_LOCATION)) { 206 float dist = curr.getLocation().length(); 207 if (dist >= minDist && dist <= 8000f) { 208 found = curr; 209 break; 210 } 211 } 212 if (found == null) { 213 for (PlanetAPI curr : destination.getPlanets()) { 214 if (curr.isMoon()) continue; 215 float dist = curr.getLocation().length(); 216 if (dist >= minDist && dist <= 8000f) { 217 found = curr; 218 break; 219 } 220 } 221 } 222 223 if (found != null) { 224 Vector2f loc = Misc.getPointAtRadius(found.getLocation(), found.getRadius() + 400f); 225 parkingOrbit = destination.createToken(loc); 226 float orbitRadius = found.getRadius() + 250f; 227 float orbitDays = orbitRadius / (20f + Misc.random.nextFloat() * 5f); 228 parkingOrbit.setCircularOrbit(found, Misc.random.nextFloat() * 360f, orbitRadius, orbitDays); 229 } else { 230 List<OrbitGap> gaps = BaseThemeGenerator.findGaps( 231 destination.getCenter(), minDist, maxDist, gateHauler.getRadius() + 50f); 232 if (!gaps.isEmpty()) { 233 OrbitGap gap = gaps.get(0); 234 float orbitRadius = (gap.start + gap.end) * 0.5f; 235 Vector2f loc = Misc.getPointAtRadius(destination.getCenter().getLocation(), orbitRadius); 236 parkingOrbit = destination.createToken(loc); 237 238 if (!destination.isNebula()) { 239 float orbitDays = orbitRadius / (20f + Misc.random.nextFloat() * 5f); 240 parkingOrbit.setCircularOrbit(destination.getCenter(), Misc.random.nextFloat() * 360f, orbitRadius, orbitDays); 241 } 242 } 243 } 244 245 if (parkingOrbit == null) { 246 float orbitRadius = minDist + (maxDist - minDist) * Misc.random.nextFloat(); 247 Vector2f loc = Misc.getPointAtRadius(destination.getCenter().getLocation(), orbitRadius); 248 parkingOrbit = destination.createToken(loc); 249 250 if (!destination.isNebula()) { 251 float orbitDays = orbitRadius / (20f + Misc.random.nextFloat() * 5f); 252 parkingOrbit.setCircularOrbit(destination.getCenter(), Misc.random.nextFloat() * 360f, orbitRadius, orbitDays); 253 } 254 } 255 256 destination.addEntity(parkingOrbit); 257 } 258 259 protected void setAction(GateHaulerAction action) { 260 this.action = action; 261 elapsedDaysInAction = 0f; 262 } 263 264 public GateHaulerEntityPlugin getPlugin() { 265 return (GateHaulerEntityPlugin) gateHauler.getCustomPlugin(); 266 } 267 268 @Override 269 public void advance(float amount) { 270 super.advance(amount); 271 272 if (action != null) { 273 float days = Misc.getDays(amount); 274 elapsedDaysInAction += days; 275 276 gateHauler.fadeOutIndicator(); 277 if (action == GateHaulerAction.DEPLOYING && stableLocation != null) { 278 stableLocation.fadeOutIndicator(); 279 } 280 } 281 282 //System.out.println("Gate Hauler speed: " + gateHauler.getVelocity().length() + ", loc: " + gateHauler.getLocation()); 283 //System.out.println("Loc: " + gateHauler.getLocation()); 284 //System.out.println("Player speed: " + Global.getSector().getPlayerFleet().getVelocity().length()); 285 if (action == GateHaulerAction.OUTBOUND) { 286 float speed = gateHauler.getVelocity().length(); 287 float dist = gateHauler.getLocation().length(); 288 CampaignFleetAPI pf = Global.getSector().getPlayerFleet(); 289 boolean nearPlayer = pf != null && gateHauler.isInCurrentLocation() && 290 Misc.getDistance(pf, gateHauler) < 10000f; 291 if (!nearPlayer && elapsedDaysInAction > 20f && 292 speed >= GateHaulerEntityPlugin.MAX_SPEED * 0.95f && dist > 40000f) { 293 Misc.fadeAndExpire(gateHauler); 294 setAction(GateHaulerAction.DEEP_SPACE_TRANSIT); 295 sendUpdateIfPlayerHasIntel(GateHaulerAction.DEEP_SPACE_TRANSIT, false); 296 } 297 } 298 299 if (action == GateHaulerAction.DEEP_SPACE_TRANSIT) { 300 if (elapsedDaysInAction >= transitDays) { 301 initiateArrival(); 302 sendUpdateIfPlayerHasIntel(GateHaulerAction.INBOUND, false); 303 } 304 } 305 306 if (action == GateHaulerAction.INBOUND) { 307 getPlugin().getMovement().moveToLocation(parkingOrbit.getLocation()); 308 float speed = gateHauler.getVelocity().length(); 309 float dist = Misc.getDistance(parkingOrbit, gateHauler); 310 311 boolean overshot = Misc.isInArc(gateHauler.getFacing(), 270f, 312 gateHauler.getLocation(), parkingOrbit.getLocation()); 313 if (overshot || dist < 700f) { 314 getPlugin().getMovement().setTurnThenAccelerate(false); 315 getPlugin().getMovement().setFaceInOppositeDirection(false); 316 } 317 boolean closeEnough = speed < 20f && dist < 100f + parkingOrbit.getRadius() + gateHauler.getRadius(); 318 if (dist < 200f + parkingOrbit.getRadius() + gateHauler.getRadius() && elapsedDaysInAction > 30f) { 319 closeEnough = true; 320 } 321 if (closeEnough) { 322 setAction(null); 323 destination = null; 324 gateHauler.fadeInIndicator(); 325 getPlugin().getMovement().setFaceInOppositeDirection(false); 326 getPlugin().setLongBurn(false); 327 float orbitAngle = Misc.getAngleInDegrees(parkingOrbit.getLocation(), gateHauler.getLocation()); 328 float orbitDays = 1000000f; 329 gateHauler.setCircularOrbit(parkingOrbit, orbitAngle, dist, orbitDays); 330 331 if (!gateHauler.isInCurrentLocation()) { 332 for (int i = 0; i < 10; i++) { 333 getPlugin().getEngineGlow().showIdling(); 334 getPlugin().getEngineGlow().advance(1f); 335 } 336 } 337 gateHauler.getMemoryWithoutUpdate().unset("$inTransit"); 338 339 if (gateHauler.isInCurrentLocation()) { 340 String key = "$witnessedGateHaulerArrival"; 341 MemoryAPI mem = Global.getSector().getPlayerMemoryWithoutUpdate(); 342 if (!mem.getBoolean(key)) { 343 float distToPlayer = Misc.getDistance(Global.getSector().getPlayerFleet(), gateHauler); 344 if (distToPlayer < 2000f) { 345 sendUpdateIfPlayerHasIntel(UPDATE_WITNESSED_ARRIVAL, false); 346 Global.getSector().getPlayerStats().addStoryPoints(1, null, false); 347 mem.set(key, true); 348 } 349 } 350 } 351 } 352 } 353 354 355 if (action == GateHaulerAction.DEPLOYING) { 356 if (gateHauler.getOrbit() == null) { 357 getPlugin().getMovement().moveToLocation(stableLocation.getLocation()); 358 } 359 360 if (elapsedDaysInAction > 1f) { 361 if (gateHauler.getOrbit() == null) { 362 float speed = gateHauler.getVelocity().length(); 363 float dist = Misc.getDistance(stableLocation, gateHauler); 364 365 if (dist < 1000f) { 366 getPlugin().getMovement().setTurnThenAccelerate(false); 367 } 368 float test = 100f; 369 if (!gateHauler.isInCurrentLocation()) test = 400f; 370 boolean closeEnough = speed < 20f && dist < test + stableLocation.getRadius() + gateHauler.getRadius(); 371 if (dist < 500f + stableLocation.getRadius() + gateHauler.getRadius() + 372 (elapsedDaysInAction - 50f) * 50f && elapsedDaysInAction > 50f) { 373 closeEnough = true; 374 } 375 if (closeEnough) { 376 float orbitAngle = Misc.getAngleInDegrees(stableLocation.getLocation(), gateHauler.getLocation()); 377 float orbitDays = 1000000f; 378 gateHauler.setCircularOrbit(stableLocation, orbitAngle, dist, orbitDays); 379 elapsedDaysInAction = 0f; 380 } 381 } else { 382 // set the orbit and waited a day; deploy 383 setAction(null); 384 385 addDebrisField(); 386 387 EntityLocation loc = new EntityLocation(); 388 if (stableLocation.getOrbit() != null) { 389 loc.orbit = stableLocation.getOrbit().makeCopy(); 390 } else { 391 loc.location = new Vector2f(stableLocation.getLocation()); 392 } 393 stableLocation.getStarSystem().getMemoryWithoutUpdate().set("$deployedGateHaulerHere", true); 394 395 AddedEntity added = BaseThemeGenerator.addNonSalvageEntity( 396 stableLocation.getStarSystem(), loc, Entities.INACTIVE_GATE, Factions.NEUTRAL); 397 398 gateHauler.getMemoryWithoutUpdate().unset("$deploying"); 399 gateHauler.addTag(Tags.NO_ENTITY_TOOLTIP); 400 Misc.fadeAndExpire(gateHauler, 10f); 401 Misc.fadeAndExpire(stableLocation, 10f); 402 endImmediately(); 403 404 if (added.entity != null) { 405 Misc.fadeIn(added.entity, 3f); 406 } 407 408 409 } 410 } 411 } 412 } 413 414 415 protected void addDebrisField() { 416 if (stableLocation == null) return; 417 418 DebrisFieldParams params = new DebrisFieldParams( 419 400f, // field radius - should not go above 1000 for performance reasons 420 -1f, // density, visual - affects number of debris pieces 421 3f, // duration in days 422 0f); // days the field will keep generating glowing pieces 423 params.source = DebrisFieldSource.MIXED; 424 params.density = 1f; 425 params.baseSalvageXP = (long) 500; // base XP for scavenging in field 426 427 SectorEntityToken debris = (CampaignTerrainAPI) Misc.addDebrisField( 428 stableLocation.getContainingLocation(), params, null); 429 430 debris.setDiscoverable(null); 431 debris.setDiscoveryXP(null); 432 433 debris.addDropValue(Drops.EXTENDED, 100000); 434 435 debris.getLocation().set(stableLocation.getLocation()); 436 if (stableLocation.getOrbit() != null) { 437 debris.setOrbit(stableLocation.getOrbit().makeCopy()); 438 } 439 } 440 441 442 443 protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) { 444 445 Color h = Misc.getHighlightColor(); 446 Color g = Misc.getGrayColor(); 447 float pad = 3f; 448 float opad = 10f; 449 450 FactionAPI faction = getFactionForUIColors(); 451 Color base = faction.getBaseUIColor(); 452 Color dark = faction.getDarkUIColor(); 453 454 float initPad = pad; 455 if (mode == ListInfoMode.IN_DESC) initPad = opad; 456 457 Color tc = getBulletColorForMode(mode); 458 459 bullet(info); 460 boolean isUpdate = getListInfoParam() != null; 461 462 if (isUpdate) { 463 if (getListInfoParam() == GateHaulerAction.DEEP_SPACE_TRANSIT) { 464 info.addPara("Entered open space", tc, initPad); 465 String dStr = "days"; 466 if (transitDays == 1) dStr = "day"; 467 info.addPara("Estimated %s " + dStr + " to complete transit", initPad, tc, 468 h, "" + transitDays); 469 return; 470 } 471 if (getListInfoParam() == GateHaulerAction.INBOUND) { 472 info.addPara("Arrived at " + destination.getNameWithLowercaseType(), tc, initPad); 473 return; 474 } 475 if (getListInfoParam() == UPDATE_WITNESSED_ARRIVAL) { 476 info.addPara("Witnessed the arrival of a Gate Hauler to a star system", tc, initPad); 477 return; 478 } 479 } 480 481 if (mode == ListInfoMode.INTEL) { 482 String locStr = gateHauler.getContainingLocation().getNameWithLowercaseTypeShort(); 483 if (gateHauler.getContainingLocation() != null && gateHauler.getContainingLocation().isDeepSpace()) { 484 locStr = "deep space"; 485 } else if (gateHauler.getContainingLocation() != null) { 486 locStr = gateHauler.getContainingLocation().getNameWithLowercaseTypeShort(); 487 } 488 if (getPlugin().isInTransit() && action == GateHaulerAction.DEEP_SPACE_TRANSIT) { 489 locStr = "transiting deep space"; 490 } 491 492 info.addPara("Location: " + locStr, tc, initPad); 493 initPad = 0f; 494 495 GateHaulerEntityPlugin plugin = getPlugin(); 496 if (!plugin.isActivated()) { 497 info.addPara("Status: dormant", tc, initPad); 498 } else if (plugin.isActivating()) { 499 info.addPara("Status: activating", tc, initPad); 500 } else if (action == null) { 501 info.addPara("Status: operational", tc, initPad); 502 } else if (action == GateHaulerAction.OUTBOUND) { 503 info.addPara("Departing current location", tc, initPad); 504 505 String dStr = "days"; 506 if (transitDays == 1) dStr = "day"; 507 info.addPara("Estimated %s " + dStr + " for transit", initPad, tc, 508 h, "" + transitDays); 509 } else if (action == GateHaulerAction.DEEP_SPACE_TRANSIT) { 510 String dStr = "days"; 511 int daysRemaining = (int) Math.round(transitDays - elapsedDaysInAction); 512 if (daysRemaining < 1) daysRemaining = 1; 513 if (daysRemaining == 1) dStr = "day"; 514 info.addPara("Estimated %s " + dStr + " to complete transit", initPad, tc, 515 h, "" + daysRemaining); 516 } else if (action == GateHaulerAction.INBOUND) { 517 info.addPara("Arriving at " + destination.getNameWithLowercaseType(), tc, initPad); 518 } 519 } 520 521// if (GateEntityPlugin.isScanned(gateHauler)) { 522// info.addPara("Scanned", tc, initPad); 523// initPad = 0f; 524// } 525 526 unindent(info); 527 } 528 529 530 @Override 531 public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) { 532 String pre = ""; 533 String post = ""; 534// if (mode == ListInfoMode.MESSAGES && !getPlugin().isActivated()) { 535// pre = "Discovered: "; 536// } 537 538 Color c = getTitleColor(mode); 539 info.addPara(pre + getName() + post, c, 0f); 540 addBulletPoints(info, mode); 541 } 542 543 @Override 544 public void createSmallDescription(TooltipMakerAPI info, float width, float height) { 545 Color h = Misc.getHighlightColor(); 546 Color g = Misc.getGrayColor(); 547 Color tc = Misc.getTextColor(); 548 float pad = 3f; 549 float opad = 10f; 550 551 if (gateHauler.getCustomInteractionDialogImageVisual() != null) { 552 info.addImage(gateHauler.getCustomInteractionDialogImageVisual().getSpriteName(), width, opad); 553 } 554 555 Description desc = Global.getSettings().getDescription(gateHauler.getCustomDescriptionId(), Type.CUSTOM); 556 info.addPara(desc.getText1(), opad); 557 558 FactionAPI faction = getFactionForUIColors(); 559 Color base = faction.getBaseUIColor(); 560 Color dark = faction.getDarkUIColor(); 561 562 info.addSectionHeading("Status", base, dark, Alignment.MID, opad); 563 564 GateHaulerEntityPlugin plugin = getPlugin(); 565 if (!plugin.isActivated()) { 566 GateHaulerCMD cmd = new GateHaulerCMD(); 567 info.addPara("The gate hauler is dormant, its systems shut down to conserve power.", opad); 568 info.showCost("Resources required to activate:", false, base, dark, opad, cmd.getResources(), cmd.getQuantities()); 569 } else if (plugin.isActivating()) { 570 info.addPara("The gate hauler is in the process of reactivating its systems and should be operational " 571 + "within a day.", opad); 572 } else if (action == null) { 573 info.addPara("The gate hauler is operational and ready to travel to another star system or " 574 + "deploy its gate at a stable location.", opad); 575 } else if (action == GateHaulerAction.OUTBOUND) { 576 info.addPara("The gate hauler is outbound from its current location, " 577 + "heading for open space and accelerating.", opad); 578 579 String dStr = "days"; 580 if (transitDays == 1) dStr = "day"; 581 info.addPara("Once it's in open space, it's estimated that it will take %s " + dStr + " until it arrives " 582 + "to its destination, the " + destination.getNameWithLowercaseTypeShort() + ". On arrival, " 583 + "it will take some time to decelerate and attain a parking orbit.", opad, 584 h, "" + transitDays); 585 } else if (action == GateHaulerAction.DEEP_SPACE_TRANSIT) { 586 String dStr = "days"; 587 int daysRemaining = (int) Math.round(transitDays - elapsedDaysInAction); 588 if (daysRemaining < 1) daysRemaining = 1; 589 if (daysRemaining == 1) dStr = "day"; 590 info.addPara("The gate hauler is in transit, in deep space. It's estimated that it will take %s " + dStr + " until it arrives " 591 + "to its destination, the " + destination.getNameWithLowercaseTypeShort() + ". On arrival, " 592 + "it will take some time to decelerate and attain a parking orbit.", opad, 593 h, "" + daysRemaining); 594 } else if (action == GateHaulerAction.INBOUND) { 595 info.addPara("The gate hauler has arrived to the " + destination.getNameWithLowercaseTypeShort() + " " 596 + "and is decelerating in order to attain a parking orbit.", opad); 597 } else if (action == GateHaulerAction.DEPLOYING) { 598 info.addPara("The gate hauler has been given an order to deploy its gate.", opad); 599 } 600 601 602 addLogTimestamp(info, tc, opad); 603 604 //addBulletPoints(info, ListInfoMode.IN_DESC); 605 606 } 607 608 @Override 609 public String getIcon() { 610 return Global.getSettings().getSpriteName("intel", "gate_hauler"); 611 } 612 613 @Override 614 public Set<String> getIntelTags(SectorMapAPI map) { 615 Set<String> tags = super.getIntelTags(map); 616 tags.add(Tags.INTEL_GATES); 617 tags.add(Tags.INTEL_FLEET_LOG); 618 //tags.add(Tags.INTEL_EXPLORATION); 619 return tags; 620 } 621 622 public String getSortString() { 623 if (getTagsForSort().contains(Tags.INTEL_FLEET_LOG) || getTagsForSort().contains(Tags.INTEL_EXPLORATION)) { 624 return getSortStringNewestFirst(); 625 } 626 return "AAA"; 627 } 628 629 630 public String getName() { 631 return "Gate Hauler"; 632 } 633 634 @Override 635 public FactionAPI getFactionForUIColors() { 636 return gateHauler.getFaction(); 637 //return super.getFactionForUIColors(); 638 } 639 640 public String getSmallDescriptionTitle() { 641 //return getName() + " - " + gateHauler.getContainingLocation().getNameWithTypeShort(); 642 return getName(); 643 } 644 645 @Override 646 public SectorEntityToken getMapLocation(SectorMapAPI map) { 647 if (!gateHauler.isAlive() && destination != null) { 648 return destination.getCenter(); 649 } 650 return gateHauler; 651 } 652 653 @Override 654 public String getCommMessageSound() { 655 return "ui_discovered_entity"; 656 } 657 658 public SectorEntityToken getGateHauler() { 659 return gateHauler; 660 } 661 662 @Override 663 public List<ArrowData> getArrowData(SectorMapAPI map) { 664 if (destination == null || action == null) { 665 return null; 666 } 667 668 boolean showArrow = action == GateHaulerAction.OUTBOUND || action == GateHaulerAction.DEEP_SPACE_TRANSIT; 669 if (!showArrow) return null; 670 671 if (gateHauler.getContainingLocation() == destination) { 672 return null; 673 } 674 675 List<ArrowData> result = new ArrayList<ArrowData>(); 676 677 ArrowData arrow = new ArrowData(gateHauler, destination.getCenter()); 678 arrow.color = getFactionForUIColors().getBaseUIColor(); 679 arrow.width = 20f; 680 result.add(arrow); 681 682 return result; 683 } 684 685 public GateHaulerAction getAction() { 686 return action; 687 } 688 689} 690 691 692 693 694 695 696