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----*/