1
/*------------------------------------------------------------------
2
Copyright 1989 Kevin P. Smith
5
Permission to use, copy, modify, and distribute this
6
software and its documentation for any purpose and without
7
fee is hereby granted, provided that the above copyright
8
notice appear in all copies.
12
Permission to use, copy, modify, and distribute this software and
13
its documentation, or any derivative works thereof, for any
14
NON-COMMERCIAL purpose and without fee is hereby granted, provided
15
that this copyright notice appear in all copies. No
16
representations are made about the suitability of this software for
17
any purpose. This software is provided "as is" without express or
20
Xtrek Copyright 1986 Chris Guthrie
21
Netrek (Xtrek II) Copyright 1989 Kevin P. Smith
23
Paradise II (Netrek II) Copyright 1993 Larry Denys
26
Copyright 2000 Bob Glamm
28
--------------------------------------------------------------------*/
37
/*-----------------------------NUMBER DEFINES----------------------------*/
38
/* defines dealing with ships exploding */
39
#define MAXDAMDIST 3000 /* range at which shipexplosions do damage */
42
#define YRANGE ((100000)/7) /* range yellow alert comes on */
43
#define RRANGE ((100000)/10) /* range red alert comes on */
46
#define DOCKDAMAGE 10 /* the amount of damage inflicted when you
47
lose a docking ring... */
49
/*-----------------------------------------------------------------------*/
51
/*---------------------------EXTERNAL GLOBALS-----------------------------*/
55
/* this doesn't look like it's used BUT check the definition of NotTmode
57
extern int tourntimestamp;
59
/*---------------------------INTERNAL FUNCTIONS---------------------------*/
61
/*-----------------------------BEAMMEUPSCOTTY-----------------------------*/
62
/* This function does the beamup for a player. It allows the player
63
to beam up all the armies on a planet. */
66
beammeupscotty(struct player *j) /* the player beaming */
68
struct planet *l; /* to point to planet beaming from */
70
if (j->p_flags & PFORBIT) { /* if orbiting a planet */
71
l = &planets[j->p_planet]; /* get planet player is beaming from */
72
if (l->pl_armies == 0 /* cannot beam if no armies */
73
/* this prevents you from beaming up outside T-mode in a league game */
74
|| (!(configvals->evacuation) && (l->pl_armies < 5))
75
|| (status2->league && !status->tourn)
76
|| j->p_armies >= j->p_ship.s_maxarmies
77
|| ((j->p_ship.s_nflags & SFNARMYNEEDKILL)
78
&& (j->p_armies >= (int) (j->p_kills * j->p_ship.s_armyperkill)))
80
j->p_flags &= ~PFBEAMUP;
81
return; /* max armies for number of kills? */
83
if (l->pl_owner != j->p_team)
84
return; /* no picking up foreign troops */
88
if (j->p_ship.s_nflags & SFNHASFIGHTERS) {
89
j->p_ship.s_missilestored = j->p_ship.s_missilestored + FAE_RATE;
90
j->p_armies = (int) (j->p_ship.s_missilestored / FAE_RATE);
93
j->p_armies++; /* pick an army up */
95
l->pl_armies--; /* dec armies on planet */
96
l->pl_tinfo[j->p_team].armies = l->pl_armies; /* update info */
97
l->pl_tinfo[j->p_team].timestamp = status->clock; /* timestamp it */
99
if (l->pl_armies == 0) {/* if we beamed them all up then */
100
l->pl_tinfo[l->pl_owner].owner = NOBODY; /* no longer owner */
101
/* these penalties apply even outside of T-mode */
102
j->p_stats.st_tplanets--; /* prevent scumming */
104
j->p_stats.st_di -= 0.25;
105
if (j->p_stats.st_di < 0.0)
106
j->p_stats.st_di = 0.0;
109
if (j->p_kills < 0.0)
114
l->pl_owner = NOBODY; /* planet goes to nobody */
115
checkwin(enemy_admiral(j->p_no)); /* check for winner */
117
if (j->p_lastman == 2) /* KAO */
118
/* j->p_flags &= ~PFBEAMUP; */
122
else if (j->p_flags & PFDOCK) { /* else if docked to another ship */
123
if (players[j->p_docked].p_armies == 0
124
|| j->p_armies >= j->p_ship.s_maxarmies
125
|| ((j->p_ship.s_nflags & SFNARMYNEEDKILL)
126
&& (j->p_armies >= (int)(j->p_kills * j->p_ship.s_armyperkill))))
128
j->p_flags &= ~PFBEAMUP;
132
tlog_Bbeamup(&players[j->p_docked], j);
134
if (j->p_ship.s_nflags & SFNHASFIGHTERS) {
135
j->p_ship.s_missilestored = j->p_ship.s_missilestored + FAE_RATE;
136
j->p_armies = (int) (j->p_ship.s_missilestored / FAE_RATE);
139
j->p_armies++; /* add to armies */
140
players[j->p_docked].p_armies--; /* subtract from dockee */
148
/*-------------------------------BEAMDOWN---------------------------------*/
149
/* This function beams armies down to a planet or to a ship the player
150
is dowcked on. This function also has Kurt's mod for beaming while at
151
different alert statuses. You get more stats from taking while alert status
152
is red than green. */
155
beamdown(struct player *j) /* the player beaming */
157
char buf[90]; /* to sprintf into */
159
struct planet *l; /* the planet beaming to */
160
/* int oldowner; */ /*to keep track of old planet owner */
162
if (j->p_armies == 0) /* player cannot beam down if */
163
return; /* he has no armies */
165
if (j->p_flags & PFORBIT) { /* if beaming to planet then */
167
l = &planets[j->p_planet]; /* get planet beaming to */
168
/* oldowner = l->pl_owner; */ /*record old owner */
169
if ((!((j->p_swar | j->p_hostile) & l->pl_owner))
170
&& (j->p_team != l->pl_owner) && (l->pl_owner != NOBODY))
171
return; /* no beaming down if not hostile */
175
if (l->pl_owner == j->p_team) { /* if beaming to own planet */
176
if ((j->p_ship.s_nflags & SFNHASFIGHTERS) &&
177
(j->p_ship.s_missilestored >= FAE_RATE)) {
178
j->p_ship.s_missilestored = j->p_ship.s_missilestored - FAE_RATE;
179
j->p_armies = (int) (j->p_ship.s_missilestored / FAE_RATE);
182
j->p_armies--; /* decrease by one army */
184
l->pl_armies++; /* increase planet armies */
185
l->pl_tinfo[j->p_team].armies = l->pl_armies;
186
l->pl_tinfo[j->p_team].timestamp = status->clock;
188
else { /* else beaming to foreign planet */
189
j->p_swar |= l->pl_owner; /* start war if necessay */
190
j->p_armies--; /* beam an army down */
191
/* the defender might get a chance to destroy beamed-down
192
army. Check configvals. */
193
if(l->pl_armies > 0 && (l->pl_flags & PLRESMASK) &&
194
configvals->army_defend_facilities > 0.0)
196
if(drand48() > configvals->army_defend_facilities)
199
else if(l->pl_armies > 0 && !(l->pl_flags & PLRESMASK) &&
200
configvals->army_defend_bare > 0.0)
202
if(drand48() > configvals->army_defend_bare)
207
l->pl_tinfo[j->p_team].armies = l->pl_armies;
208
l->pl_tinfo[j->p_team].timestamp = status->clock;
209
l->pl_tinfo[l->pl_owner].armies = l->pl_armies;
211
credit_armiesbombed(j, 1, l);
213
if (l->pl_armies == 0) { /* if all armies knocked off */
214
(void) sprintf(buf, "%s destroyed by %s (%s)", l->pl_name,
215
j->p_name, twoletters(j));
216
(void) sprintf(buf1, "%-3s->%-3s", l->pl_name,
217
teams[l->pl_owner].shortname);
218
pmessage(buf, l->pl_owner, MTEAM | MDEST, buf1);
220
l->pl_tinfo[l->pl_owner].owner = NOBODY;
221
l->pl_tinfo[l->pl_owner].timestamp = status->clock;
222
l->pl_tinfo[j->p_team].owner = NOBODY;
223
l->pl_tinfo[j->p_team].armies = 0;
224
l->pl_tinfo[j->p_team].timestamp = status->clock;
225
l->pl_owner = NOBODY;
226
l->pl_trevolt = 0; /* stop revolution */
227
if (NotTmode(ticks)) { /* if not t-mode then */
228
rescue(STERMINATOR, j->p_no, l->pl_no); /* send in the
230
rescue(STERMINATOR, j->p_no, l->pl_no);
232
checkwin(j->p_no); /* check for genocide */
234
else if (l->pl_armies < 0) { /* planet taken over */
235
l->pl_armies *= -1; /* newly taken planet has one army */
236
if (status->tourn) { /* if in t-mode then */
237
j->p_planets++; /* inc game planets taken */
238
j->p_stats.st_tplanets++; /* inc t-mode planets taken */
239
j->p_stats.st_di += 0.25; /* inc DI for player */
240
status->planets++; /* inc global planets */
242
if ((j->p_jsdock > 0) && (j->p_jsdock < 600)) { /* give JS credit? */
243
struct player *js = &players[j->p_lastjs]; /* yes */
244
(void) sprintf(buf1, "%-3s->%s ", l->pl_name,
246
(void) sprintf(buf, "Good assist, %s", js->p_name);
247
js->p_stats.st_jsplanets++;
249
if(configvals->js_assist_credit)
250
js->p_stats.st_tplanets++;
253
pmessage(buf, j->p_lastjs, MINDIV | MTAKE, buf1);
256
j->p_kills += 0.25; /* inc kills for taking planet */
257
checkmaxkills(j->p_no); /* check max kills */
259
(void) sprintf(buf, "%s taken over by %s (%s)", l->pl_name,
260
j->p_name, twoletters(j));
261
l->pl_owner = j->p_team; /* switch owner */
263
l->pl_hinfo |= j->p_team; /* set up info */
264
l->pl_tinfo[j->p_team].owner = l->pl_owner;
265
l->pl_tinfo[j->p_team].armies = l->pl_armies;
266
l->pl_tinfo[j->p_team].flags = l->pl_flags;
267
l->pl_tinfo[j->p_team].timestamp = status->clock;
268
checkwin(j->p_no); /* check for win */
269
(void) sprintf(buf1, "%-3s->%-3s", l->pl_name, teams[l->pl_owner].shortname);
270
pmessage(buf, l->pl_owner, MTEAM | MTAKE, buf1);
273
} /* end of beaming to foreign planets */
274
else if (j->p_flags & PFDOCK) { /* if beaming to ship docked to */
275
if (players[j->p_docked].p_team != j->p_team)
276
return; /* no beaming to foreign dockees */
277
if (players[j->p_docked].p_armies ==
278
players[j->p_docked].p_ship.s_maxarmies)
279
return; /* no beaming over max armies */
280
tlog_Bbeamdown(&players[j->p_docked], j);
281
j->p_armies--; /* transfer one army over */
282
players[j->p_docked].p_armies++;
288
/*----------------------------------BLOWUP--------------------------------*/
289
/* This function does the explosion damage of a ship explosion. It
290
inflicts damage on the nearby players. The damage has been changed to be
291
based on the amount of fuel the ship has when it explodes. */
294
blowup(struct player *sh) /* the player that blew up */
296
register int i; /* looping vars */
297
int dx, dy; /* delta coords of a ship */
298
double dist2; /* for distance of ship (sqared) */
299
double maxdist, maxdist2; /* to hold max damage dist */
300
int damage; /* to hold calculated damage */
301
register struct player *j; /* to point to other players */
302
double ft, expl; /* floating point temp */
305
/* moved some of this stuff out of the for loop... */
306
maxdist = sqrt((double) MAX(sh->p_fuel, 0) / 6.0) * 20.0;
307
if (maxdist > MAXDAMDIST)
308
maxdist = MAXDAMDIST;
309
maxdist2 = maxdist * maxdist;
311
expl = (double) ((sh->p_ship.s_expldam
312
+ sqrt(MAX(sh->p_fuel, 0) / (double) sh->p_ship.s_maxfuel) * sh->p_ship.s_fueldam)
313
/ get_explode_views(sh->p_ship.s_type));
315
if (sh->p_whydead == KGHOST)
316
return; /* no gostbusted ships blowing up */
318
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
320
if ((j->p_status != PALIVE) || (sh == j)) /* player no alive or is
322
continue; /* as exploding ship, then continue */
323
me = sh; /* for friendlyPlayer macro below */
324
if ((sh->p_whydead == KQUIT) && (friendlyPlayer(j)))
325
continue; /* No quiting to blow up on people */
326
dx = sh->p_x - j->p_x; /* delta coords */
327
dy = sh->p_y - j->p_y;
328
if ((ABS(dx) > (int) maxdist) || (ABS(dy) > (int) maxdist))
329
continue; /* continue if obviously too far away */
330
dist2 = (double) dx *(double) dx + (double) dy *(double) dy;
331
if (dist2 >= maxdist2) /* if too far away to damage */
332
continue; /* then check next player */
334
ft = sqrt(1.0 - dist2 / maxdist2);
335
damage = (int) (expl * ft); /* scale by distance */
336
if (damage > 0) { /* if damage done then */
338
inflict damage, and maybe credit the person who killed us if
339
we cause the death of a teammate
341
inflict_damage(sh, &players[sh->p_whodead], j, damage, KSHIP);
349
/*--------------------------------DOSHIPEXPLODE---------------------------*/
350
/* This function makes a ship explode. It resets various fields in the
351
players structure and decs the timer before the player's explosion is done
352
and he is really dead. */
355
doshipexplode(struct player *j) /* the player to explode */
357
int k; /* another damned looping var */
359
j->p_flags &= ~PFCLOAK; /* the cloaking device is kaputt */
361
blowup(j); /* damage surrounding players */
363
if (--j->p_explode <= 0) { /* dec explode timer until really gone */
364
j->p_status = PDEAD; /* explosion done--make player dead */
365
j->p_explode = 600 / PLAYERFUSE; /* set timer for ghost buster */
367
undock_player(j); /* if player docked then undock him */
369
if (allows_docking(j->p_ship)) { /* if ships can dock */
370
for (k = 0; k < j->p_ship.s_numports; k++) /* remove all docked
373
j->p_docked = 0; /* no ships docked anymore */
375
if (j->p_flags & PFORBIT) { /* if orbiting then */
376
j->p_flags &= ~PFORBIT; /* eject him from orbit */
377
} /* reset ship timers */
378
if (j->p_status == PDEAD) {
380
this is the last time doshipexplode will be called for this
381
player. increment the rebuild timer
383
if ((j->p_whydead == KSHIP) || (j->p_whydead == KTORP)
384
|| (j->p_whydead == KPHASER) || (j->p_whydead == KPLASMA)
385
|| (j->p_whydead == KPLANET) || (j->p_whydead == KGENOCIDE))
386
/* we have to build ANOTHER one */
388
|| configvals->affect_shiptimers_outside_T)
389
teams[j->p_team].s_turns[j->p_ship.s_type] += j->p_ship.s_timer;
396
/*----------------------------------DOORBIT--------------------------------*/
397
/* This function makes a player orbit around a planet by adjusting his
398
coordinates to go around in a circle. */
401
doorbit(struct player *j) /* the player in orbit */
407
j->p_dir += 2; /* make player rotate */
409
j->p_dir -= 2; /* make player rotate */
411
j->p_desdir = j->p_dir;
413
angle = j->p_dir + (j->p_orbitdir ? -64 : 64);
414
x = planets[j->p_planet].pl_x + ORBDIST /* new x coord */
415
* Cos[(unsigned char) angle];
416
y = planets[j->p_planet].pl_y + ORBDIST /* new y coord */
417
* Sin[(unsigned char) angle];
418
move_player(j->p_no, x, y, 1);
423
repair_docking_ring(struct player *j)
427
for (i = 0; i < j->p_ship.s_numports; i++) {
428
if (j->p_port[i] == PDAMAGE)
431
/* check to see if we've repaired any docking ring damage */
433
(damaged - 1) * DOCKDAMAGE + 1 > j->p_damage && i < j->p_ship.s_numports;
435
if (j->p_port[i] == PDAMAGE) {
436
j->p_port[i] = VACANT;
442
/*---------------------------------DORESOURCES----------------------------*/
443
/* This function adjusts various things on a ship, like the fuel regen-
444
eration, repair, etc. Some changes: fuel cost of cloaking is based on
445
the speed of the ship. There is a ver for how fast each ship can take on
446
fuel from a planet of other ship */
449
doresources(struct player *j) /* the player in orbit */
453
/* Charge for shields */
454
if (j->p_flags & PFSHIELD)
455
j->p_fuel -= j->p_ship.s_shieldcost;
458
j->p_wtemp -= j->p_ship.s_wpncoolrate; /* subract from W-temp */
459
if (j->p_wtemp < 0) /* no going below zero */
461
if (j->p_flags & PFWEP) { /* if weapon temped */
462
if (--j->p_wtime <= 0) /* then w-tep ends when */
463
j->p_flags &= ~PFWEP; /* w timer goes to zero */
465
else if (j->p_wtemp > j->p_ship.s_maxwpntemp) { /* weapons too hot? */
466
if (!(lrand48() % 40)) {/* chance to turn on W-temp */
467
j->p_flags |= PFWEP;/* W-temp the poor sucker */
468
j->p_wtime = ((lrand48() % 150) + 100) / PLAYERFUSE;
472
j->p_etemp -= j->p_ship.s_egncoolrate; /* cool the engine */
473
if (j->p_etemp < 0) /* no going below zero */
475
if (j->p_flags & PFENG) { /* if E-temped */
476
/* see if timer has expired and we're not hot. if we don't
477
* check for current temp, PFENG will blink on and off and
478
* you can actually move in a bursty fashion :) */
479
if ( (--j->p_etime <= 0) && !(j->p_etemp > j->p_ship.s_maxegntemp) )
480
j->p_flags &= ~PFENG; /* turn off E-temp if need be */
482
else if (j->p_etemp > j->p_ship.s_maxegntemp) { /* engine too hot? */
483
if (!(lrand48() % 20)) {/* random chance for E-temp */
484
j->p_flags |= PFENG;/* set E-temp flag */
485
j->p_etime = ((lrand48() % 150) + 100) / PLAYERFUSE; /* set E-tmp timer */
486
j->p_desspeed = 1; /* desired speed goes to zero (one?) */
489
if (configvals->newcloak) /* cloak cost based on speed */
490
ccost = (int) (((float) j->p_ship.s_cloakcost / 10.0) *
491
isqrt(j->p_speed + 1));
493
ccost = j->p_ship.s_cloakcost / 5; /* 5 because regens have
496
if (j->p_flags & PFCLOAK) { /* do cloaking cost */
497
if (j->p_fuel < ccost) /* if not enough fuel */
498
j->p_flags &= ~PFCLOAK; /* then decloak */
503
if ((j->p_flags & PFORBIT) /* if orbiting */
504
&&(planets[j->p_planet].pl_flags & PLFUEL) /* a fuel planet */
505
&&(!(planets[j->p_planet].pl_owner /* and not hostile */
506
& (j->p_swar | j->p_hostile)))) { /* or at war */
507
j->p_fuel += j->p_ship.s_takeonfuel * 2; /* then take on fuel */
508
if( configvals->helpfulplanets ) { /* helpful planets? */
509
j->p_etemp -= j->p_ship.s_egncoolrate; /* cool engine too */
513
} else if ((j->p_flags & PFORBIT) /* if orbiting */
514
&&(!(planets[j->p_planet].pl_owner /* and not hostile */
515
& (j->p_swar | j->p_hostile)))) { /* or at war */
516
if( configvals->helpfulplanets ) { /* helpful planets? */
517
j->p_etemp -= j->p_ship.s_egncoolrate; /* cool engine too */
520
j->p_fuel += j->p_ship.s_takeonfuel;
521
if( j->p_fuel > j->p_ship.s_maxfuel )
522
j->p_fuel = j->p_ship.s_maxfuel; /* don't let it run over */
524
j->p_fuel += j->p_ship.s_takeonfuel / 3; /* then take on fuel */
525
} else if ((j->p_flags & PFDOCK) /* if docked */
526
&&(j->p_fuel < j->p_ship.s_maxfuel)) { /* and room for fuel */
527
struct player *base = &players[j->p_docked];
528
if ((base->p_fuel > base->p_ship.s_mingivefuel) /* can't fuel below min */
529
&&(base->p_ship.s_nflags & SFNCANFUEL)
530
&& (j->p_fuel < j->p_ship.s_maxfuel)) {
531
j->p_fuel += j->p_ship.s_takeonfuel; /* suck some fuel off */
532
base->p_fuel -= j->p_ship.s_takeonfuel;
535
/* else *//* if in free space */
536
else if ((j->p_flags & PFDOCK) /* if docked */
537
&&(j->p_fuel >= j->p_ship.s_maxfuel) &&
538
(j->p_ship.s_type == PATROL)) {
539
if (j->p_ship.s_missilestored < shipvals[PATROL].s_missilestored) {
540
struct player *base = &players[j->p_docked];
541
base->p_fuel -= j->p_ship.s_missile.cost;
542
j->p_ship.s_missilestored++;
546
j->p_fuel += j->p_ship.s_recharge; /* add regen fuel */
548
if (j->p_fuel > j->p_ship.s_maxfuel) { /* over max fuel? */
549
if (j->p_flags & PFDOCK) {
550
struct player *base = &players[j->p_docked];
551
if (base->p_fuel < base->p_ship.s_maxfuel) { /* give excess to base */
552
base->p_fuel += j->p_fuel - j->p_ship.s_maxfuel;
553
if (base->p_fuel > base->p_ship.s_maxfuel)
554
base->p_fuel = base->p_ship.s_maxfuel;
557
j->p_fuel = j->p_ship.s_maxfuel; /* set to max */
559
if (j->p_fuel < 0) { /* if below zero */
560
j->p_desspeed = 0; /* come to a stop */
561
j->p_flags &= ~PFCLOAK; /* uncloak */
562
j->p_fuel = 0; /* set it to zero */
565
if (j->p_flags & PFREPAIR)
569
if ((j->p_flags & PFORBIT) && !((j->p_swar |
570
j->p_hostile) & planets[j->p_planet].pl_owner)) {
571
switch (planets[j->p_planet].pl_flags & (PLREPAIR | PLSHIPYARD)) {
581
case PLREPAIR | PLSHIPYARD:
586
else if ((j->p_flags & PFDOCK) &&
587
(players[j->p_docked].p_ship.s_nflags & SFNCANREPAIR)) {
590
if (j->p_shield < j->p_ship.s_maxshield) { /* if shields damaged */
591
/* repair the shields */
592
j->p_subshield += j->p_ship.s_repair * factor; /* add to shields fract */
594
if (j->p_subshield / 1000) { /* if fract over 1000 */
595
j->p_shield += j->p_subshield / 1000; /* then add to shields */
596
j->p_subshield %= 1000; /* take mod */
598
if (j->p_shield > j->p_ship.s_maxshield) { /* went over max */
599
j->p_shield = j->p_ship.s_maxshield; /* then no overflow */
602
} /* end of if shields damaged */
603
/* do repair of ship */
604
if (j->p_damage && !(j->p_flags & PFSHIELD)) {
605
j->p_subdamage += j->p_ship.s_repair * factor; /* add to fract repair */
606
if (j->p_subdamage / 1000) { /* if fract repair too high */
607
j->p_damage -= j->p_subdamage / 1000; /* take away real damage */
608
j->p_subdamage %= 1000; /* mod the fract repair */
610
if (j->p_damage < 0) { /* do not want damge < 0 */
611
j->p_damage = 0; /* set it */
612
j->p_subdamage = 0; /* zero the fract part too */
615
if (allows_docking(j->p_ship))
616
repair_docking_ring(j);
622
/*--------------------------------DOBOUNCE--------------------------------*/
623
/* This function checks to see if the player has hit a wall. If he has his
624
direction and position are adjusted. */
627
dobounce(struct player *j) /* the player to bounce */
631
if (j->p_x < 0) { /* past left wall? */
632
x = -j->p_x; /* set him to right of wall */
633
j->p_dir = j->p_desdir = 64 - (j->p_dir - 192); /* adjust direction */
635
else if (j->p_x > configvals->gwidth) { /* past right wall? */
636
x = configvals->gwidth - (j->p_x - configvals->gwidth);
637
/* set him left of wall */
638
j->p_dir = j->p_desdir = 192 - (j->p_dir - 64); /* adjust direction */
640
if (j->p_y < 0) { /* past top wall? */
641
y = -j->p_y; /* set inside galactic */
642
j->p_dir = j->p_desdir = 128 - j->p_dir; /* adjust direction */
644
else if (j->p_y > configvals->gwidth) { /* below bottom wall */
645
y = configvals->gwidth - (j->p_y - configvals->gwidth);
646
/* place on right side of bed */
647
j->p_dir = j->p_desdir = 0 - (j->p_dir - 128); /* adjust position */
649
move_player(j->p_no, x, y, 1);
655
/*---------------------------------DOALERT-------------------------------*/
656
/* This function sets the player's alert status by checking the other
657
players in the game and seeing if they are too close. Should probably be
658
moved to the code that does visibility. */
661
doalert(struct player *j) /* the player to check for */
663
int k; /* Oh, no. Another looping var */
664
int dx, dy, dist; /* to find distances */
666
j->p_flags |= PFGREEN; /* default is green status */
667
j->p_flags &= ~(PFRED | PFYELLOW); /* clear red and yellow alert */
668
for (k = 0; k < MAXPLAYER; k++) { /* go through all players */
669
if ((players[k].p_status != PALIVE) /* should we check player */
670
||((!((j->p_swar | j->p_hostile) & players[k].p_team))
671
&& (!((players[k].p_swar | players[k].p_hostile) & j->p_team)))) {
672
continue; /* no, don't waste the time */
674
else if (j == &players[k]) /* do not check ourself */
676
else { /* we will check this player */
677
dx = j->p_x - players[k].p_x; /* take delta coords */
678
dy = j->p_y - players[k].p_y;
679
if (ABS(dx) > YRANGE || ABS(dy) > YRANGE) /* obviously out of
681
continue; /* stop checking him */
682
dist = dx * dx + dy * dy; /* calc dist squared */
683
if ((dist < YRANGE * YRANGE)) { /* close enough for yellow
685
j->p_flags |= PFYELLOW;
686
j->p_flags &= ~(PFGREEN);
688
if (dist < RRANGE * RRANGE) { /* if close enough for red
690
j->p_flags |= PFRED; /* set red alert status */
691
j->p_flags &= ~(PFGREEN | PFYELLOW);
693
if (j->p_flags & PFRED) /* if yellow set then check no */
702
/*--------------------------------CHANGEDIR--------------------------------*/
703
/* This function does the turning for a ship. It changes the players
704
direction to his desired direction, with the rate of change based on the
705
player's speed and maneuveribility of his ship. This function includes
706
optional use of TC's new-style turn rates. */
709
changedir(struct player *sp) /* the player to turn */
711
unsigned int ch_ticks;
712
unsigned int min, max;
715
speed = sp->p_speed; /* get player's speed */
716
if (speed == 0) { /* if player is at speed zero then */
717
sp->p_dir = sp->p_desdir; /* change in direction is instant */
720
else { /* else we are moving */
721
if (configvals->newturn)/* newstyle turn */
722
sp->p_subdir += sp->p_ship.s_turns / (speed * speed);
723
else /* old style turn */
724
sp->p_subdir += sp->p_ship.s_turns / ((sp->p_speed < 30) ?
725
(1 << sp->p_speed) : 1000000000);
726
ch_ticks = sp->p_subdir / 1000; /* get upper digits of subdir */
727
if (ch_ticks) { /* if more than one then we turn */
728
if (sp->p_dir > sp->p_desdir) { /* find the min and max of
730
min = sp->p_desdir; /* direction and desired direction */
737
if ((ch_ticks > max - min) || (ch_ticks > 256 - max + min)) /* can we immediately */
738
sp->p_dir = sp->p_desdir; /* get to desired direction */
739
else if ((unsigned char) ((int) sp->p_dir - (int) sp->p_desdir) > 127)
740
sp->p_dir += ch_ticks; /* else move to the right */
742
sp->p_dir -= ch_ticks; /* move to the left */
743
sp->p_subdir %= 1000; /* take off upper digits */
752
being_tractored(struct player *victim)
755
for (i = 0; i < MAXPLAYER; i++)
756
if (players[i].p_status == PALIVE
757
&& (players[i].p_flags & (PFTRACT | PFPRESS))
758
&& (players[i].p_tractor == victim->p_no)
759
&& (players[i].p_no != victim->p_no) /* can happen */
760
&& (players[i].p_team != victim->p_team)
768
/*----------------------------------DOMOVE-------------------------------*/
769
/* This function calls the change direction function then accellerates or
770
decellerates the ship if it is needed. The coordinates of the ship are
774
domove(struct player *j) /* the player to move */
776
int maxspeed; /* to hold max speed */
777
int acc; /* to hold accelleration */
778
int dcc; /* to hold decelleration */
779
int fcost; /* to hold fuel cost */
780
int ecost; /* to hold E-temp cost */
781
float t; /* temp float */
782
int k; /* looping var */
785
if (j->p_desspeed <= j->p_speed && j->p_speed <= j->p_ship.s_imp.maxspeed)
786
j->p_flags &= ~(PFWARP | PFAFTER);
788
if (j->p_warptime > 0
789
&& configvals->warpprepstyle == WPS_TABORTNOW
790
&& being_tractored(j)) {
791
j->p_warptime = 0; /* abort warp prep now */
792
j->p_flags &= ~PFWARPPREP;
793
god2player("Tractor beam aborted warp prep immediately", j->p_no);
796
if (j->p_warptime > 0 ||
797
(configvals->warpprep_suspendable && j->p_flags & PFWPSUSPENDED)) {
798
if (j->p_speed == j->p_ship.s_warpprepspeed /* don't speed */
799
&& (configvals->cloakduringwarpprep /* is cloaking legal? */
800
|| !(j->p_flags & PFCLOAK)) /* or is it not engaged? */
802
if (configvals->warpprepstyle == WPS_TSUSPEND && being_tractored(j)) {
803
/* whoa, warp prep suspended */
806
j->p_warptime--;/* countdown to warp powerup. */
807
/* put off warping if warpprep suspended [BDyess] */
808
if (j->p_warptime == 0 && (j->p_flags & PFWPSUSPENDED) &&
809
configvals->warpprep_suspendable)
811
if (0 == j->p_warptime) {
813
/* warp drives have finished prepping */
814
j->p_flags &= ~PFWARPPREP;
815
if (configvals->warpprepstyle == WPS_TABORT) {
816
if (being_tractored(j)) {
817
god2player("Tractor beam aborted warp engagement", j->p_no);
821
else if (configvals->warpprepstyle == WPS_TPREVENT) {
822
if (being_tractored(j)) {
828
j->p_flags |= PFWARP;
829
j->p_desspeed = j->p_warpdesspeed; /* go however fast he
837
j->p_flags |= PFWARPPREP;
838
j->p_desspeed = j->p_ship.s_warpprepspeed;
839
if (!configvals->cloakduringwarpprep)
840
j->p_flags &= ~PFCLOAK;
844
/**********************************************************************/
846
* for some reason this would occasionally be zero and cause an FPE in
849
if (!j->p_ship.s_maxdamage)
852
if ((j->p_dir != j->p_desdir) && (j->p_status != PEXPLODE))
853
changedir(j); /* change direction if needed */
855
if((j->p_flags & PFWARP) && !j->p_warptime && configvals->tractabortwarp)
856
if(being_tractored(j))
857
j->p_flags &= ~PFWARP;
860
if ((j->p_flags & PFWARP) &&
861
j->p_warptime == 0) { /* make sure we are really warping */
862
maxspeed = j->p_ship.s_warp.maxspeed;
863
if(configvals->warpzone) {
865
maxspeed = maxspeed * 3 / 2;
867
/* get damage adjusted max speed */
868
maxspeed -= (int) ((float) maxspeed *
869
(float) j->p_damage / (float) j->p_ship.s_maxdamage);
870
maxspeed = (maxspeed < 0) ? 0 : maxspeed; /* no going backward */
871
acc = j->p_ship.s_warp.acc; /* get accelleration for warp */
872
dcc = j->p_ship.s_warp.dec; /* get decelleration for warp */
873
fcost = j->p_ship.s_warp.cost; /* get fuel for warping */
874
ecost = j->p_ship.s_warp.etemp; /* get e-temp for warping */
876
else if (j->p_flags & PFAFTER) { /* if after burners on */
877
maxspeed = j->p_ship.s_after.maxspeed -
878
(int) ((float) j->p_ship.s_after.maxspeed *
879
(float) j->p_damage / (float) j->p_ship.s_maxdamage);
880
maxspeed = (maxspeed < 0) ? 0 : maxspeed; /* no going backward */
881
acc = j->p_ship.s_after.acc; /* get acc for afterburners */
882
dcc = j->p_ship.s_after.dec; /* get decel for afterburners */
883
fcost = j->p_ship.s_after.cost; /* fuel used for after */
884
ecost = j->p_ship.s_after.etemp; /* E-temp for after */
886
else { /* if normal speed */
887
maxspeed = j->p_ship.s_imp.maxspeed - (int) ((float) j->p_ship.s_imp.maxspeed *
888
(float) j->p_damage / (float) j->p_ship.s_maxdamage);
889
maxspeed = (maxspeed < 0) ? 0 : maxspeed; /* no going backward */
890
acc = j->p_ship.s_imp.acc; /* accelleration for impulse */
891
dcc = j->p_ship.s_imp.dec; /* decelleration for impulse */
892
fcost = j->p_ship.s_imp.cost * j->p_speed; /* fuel used for impulse */
893
ecost = j->p_ship.s_imp.etemp * j->p_speed; /* E-temp for impulse */
895
if ((j->p_desspeed > maxspeed) /* if we are too damage to go max */
896
/* && (j->p_damage < 0.9 * j->p_ship.s_maxdamage) */
898
j->p_desspeed = maxspeed; /* then set a new desired speed */
899
if ((j->p_flags & PFENG) /* if E-temped or repairing */
900
&&!(j->p_flags & PFREPAIR))
901
j->p_desspeed = 0; /* speed drops to 0 */
902
j->p_fuel -= fcost; /* suck up fuel */
903
j->p_subetemp += ecost; /* heat the engines */
904
if (allows_docking(j->p_ship)) { /* if ships can dock to this */
905
for (k = 0; k < j->p_ship.s_numports; k++) /* go through all ports */
906
if (j->p_port[k] >= 0) { /* if ship docked there */
907
t = (float) players[j->p_port[k]].p_ship.s_mass /
908
(float) j->p_ship.s_mass;
909
j->p_fuel -= (int) (t * (float) fcost);
910
j->p_subetemp += (int) (t * (float) ecost);
913
while (j->p_subetemp > 1000) { /* add on the high part of subetemp */
914
j->p_etemp += 1; /* to etemp */
915
j->p_subetemp -= 1000;
919
* check acceleration, only if we have fuel.
920
* if we need to slow down, do that, but do it if we are
921
* out of fuel as well.
923
if ( (j->p_desspeed > j->p_speed) && (j->p_fuel > j->p_ship.s_recharge) ) {
924
j->p_subspeed += acc; /* add on accelleration */
927
* no fuel? force him to slow down.
931
if ( j->p_desspeed < j->p_speed ) {/* if we need to go slower */
932
j->p_subspeed -= dcc; /* decrease our speed */
934
if (j->p_subspeed / 1000) { /* if fractional part big enough */
935
j->p_speed += j->p_subspeed / 1000; /* change integer speed */
936
if ((j->p_subspeed < 0 && j->p_speed < j->p_desspeed) ||
937
(j->p_subspeed > 0 && j->p_speed > j->p_desspeed)) {
938
/* went too far, adjust [BDyess] */
939
j->p_speed = j->p_desspeed;
943
j->p_subspeed %= 1000; /* adjust the fractional part */
944
if (j->p_speed < 0) /* can't go below zero speed */
948
if ((!configvals->warpdecel) && j->p_speed > maxspeed)
949
/* can't exceed maxspeed */
950
j->p_speed = maxspeed;
954
j->p_x += (double) j->p_speed * Cos[j->p_dir] * WARP1; /* adjust coords */
955
j->p_y += (double) j->p_speed * Sin[j->p_dir] * WARP1;
956
move_player(j->p_no, j->p_x, j->p_y, 1);
964
/*-------------------------------DOTRACTOR-------------------------------*/
965
/* This function handles the tractoring and pressoring for a player.
966
There is a long set of conditions that can turn off tractors. */
969
dotractor(struct player *j) /* the player to do */
971
float cosTheta, sinTheta; /* Cos and Sin from me to him */
972
int halfforce; /* Half force of tractor */
973
float dist; /* for finding distance */
974
struct player *victim;
976
if (j->p_flags & PFTRACT) { /* tractor beam on? */
977
victim = &players[j->p_tractor];
978
if ((isAlive(victim))
979
&& ((j->p_fuel > j->p_ship.s_tractcost) && !(j->p_flags & PFENG))
980
&& ((dist = ihypot(j->p_x - victim->p_x, j->p_y - victim->p_y))
981
< (TRACTDIST) * j->p_ship.s_tractrng)
982
&& (!(j->p_flags & (PFORBIT | PFDOCK)))
983
/* && (!(victim->p_flags & PFDOCK)) */ ) {
985
if (victim->p_flags & PFORBIT) { /* pullplayer out of */
986
victim->p_flags &= ~PFORBIT; /* orbit */
988
else if (victim->p_flags & PFDOCK) {
989
/* ooOooo, damage the base */
990
struct player *base = &players[victim->p_docked];
991
int port_num = victim->p_port[0];
994
undock_player(victim);
996
/* we need a better reason than KSHIP */
997
flags = victim->p_flags;
998
victim->p_flags &= ~PFSHIELD; /* inflict damage on hull */
999
inflict_damage(j, (struct player *) 0, victim, DOCKDAMAGE, KSHIP);
1000
victim->p_flags = flags;
1002
flags = base->p_flags;
1003
base->p_flags &= ~PFSHIELD; /* inflict damage on hull */
1004
inflict_damage(j, (struct player *) 0, base, DOCKDAMAGE, KSHIP);
1005
base->p_flags = flags;
1006
base->p_port[port_num] = PDAMAGE; /* disable that docking
1009
j->p_fuel -= j->p_ship.s_tractcost; /* take fuel for tractors */
1010
j->p_subetemp += j->p_ship.s_tractetemp; /* heat engines up */
1011
cosTheta = victim->p_x - j->p_x;
1012
sinTheta = victim->p_y - j->p_y;
1013
if (dist == 0) /* like groos in the dark */
1014
dist = 1; /* avoid the divide by zero */
1015
cosTheta /= dist; /* normalize sin and cos */
1017
halfforce = (WARP1 * j->p_ship.s_tractstr);
1018
if (j->p_flags & PFPRESS) /* if pressors being */
1019
halfforce = -halfforce; /* used */
1020
/* move the players */
1022
j->p_x += cosTheta * halfforce / (j->p_ship.s_mass);
1023
j->p_y += sinTheta * halfforce / (j->p_ship.s_mass);
1024
move_player(j->p_no, j->p_x, j->p_y, 1);
1025
victim->p_x -= cosTheta * halfforce / (victim->p_ship.s_mass);
1026
victim->p_y -= sinTheta * halfforce / (victim->p_ship.s_mass);
1027
move_player(j->p_tractor, victim->p_x, victim->p_y, 1);
1029
else /* else if conditions not met */
1030
j->p_flags &= ~(PFTRACT | PFPRESS); /* for tractor turn off */
1034
/*-----------------------------------------------------------------------*/
1043
/*------------------------------VISIBLE FUNCTIONS-------------------------*/
1045
/*----------------------------------LOSERSTATS----------------------------*/
1046
/* This function is called when a player is killed and his losses need to
1050
loserstats(int pl) /* the dead player's number */
1052
struct player *dude; /* to point to player */
1054
if (!status->tourn &&
1055
(configvals->robot_stats && !(players[pl].p_flags & PFROBOT)))
1058
dude = &players[pl]; /* get pointer to player's structure */
1059
if (dude->p_ship.s_type == STARBASE) { /* if ship was a SB */
1060
dude->p_stats.st_sblosses++; /* then inc starbase losses */
1061
status->sblosses++; /* inc global stats */
1063
if (dude->p_ship.s_type == WARBASE) { /* if ship was a WB */
1064
dude->p_stats.st_wblosses++; /* then inc warbase losses */
1065
status->wblosses++; /* inc global stats */
1067
else { /* else if normal ship */
1068
dude->p_stats.st_tlosses++; /* inc t-mode losses */
1069
status->losses++; /* inc games t-mode losses */
1076
/*--------------------------------KILLERSTATS-----------------------------*/
1077
/* This function is called when a player kills another player and his
1078
kills need to be increased. This function will add partial kills if the
1079
victim was carrying armies. */
1082
killerstats(int pl, struct player *victim)
1084
struct player *dude; /* to point to killer's player struct */
1086
if (!status->tourn &&
1087
(configvals->robot_stats && !(players[pl].p_flags & PFROBOT)))
1090
dude = &players[pl]; /* get killer's player struct */
1091
if (dude->p_ship.s_type == STARBASE) { /* if player in SB then */
1092
dude->p_stats.st_sbkills++; /* inc SB kills */
1093
status->sbkills++; /* inc global SB kills */
1095
else if (dude->p_ship.s_type == WARBASE) { /* else if in warbase */
1096
dude->p_stats.st_wbkills++; /* inc warbase kills */
1097
status->wbkills++; /* inc global WB kills */
1099
else { /* else in normal ship */
1100
dude->p_stats.st_tkills++; /* inc t-mode kills */
1101
status->kills++; /* inc global kills */
1103
dude->p_stats.st_tdooshes += victim->p_armies;
1104
dude->p_dooshes += victim->p_armies;
1105
status->dooshes += victim->p_armies; /* add to global dooshes */
1106
dude->p_stats.st_di += 0.02 * 5.0 * (float) victim->p_armies;
1107
if (victim->p_ship.s_type == STARBASE)
1108
dude->p_stats.st_di += 3.0;
1109
if (victim->p_ship.s_type == WARBASE)
1110
dude->p_stats.st_di += 1.5;
1111
if (victim->p_ship.s_type == PATROL)
1112
dude->p_stats.st_di += 0.03;
1114
dude->p_stats.st_di += 0.04;
1115
/* give robots additional DI for kills, since it's all they ever do ;)*/
1116
if (dude->p_flags & PFROBOT && configvals->robot_stats)
1117
dude->p_stats.st_di += 0.05;
1123
/*------------------------------CHECKMAXKILLS-------------------------------*/
1124
/* This function checks to see if a player has exceeded his max kills and if
1125
he has, it records the new max kills. */
1128
checkmaxkills(int pl) /* # of player to check */
1130
struct stats *stats; /* to point to player's struct */
1131
struct player *dude; /* to point to his stats struct */
1133
if (!status->tourn &&
1134
(configvals->robot_stats && !(players[pl].p_flags & PFROBOT)))
1136
dude = &(players[pl]); /* get player's player struct */
1137
stats = &(dude->p_stats); /* get player's stat struct */
1138
if (dude->p_ship.s_type == STARBASE) { /* if in starbase then */
1139
if (stats->st_sbmaxkills < dude->p_kills) /* check max SB kills */
1140
stats->st_sbmaxkills = dude->p_kills; /* set if new max kills */
1142
else if (dude->p_ship.s_type == WARBASE) { /* warbase max kills */
1143
if (stats->st_wbmaxkills < dude->p_kills) /* check max WB kills */
1144
stats->st_wbmaxkills = dude->p_kills; /* set if new max kills */
1146
else if (stats->st_tmaxkills < dude->p_kills) { /* else normal ship */
1147
stats->st_tmaxkills = dude->p_kills; /* set if new max kills */
1154
/*----------------------------------BEAM----------------------------------*/
1155
/* This function goes through all the players and if any are beaming up
1156
or down, the beaming is done here. */
1161
register int i; /* looping variable */
1162
register struct player *j;
1164
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
1165
if ((j->p_status != PALIVE) || !(j->p_flags & (PFORBIT | PFDOCK)))
1167
if (j->p_flags & PFBEAMUP) { /* if beaming up */
1168
beammeupscotty(j); /* do the beamup */
1170
else if (j->p_flags & PFBEAMDOWN) { /* else if beaming down */
1171
beamdown(j); /* do the beam down */
1179
/*---------------------------------UDCLOAK--------------------------------*/
1180
/* This function incs/decs the cloakphase for the players. */
1185
register int i; /* looping var */
1187
for (i = 0; i < MAXPLAYER; i++) { /* go through all players */
1188
if (isAlive(&players[i])) /* if player is alive */
1190
if ((players[i].p_flags & PFCLOAK) /* if cloaking */
1191
&&(players[i].p_cloakphase < (CLOAK_PHASES - 1)))
1192
players[i].p_cloakphase++; /* on to next pahse */
1193
else if (!(players[i].p_flags & PFCLOAK) /* if uncloaking */
1194
&&(players[i].p_cloakphase > 0))
1195
players[i].p_cloakphase--; /* on to next phase */
1202
/*-------------------------------UDPLAYERS---------------------------------*/
1203
/* This function updates all the players. It handles most of the functions
1204
dealing with the player's ship. If there are no players in the game, then
1205
this function will set the dietime variable that the move function in the
1206
daemon will use to shut down the deamon. */
1211
register int i; /* looping vars */
1212
register struct player *j; /* to point to players */
1213
int nplayers; /* number of open slots */
1215
nplayers = 0; /* zero the player count */
1216
for (i = status->active = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
1217
switch (j->p_status) { /* test the player's status */
1218
case POUTFIT: /* player being ghostbusted */
1219
if (++(j->p_ghostbuster) > OUTFITTIME) { /* if time ran out */
1220
saveplayer(j); /* then save the player */
1221
j->p_status = PFREE; /* free up the player slot */
1222
move_player(j->p_no, -1, -1, 1);
1224
break; /* on to next player */
1225
case PFREE: /* if slot free then */
1226
nplayers++; /* inc players not here */
1227
j->p_ghostbuster = 0; /* so not to bust new players */
1228
break; /* on to next player */
1229
case PDEAD: /* if player dead */
1230
if (--j->p_explode <= 0) { /* dec exp timer, if below zero then */
1231
saveplayer(j); /* player is busted, save him */
1232
j->p_status = POUTFIT; /* change status to busted */
1234
break; /* on to next player */
1235
case PEXPLODE: /* if player exploding */
1236
doshipexplode(j); /* do the explosion stuff */
1237
/* no break, so this will fall through */
1238
/* and the explosion will move */
1239
case PALIVE: /* the player is alive */
1240
if ((j->p_flags & PFORBIT) && !(j->p_flags & PFDOCK))
1241
doorbit(j); /* if player orbiting him */
1242
else if (!(j->p_flags & PFDOCK))
1243
domove(j); /* move player through space */
1245
dobounce(j); /* bounce off of walls */
1246
if (j->p_status == PEXPLODE || j->p_status == PDEAD)
1247
break; /* player dead or exploding then stop */
1248
if (status->tourn && j->p_status == PALIVE)
1249
switch (j->p_ship.s_type) {
1251
j->p_stats.st_sbticks++; /* inc SB ticks */
1252
status->sbtime++; /* inc global SB time */
1255
j->p_stats.st_wbticks++; /* inc WB ticks */
1256
status->wbtime++; /* inc global WB time */
1259
j->p_stats.st_jsticks++; /* inc JS ticks */
1260
status->jstime++; /* inc global JS time */
1263
j->p_stats.st_tticks++; /* inc t-mode ticks */
1264
status->timeprod++; /* and global t-mode ticks */
1267
else if (j->p_flags & PFROBOT && configvals->robot_stats)
1268
switch (j->p_ship.s_type) {
1270
j->p_stats.st_sbticks++; /* inc SB ticks */
1273
j->p_stats.st_wbticks++; /* inc WB ticks */
1276
j->p_stats.st_jsticks++; /* inc JS ticks */
1279
j->p_stats.st_tticks++; /* inc t-mode ticks */
1283
if (j->p_jsdock > 0)/* inc js dock time */
1284
j->p_jsdock = (++j->p_jsdock < 1200) ? j->p_jsdock : 0;
1285
if (++(j->p_ghostbuster) > GHOSTTIME) { /* if ghost timer */
1286
cause_kaboom(j);/* ghost bust him--explode */
1287
ghostmess(j); /* go do the ghost shit */
1288
saveplayer(j); /* save the sorry bastard */
1289
j->p_whydead = KGHOST; /* killed by ghostbusters */
1290
j->p_whodead = i; /* killed by himself */
1292
status->active += (1 << i); /* ??????????? */
1293
j->p_updates++; /* inc time alive */
1294
doresources(j); /* go do various ship things */
1295
dotractor(j); /* do the tractors */
1297
enforce_dock_position(j);
1298
doalert(j); /* check alert status */
1302
if (++(j->p_ghostbuster) > GHOSTTIME) { /* if ghost timer */
1303
saveplayer(j); /* save the sorry bastard */
1304
j->p_status = PFREE;
1305
move_player(j->p_no, -1, -1, 1);
1307
if (j->p_flags & PFPLOCK) { /* watching a player */
1308
struct player *watched = &players[j->p_playerl];
1309
if (watched->p_team == j->p_team) {
1310
j->p_x = watched->p_x;
1311
j->p_y = watched->p_y;
1314
j->p_flags &= ~(PFPLOCK | PFPLLOCK);
1317
else if (j->p_flags & PFPLLOCK) { /* watching a planet */
1318
struct planet *watched = &planets[j->p_planet];
1319
if (watched->pl_owner == j->p_team) {
1320
j->p_x = watched->pl_x;
1321
j->p_y = watched->pl_y;
1324
j->p_flags &= ~(PFPLOCK | PFPLLOCK);
1329
j->p_y = -10000;/* out of the action... */
1334
if (++(j->p_ghostbuster) > GHOSTTIME) { /* if ghost timer */
1335
ghostmess(j); /* go do the ghost shit */
1336
saveplayer(j); /* save the sorry bastard */
1337
j->p_status = PFREE;
1338
move_player(j->p_no, -1, -1, 1);
1341
} /* end of switch */
1342
} /* end of for loop through players */
1343
if (nplayers == MAXPLAYER) {/* if no players playing */
1344
if (dietime == -1) /* if daemon die timer not running */
1345
dietime = ticks + 600 / PLAYERFUSE; /* set it for one minute */
1346
if(status2->starttourn) /* no players, so reset to make it a fresh */
1347
status2->newgalaxy = 1; /* galaxy */
1349
else /* else stop daemon die timer */
1352
if (status2->league && status->tourn) {
1353
int leaguecount[2]; /* used to bench excess players */
1355
leaguecount[0] = leaguecount[1] = 0;
1357
/* count up how many live players on each team */
1358
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
1359
if (players[i].p_status == PALIVE) {
1360
int which = (j->p_team == idx_to_mask(status2->away.index));
1361
leaguecount[which]++;
1365
if (leaguecount[0] >= configvals->playersperteam ||
1366
leaguecount[1] >= configvals->playersperteam) {
1368
if we're full of live players then all non-live players must
1371
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
1372
int which = (j->p_team == idx_to_mask(status2->away.index));
1373
if (j->p_status != PALIVE && j->p_status != POBSERVE
1374
&& leaguecount[which] >= configvals->playersperteam) {
1380
leaguecount[0] = leaguecount[1] = 0;
1382
/* count up how many playing players on each team */
1383
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
1384
if (players[i].p_status != PFREE &&
1385
players[i].p_status != POBSERVE) {
1386
int which = (j->p_team == idx_to_mask(status2->away.index));
1387
leaguecount[which]++;
1391
if (leaguecount[0] < configvals->playersperteam ||
1392
leaguecount[1] < configvals->playersperteam) {
1394
if a team is short, let an observer who doesn't want to
1397
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
1398
int which = (j->p_team == idx_to_mask(status2->away.index));
1399
if (j->p_status == POBSERVE
1400
&& leaguecount[which] < configvals->playersperteam
1401
&& j->p_observer == 0) {
1402
j->p_whydead = KPROVIDENCE;
1404
j->p_status = POUTFIT;
1405
leaguecount[which]++;
1410
/* check for refits and unexpected deaths */
1411
scan_for_unexpected_tourny_events();
1415
/*------------------------------------------------------------------------*/
1421
/*----------END OF FILE--------*/