Mercurial > ~darius > hgwebdir.cgi > paradise_server
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--------*/ |