BrokenRegistry / Rotp-Fusion

Other
22 stars 4 forks source link

Extract functions from ShipFleet and Transport to Ship #10

Closed dHannasch closed 1 year ago

dHannasch commented 1 year ago

This doesn't change any behavior, but textually it makes changes to some hugely important classes, so it seemed wise to check in.

This extracts functions that are common to both ShipFleet and Transport into Ship.

(A ShipFleet is a Ship, not a collection of Ships. I don't make the rules.)

I didn't get into pondering why, for example, Transport has a star system it's from() but ShipFleet doesn't necessarily; I just extracted fromX and fromY which they both have.

This also adds transitXlastTurn() and transitYlastTurn() to Ship; these were all I really wanted in the first place. (I want to show the player where a ship was last turn if they don't have Improved Space Scanner but they did see this particular ship last turn.) Previously travelPct was available from both ShipFleet and Transport, but not from Ship.

(We could store the Ship.x() and Ship.y() when seen, of course, which would be more strictly correct in terms of firewalling off information that isn't available to the player, but more on-the-fly memory allocations would make it more expensive, versus just saving which ships were visible last turn and trusting those Ships to know where they were last turn. Anyway, this branch doesn't do any of that, it just extracts functions from ShipFleet and Transport to Ship so that they're callable when you only know you have a Ship.)

BrokenRegistry commented 1 year ago

Good idea! Note: Only improved scanner are able to identify a ship. Then I'll suggest showing all previous ships or none! It's up to the player to guess which is which.

dHannasch commented 1 year ago

Only improved scanner are able to identify a ship. Then I'll suggest showing all previous ships or none! It's up to the player to guess which is which.

Oh. Ohhhh. I forgot about that.

In the vast majority of cases, you can uniquely identify every single fleet, just from the combination of empire color plus number of ships of each size. But...it's theoretically possible that some empire could have Hyper Drives when everyone else has retros, and that empire could have one small ship in range of your Deep Space Scanner, then have that ship fly entirely out of your scanner range, while simultaneously, coincidentally, a different small ship belonging to the same empire appears into a position one light-year away from where the first ship was last turn.

I've been treating this like it's always possible to say "Here's where this ship is this turn, here's where this ship was last turn, here's the vector along which it moved." And, I mean, I still think that's true in practice in the overwhelming majority of cases...and I'd be happy to just display nothing in the crazy edge cases...but we can't necessarily say, based solely on visible information, whether or not we're in one of the crazy edge cases, which means there's nothing safe to display.

At that point, this might not be a good idea at all. Without the little arrow, it's mostly just adding visual noise.

Except, wait, hmm. Ignore unknown empires. Assuming the player has encountered the empire, then currently, needing no scanning technology, the player can always distinguish ship classes from each other, and always knows the Travel Speed. https://github.com/BrokenRegistry/Rotp-Fusion/blob/main/src/rotp/ui/races/RacesMilitaryUI.java#L546

    private void  drawShipNameAndIcon(Graphics2D g, ShipView view, int x, int y, int w, int h) {     
        ShipDesign d = view.design();
        String s = d.name();

(On the one hand we could swap the real design name for a NATO-style reporting name, but from the player's perspective the design name might well be a reporting name, since this is the only place they'll ever see it.) https://github.com/BrokenRegistry/Rotp-Fusion/blob/main/src/rotp/ui/races/RacesMilitaryUI.java#L640

    private void  drawShipTactical1(Graphics2D g, ShipView view, int x, int y, int w, int h) { 
        ShipDesign d = view.design();
        String val = d.sizeDesc();
        val = view.armorKnown() ? str((int)d.hits()) : unk;
        val =  view.shieldKnown() ? str((int)d.shieldLevel()) : unk;
        val = str(d.warpSpeed());

The warp speed, like the size and the icon, is always unconditionally known. To know the combat speed, they need to have actually encountered the ship, though they don't need a Battle Scanner. But they always know the warp speed.

(The warp speed is, in fact, the only thing that's unconditionally displayed except the size and the icon. I guess the assumption is that the scanners have "really" been tracking the object all year so they know how fast it's moving? I really don't know.)

So if they know the warp speed of a Frogfoot is 1, and there's a Frogfoot at some location this turn, then there's going to be a Frogfoot 1 light-year away next turn. (Unless the Frogfoot is scrapped in flight, I suppose.)

From the opposite direction, if last year there was only one Frogfoot 1 light-year away from where we see a Frogfoot this year, and we're more than 1 light-year away from the edge of the scanning range, then we can say with certainty, based solely on that information, that this must be the same Frogfoot.

They might not have a spy, so they might have no idea what warp tech is available to the other empire, but they know the speed of this ship.

(We might be able to be certain even if we're within 1 light-year of the edge of the scanner's range, if we'd already been tracking this particular Frogfoot from the turn before last, but never mind that. The point is that there's a "safe" set of conditions where showing the trajectory wouldn't be leaking any information that wasn't already available; for the other cases like the edge of the scanning range or two Frogfoots close together we can just display nothing about where the ship was last turn, like we're already doing anyway.)

BrokenRegistry commented 1 year ago

Good point! I never realised the warpspeed was always known... I guess multiple levels of visibility might be needed in the options, and I don't know how complicated my options tool might look. I can create the base for this option if that helps.

dHannasch commented 1 year ago

To be honest, I'm thinking to shelve the trajectory for now in favor of making the governor stop sending transports to besieged colonies to get shot down. This is more complicated than I realized.