Vanilla List Mailing List Archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [VANILLA-LIST:2603] base etempbug...



Carlos & Others,

I've figured out a probable cause due to an overloading of the p_docked
and p_port definitions in the player struct.  Here's the secret:
sometimes a ship is made to be an SB on death!

Details:

	p_port[0:4] is used by an SB as the list of ships docked,
	p_docked is used by an SB as the number of ships docked.

	p_port[0] is used by a non-SB as the port number docked to,
	p_docked is used by a non-SB as the SB ship number docked to.

So what happens if a docked ship undergoes a transition to STARBASE on
death?  Answer: strange things ...

Imagine F0 (CA) docked to F1 (SB) on port 2, with another three ships
also docked.  F0 is ejected by the players.  The result as seen by the
starbase F1 will be;

a) F0 immediately explodes mightily,
b) F2 immediately leaves dock, (only visible if the SB is in motion)
c) SB engine temperature will behave as if F2 is still docked.

Odd huh?  But true.  F2 believes they have been dropped by the base,
but the base believes that F2 left of her own accord.  F2 should have
noted that the other two ships were not undocked!

The appropriate parts of the player struct are:

players[0].p_port[0] = 2;  /* F0 is docked on port 2 */
players[0].p_docked = 1;   /* F0 is docked to F1 */

players[1].p_docked = 4;   /* F1 (SB) has four ships docked */
players[1].p_port[0] = 5;  /* F5 is docked on port 0 */
players[1].p_port[1] = 6;  /* F6 is docked on port 1 */
players[1].p_port[2] = 0;  /* F0 is docked on port 2 */
players[1].p_port[3] = 2;  /* F2 is docked on port 3 */

Now, F0 dies and is made into a STARBASE for the explosion effect.
Line 808 of daemonII.c will cause the following;
(It aims to remove from the starbase the ship that died.)

players[1].p_docked = 3;   /* F1 (SB) has three ships now docked */
players[1].p_port[2] = 0;  /* F1's port 2 is now free */

And this is fine and dandy, but since the ship that was docked and has
exploded is now a STARBASE, line 821 comes into play;
(It aims to remove all ships from the dying starbase.)

players[2].p_flags &= ~PFDOCK;
players[0].p_port[0] = -1;

Which causes F2 to be knocked from dock, but without the corresponding
adjustment to F1's port array.

So now F1 has a port array which is inconsistent with F2's state.


Survey of situations in which a ship is changed to be a STARBASE just
before it dies; for the effect of the bigger explosion;

- cluecheck failure,
- ejection by players,
- topgun random nuke (tools/fun.c line 245),
- obliteration (tools/xtkill without flags),
- xsg nuke,
- xsg eject.

Now, the fun thing is that the player doesn't need to be docked for this
corruption to occur; they only need to have docked to the starbase before
they are ejected.  p_docked and p_port will still have data in them.

As I look at the code that causes docking to cease, I see that p_docked
for the non-SB ship is not cleared at all.  Luckily it is not set to -1
or something, or we would be having daemonII core dumps.

Since the problem is seen on Continuum, where no cluecheck is done, it
must be being caused by ejection.

I propose the best solution would be to avoid the duplication of use for
the variables in question, adding two new variables for keeping track
of the linkages:

	p_ports[4]	/* array of docked ship numbers */
	p_docks		/* count of ports in use */
	
	p_docked	/* who we are docked to */
	p_port		/* which port on p_docked */

-- 
James Cameron                                      (quozl@us.netrek.org)

Linux, Firewalls, OpenVMS, Software Engineering, CGI, HTTP, X, C, FORTH,
COBOL, BASIC, DCL, csh, bash, ksh, sh, Electronics, Microcontrollers,
Disability Engineering, Netrek, Bicycles, Pedant, Farming, Home Control,
Remote Area Power, Greek Scholar, Tenor Vocalist, Church Sound, Husband.

"Specialisation is for insects." -- Robert Heinlein.