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
--------------------------------------------------------------------*/
35
/*------------------------------NUMBER DEFINES-----------------------------*/
36
#define INDEP (GWIDTH/3) /* width of region in the center of galaxy */
37
/* that independents can join in */
39
#define MIN_DIST_FROM_STAR 3000.0 /* min distance from a star that enter() */
41
/*-------------------------------------------------------------------------*/
45
find_start_planet(int team, int flag)
47
int valid[MAXPLANETS];
52
for (i = 0; i < NUMPLANETS; i++) {
53
struct planet *pl = &planets[i];
54
if (pl->pl_owner == team && (!flag || pl->pl_flags & flag))
60
return valid[lrand48() % nvalid];
63
/*------------------------------VISIBLE FUNCTIONS-------------------------*/
65
#define BOSSMAN NUMROYALRANKS-1
66
#define SIDEKICK NUMROYALRANKS-2
67
#define AMBASSADOR NUMROYALRANKS-3
71
#define SIDEKICK NUMROYALRANKS-1
73
#define AMBASSADOR NUMROYALRANKS-1
76
/*--------------------------------PEANUT_GALLERY--------------------------*/
77
/* This function checks too see if certain "important" people have logged
78
in, and displays a special message to the rest of the players. As the chief
79
Paradise hack, I forbid removal of any of the code in this function. Other
80
names may be added. If you choose to disregard this, a malefiction will be
81
leveled upon your head and all of your progeny will be born with their noses
82
two times too large. */
84
#define AT_LEAST(rank) if (me->p_stats.st_royal<rank) me->p_stats.st_royal = rank;
92
if (strcmp(me->p_name, "a fungusamongus") == 0) { /* that's me! */
93
pmessage2(" ", 0, MALL, "LDDENYS > ", me->p_no);
94
pmessage2("Yikes. EEK! Help. There seems to be a fungus among us!", 0, MALL, "LDDENYS > ", me->p_no);
95
pmessage2(" ", 0, MALL, "LDDENYS > ", me->p_no);
98
else if (strcmp(me->p_name, "Lynx") == 0) {
99
pmessage2("\"GAME OVER MAN, GAME OVER!\"", 0, MALL, "Lynx->ALL ", me->p_no);
102
else if (strcmp(me->p_name, "Hammor") == 0) {
103
pmessage2("Please don't hurt 'em, Hammor!", 0, MALL, "GOD->ALL", me->p_no);
106
else if (strcmp(me->p_name, "Bubbles") == 0) {
107
pmessage2("Whoa!", 0, MALL, "KAOLSEN > ", me->p_no);
108
pmessage2("Dudes.", 0, MALL, "KAOLSEN > ", me->p_no);
109
pmessage2("Cool.", 0, MALL, "KAOLSEN > ", me->p_no);
112
else if (strcmp(me->p_name, "KnightRaven") == 0) {
113
pmessage2("Insert Heiji quote here", 0, MALL, "KAOLSEN > ", me->p_no);
114
AT_LEAST(AMBASSADOR);
117
else if (strcmp(me->p_name, "wibble") == 0) {
118
pmessage2("No mountain is unclimbable, no river uncrossable, no client RSA"
119
,0, MALL, "EGO->wibble", me->p_no);
120
pmessage2("key unbreakable. We can just make it bloody difficult!",
121
0, MALL, "EGO->wibble", me->p_no);
124
else if (strcmp(me->p_name, "Key") == 0) {
129
(void) time(&curtime);
130
tmstruct = localtime(&curtime);
131
if (!(hour = tmstruct->tm_hour % 12))
134
sprintf(buf, "It's %d:%02d%s, time [for me] to die.", hour,
135
tmstruct->tm_min, tmstruct->tm_hour >= 12 ? "pm" : "am");
136
pmessage2(buf, 0, MALL, "GOD->ALL", me->p_no);
139
else if (strcmp(me->p_name, "MikeL") == 0) {
140
pmessage2("<This space for rent>", 0, MALL, "GOD->ALL", me->p_no);
144
else if (strcmp(me->p_name, "Bolo") == 0) {
145
pmessage2("Bolo Mk. MCLXVII On-line.", 0, MALL, MSERVA, me->p_no);
150
advertise_tourney_queue(void)
152
char buf[80], addrbuf[10];
159
for (i = 0; i < MAXPLAYER; i++) {
160
if (players[i].p_status == PTQUEUE)
164
sprintf(addrbuf, "%s->YOU ", SERVNAME);
165
sprintf(buf, "There %s %d player%s on the tournament queue",
166
(count == 1) ? "is" : "are", count, (count == 1) ? "" : "s");
167
pmessage (buf, me->p_no, MINDIV, addrbuf);
170
/*--------------------------------AUTOPEACE------------------------------*/
171
/* This function set the player as hostile to all teams with at least one
172
player on them if it is t-mode. Otherwise if it is not t-mode the player
173
is set as hositle to everyone. */
178
int i, num[MAXTEAM + 1];/* to hold team's player counts */
179
struct player *p; /* looping var */
181
num[0] = num[FED] = num[ROM] = num[KLI] = num[ORI] = 0; /* zero counts */
182
for (i = 0, p = players; i < MAXPLAYER; i++, p++) /* loop all players */
183
if (p->p_status != PFREE) /* ince the count of the team the */
184
num[p->p_team]++; /* player is on */
185
if (status->tourn) /* if t-mode then make player hostile */
186
me->p_hostile = /* make all teams with a player on */
187
((FED * (num[FED] >= configvals->tournplayers)) |
188
(ROM * (num[ROM] >= configvals->tournplayers)) |
189
(KLI * (num[KLI] >= configvals->tournplayers)) |
190
(ORI * (num[ORI] >= configvals->tournplayers)));
191
else /* else if not t-mode then */
192
me->p_hostile = FED | ROM | KLI | ORI; /* hostile to everyone */
195
/*------------------------------PLACEINDEPENDENT---------------------------*/
196
/* This function places an independent player in the game so he is not
197
near any other players. */
200
placeIndependent(void)
202
int i; /* ye olde looping var */
203
struct player *p; /* to point to players */
204
int good, failures; /* flag for success, count of tries */
206
failures = 0; /* have started loops yet */
207
while (failures < 10) { /* only try 10 times */
208
me->p_x = GWIDTH / 2 + (lrand48() % INDEP) - INDEP / 2; /* middle 9th of */
209
me->p_y = GWIDTH / 2 + (lrand48() % INDEP) - INDEP / 2; /* galaxy */
211
for (i = 0, p = players; i < MAXPLAYER; i++, p++) {
212
if ((p->p_status != PFREE) && (p != me)) {
213
if ((ABS(p->p_x - me->p_x) < 2 * TRACTDIST) &&
214
(ABS(p->p_y - me->p_y) < 2 * TRACTDIST)) {
215
failures++; /* found a player too close */
216
good = 0; /* position not good */
217
break; /* try another positon */
221
if (good) /* if good placement found then */
224
fprintf(stderr, "Couldn't place the bot successfully.\n");
232
for (i = MAXPLAYER - configvals->ntesters; i < MAXPLAYER; i++) {
233
if (players[i].p_status == PFREE) { /* We have a free slot */
234
players[i].p_status = POUTFIT; /* possible race code */
238
if (i == MAXPLAYER) {
239
return -1; /* no room in tester slots */
241
memset(&players[i].p_stats, 0, sizeof(struct stats));
242
players[i].p_stats.st_tticks = 1;
251
/* look for tester slot first */
256
for (i = 0; i < MAXPLAYER; i++) {
257
if (players[i].p_status == PFREE) { /* We have a free slot */
258
players[i].p_status = POUTFIT; /* possible race code */
262
if ((i == MAXPLAYER) || (i == -1)) {
265
memset(&players[i].p_stats, 0, sizeof(struct stats));
266
players[i].p_stats.st_tticks = 1;
270
/*------------------------------------ENTER-------------------------------*/
271
/* This function places a player into the game. It initializes fields in
272
the player structure and his ship. It determines where in the galaxy to
273
put the player. This function is also used to place robots and independents.
274
If tno = 4, then the player is independent. If it is 5 then the player is
277
/* CRD feature: starting planet (for robots) - MAK, 2-Jun-93
278
* Also added starting planet number as a useful return value.
282
tno - team player is on
283
disp - "not used, so I used it 7/27/91 TC"
284
pno - player's number
285
s_type - player's ship type
286
startplanet - planet to enter near (or -1) */
289
enter(int tno, int disp, int pno, int s_type, int startplanet)
291
static int lastteam = -1; /* to hold team of last enter */
292
static int lastrank = -1; /* to hold rank of last enter */
293
char buf[80]; /* to sprintf into */
294
char buf2[80]; /* to sprintf into */
295
char addrbuf[10]; /* to hold address */
297
if ((startplanet < 0) || (startplanet >= NUMPLANETS))
300
(void) strncpy(me->p_name, pseudo, sizeof(me->p_name)); /* get name */
301
me->p_name[sizeof(me->p_name) - 1] = '\0'; /* delimiet just in case */
303
me->p_kills = 0.0; /* have no kills yet */
304
get_ship_for_player(me, s_type); /* get the player's ship type */
306
if (me->p_ship.s_nflags & SFNHASFIGHTERS)
307
me->p_ship.s_missilestored = 0;
309
me->p_docked = 0; /* not docked to anyone */
310
me->p_updates = 0; /* start updating immediately */
311
me->p_flags = PFSHIELD;
312
if (allows_docking(me->p_ship))
313
me->p_flags |= PFDOCKOK;/* enable docking */
314
me->p_dir = 0; /* direction angle of zero */
315
me->p_desdir = 0; /* desired direction of zero */
316
me->p_speed = 0; /* speed of zero */
317
me->p_desspeed = 0; /* desired speed of zero */
318
me->p_subspeed = 0; /* fractional part of speed zero */
320
/* Gunboat docked to ships stuff */
321
if ((me->p_ship.s_nflags & SFNMASSPRODUCED) &&
322
(shipvals[shipPick].s_numports)) {
325
me->p_team = (1 << tno);
326
for (i = 0; i < MAXPLAYER; i++)
327
if ((players[i].p_ship.s_type == shipPick) &&
328
(players[i].p_team == me->p_team) &&
329
(players[i].p_status == PALIVE) && /* if all this stuff... */
330
(players[i].p_flags & PFDOCKOK) &&
331
(players[i].p_docked < players[i].p_ship.s_numports) &&
332
(players[i].p_ship.s_missilestored)) {
333
me->p_x = players[i].p_x; /* ...dock em on */
334
me->p_y = players[i].p_y;
336
if (players[i].p_ship.s_missilestored != -1)
337
players[i].p_ship.s_missilestored--;
338
if (players[i].p_flags & PFCLOAK) {
339
me->p_flags |= PFCLOAK;
340
me->p_cloakphase = players[i].p_cloakphase;
341
} else me->p_cloakphase = 0;
345
/* End Gunboat stuff */
347
if ((tno == 4) || (tno == 5)) { /* if player indep or a robot */
348
me->p_team = 0; /* he has no team */
350
else { /* else player is normal player--find planet */
351
me->p_team = (1 << tno);/* set players team number */
353
/* forgive me father, for I have used short-circuiting to
354
emulate control flow */
355
(startplanet >= 0 /* start planet already specified? */
356
|| (((startplanet = me->p_lastrefit) >= 0 /* we've got a home
358
&& (planets[startplanet].pl_flags & PLSHIPYARD) /* and it's a yard */
359
&&(planets[startplanet].pl_owner == me->p_team)) /* and it's ours */
360
||0 < (me->p_lastrefit = -1)) /* oops, no more home
362
||(startplanet = find_start_planet(me->p_team, PLSHIPYARD)) != -1
363
|| (startplanet = find_start_planet(me->p_team, PLREPAIR)) != -1
364
|| (startplanet = find_start_planet(me->p_team, PLAGRI)) != -1
365
|| (startplanet = find_start_planet(me->p_team, PLFUEL)) != -1
366
|| (startplanet = find_start_planet(me->p_team, PLHOME)) != -1
367
|| (startplanet = find_start_planet(me->p_team, 0)) != -1
370
if (startplanet == -1) {
378
/* we have a planet */
379
/* use p_x and y as scratch registers */
381
me->p_x = planets[startplanet].pl_x + (lrand48() % 10000) - 5000;
382
me->p_y = planets[startplanet].pl_y + (lrand48() % 10000) - 5000;
383
if (me->p_x < 0) /* can't come in outside of borders */
384
me->p_x = 0; /* now can we? */
387
if (me->p_x >= GWIDTH)
389
if (me->p_y >= GWIDTH)
391
for(i = 0, l = &planets[0]; i < NUMPLANETS; i++, l++) {
392
if(PL_TYPE(*l) == PLSTAR) {
393
dx = ABS(l->pl_x - me->p_x);
394
dy = ABS(l->pl_y - me->p_y);
395
if(dx * dx + dy * dy <
396
MIN_DIST_FROM_STAR * MIN_DIST_FROM_STAR)
403
/* legitimize p_x and p_y */
404
move_player(me->p_no, me->p_x, me->p_y, 0);
406
me->p_ntorp = 0; /* have not fired torps yete */
407
if (!((me->p_ship.s_nflags & SFNMASSPRODUCED) &&
408
(shipvals[shipPick].s_numports)))
409
me->p_cloakphase = 0; /* no cloaking phase--not cloaked */
410
me->p_nplasmatorp = 0; /* no plasma torps */
411
me->p_swar = 0; /* at war with nobody */
412
me->p_armies = 0; /* carrying no armies */
415
switch_special_weapon();
417
if (!keeppeace) /* if keep peace mode then */
418
auto_peace(); /* set do automatic peace */
419
me->p_hostile &= ~me->p_team; /* hostile to all but own team */
420
me->p_swar &= ~me->p_team;
421
if ((lastteam != tno) || (lastrank != mystats->st_rank)) {
422
if ((lastteam > 0) && (lastteam < NUMTEAM) && (lastteam != tno))
423
declare_war((1 << lastteam) | me->p_hostile); /* if changing then
425
lastteam = tno; /* store team number in static */
426
lastrank = mystats->st_rank; /* store rank in static */
427
sprintf(addrbuf, " %s->ALL", twoletters(me));
428
if ((tno == 4) && (strcmp(me->p_monitor, "Nowhere") == 0)) {
429
time_t curtime; /* if a robot and independent */
430
struct tm *tmstruct;/* to hold time */
431
int queuesize; /* to hold queue size */
432
int hour; /* to hold hour */
434
time(&curtime); /* get the time */
435
tmstruct = localtime(&curtime); /* convert to local time */
436
if (!(hour = tmstruct->tm_hour % 12)) /* get the hour */
438
sprintf(buf, "It's %d:%02d%s, time to die.", hour, tmstruct->tm_min,
439
tmstruct->tm_hour >= 12 ? "pm" : "am");
440
if ((queuesize = status->count - status->wait) > 0) {
441
/* lint: queuesize set but not used in function enter */
442
sprintf(buf2, " Approximate queue size: %d.", status->answer);
443
strcat(buf, buf2); /* get queue size if queue */
445
pmessage2(buf, 0, MALL, addrbuf, me->p_no); /* display message */
447
else if (tno == 5) { /* if a robot then */
448
if (players[disp].p_status != PFREE) {
449
sprintf(buf2, "%s has been targeted for termination.",
450
twoletters(&players[disp]));
451
pmessage2(buf2, 0, MALL, addrbuf, me->p_no);
455
if (!status2->league) /* no peanut messages in a league game */
456
peanut_gallery(); /* check for important people */
458
if (me->p_stats.st_royal == 0)
459
sprintf(buf, "%s %.16s is now %2.2s (%.16s@%.32s)",
460
ranks[me->p_stats.st_rank].name, me->p_name,
461
twoletters(me), me->p_login, me->p_full_hostname);
463
sprintf(buf, "%s %.16s is now %2.2s (%.16s@%.32s)",
464
royal[me->p_stats.st_royal].name, me->p_name,
465
twoletters(me), me->p_login, me->p_full_hostname);
467
pmessage2(buf, 0, MALL | MJOIN, addrbuf, me->p_no);
469
advertise_tourney_queue();
476
/*----------END OF FILE--------*/