comparison src/enter.c @ 2:2719a89505ba

First entry of Paradise Server 2.9 patch 10 Beta
author darius
date Sat, 06 Dec 1997 04:37:01 +0000
parents
children
comparison
equal deleted inserted replaced
1:4d6502ffaa5e 2:2719a89505ba
1 /*--------------------------------------------------------------------------
2 NETREK II -- Paradise
3
4 Permission to use, copy, modify, and distribute this software and its
5 documentation, or any derivative works thereof, for any NON-COMMERCIAL
6 purpose and without fee is hereby granted, provided that this copyright
7 notice appear in all copies. No representations are made about the
8 suitability of this software for any purpose. This software is provided
9 "as is" without express or implied warranty.
10
11 Xtrek Copyright 1986 Chris Guthrie
12 Netrek (Xtrek II) Copyright 1989 Kevin P. Smith
13 Scott Silvey
14 Paradise II (Netrek II) Copyright 1993 Larry Denys
15 Kurt Olsen
16 Brandon Gillespie
17 --------------------------------------------------------------------------*/
18
19
20 #include "config.h"
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <sys/time.h>
24 #include <sys/ipc.h>
25 #include <sys/shm.h>
26 #include <errno.h>
27 #include <pwd.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <time.h>
31 #include "defs.h"
32 #include "struct.h"
33 #include "data.h"
34 #include "shmem.h"
35 #include "grid.h"
36
37 void auto_peace();
38 static void placeIndependent();
39 extern int
40 pmessage2( /* char *str, int recip, int group, char
41 address, unsigned char from */ );
42 extern int
43 pmessage( /* char *str, int recip, int group, char
44 address */ );
45
46
47
48 /*------------------------------NUMBER DEFINES-----------------------------*/
49 #define INDEP (GWIDTH/3) /* width of region in the center of galaxy */
50 /* that independents can join in */
51
52 #define MIN_DIST_FROM_STAR 3000.0 /* min distance from a star that
53 * enter() */
54 /* will place you */
55 /*-------------------------------------------------------------------------*/
56
57
58 int
59 find_start_planet(team, flag)
60 int team, flag;
61 {
62 int valid[MAXPLANETS];
63 int nvalid;
64 int i;
65
66 nvalid = 0;
67 for (i = 0; i < NUMPLANETS; i++)
68 {
69 struct planet *pl = &planets[i];
70 if (pl->pl_owner == team && (!flag || pl->pl_flags & flag))
71 valid[nvalid++] = i;
72 }
73 if (nvalid < 1)
74 return -1;
75
76 return valid[lrand48() % nvalid];
77 }
78
79
80
81 /*------------------------------VISIBLE FUNCTIONS-------------------------*/
82
83 #define BOSSMAN NUMROYALRANKS-1
84 #define SIDEKICK NUMROYALRANKS-2
85 #define AMBASSADOR NUMROYALRANKS-3
86
87 #ifdef UFL
88 #undef SIDEKICK
89 #define SIDEKICK NUMROYALRANKS-1
90 #undef AMBASSADOR
91 #define AMBASSADOR NUMROYALRANKS-1
92 #endif
93
94 /*--------------------------------PEANUT_GALLERY--------------------------*/
95 /*
96 * This function checks too see if certain "important" people have logged in,
97 * and displays a special message to the rest of the players. As the chief
98 * Paradise hack, I forbid removal of any of the code in this function.
99 * Other names may be added. If you choose to disregard this, a malefiction
100 * will be leveled upon your head and all of your progeny will be born with
101 * their noses two times too large.
102 */
103
104 #define AT_LEAST(rank) if (me->p_stats.st_royal<rank) me->p_stats.st_royal = rank;
105
106
107 void
108 peanut_gallery()
109 {
110 char buf[90];
111
112 if (strcmp(me->p_name, "a fungusamongus") == 0)
113 { /* that's me! */
114 pmessage2(" ", 0, MALL, "LDDENYS > ", me->p_no);
115 pmessage2("Yikes. EEK! Help. There seems to be a fungus among us!", 0, MALL, "LDDENYS > ", me->p_no);
116 pmessage2(" ", 0, MALL, "LDDENYS > ", me->p_no);
117
118 }
119 else if (strcmp(me->p_name, "Lynx") == 0)
120 {
121 pmessage2("\"GAME OVER MAN, GAME OVER!\"", 0, MALL, "Lynx->ALL ", me->p_no);
122
123 }
124 else if (strcmp(me->p_name, "Hammor") == 0)
125 {
126 pmessage2("Please don't hurt 'em, Hammor!", 0, MALL, "GOD->ALL", me->p_no);
127
128 }
129 else if (strcmp(me->p_name, "Bubbles") == 0)
130 {
131 pmessage2("Whoa!", 0, MALL, "KAOLSEN > ", me->p_no);
132 pmessage2("Dudes.", 0, MALL, "KAOLSEN > ", me->p_no);
133 pmessage2("Cool.", 0, MALL, "KAOLSEN > ", me->p_no);
134
135 }
136 else if (strcmp(me->p_name, "KnightRaven") == 0)
137 {
138 pmessage2("Insert Heiji quote here", 0, MALL, "KAOLSEN > ", me->p_no);
139 AT_LEAST(AMBASSADOR);
140
141 }
142 else if (strcmp(me->p_name, "wibble") == 0)
143 {
144 pmessage("No mountain is unclimbable, no river uncrossable, no client RSA"
145 ,0, MALL, "EGO->wibble", me->p_no);
146 pmessage("key unbreakable. We can just make it bloody difficult!",
147 0, MALL, "EGO->wibble", me->p_no);
148
149 }
150 else if (strcmp(me->p_name, "Key") == 0)
151 {
152 time_t curtime;
153 struct tm *tmstruct;
154 int hour;
155
156 (void) time(&curtime);
157 tmstruct = localtime(&curtime);
158 if (!(hour = tmstruct->tm_hour % 12))
159 hour = 12;
160
161 sprintf(buf, "It's %d:%02d%s, time [for me] to die.", hour,
162 tmstruct->tm_min, tmstruct->tm_hour >= 12 ? "pm" : "am");
163 pmessage(buf, 0, MALL, "GOD->ALL", me->p_no);
164
165 }
166 else if (strcmp(me->p_name, "MikeL") == 0)
167 {
168 pmessage("<This space for rent>", 0, MALL, "GOD->ALL", me->p_no);
169
170
171 }
172 else if (strcmp(me->p_name, "Bolo") == 0)
173 {
174 pmessage("Bolo Mk. MCLXVII On-line.", 0, MALL, MSERVA, me->p_no);
175 }
176 }
177
178
179
180 void
181 advertise_tourney_queue()
182 {
183 char buf[80], addrbuf[10];
184 int count = 0;
185 int i;
186
187 if (status->tourn)
188 return;
189
190 for (i = 0; i < MAXPLAYER; i++)
191 {
192 if (players[i].p_status == PTQUEUE)
193 count++;
194 }
195
196 sprintf(addrbuf, "%s->YOU ", SERVNAME);
197 sprintf(buf, "There %s %d player%s on the tournament queue",
198 (count == 1) ? "is" : "are", count, (count == 1) ? "" : "s");
199 pmessage(buf, me->p_no, MINDIV, addrbuf);
200 }
201
202
203
204
205 /*------------------------------------ENTER-------------------------------*/
206 /*
207 * This function places a player into the game. It initializes fields in the
208 * player structure and his ship. It determines where in the galaxy to put
209 * the player. This function is also used to place robots and independents.
210 * If tno = 4, then the player is independent. If it is 5 then the player is
211 * a robot.
212 */
213
214 /*
215 * CRD feature: starting planet (for robots) - MAK, 2-Jun-93 Also added
216 * starting planet number as a useful return value.
217 */
218
219 int
220 enter(tno, disp, pno, s_type, startplanet)
221 int tno; /* team player is on */
222 int disp; /* not used, so I used it 7/27/91 TC */
223 int pno; /* player's number */
224 int s_type; /* player's ship type */
225 int startplanet; /* planet to enter near (or -1) */
226 {
227 static int lastteam = -1; /* to hold team of last enter */
228 static int lastrank = -1; /* to hold rank of last enter */
229 char buf[80]; /* to sprintf into */
230 char buf2[80]; /* to sprintf into */
231 char addrbuf[10]; /* to hold address */
232
233 if ((startplanet < 0) || (startplanet >= NUMPLANETS))
234 startplanet = -1;
235
236 (void) strncpy(me->p_name, pseudo, sizeof(me->p_name)); /* get name */
237 me->p_name[sizeof(me->p_name) - 1] = '\0'; /* delimiet just in case */
238
239 me->p_kills = 0.0; /* have no kills yet */
240 get_ship_for_player(me, s_type); /* get the player's ship type */
241
242 if (me->p_ship.s_nflags & SFNHASFIGHTERS)
243 me->p_ship.s_missilestored = 0;
244
245 me->p_docked = 0; /* not docked to anyone */
246 me->p_updates = 0; /* start updating immediately */
247 me->p_flags = PFSHIELD;
248 if (allows_docking(me->p_ship))
249 me->p_flags |= PFDOCKOK; /* enable docking */
250 me->p_dir = 0; /* direction angle of zero */
251 me->p_desdir = 0; /* desired direction of zero */
252 me->p_speed = 0; /* speed of zero */
253 me->p_desspeed = 0; /* desired speed of zero */
254 me->p_subspeed = 0; /* fractional part of speed zero */
255
256 /* Gunboat docked to ships stuff */
257 if ((me->p_ship.s_nflags & SFNMASSPRODUCED) &&
258 (shipvals[shipPick].s_numports))
259 {
260 int i;
261
262 me->p_team = (1 << tno);
263 for (i = 0; i < MAXPLAYER; i++)
264 if ((players[i].p_ship.s_type == shipPick) &&
265 (players[i].p_team == me->p_team) &&
266 (players[i].p_status == PALIVE) && /* if all this stuff... */
267 (players[i].p_flags & PFDOCKOK) &&
268 (players[i].p_docked < players[i].p_ship.s_numports) &&
269 (players[i].p_ship.s_missilestored))
270 {
271 me->p_x = players[i].p_x; /* ...dock em on */
272 me->p_y = players[i].p_y;
273 newdock(i);
274 if (players[i].p_ship.s_missilestored != -1)
275 players[i].p_ship.s_missilestored--;
276 if (players[i].p_flags & PFCLOAK)
277 {
278 me->p_flags |= PFCLOAK;
279 me->p_cloakphase = players[i].p_cloakphase;
280 }
281 else
282 me->p_cloakphase = 0;
283 break;
284 }
285 }
286 /* End Gunboat stuff */
287
288 if ((tno == 4) || (tno == 5))
289 { /* if player indep or a robot */
290 me->p_team = 0; /* he has no team */
291 }
292 else
293 { /* else player is normal player--find planet */
294 me->p_team = (1 << tno); /* set players team number */
295
296 /*
297 * forgive me father, for I have used short-circuiting to emulate control
298 * flow
299 */
300 (startplanet >= 0 /* start planet already specified? */
301 || (((startplanet = me->p_lastrefit) >= 0 /* we've got a home planet */
302 && (planets[startplanet].pl_flags & PLSHIPYARD) /* and it's a yard */
303 && (planets[startplanet].pl_owner == me->p_team)) /* and it's ours */
304 || 0 < (me->p_lastrefit = -1)) /* oops, no more home shipyard, F */
305 || (startplanet = find_start_planet(me->p_team, PLSHIPYARD)) != -1
306 || (startplanet = find_start_planet(me->p_team, PLREPAIR)) != -1
307 || (startplanet = find_start_planet(me->p_team, PLAGRI)) != -1
308 || (startplanet = find_start_planet(me->p_team, PLFUEL)) != -1
309 || (startplanet = find_start_planet(me->p_team, PLHOME)) != -1
310 || (startplanet = find_start_planet(me->p_team, 0)) != -1
311 );
312 }
313 if (startplanet == -1)
314 {
315 placeIndependent();
316 }
317 else
318 {
319 int i;
320 double dx, dy;
321 struct planet *l;
322
323 /* we have a planet */
324 /* use p_x and y as scratch registers */
325 while (1)
326 {
327 me->p_x = planets[startplanet].pl_x + (lrand48() % 10000) - 5000;
328 me->p_y = planets[startplanet].pl_y + (lrand48() % 10000) - 5000;
329 if (me->p_x < 0) /* can't come in outside of borders */
330 me->p_x = 0; /* now can we? */
331 if (me->p_y < 0)
332 me->p_y = 0;
333 if (me->p_x >= GWIDTH)
334 me->p_x = GWIDTH - 1;
335 if (me->p_y >= GWIDTH)
336 me->p_y = GWIDTH - 1;
337 for (i = 0, l = &planets[0]; i < NUMPLANETS; i++, l++)
338 {
339 if (PL_TYPE(*l) == PLSTAR)
340 {
341 dx = ABS(l->pl_x - me->p_x);
342 dy = ABS(l->pl_y - me->p_y);
343 if (dx * dx + dy * dy <
344 MIN_DIST_FROM_STAR * MIN_DIST_FROM_STAR)
345 break;
346 }
347 }
348 if (i == NUMPLANETS)
349 break;
350 }
351 /* legitimize p_x and p_y */
352 move_player(me->p_no, me->p_x, me->p_y, 0);
353 }
354 me->p_ntorp = 0; /* have not fired torps yete */
355 if (!((me->p_ship.s_nflags & SFNMASSPRODUCED) &&
356 (shipvals[shipPick].s_numports)))
357 me->p_cloakphase = 0; /* no cloaking phase--not cloaked */
358 me->p_nplasmatorp = 0; /* no plasma torps */
359 me->p_swar = 0; /* at war with nobody */
360 me->p_armies = 0; /* carrying no armies */
361 tmpPick = 0;
362
363 switch_special_weapon();
364
365 if (!keeppeace) /* if keep peace mode then */
366 auto_peace(); /* set do automatic peace */
367 me->p_hostile &= ~me->p_team; /* hostile to all but own team */
368 me->p_swar &= ~me->p_team;
369 #if 0
370 sprintf(buf, "%c%c", teamlet[me->p_team], shipnos[me->p_no]);
371 strncpy(me->p_mapchars, buf, 2);
372 #endif
373 if ((lastteam != tno) || (lastrank != mystats->st_rank))
374 {
375 if ((lastteam > 0) && (lastteam < NUMTEAM) && (lastteam != tno))
376 declare_war((1 << lastteam) | me->p_hostile); /* if changing then
377 * adjust war stat */
378 lastteam = tno; /* store team number in static */
379 lastrank = mystats->st_rank;/* store rank in static */
380 sprintf(addrbuf, " %s->ALL", twoletters(me));
381 if ((tno == 4) && (strcmp(me->p_monitor, "Nowhere") == 0))
382 {
383 time_t curtime; /* if a robot and independent */
384 struct tm *tmstruct; /* to hold time */
385 int queuesize; /* to hold queue size */
386 int hour; /* to hold hour */
387
388 time(&curtime); /* get the time */
389 tmstruct = localtime(&curtime); /* convert to local time */
390 if (!(hour = tmstruct->tm_hour % 12)) /* get the hour */
391 hour = 12;
392 sprintf(buf, "It's %d:%02d%s, time to die.", hour, tmstruct->tm_min,
393 tmstruct->tm_hour >= 12 ? "pm" : "am");
394 if ((queuesize = status->count - status->wait) > 0)
395 {
396 /* lint: queuesize set but not used in function enter */
397 sprintf(buf2, " Approximate queue size: %d.", status->answer);
398 strcat(buf, buf2); /* get queue size if queue */
399 }
400 pmessage2(buf, 0, MALL, addrbuf, me->p_no); /* display message */
401 }
402 else if (tno == 5)
403 { /* if a robot then */
404 if (players[disp].p_status != PFREE)
405 {
406 sprintf(buf2, "%s has been targeted for termination.",
407 twoletters(&players[disp]));
408 pmessage2(buf2, 0, MALL, addrbuf, me->p_no);
409 }
410 }
411 #ifdef LEAGUE_SUPPORT
412 if (!status2->league) /* no peanut messages in a league game */
413 #endif
414 peanut_gallery(); /* check for important people */
415
416 if (me->p_stats.st_royal == 0)
417 sprintf(buf, "%s %.16s is now %2.2s (%.16s@%.32s)",
418 ranks[me->p_stats.st_rank].name, me->p_name,
419 twoletters(me), me->p_login, me->p_full_hostname);
420 else
421 sprintf(buf, "%s %.16s is now %2.2s (%.16s@%.32s)",
422 royal[me->p_stats.st_royal].name, me->p_name,
423 twoletters(me), me->p_login, me->p_full_hostname);
424
425 pmessage2(buf, 0, MALL | MJOIN, addrbuf, me->p_no);
426
427 #if 1
428 advertise_tourney_queue();
429 #endif
430
431 }
432 delay = 0;
433 return startplanet;
434 }
435
436
437
438
439 /*--------------------------------AUTOPEACE------------------------------*/
440 /*
441 * This function set the player as hostile to all teams with at least one
442 * player on them if it is t-mode. Otherwise if it is not t-mode the player
443 * is set as hositle to everyone.
444 */
445
446 void
447 auto_peace()
448 {
449 int i, num[MAXTEAM + 1]; /* to hold team's player counts */
450 struct player *p; /* looping var */
451
452 num[0] = num[FED] = num[ROM] = num[KLI] = num[ORI] = 0; /* zero counts */
453 for (i = 0, p = players; i < MAXPLAYER; i++, p++) /* loop all players */
454 if (p->p_status != PFREE) /* ince the count of the team the */
455 num[p->p_team]++; /* player is on */
456 if (status->tourn) /* if t-mode then make player hostile */
457 me->p_hostile = /* make all teams with a player on */
458 ((FED * (num[FED] >= configvals->tournplayers)) |
459 (ROM * (num[ROM] >= configvals->tournplayers)) |
460 (KLI * (num[KLI] >= configvals->tournplayers)) |
461 (ORI * (num[ORI] >= configvals->tournplayers)));
462 else /* else if not t-mode then */
463 me->p_hostile = FED | ROM | KLI | ORI; /* hostile to everyone */
464 }
465
466
467
468
469 /*------------------------------PLACEINDEPENDENT---------------------------*/
470 /*
471 * This function places an independent player in the game so he is not near
472 * any other players.
473 */
474
475 static void
476 placeIndependent()
477 {
478 int i; /* ye olde looping var */
479 struct player *p; /* to point to players */
480 int good, failures; /* flag for success, count of tries */
481
482 failures = 0; /* have started loops yet */
483 while (failures < 10)
484 { /* only try 10 times */
485 me->p_x = GWIDTH / 2 + (lrand48() % INDEP) - INDEP / 2; /* middle 9th of */
486 me->p_y = GWIDTH / 2 + (lrand48() % INDEP) - INDEP / 2; /* galaxy */
487 good = 1;
488 for (i = 0, p = players; i < MAXPLAYER; i++, p++)
489 {
490 if ((p->p_status != PFREE) && (p != me))
491 {
492 if ((ABS(p->p_x - me->p_x) < 2 * TRACTDIST) &&
493 (ABS(p->p_y - me->p_y) < 2 * TRACTDIST))
494 {
495 failures++; /* found a player too close */
496 good = 0; /* position not good */
497 break; /* try another positon */
498 }
499 }
500 }
501 if (good) /* if good placement found then */
502 return; /* return */
503 }
504 fprintf(stderr, "Couldn't place the bot successfully.\n");
505 }
506
507
508
509
510 /*------------------------------------------------------------------------*/
511
512
513
514
515 /*----------END OF FILE--------*/