Mercurial > ~darius > hgwebdir.cgi > paradise_server
comparison src/interface.c @ 4:aa38447a4b21
First entry of Paradise Server 2.9 patch 10 Beta
author | darius |
---|---|
date | Sat, 06 Dec 1997 04:37:03 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:cafa94d86546 | 4:aa38447a4b21 |
---|---|
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 | |
22 #include <stdio.h> | |
23 #include <math.h> | |
24 #include <signal.h> | |
25 #include "defs.h" | |
26 #include "struct.h" | |
27 #include "data.h" | |
28 #include "shmem.h" | |
29 | |
30 void cloak_off(); | |
31 void cloak_on(); | |
32 int numShips(); | |
33 void sendwarn(); | |
34 extern int pmessage2(); | |
35 int allowed_ship(); | |
36 int numPlanets(); | |
37 void suspendPrep(); | |
38 void unsuspendPrep(); | |
39 | |
40 /*-----------------------------VISIBLE FUNCTIONS---------------------------*/ | |
41 | |
42 /*--------------------------------SETSPEED---------------------------------*/ | |
43 /* | |
44 * This function takes the desired speed from the client and translates it | |
45 * into impulse, afterburners, or warp. 99 = warp. 98 = afterburners. 97 = | |
46 * suspend warp prep, 96 = resume warp prep, 0-x = impulse. This function is | |
47 * used for both requests to set a ships speed from the client and from the | |
48 * server. The client requests are requests that are received directly from | |
49 * the client. A speed of 99 is treated as a request for warp speed. A | |
50 * request of 98 is a request for afterburners. | |
51 */ | |
52 | |
53 | |
54 | |
55 void | |
56 set_speed(speed, type) | |
57 int speed; /* the desired speed */ | |
58 int type; /* type of request. 0=server 1=client */ | |
59 { | |
60 if (me->p_flags & PFDOCK) | |
61 { /* if docked then */ | |
62 if (players[me->p_docked].p_speed > 4) | |
63 { /* you cannot get off >= 4 */ | |
64 warning("You are going too fast to disengage safely"); | |
65 return; | |
66 } | |
67 else | |
68 undock_player(me); | |
69 } | |
70 speed = (speed < 0) ? 0 : speed; /* no negative speeds */ | |
71 /* suspend warp [BDyess] */ | |
72 if (speed == 97 && configvals->warpprep_suspendable) | |
73 { /* suspend warp */ | |
74 suspendPrep(); | |
75 } | |
76 else if (speed == 96 && configvals->warpprep_suspendable) | |
77 { | |
78 /* unsuspend warp [BDyess] */ | |
79 unsuspendPrep(); | |
80 } | |
81 else if ((speed == 98) && (configvals->afterburners)) | |
82 { /* afterburners */ | |
83 /* turn off warp, warpprep, and warp suspended flags */ | |
84 me->p_flags &= ~(PFWARP | PFWARPPREP | PFWPSUSPENDED); | |
85 me->p_warptime = 0; | |
86 me->p_flags |= PFAFTER; /* turn on after burners */ | |
87 me->p_desspeed = me->p_ship.s_after.maxspeed; /* set speed of | |
88 * afterburn */ | |
89 /* | |
90 * go to warp if speed 99 is sent, OR if the speed sent is greater than | |
91 * max impulse and the VARIABLE_WARP sysdef is set, AND the ship can warp | |
92 * [BDyess] | |
93 */ | |
94 } | |
95 else if ((speed == 99 | |
96 || (configvals->variable_warp | |
97 && speed > me->p_ship.s_imp.maxspeed | |
98 && me->p_flags & (PFWARPPREP | PFWARP | PFWPSUSPENDED)) | |
99 ) | |
100 && (me->p_ship.s_nflags & SFNCANWARP)) | |
101 { | |
102 int maxspeed = me->p_ship.s_warp.maxspeed; | |
103 int preptime = myship->s_warpinittime; /* timer before warping */ | |
104 | |
105 if (configvals->warpzone) | |
106 { | |
107 if (me->p_zone < 0) | |
108 { | |
109 warning("The enemy is neutralizing our warp field, sir!"); | |
110 return; | |
111 } | |
112 else if (me->p_zone > 0) | |
113 { | |
114 maxspeed = maxspeed * 3 / 2; /* can go faster with boost [BDyess] */ | |
115 if (maxspeed > 99) | |
116 maxspeed = 99; | |
117 preptime /= 2; /* takes less time to build up when you have | |
118 * help */ | |
119 if (preptime == 0) | |
120 preptime = 1; | |
121 warning("warp boost!"); | |
122 } | |
123 } | |
124 | |
125 speed = (speed > maxspeed) | |
126 ? maxspeed | |
127 : speed; /* cap the request at max warp */ | |
128 | |
129 me->p_warpdesspeed = speed; /* remember how fast to warp for later | |
130 * [BDyess] */ | |
131 if (me->p_warptime > 0) | |
132 { | |
133 warning("Hold your horses, Speed Racer. These things take time."); | |
134 return; | |
135 } | |
136 if (me->p_flags & PFWARP) | |
137 { | |
138 me->p_desspeed = speed; | |
139 return; | |
140 } | |
141 if (me->p_damage > me->p_ship.s_maxdamage / 2) | |
142 { | |
143 warning("We are too damaged to risk warp speeds, Captain."); | |
144 return; | |
145 } | |
146 if (me->p_fuel < me->p_ship.s_warpinitcost) | |
147 { | |
148 warning("Not enough fuel for warp, Captain!"); | |
149 return; | |
150 } | |
151 me->p_desspeed = myship->s_warpprepspeed; /* slow ship down */ | |
152 me->p_flags |= PFWARPPREP; /* set warp prep flag [BDyess] */ | |
153 if (!configvals->cloakduringwarpprep) | |
154 cloak_off(); | |
155 | |
156 if (me->p_speed < me->p_desspeed) | |
157 me->p_speed = me->p_desspeed; | |
158 | |
159 /* turn off after burners and warpprep suspended flag [BDyess] */ | |
160 me->p_flags &= ~(PFAFTER | PFWPSUSPENDED); | |
161 me->p_warptime = preptime; /* timer before warping */ | |
162 me->p_fuel -= me->p_ship.s_warpinitcost; /* subtract off fuel */ | |
163 warning("Warp drive engaged!"); /* let him know its working */ | |
164 } | |
165 else if (type == 0) | |
166 { /* else if server request */ | |
167 me->p_desspeed = speed; /* grant speed request */ | |
168 } | |
169 else | |
170 { /* else client request for impulse */ | |
171 | |
172 if (!configvals->warpdecel) | |
173 me->p_flags &= ~(PFWARP | PFAFTER); | |
174 | |
175 me->p_warptime = 0; | |
176 me->p_flags &= ~(PFWARPPREP | PFWPSUSPENDED); /* turn off warpprep | |
177 * flag [BDyess] */ | |
178 speed = (speed > me->p_ship.s_imp.maxspeed) ? me->p_ship.s_imp.maxspeed : | |
179 speed; | |
180 me->p_desspeed = speed; /* set the speed */ | |
181 } | |
182 #if 0 | |
183 if (me->p_flags & PFORBIT) /* if we were orbiting */ | |
184 planets[me->p_planet].pl_torbit &= ~me->p_team; | |
185 #endif | |
186 me->p_flags &= ~(PFREPAIR | PFBOMB | PFORBIT | PFDOCK | PFBEAMUP | PFBEAMDOWN); | |
187 me->p_lastman = 0; | |
188 } | |
189 | |
190 | |
191 | |
192 | |
193 /*--------------------------------SET_COURSE-------------------------------*/ | |
194 /* | |
195 * Set the players course. This function takes a direction and sets the | |
196 * players direction to it. Certain flags are cleared. | |
197 */ | |
198 | |
199 void | |
200 set_course(dir) | |
201 unsigned char dir; | |
202 { | |
203 me->p_desdir = dir; /* set the desired direction */ | |
204 if (me->p_flags & PFDOCK) | |
205 { /* if player is docked then he cannot */ | |
206 if (players[me->p_docked].p_speed > 4) | |
207 { /* undock if dockee going fast */ | |
208 warning("It's unsafe to disengage from bases while moving more that warp 4."); | |
209 return; | |
210 } | |
211 else | |
212 undock_player(me); | |
213 | |
214 } | |
215 #if 0 | |
216 if (me->p_flags & PFORBIT) /* if in orbit then take */ | |
217 planets[me->p_planet].pl_torbit &= ~me->p_team; /* team out of orbit */ | |
218 #endif | |
219 me->p_flags &= ~(PFBOMB | PFORBIT | PFDOCK | PFBEAMUP | PFBEAMDOWN); | |
220 me->p_lastman = 0; /* not beamin all armies up */ | |
221 } | |
222 | |
223 | |
224 | |
225 | |
226 /*----------------------------------SHIELD_UP-----------------------------*/ | |
227 /* This function raises the players shields. */ | |
228 | |
229 void | |
230 shield_up() | |
231 { | |
232 me->p_flags |= PFSHIELD; /* some flags go up and some down */ | |
233 me->p_flags &= ~(PFBOMB | PFREPAIR | PFBEAMUP | PFBEAMDOWN); | |
234 me->p_lastman = 0; /* not beaming up all armies */ | |
235 } | |
236 | |
237 | |
238 | |
239 | |
240 /*---------------------------------SHIELD_DOWN----------------------------*/ | |
241 /* This function lowers the players shields. */ | |
242 | |
243 void | |
244 shield_down() | |
245 { | |
246 me->p_flags &= ~PFSHIELD; /* shield flag clear */ | |
247 } | |
248 | |
249 | |
250 | |
251 | |
252 /*--------------------------------SHIELD_TOGGLE---------------------------*/ | |
253 /* This function toggles the players shields on and off. */ | |
254 | |
255 void | |
256 shield_tog() | |
257 { | |
258 me->p_flags ^= PFSHIELD; /* toggle shield flag */ | |
259 me->p_flags &= ~(PFBOMB | PFREPAIR | PFBEAMUP | PFBEAMDOWN); | |
260 me->p_lastman = 0; | |
261 } | |
262 | |
263 | |
264 | |
265 | |
266 /*--------------------------------BOMB_PLANET------------------------------*/ | |
267 /* | |
268 * This function sets the bomb flag if certain conditions are met, such as | |
269 * you are bombing enemy planets. | |
270 */ | |
271 | |
272 void | |
273 bomb_planet() | |
274 { | |
275 static int bombsOutOfTmode = 0; /* confirm bomb out of t-mode */ | |
276 int owner; /* owner of planet */ | |
277 | |
278 owner = planets[me->p_planet].pl_owner; /* get planet's owner */ | |
279 if (!(me->p_flags & PFORBIT)) | |
280 { /* can't bomb anything in */ | |
281 warning("Must be orbiting to bomb"); /* open space, now can you? */ | |
282 return; | |
283 } | |
284 if (me->p_team == planets[me->p_planet].pl_owner) | |
285 { | |
286 warning("Can't bomb your own armies. Have you been reading Catch-22 again?"); /* can't bomb own armies */ | |
287 return; | |
288 } | |
289 if (!((me->p_swar | me->p_hostile) & owner) && (owner != 0)) | |
290 { | |
291 warning("Must declare war first (no Pearl Harbor syndrome allowed here)."); | |
292 return; /* can't bomb friendlies */ | |
293 } | |
294 if ((!status->tourn) && (bombsOutOfTmode == 0)) | |
295 { | |
296 warning("Bomb out of T-mode? Please verify your order to bomb."); | |
297 bombsOutOfTmode++; /* warning about bombing out of T */ | |
298 return; | |
299 } | |
300 if ((!status->tourn) && (bombsOutOfTmode == 1)) | |
301 { | |
302 warning("Hoser!"); /* if he really wants to bomb, then */ | |
303 bombsOutOfTmode++; /* let him bomb out of T. Hoser */ | |
304 } /* warning */ | |
305 if (!numShips(planets[me->p_planet].pl_owner) | |
306 && (planets[me->p_planet].pl_owner != NOBODY)) | |
307 { | |
308 warning("You can't break the peace treaty, Captain"); | |
309 return; | |
310 } | |
311 if (status->tourn) /* reset the bombs out of t-mode */ | |
312 bombsOutOfTmode = 0; /* variable */ | |
313 me->p_flags |= PFBOMB; /* set the bomb flag */ | |
314 #if 1 | |
315 planets[me->p_planet].pl_hostile |= me->p_team; | |
316 #else | |
317 planets[me->p_planet].pl_torbit |= (me->p_team) << 4; | |
318 #endif | |
319 me->p_flags &= ~(PFSHIELD | PFREPAIR | PFBEAMUP | PFBEAMDOWN); | |
320 } | |
321 | |
322 | |
323 | |
324 | |
325 /*---------------------------------BEAM_UP---------------------------------*/ | |
326 /* This function set the beam up flag if it is allowable to beam men up. */ | |
327 | |
328 void | |
329 beam_up() | |
330 { | |
331 if (!status2->starttourn && configvals->nopregamebeamup) | |
332 { | |
333 warning("You can't beam up armies before a game starts"); | |
334 return; | |
335 } | |
336 if (!(me->p_flags & (PFORBIT | PFDOCK))) | |
337 { | |
338 warning("Must be orbiting or docked to beam up."); | |
339 return; /* have to be orbiting or docked */ | |
340 } | |
341 if (me->p_flags & PFORBIT) | |
342 { /* if orbiting and not owner */ | |
343 if (me->p_team != planets[me->p_planet].pl_owner) | |
344 { | |
345 warning("Those aren't our men."); | |
346 return; | |
347 } | |
348 if (me->p_lastman == 0) /* if we have not signalled to pick */ | |
349 me->p_lastman = 1; /* up all armies */ | |
350 else if (planets[me->p_planet].pl_armies <= 4) | |
351 { /* else if less than 5 */ | |
352 if (numPlanets((int) me->p_team && configvals->beamlastarmies) == 1) | |
353 { | |
354 warning("You can't take those armies, they're on your only planet!"); | |
355 return; | |
356 } | |
357 me->p_lastman = 2; /* set status to beaming up all */ | |
358 } | |
359 } | |
360 else if (me->p_flags & PFDOCK) | |
361 { /* if docked must be to own team ship */ | |
362 if (me->p_team != players[me->p_docked].p_team) | |
363 { | |
364 warning("Comm Officer: Uhhh, they aren't our men!"); | |
365 return; | |
366 } | |
367 } | |
368 me->p_flags |= PFBEAMUP; /* set the beam up flag */ | |
369 me->p_flags &= ~(PFSHIELD | PFREPAIR | PFBOMB | PFBEAMDOWN); | |
370 } | |
371 | |
372 | |
373 | |
374 | |
375 /*--------------------------------BEAM_DOWN--------------------------------*/ | |
376 /* This function sets the beam up flag if certain conditions are met */ | |
377 | |
378 void | |
379 beam_down() | |
380 { | |
381 int i; /* looping var */ | |
382 struct planet *pl; /* to access planets */ | |
383 int total; /* for total number of planets */ | |
384 char buf[80]; | |
385 | |
386 if (!(me->p_flags & (PFORBIT | PFDOCK))) | |
387 { | |
388 warning("Must be orbiting or docked to beam down."); | |
389 return; /* have to be docked or orbiting */ | |
390 } | |
391 if ((!((me->p_swar | me->p_hostile) & planets[me->p_planet].pl_owner)) | |
392 && (me->p_team != planets[me->p_planet].pl_owner) | |
393 && (planets[me->p_planet].pl_owner != NOBODY)) | |
394 { | |
395 warning("You can't beam down, you have not declared war"); | |
396 return; /* no beaming down if not hostile */ | |
397 } | |
398 if (!numShips(planets[me->p_planet].pl_owner) | |
399 && (planets[me->p_planet].pl_owner != NOBODY)) | |
400 { | |
401 warning("You can't break the peace treaty, Captain"); | |
402 return; | |
403 } | |
404 if (me->p_flags & PFDOCK) | |
405 { | |
406 if (me->p_team != players[me->p_docked].p_team) | |
407 { | |
408 warning("Comm Officer: Starbase refuses permission to beam our troops over."); /* no beaming to foreign | |
409 * bases */ | |
410 return; | |
411 } | |
412 } | |
413 | |
414 else if (configvals->planetlimittype) | |
415 { /* new planet limit */ | |
416 total = numPlanets(me->p_team); | |
417 | |
418 if (total >= configvals->planetsinplay | |
419 && planets[me->p_planet].pl_owner == NOBODY | |
420 && planets[me->p_planet].pl_armies) | |
421 { | |
422 sprintf(buf, "You may only take enemy planets when your team has %d or more planets.", | |
423 configvals->planetsinplay); | |
424 warning(buf); | |
425 me->p_flags &= ~(PFBOMB); | |
426 return; | |
427 } | |
428 } | |
429 else | |
430 { | |
431 int ns[MAXTEAM]; | |
432 for (i = 0; i < NUMTEAM; i++) | |
433 ns[1 << i] = numShips(1 << i); | |
434 | |
435 total = 0; | |
436 for (i = 0, pl = &planets[i]; i < NUMPLANETS; i++, pl++) | |
437 { | |
438 if (pl->pl_owner && ns[pl->pl_owner] > configvals->tournplayers - 1) | |
439 total++; | |
440 } | |
441 if ((total >= configvals->planetsinplay) | |
442 && (!(me->p_flags & PFDOCK)) | |
443 && (planets[me->p_planet].pl_owner == NOBODY)) | |
444 { | |
445 sprintf(buf, "Sorry, there are already %d planets in play.", | |
446 configvals->planetsinplay); | |
447 warning(buf); | |
448 me->p_flags &= ~(PFBOMB); | |
449 return; | |
450 } | |
451 } | |
452 me->p_flags |= PFBEAMDOWN; /* set beam down flag */ | |
453 me->p_flags &= ~(PFSHIELD | PFREPAIR | PFBOMB | PFBEAMUP); | |
454 me->p_lastman = 0; | |
455 } | |
456 | |
457 | |
458 | |
459 | |
460 /*---------------------------------REPAIR---------------------------------*/ | |
461 /* | |
462 * This function sets the reapair flag and turns off other flags. You cannot | |
463 * repair while in warp. | |
464 */ | |
465 | |
466 void | |
467 repair() | |
468 { | |
469 #if !defined(AEDILE) || !defined(REPAIR_IN_WARP) | |
470 if (me->p_flags & PFWARP) | |
471 { /* no repairing in warp */ | |
472 warning("You cannot repair while in warp!"); | |
473 return; | |
474 } | |
475 #endif | |
476 me->p_desspeed = 0; /* speed goes to zero */ | |
477 me->p_warptime = 0; /* turn off warp prep */ | |
478 me->p_flags |= PFREPAIR; /* reair flag goes up */ | |
479 me->p_flags &= ~(PFSHIELD | PFBOMB | PFBEAMUP | PFBEAMDOWN | PFPLOCK | PFPLLOCK | PFWARP | PFAFTER | PFWARPPREP | PFWPSUSPENDED); | |
480 me->p_lastman = 0; /* not beaming all armies */ | |
481 } | |
482 | |
483 | |
484 | |
485 | |
486 /*--------------------------------REPAIR_OFF------------------------------*/ | |
487 /* This function takes the repair flag off. */ | |
488 | |
489 void | |
490 repair_off() | |
491 { | |
492 me->p_flags &= ~PFREPAIR; | |
493 } | |
494 | |
495 | |
496 | |
497 | |
498 /*---------------------------------REPEAT---------------------------------*/ | |
499 /* This function repeats the last message. */ | |
500 | |
501 void | |
502 repeat_message() | |
503 { | |
504 if (++lastm == MAXMESSAGE) /* go to next message */ | |
505 lastm = 0; /* account for rollover */ | |
506 } | |
507 | |
508 | |
509 | |
510 | |
511 /*---------------------------------CLOAK----------------------------------*/ | |
512 /* | |
513 * This function toggles the cloak flag. Tractors and pressor are turned | |
514 * off. | |
515 */ | |
516 | |
517 void | |
518 cloak() | |
519 { | |
520 if (me->p_flags & PFCLOAK) | |
521 cloak_off(); | |
522 else | |
523 cloak_on(); | |
524 } | |
525 | |
526 | |
527 | |
528 | |
529 /*---------------------------------CLOAK_ON-------------------------------*/ | |
530 /* This function turns cloak on. Tractors and pressors are turned off. */ | |
531 | |
532 void | |
533 cloak_on() | |
534 { | |
535 if (me->p_warptime && !configvals->cloakduringwarpprep) | |
536 { | |
537 warning("Can't cloak during warp preparation."); | |
538 return; | |
539 } | |
540 if (me->p_flags & PFWARP && !configvals->cloakwhilewarping) | |
541 { | |
542 warning("Can't cloak while warp engines are engaged."); | |
543 return; | |
544 } | |
545 me->p_flags |= PFCLOAK; | |
546 me->p_flags &= ~(PFTRACT | PFPRESS); | |
547 } | |
548 | |
549 | |
550 | |
551 | |
552 /*---------------------------------CLOAK_OFF------------------------------*/ | |
553 /* This function turns the cloak off. */ | |
554 | |
555 void | |
556 cloak_off() | |
557 { | |
558 me->p_flags &= ~PFCLOAK; | |
559 } | |
560 | |
561 | |
562 | |
563 | |
564 /*-------------------------------LOCK_PLANET-----------------------------*/ | |
565 /* This function locks the player onto a planet. */ | |
566 | |
567 void | |
568 lock_planet(planet) | |
569 int planet; /* planet locking onto */ | |
570 { | |
571 char buf[80]; /* to sprintf into */ | |
572 | |
573 if ((planet < 0) || (planet >= NUMPLANETS)) /* bad planet number? */ | |
574 return; | |
575 | |
576 if (me->p_status == POBSERVE) | |
577 { | |
578 if (planets[planet].pl_owner != me->p_team) | |
579 { | |
580 warning("Unable to observe enemy planets."); | |
581 me->p_flags &= ~(PFPLLOCK | PFPLOCK); | |
582 return; | |
583 } | |
584 else if (!(planets[planet].pl_owner & me->p_teamspy)) | |
585 { | |
586 warning("That team has barred you from observing."); | |
587 me->p_flags &= ~(PFPLLOCK | PFPLOCK); | |
588 return; | |
589 } | |
590 } | |
591 | |
592 me->p_flags |= PFPLLOCK; /* turn on the lock */ | |
593 #if 0 | |
594 if (me->p_flags & PFORBIT) /* if orbiting then leave torbit var */ | |
595 planets[me->p_planet].pl_torbit &= ~me->p_team; | |
596 #endif | |
597 me->p_flags &= ~(PFPLOCK | PFORBIT | PFBEAMUP | PFBEAMDOWN | PFBOMB); | |
598 me->p_lastman = 0; | |
599 me->p_planet = planet; /* set planet locked onto */ | |
600 sprintf(buf, "Locking onto %s", planets[planet].pl_name); | |
601 warning(buf); /* send message to player */ | |
602 } | |
603 | |
604 | |
605 | |
606 | |
607 /*-------------------------------LOCK_PLAYER-------------------------------*/ | |
608 /* This function locks the player onto another player. */ | |
609 | |
610 void | |
611 lock_player(player) | |
612 int player; /* player locking onto */ | |
613 { | |
614 char buf[80]; | |
615 | |
616 if ((player < 0) || (player >= MAXPLAYER)) /* bad planet num? */ | |
617 return; | |
618 if (players[player].p_status != PALIVE) /* player not alive? */ | |
619 return; | |
620 if (players[player].p_flags & PFCLOAK) /* player is cloaked */ | |
621 return; | |
622 | |
623 if (me->p_status == POBSERVE && players[player].p_team != me->p_team) | |
624 { | |
625 sprintf(buf, "Unable to observe enemy players."); | |
626 warning(buf); | |
627 me->p_flags &= ~(PFPLLOCK | PFPLOCK); | |
628 return; | |
629 } | |
630 | |
631 me->p_flags |= PFPLOCK; /* set player lock flag */ | |
632 #if 0 | |
633 if (me->p_flags & PFORBIT) /* if in orbit take team out */ | |
634 planets[me->p_planet].pl_torbit &= ~me->p_team; /* of torbit */ | |
635 #endif | |
636 me->p_flags &= ~(PFPLLOCK | PFORBIT | PFBEAMUP | PFBEAMDOWN | PFBOMB); | |
637 me->p_lastman = 0; /* turn off taking all armies */ | |
638 me->p_playerl = player; /* set player loked oto */ | |
639 /* player locking onto own base */ | |
640 if ((players[player].p_team == me->p_team) && | |
641 allows_docking(players[player].p_ship)) | |
642 sprintf(buf, "Locking onto %s (%s) (docking is %s)", | |
643 players[player].p_name, twoletters(&players[player]), | |
644 (players[player].p_flags & PFDOCKOK) ? "enabled" : "disabled"); | |
645 else /* message for locking onto player */ | |
646 sprintf(buf, "Locking onto %s (%s)", players[player].p_name, | |
647 twoletters(&players[player])); | |
648 warning(buf); | |
649 } | |
650 | |
651 | |
652 | |
653 | |
654 /*-------------------------------TRACTOR_PLAYER----------------------------*/ | |
655 /* | |
656 * This function does the tractoring for the player. There are a few times | |
657 * when the tractor cannot be used. | |
658 */ | |
659 | |
660 void | |
661 tractor_player(player) | |
662 int player; | |
663 { | |
664 struct player *victim; | |
665 | |
666 if (weaponsallowed[WP_TRACTOR] == 0) /* tractors allowed? */ | |
667 return; | |
668 if ((player < 0) || (player > MAXPLAYER)) | |
669 { /* out of bounds = cancel */ | |
670 me->p_flags &= ~(PFTRACT | PFPRESS); | |
671 return; | |
672 } | |
673 if (me->p_flags & PFCLOAK) /* no tractoring while */ | |
674 return; /* cloaked */ | |
675 if (player == me->p_no) /* can't tractor yourself */ | |
676 return; | |
677 victim = &players[player]; /* get player number */ | |
678 if (victim->p_flags & PFCLOAK) | |
679 return; | |
680 if (ihypot(me->p_x - victim->p_x, me->p_y - victim->p_y) < | |
681 (TRACTDIST) * me->p_ship.s_tractrng) | |
682 { | |
683 if (me->p_flags & PFDOCK && players[me->p_docked].p_speed > 4) | |
684 { | |
685 warning("It's unsafe to tractor while docked and base is moving more then warp 4."); | |
686 return; | |
687 } | |
688 #if 0 | |
689 undock_player(victim); /* harmless if not docked, handles js */ | |
690 undock_player(me); | |
691 | |
692 #if 0 | |
693 if (me->p_flags & PFORBIT) /* are we orbiting */ | |
694 planets[me->p_planet].pl_torbit &= ~me->p_team; | |
695 if (victim->p_flags & PFORBIT) /* is victim orbiting */ | |
696 planets[victim->p_planet].pl_torbit &= ~victim->p_team; | |
697 victim->p_flags &= ~(PFORBIT | PFDOCK); /* clear DOCK/ORBIT flags */ | |
698 #endif | |
699 me->p_flags &= ~(PFORBIT | PFDOCK); | |
700 #endif | |
701 me->p_tractor = player; /* set victim number */ | |
702 me->p_flags |= PFTRACT; /* set tractor flag */ | |
703 } | |
704 } | |
705 | |
706 | |
707 | |
708 | |
709 /*---------------------------------PRESSOR--------------------------------*/ | |
710 /* | |
711 * This function activates the tractors for the player. There are a number | |
712 * of conditions where tractors will not work. | |
713 */ | |
714 | |
715 void | |
716 pressor_player(player) | |
717 int player; /* the player to presoor */ | |
718 { | |
719 int target; | |
720 struct player *victim; | |
721 | |
722 if (weaponsallowed[WP_TRACTOR] == 0) | |
723 { /* tractors allowed? */ | |
724 warning("Pressor beams haven't been invented yet."); | |
725 return; | |
726 } | |
727 target = player; /* save target */ | |
728 if ((target < 0) || (target > MAXPLAYER)) | |
729 { /* out of bounds = cancel */ | |
730 me->p_flags &= ~(PFTRACT | PFPRESS); | |
731 return; | |
732 } | |
733 if (me->p_flags & PFPRESS) /* already pressoring? */ | |
734 return; | |
735 if (me->p_flags & PFCLOAK) | |
736 { /* cloaked? */ | |
737 warning("Weapons's Officer: Cannot pressor while cloaked, sir!"); | |
738 return; | |
739 } | |
740 victim = &players[target]; /* get victim's struct */ | |
741 if (victim->p_flags & PFCLOAK)/* victim cloaked */ | |
742 return; | |
743 if (ihypot(me->p_x - victim->p_x, me->p_y - victim->p_y) < | |
744 (TRACTDIST) * me->p_ship.s_tractrng) | |
745 { | |
746 if (me->p_flags & PFDOCK && players[me->p_docked].p_speed > 4) | |
747 { | |
748 warning("It's unsafe to pressor while docked and base is moving more then warp 4."); | |
749 return; | |
750 } | |
751 #if 0 | |
752 undock_player(victim); | |
753 undock_player(me); | |
754 | |
755 #if 0 | |
756 if (me->p_flags & PFORBIT) /* are we orbiting */ | |
757 planets[me->p_planet].pl_torbit &= ~me->p_team; | |
758 if (victim->p_flags & PFORBIT) /* is victim orbiting */ | |
759 planets[victim->p_planet].pl_torbit &= ~victim->p_team; | |
760 #endif | |
761 victim->p_flags &= ~(PFORBIT | PFDOCK); /* clear orbit and dock flags */ | |
762 me->p_flags &= ~(PFORBIT | PFDOCK); | |
763 #endif | |
764 me->p_tractor = target; /* set the target */ | |
765 me->p_flags |= (PFTRACT | PFPRESS); /* set the tract and press */ | |
766 } | |
767 /* flags */ | |
768 else | |
769 warning("Weapon's Officer: Vessel is out of range of our pressor beam."); | |
770 } | |
771 | |
772 | |
773 | |
774 | |
775 /*-------------------------------DECLARE_WAR-----------------------------*/ | |
776 /* This function changes the war mask of a player. */ | |
777 | |
778 void | |
779 declare_war(mask) | |
780 int mask; /* who are we declaring war against */ | |
781 { | |
782 int changes; /* to hold changes in war mask */ | |
783 int i; /* looping var */ | |
784 | |
785 mask &= ALLTEAM; /* mask off extraneous bits */ | |
786 mask &= ~me->p_team; /* mask out our team bit */ | |
787 mask |= me->p_swar; | |
788 changes = mask ^ me->p_hostile; /* determine changes */ | |
789 if (changes == 0) /* if no changes then we are done */ | |
790 return; | |
791 if (changes & FED) /* if Fed status changed then warn them */ | |
792 sendwarn("Federation", mask & FED, FED); | |
793 if (changes & ROM) /* if Rom status changed then warn them */ | |
794 sendwarn("Romulans", mask & ROM, ROM); | |
795 if (changes & KLI) /* if Kli status changed then warn them */ | |
796 sendwarn("Klingons", mask & KLI, KLI); | |
797 if (changes & ORI) /* if Orion status changed then warn them */ | |
798 sendwarn("Orions", mask & ORI, ORI); | |
799 if (me->p_flags & PFDOCK) | |
800 { /* if docked and now at war with */ | |
801 if (players[me->p_docked].p_team & mask) | |
802 { /* dockee then undock */ | |
803 undock_player(me); | |
804 } | |
805 } | |
806 else if (allows_docking(me->p_ship)) | |
807 { /* if ship is dockable then */ | |
808 if (me->p_docked > 0) | |
809 { /* go through ports and */ | |
810 for (i = 0; i < me->p_ship.s_numports; i++) | |
811 { /* kick off warring ships */ | |
812 if (me->p_port[i] >= 0 && | |
813 (mask & players[me->p_port[i]].p_team)) | |
814 { | |
815 base_undock(me, i); | |
816 } | |
817 } | |
818 } | |
819 } | |
820 if (mask & ~me->p_hostile) | |
821 { /* no sudden changing of */ | |
822 me->p_flags |= PFWAR; /* war status */ | |
823 delay = me->p_updates + 100; | |
824 warning("Pausing ten seconds to re-program battle computers."); | |
825 } | |
826 me->p_hostile = mask; /* new hostile mask */ | |
827 } | |
828 | |
829 | |
830 | |
831 | |
832 /*-----------------------------------SENDWARN------------------------------*/ | |
833 /* | |
834 * This function sends the warning message to the other players when a player | |
835 * switches his war status with that team. | |
836 */ | |
837 | |
838 void | |
839 sendwarn(string, atwar, team) | |
840 char *string; /* the name of the team changing status | |
841 * towards */ | |
842 int atwar; /* 1 if declarig war 0 if decalring peace */ | |
843 int team; /* name of team we are switching in regards | |
844 * to */ | |
845 { | |
846 char buf[BUFSIZ]; /* to hold sprintfed message */ | |
847 char addrbuf[10]; /* to hold ship number and team letter */ | |
848 | |
849 if (atwar) | |
850 { /* if decalring war */ | |
851 (void) sprintf(buf, "%s (%s) declaring war on the %s", | |
852 me->p_name, twoletters(me), string); | |
853 } | |
854 else | |
855 { /* else decalring peace */ | |
856 (void) sprintf(buf, "%s (%s) declaring peace with the %s", | |
857 me->p_name, twoletters(me), string); | |
858 } | |
859 (void) sprintf(addrbuf, " %s->%-3s", twoletters(me), teams[team].shortname); | |
860 pmessage2(buf, team, MTEAM, addrbuf, me->p_no); | |
861 } | |
862 | |
863 | |
864 /* switches the special weapon of the player */ | |
865 | |
866 void | |
867 switch_special_weapon() | |
868 { | |
869 int mask = 0; | |
870 int currflag; | |
871 int i, j; | |
872 | |
873 mask = me->p_ship.s_nflags & (SFNHASMISSILE | SFNPLASMAARMED); | |
874 | |
875 if (!mask) | |
876 { | |
877 warning("This ship is not armed with any special weapons"); | |
878 me->p_specweap = 0; | |
879 return; | |
880 } | |
881 for (i = 0; i < sizeof(int) * 8; i++) | |
882 { | |
883 currflag = 1 << i; | |
884 if (!mask & currflag) | |
885 continue; | |
886 if (me->p_specweap & currflag) | |
887 { | |
888 i++; | |
889 break; | |
890 } | |
891 } | |
892 | |
893 for (j = 0; j < sizeof(int) * 8; i++, j++) | |
894 { | |
895 if (i > sizeof(int) * 8) | |
896 i = 0; | |
897 currflag = 1 << i; | |
898 if (mask & currflag) | |
899 { | |
900 me->p_specweap = currflag; | |
901 break; | |
902 } | |
903 } | |
904 | |
905 if (me->p_specweap & SFNHASMISSILE) | |
906 { | |
907 if (me->p_ship.s_nflags & SFNHASFIGHTERS) | |
908 warning("Fighters ready"); | |
909 else | |
910 warning("Missiles armed"); | |
911 } | |
912 else if (me->p_specweap & SFNPLASMAARMED) | |
913 { | |
914 warning("Plasmas armed"); | |
915 } | |
916 } | |
917 | |
918 /*-------------------------------DO_REFIT---------------------------------*/ | |
919 /* | |
920 * This function will attempt to refit a player to another ship. There are | |
921 * all sorts of nasty reasons why it might fail. | |
922 */ | |
923 | |
924 void | |
925 do_refit(type) | |
926 int type; /* type of ship to refit to */ | |
927 { | |
928 int i; /* looping var */ | |
929 | |
930 if (type < 0 || type >= NUM_TYPES) /* ship type select out of range */ | |
931 return; | |
932 if (me->p_flags & PFORBIT) | |
933 { /* if orbiting must be a shipyard */ | |
934 if (!(planets[me->p_planet].pl_flags & PLSHIPYARD)) | |
935 { | |
936 warning("You can change ships at a planet with a shipyard on it."); | |
937 return; | |
938 } | |
939 #if 0 | |
940 if (planets[me->p_planet].pl_owner != me->p_team) | |
941 { | |
942 warning("You can only refit on planets that your team owns."); | |
943 return; | |
944 } | |
945 #endif | |
946 } | |
947 else if (me->p_flags & PFDOCK) | |
948 { /* if docked then */ | |
949 if (allows_docking(shipvals[type])) | |
950 { /* cannot refit to a starbase */ | |
951 warning("Can only refit to a base in a shipyard"); | |
952 return; | |
953 } | |
954 if (players[me->p_docked].p_team != me->p_team) | |
955 { | |
956 warning("You must dock with YOUR base to apply for command reassignment!"); /* no refitting on enemy | |
957 * SB's */ | |
958 return; | |
959 } | |
960 if (!(players[me->p_docked].p_ship.s_nflags & SFNCANREFIT)) | |
961 { | |
962 warning("This base can not provide you with a new ship."); | |
963 return; | |
964 } | |
965 } | |
966 else | |
967 { /* planet does not have shipyard */ | |
968 warning("Must orbit a shipyard or dock with your base to apply for command reassignment!"); | |
969 return; | |
970 } | |
971 if ((me->p_damage > ((float) me->p_ship.s_maxdamage) * .75) || | |
972 (me->p_shield < ((float) me->p_ship.s_maxshield) * .75) || | |
973 (me->p_fuel < ((float) me->p_ship.s_maxfuel) * .75)) | |
974 { | |
975 warning("Central Command refuses to accept a ship in this condition!"); | |
976 return; /* ship must be in good condition */ | |
977 } | |
978 if ((me->p_armies > 0)) | |
979 { /* no refitting with armies on board */ | |
980 warning("You must beam your armies down before moving to your new ship"); | |
981 return; | |
982 } | |
983 | |
984 { | |
985 int oldt, oldd, oldp, allowed; | |
986 oldt = me->p_ship.s_type; | |
987 oldd = me->p_ship.s_numdefn; | |
988 oldp = me->p_ship.s_numplan; | |
989 me->p_ship.s_type = -1; | |
990 me->p_ship.s_numdefn = 0; | |
991 me->p_ship.s_numplan = 0; | |
992 allowed = allowed_ship(me->p_team, me->p_stats.st_rank, | |
993 me->p_stats.st_royal, type); | |
994 me->p_ship.s_type = oldt; | |
995 me->p_ship.s_numdefn = oldd; | |
996 me->p_ship.s_numplan = oldp; | |
997 if (!allowed) | |
998 return; | |
999 } | |
1000 | |
1001 if (me->p_ship.s_type == STARBASE || | |
1002 me->p_ship.s_type == WARBASE || | |
1003 me->p_ship.s_type == CARRIER) | |
1004 me->p_kills = 0; /* reset kills to zero if coming */ | |
1005 /* from a base */ | |
1006 | |
1007 if (allows_docking(me->p_ship)) | |
1008 { /* if ship dockable then */ | |
1009 for (i = 0; i < me->p_ship.s_numports; i++) | |
1010 { /* dump all ship out of dock */ | |
1011 base_undock(me, i); | |
1012 } | |
1013 } | |
1014 get_ship_for_player(me, type);/* place ship in player strct */ | |
1015 | |
1016 switch_special_weapon(); | |
1017 | |
1018 if (me->p_flags & PFORBIT) | |
1019 { | |
1020 char buf[120]; | |
1021 me->p_lastrefit = me->p_planet; | |
1022 sprintf(buf, "%s is now your home port", planets[me->p_lastrefit].pl_name); | |
1023 warning(buf); | |
1024 } | |
1025 | |
1026 me->p_flags &= ~(PFREFIT); | |
1027 me->p_flags |= PFREFITTING; | |
1028 rdelay = me->p_updates + 50; | |
1029 warning("You are being transported to your new vessel .... "); | |
1030 } | |
1031 | |
1032 | |
1033 /* | |
1034 * Is a person with this rank on this team able to requisition a ship of this | |
1035 * type? | |
1036 */ | |
1037 int | |
1038 allowed_ship(team, rank, royal, type) | |
1039 int team; | |
1040 int rank; | |
1041 int royal; | |
1042 int type; | |
1043 { | |
1044 struct ship *tempship; | |
1045 int shipcount; | |
1046 int used_teamstr; /* people required to support flying bases */ | |
1047 int used_planstr; /* planets required to support flying bases */ | |
1048 int i, maxrank = 0; | |
1049 | |
1050 if (!shipsallowed[type]) | |
1051 { | |
1052 warning("That ship hasn't been designed yet."); | |
1053 return 0; | |
1054 } | |
1055 tempship = &shipvals[type]; | |
1056 | |
1057 #ifdef LEAGUE_SUPPORT | |
1058 if (status2->league == 1) | |
1059 return 1; | |
1060 | |
1061 if (!status2->league) | |
1062 { | |
1063 #endif | |
1064 if (configvals->baserankstyle) | |
1065 { | |
1066 for (i = 0; i < MAXPLAYER; i++) | |
1067 if ((players[i].p_status == PALIVE || | |
1068 players[i].p_status == POUTFIT) | |
1069 && players[i].p_team == team) | |
1070 maxrank = MAX(rank, players[i].p_stats.st_rank); | |
1071 } | |
1072 else | |
1073 maxrank = NUMRANKS; | |
1074 | |
1075 if ((rank < MIN(tempship->s_rank, maxrank) && !(royal > GODLIKE)) && | |
1076 !(shipvals[tmpPick].s_nflags & SFNMASSPRODUCED)) | |
1077 { | |
1078 char buf[100]; | |
1079 sprintf(buf, "Sorry %s, a rank of %s is required to command that ship.", | |
1080 ranks[rank].name, ranks[tempship->s_rank].name); | |
1081 warning(buf); | |
1082 return 0; | |
1083 } | |
1084 #ifdef LEAGUE_SUPPORT | |
1085 } | |
1086 #endif | |
1087 used_teamstr = used_planstr = 0; | |
1088 shipcount = 0; /* How many ships of that type */ | |
1089 /* are on our team already? */ | |
1090 for (i = 0; i < MAXPLAYER; i++) | |
1091 { | |
1092 if (players[i].p_status == PALIVE && players[i].p_team == team) | |
1093 { | |
1094 if (players[i].p_ship.s_type == type) | |
1095 shipcount++; | |
1096 used_teamstr += players[i].p_ship.s_numdefn; | |
1097 used_planstr += players[i].p_ship.s_numplan; | |
1098 } | |
1099 } | |
1100 /* | |
1101 * if you are in a base, and near the limits, you will sometimes have to | |
1102 * switch into a normal ship before changing into another base | |
1103 */ | |
1104 | |
1105 if ((shipcount >= tempship->s_maxnum) && !(shipvals[tmpPick].s_nflags & SFNMASSPRODUCED)) | |
1106 { | |
1107 char buf[100]; | |
1108 sprintf(buf, "We already have %d %ss.", shipcount, tempship->s_name); | |
1109 warning(buf); | |
1110 return 0; | |
1111 } | |
1112 if ((teams[team].s_turns[type] > | |
1113 (tempship->s_maxnum - shipcount - 1) * tempship->s_timer) && | |
1114 !(shipvals[tmpPick].s_nflags & SFNMASSPRODUCED)) | |
1115 { | |
1116 char buf[100]; | |
1117 int turnsleft = teams[team].s_turns[type] - | |
1118 (tempship->s_maxnum - shipcount - 1) * tempship->s_timer; | |
1119 if (teams[team].s_turns[type] > 1) | |
1120 { | |
1121 sprintf(buf, "We are still building that ship (%d minutes until finished.)", turnsleft); | |
1122 warning(buf); | |
1123 } | |
1124 else | |
1125 warning("We are still building that ship (1 minute until finished.)"); | |
1126 return 0; | |
1127 } | |
1128 if ((tempship->s_numdefn && | |
1129 numShips(team) < tempship->s_numdefn + used_teamstr) && | |
1130 !(shipvals[tmpPick].s_nflags & SFNMASSPRODUCED)) | |
1131 { | |
1132 char buf[100]; | |
1133 sprintf(buf, "Your team is not strong enough to defend a %s (%d+%d players needed).", | |
1134 tempship->s_name, tempship->s_numdefn, used_teamstr); | |
1135 warning(buf); | |
1136 return 0; | |
1137 } | |
1138 if ((tempship->s_numplan && | |
1139 numPlanets(team) < tempship->s_numplan + used_planstr) && | |
1140 !(shipvals[tmpPick].s_nflags & SFNMASSPRODUCED)) | |
1141 { | |
1142 char buf[100]; | |
1143 sprintf(buf, "Your team's struggling economy cannot support a %s (%d+%d planets needed).", tempship->s_name, tempship->s_numplan, used_planstr); | |
1144 warning(buf); | |
1145 return 0; /* have enough planets? */ | |
1146 } | |
1147 return 1; | |
1148 } | |
1149 | |
1150 | |
1151 /*----------------------------------NUMSHIPS------------------------------*/ | |
1152 /* This function counts the number of players on a team. */ | |
1153 | |
1154 int | |
1155 numShips(owner) | |
1156 int owner; /* the team to count for */ | |
1157 { | |
1158 int i; /* looping var */ | |
1159 int num; /* to hold player count */ | |
1160 struct player *p; /* to point to players */ | |
1161 | |
1162 num = 0; /* zero the count */ | |
1163 for (i = 0, p = players; i < MAXPLAYER; i++, p++) | |
1164 { /* go throgh players */ | |
1165 if (p->p_status != PFREE && p->p_team == owner) /* if alive then */ | |
1166 num++; /* inc player count */ | |
1167 } | |
1168 return (num); /* return number of ships */ | |
1169 } | |
1170 | |
1171 | |
1172 | |
1173 | |
1174 /*------------------------------NUMPLANETS--------------------------------*/ | |
1175 /* This function counts the number of planets a team has. */ | |
1176 | |
1177 int | |
1178 numPlanets(owner) | |
1179 int owner; /* the team to check for */ | |
1180 { | |
1181 int i; /* looping var */ | |
1182 int num; /* to hold count */ | |
1183 struct planet *p; /* to point to a planet */ | |
1184 | |
1185 num = 0; /* no planets found yet */ | |
1186 for (i = 0, p = planets; i < MAXPLANETS; i++, p++) | |
1187 { | |
1188 if (p->pl_owner == owner) /* if planet owned by team then inc */ | |
1189 num++; | |
1190 } | |
1191 return (num); /* return number of planets */ | |
1192 } | |
1193 | |
1194 /*-------------------------------------------------------------------------*/ | |
1195 | |
1196 /* | |
1197 * Suspends warp prep [BDyess] | |
1198 */ | |
1199 void | |
1200 suspendPrep() | |
1201 { | |
1202 /* check to see if the server allows warp prep to be suspended [BDyess] */ | |
1203 if (!configvals->warpprep_suspendable) | |
1204 return; | |
1205 if (me->p_flags & PFWARPPREP) | |
1206 { | |
1207 me->p_flags |= PFWPSUSPENDED; /* turn on suspended flag */ | |
1208 warning("Warp prep suspended."); | |
1209 } | |
1210 else | |
1211 { | |
1212 warning("Not in warp prep!"); | |
1213 } | |
1214 } | |
1215 | |
1216 /* | |
1217 * Unsuspends warp prep [BDyess] | |
1218 */ | |
1219 void | |
1220 unsuspendPrep() | |
1221 { | |
1222 /* check to see if the server allows warp prep to be suspended [BDyess] */ | |
1223 if (!configvals->warpprep_suspendable) | |
1224 return; | |
1225 if (me->p_flags & PFWARPPREP) | |
1226 { | |
1227 me->p_flags &= ~PFWPSUSPENDED; /* turn off suspended flag */ | |
1228 warning("Warp prep continued."); | |
1229 } | |
1230 else | |
1231 { | |
1232 warning("Not in warp prep!"); | |
1233 } | |
1234 } | |
1235 | |
1236 /*-------END OF LINE----*/ |