1 /*
2 * XPilot NG, a multiplayer space war game.
3 *
4 * Copyright (C) 1991-2001 by
5 *
6 * Bj�rn Stabell <bjoern@xpilot.org>
7 * Ken Ronny Schouten <ken@xpilot.org>
8 * Bert Gijsbers <bert@xpilot.org>
9 * Dick Balaska <dick@xpilot.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26 #ifndef PLAYER_H
27 #define PLAYER_H
28
29 #ifndef OBJECT_H
30 /* need OBJECT_BASE */
31 #include "object.h"
32 #endif
33 #ifndef CONNECTION_H
34 /* need connection_t */
35 #include "connection.h"
36 #endif
37 #ifndef SERVERCONST_H
38 /* need MAX_TANKS */
39 #include "serverconst.h"
40 #endif
41 #ifndef KEYS_H
42 /* need NUM_KEYS */
43 #include "keys.h"
44 #endif
45 #ifndef BIT_H
46 /* need BITV_DECL */
47 #include "bit.h"
48 #endif
49 #ifndef DRAW_H
50 /* need shipshape_t */
51 #include "shipshape.h"
52 #endif
53 #ifndef ITEM_H
54 /* need NUM_ITEMS */
55 #include "item.h"
56 #endif
57 #ifndef CLICK_H
58 /* need CLICK */
59 #include "click.h"
60 #endif
61 #ifndef OPTION_H
62 /* need options */
63 #include "option.h"
64 #endif
65
66 extern bool updateScores;
67
68 /*
69 * These values are set in the player->pl_type field.
70 */
71 #define PL_TYPE_HUMAN 0
72 #define PL_TYPE_ROBOT 1
73 #define PL_TYPE_TANK 2
74
75 /*
76 * These values are set in the player->pl_state field.
77 */
78 #define PL_STATE_UNDEFINED 0
79 #define PL_STATE_WAITING 1
80 #define PL_STATE_APPEARING 2
81 #define PL_STATE_ALIVE 3
82 #define PL_STATE_KILLED 4
83 #define PL_STATE_DEAD 5
84 #define PL_STATE_PAUSED 6
85
86 /*
87 * Different types of attributes a player can have.
88 * These are the bits of the player->have and player->used fields.
89 */
90 #define HAS_EMERGENCY_THRUST (1U<<30)
91 #define HAS_AUTOPILOT (1U<<29)
92 #define HAS_TRACTOR_BEAM (1U<<28)
93 #define HAS_LASER (1U<<27)
94 #define HAS_CLOAKING_DEVICE (1U<<26)
95 #define HAS_SHIELD (1U<<25)
96 #define HAS_REFUEL (1U<<24)
97 #define HAS_REPAIR (1U<<23)
98 #define HAS_COMPASS (1U<<22)
99 #define HAS_AFTERBURNER (1U<<21)
100 #define HAS_CONNECTOR (1U<<20)
101 #define HAS_EMERGENCY_SHIELD (1U<<19)
102 #define HAS_DEFLECTOR (1U<<18)
103 #define HAS_PHASING_DEVICE (1U<<17)
104 #define HAS_MIRROR (1U<<16)
105 #define HAS_ARMOR (1U<<15)
106 #define HAS_SHOT (1U<<4)
107 #define HAS_BALL (1U<<3)
108
109 #define USES_EMERGENCY_THRUST HAS_EMERGENCY_THRUST
110 #define USES_AUTOPILOT HAS_AUTOPILOT
111 #define USES_TRACTOR_BEAM HAS_TRACTOR_BEAM
112 #define USES_LASER HAS_LASER
113 #define USES_CLOAKING_DEVICE HAS_CLOAKING_DEVICE
114 #define USES_SHIELD HAS_SHIELD
115 #define USES_REFUEL HAS_REFUEL
116 #define USES_REPAIR HAS_REPAIR
117 #define USES_COMPASS HAS_COMPASS
118 #define USES_AFTERBURNER HAS_AFTERBURNER
119 #define USES_CONNECTOR HAS_CONNECTOR
120 #define USES_EMERGENCY_SHIELD HAS_EMERGENCY_SHIELD
121 #define USES_DEFLECTOR HAS_DEFLECTOR
122 #define USES_PHASING_DEVICE HAS_PHASING_DEVICE
123 #define USES_MIRROR HAS_MIRROR
124 #define USES_ARMOR HAS_ARMOR
125 #define USES_SHOT HAS_SHOT
126 #define USES_BALL HAS_BALL
127
128 /*
129 * Possible player status bits.
130 * The bits that the client needs must fit into a byte,
131 * so the first 8 bitvalues are reserved for that purpose,
132 * those are defined in common/rules.h.
133 */
134 #define HOVERPAUSE (1U<<9) /* Hovering pause */
135 #define REPROGRAM (1U<<10) /* Player reprogramming */
136 #define FINISH (1U<<11) /* Finished a lap this frame */
137 #define RACE_OVER (1U<<12) /* After finished and score */
138
139 #define LOCK_NONE 0x00 /* No lock */
140 #define LOCK_PLAYER 0x01 /* Locked on player */
141 #define LOCK_VISIBLE 0x02 /* Lock information was on HUD */
142 /* computed just before frame shown */
143 /* and client input checked */
144 #define LOCKBANK_MAX 4 /* Maximum number of locks in bank */
145
146 /*
147 * Fuel structure, used by player
148 */
149 typedef struct {
150 double sum; /* Sum of fuel in all tanks */
151 double max; /* How much fuel can you take? */
152 int current; /* Number of currently used tank */
153 int num_tanks; /* Number of tanks */
154 double tank[1 + MAX_TANKS]; /* main fixed tank + extra tanks. */
155 } pl_fuel_t;
156
157 typedef struct visibility {
158 bool canSee;
159 long lastChange;
160 } visibility_t;
161
162 /*
163 * Shove-information.
164 *
165 * This is for keeping a record of the last N times the player was shoved,
166 * for assigning wall-smash-blame, where N=MAX_RECORDED_SHOVES.
167 */
168 #define MAX_RECORDED_SHOVES 4
169
170 typedef struct {
171 int pusher_id;
172 int time;
173 } shove_t;
174
175 struct robot_data;
176 struct ranknode;
177
178 /* IMPORTANT
179 *
180 * This is the player structure, the first part MUST be similar to object_t,
181 * this makes it possible to use the same basic operations on both of them
182 * (mainly used in update.c).
183 */
184 typedef struct player {
185
186 OBJECT_BASE
187
188 /* up to here the player type should be the same as an object. */
189
190 int pl_type; /* extended type info (tank, robot) */
191 char pl_type_mychar; /* Special char for player type */
192 uint8_t pl_old_status; /* OLD_PLAYING etc. */
193
194 uint16_t pl_status; /* HOVERPAUSE etc. */
195 uint16_t pl_state; /* one of PL_STATE_* */
196 int pl_life; /* Lives left (if lives limited) */
197 int pl_deaths_since_join; /* Deaths since last joining server */
198
199 uint16_t pl_prev_team; /* Team before pause */
200
201 double turnspeed; /* How fast player acc-turns */
202 double velocity; /* Absolute speed */
203
204 int kills; /* Number of kills this round */
205 int deaths; /* Number of deaths this round */
206
207 long used; /* Items you use */
208 long have; /* Items you have */
209
210 double shield_time; /* Shields if no options.playerShielding */
211 pl_fuel_t fuel; /* ship tanks and the stored fuel */
212 double emptymass; /* Mass of empty ship */
213 double float_dir; /* Direction, in float var */
214 double wanted_float_dir; /*TURNQUEUE*//* Direction, in float var */
215 double float_dir_cos; /* Cosine of float_dir */
216 double float_dir_sin; /* Sine of float_dir */
217 double turnresistance; /* How much is lost in % */
218 double turnvel; /* Current velocity of turn (right) */
219 double oldturnvel; /* Last velocity of turn (right) */
220 double turnacc; /* Current acceleration of turn */
221 double score; /* Current score of player */
222 bool update_score; /* score table info needs to be sent */
223 shipshape_t *ship; /* wire model of ship shape */
224 double power; /* Force of thrust */
225 double power_s; /* Saved power fiks */
226 double turnspeed_s; /* Saved turnspeed */
227 double turnresistance_s; /* Saved (see above) */
228 double sensor_range; /* Range of sensors (radar) */
229 int shots; /* Number of active shots by player */
230 int missile_rack; /* Next missile rack to be active */
231
232 int num_pulses; /* Number of laser pulses "flying". */
233
234 double emergency_thrust_left; /* how much emergency thrust left */
235 double emergency_shield_left; /* how much emergency shield left */
236 double phasing_left; /* how much time left */
237
238 double pause_count; /* ticks until unpause possible */
239 double recovery_count; /* ticks to recovery */
240 double self_destruct_count; /* if > 0, ticks before boom */
241
242 int item[NUM_ITEMS]; /* for each item type how many */
243 int initial_item[NUM_ITEMS];/* items player had initially */
244 int lose_item; /* which item to drop */
245 int lose_item_state; /* lose item key state, 2=up,1=down */
246
247 double auto_power_s; /* autopilot saves of current */
248 /* power, turnspeed and */
249 double auto_turnspeed_s; /* turnresistance settings. Restored */
250 double auto_turnresistance_s; /* when autopilot turned off */
251 modifiers_t modbank[NUM_MODBANKS]; /* useful modifier settings */
252 double shot_time; /* Time of last shot fired by player */
253 double laser_time; /* Time of last laser pulse fired by player */
254 bool did_shoot; /* Pressed fire during this frame */
255 bool tractor_is_pressor; /* on if tractor is pressor */
256 int repair_target; /* Repairing this target */
257 int fs; /* Connected to fuel station fs */
258 int check; /* Next check point to pass */
259 int prev_check; /* Previous check point for score */
260 int time; /* The time a player has used */
261 int round; /* Number of rounds player have done */
262 int prev_round; /* Previous rounds value for score */
263 int best_lap; /* Players best lap time */
264 int last_lap; /* Time on last pass */
265 int last_lap_time; /* What was your last pass? */
266 int last_check_dir; /* player dir at last checkpoint */
267 long last_wall_touch; /* last time player touched a wall */
268 double survival_time; /* time player has survived unshielded*/
269
270 base_t *home_base;
271 struct {
272 int tagged; /* Flag, what is tagged? */
273 int pl_id; /* Tagging player id */
274 double distance; /* Distance to object */
275 } lock;
276 int lockbank[LOCKBANK_MAX]; /* Saved player locks */
277
278 short dir; /* Direction of acceleration */
279 char mychar; /* Special char for player */
280 char name[MAX_CHARS]; /* Nick-name of player */
281 char username[MAX_CHARS]; /* Real name of player */
282 char hostname[MAX_CHARS]; /* Hostname of client player uses */
283 uint16_t pseudo_team; /* Which team for detaching tanks */
284 int alliance; /* Member of which alliance? */
285 int invite; /* Invitation for alliance */
286 ballobject_t *ball;
287
288 /*
289 * Pointer to robot private data (dynamically allocated).
290 * Only used in robot code.
291 */
292 struct robot_data *robot_data_ptr;
293
294 /*
295 * A record of who's been pushing me (a circular buffer).
296 */
297 shove_t shove_record[MAX_RECORDED_SHOVES];
298 int shove_next;
299
300 visibility_t *visibility;
301
302 double forceVisible;
303 double damaged;
304 double stunned;
305 bool updateVisibility;
306
307 int last_target_update; /* index of last updated target */
308 int last_cannon_update; /* index of last updated cannon */
309 int last_fuel_update; /* index of last updated fuel */
310 int last_polystyle_update; /* index of last updated polygon */
311
312 int ecmcount; /* number of active ecms */
313
314 connection_t *conn; /* connection index, NULL if robot */
315 unsigned version; /* XPilot version number of client */
316
317 BITV_DECL(last_keyv, NUM_KEYS); /* Keyboard state */
318 BITV_DECL(prev_keyv, NUM_KEYS); /* Keyboard state */
319
320 long frame_last_busy; /* When player touched keyboard. */
321
322 void *audio; /* audio private data */
323
324 int player_fps; /* FPS that this player can do */
325 int maxturnsps; /* turns per second limit */
326
327 int rectype; /* normal, saved or spectator */
328 struct ranknode *rank;
329
330 double pauseTime; /* seconds player has paused */
331 double idleTime; /* seconds player has idled */
332
333 int flooding;
334
335 bool muted; /* player started is muted? */
336 bool isoperator; /* player has operator privileges? */
337 bool want_audio; /* player wants audio from server */
338
339 int privs; /* Player privileges */
340
341 #define PRIV_NOAUTOKICK 1
342 #define PRIV_AUTOKICKLAST 2
343
344 double snafu_count; /* Misc. snafus */
345
346 } player_t;
347
348 extern int playerArrayNumber;
349 extern player_t **PlayersArray;
350
351 int GetInd(int id);
352
353 /*
354 * Get player with index 'ind' from Players array.
355 */
Player_by_index(int ind)356 static inline player_t *Player_by_index(int ind)
357 {
358 if (ind < 0 || ind >= playerArrayNumber)
359 return NULL;
360 return PlayersArray[ind];
361 }
362
Player_by_id(int id)363 static inline player_t *Player_by_id(int id)
364 {
365 return Player_by_index(GetInd(id));
366 }
367
Player_is_waiting(player_t * pl)368 static inline bool Player_is_waiting(player_t *pl)
369 {
370 return pl->pl_state == PL_STATE_WAITING ? true : false;
371 }
372
Player_is_appearing(player_t * pl)373 static inline bool Player_is_appearing(player_t *pl)
374 {
375 return pl->pl_state == PL_STATE_APPEARING ? true : false;
376 }
377
Player_is_alive(player_t * pl)378 static inline bool Player_is_alive(player_t *pl)
379 {
380 return pl->pl_state == PL_STATE_ALIVE ? true : false;
381 }
382
383 /* player was killed this frame ? */
Player_is_killed(player_t * pl)384 static inline bool Player_is_killed(player_t *pl)
385 {
386 return pl->pl_state == PL_STATE_KILLED ? true : false;
387 }
388
Player_is_dead(player_t * pl)389 static inline bool Player_is_dead(player_t *pl)
390 {
391 return pl->pl_state == PL_STATE_DEAD ? true : false;
392 }
393
Player_is_paused(player_t * pl)394 static inline bool Player_is_paused(player_t *pl)
395 {
396 return pl->pl_state == PL_STATE_PAUSED ? true : false;
397 }
398
Player_is_hoverpaused(player_t * pl)399 static inline bool Player_is_hoverpaused(player_t *pl)
400 {
401 if (BIT(pl->pl_status, HOVERPAUSE))
402 return true;
403 return false;
404 }
405
406 extern void Set_Score(player_t *pl, double score);
407 extern void Add_Score(player_t *pl, double score);
408
Player_add_score(player_t * pl,double points)409 static inline void Player_add_score(player_t *pl, double points)
410 {
411 Add_Score(pl,points);
412 pl->update_score = true;
413 updateScores = true;
414 }
415
Player_set_score(player_t * pl,double points)416 static inline void Player_set_score(player_t *pl, double points)
417 {
418 Set_Score(pl,points);
419 pl->update_score = true;
420 updateScores = true;
421 }
422
Player_set_mychar(player_t * pl,char mychar)423 static inline void Player_set_mychar(player_t *pl, char mychar)
424 {
425 pl->mychar = mychar;
426 pl->update_score = true;
427 updateScores = true;
428 }
429
Player_set_life(player_t * pl,int life)430 static inline void Player_set_life(player_t *pl, int life)
431 {
432 pl->pl_life = life;
433 pl->update_score = true;
434 updateScores = true;
435 }
436
Player_set_alliance(player_t * pl,int alliance)437 static inline void Player_set_alliance(player_t *pl, int alliance)
438 {
439 pl->alliance = alliance;
440 pl->update_score = true;
441 updateScores = true;
442 }
443
444 /*
445 * Should be:
446 * if (pl->item[ITEM_AFTERBURNER] > 0) return true; else return false;
447 */
Player_has_afterburner(player_t * pl)448 static inline bool Player_has_afterburner(player_t *pl)
449 {
450 if (BIT(pl->have, HAS_AFTERBURNER))
451 return true;
452 return false;
453 }
454
455 /*
456 * Should be:
457 * if (pl->item[ITEM_ARMOR] > 0) return true; else return false;
458 */
Player_has_armor(player_t * pl)459 static inline bool Player_has_armor(player_t *pl)
460 {
461 if (BIT(pl->have, HAS_ARMOR))
462 return true;
463 return false;
464 }
465
466 /*
467 * Should be:
468 * if (pl->item[ITEM_AUTOPILOT] > 0) return true; else return false;
469 */
Player_has_autopilot(player_t * pl)470 static inline bool Player_has_autopilot(player_t *pl)
471 {
472 if (BIT(pl->have, HAS_AUTOPILOT))
473 return true;
474 return false;
475 }
476
477 /*
478 * Should be:
479 * if (pl->item[ITEM_CLOAK] > 0) return true; else return false;
480 */
Player_has_cloaking_device(player_t * pl)481 static inline bool Player_has_cloaking_device(player_t *pl)
482 {
483 if (BIT(pl->have, HAS_CLOAKING_DEVICE))
484 return true;
485 return false;
486 }
487
488 /*
489 * Should be:
490 * if (pl->item[ITEM_DEFLECTOR] > 0) return true; else return false;
491 */
Player_has_deflector(player_t * pl)492 static inline bool Player_has_deflector(player_t *pl)
493 {
494 if (BIT(pl->have, HAS_DEFLECTOR))
495 return true;
496 return false;
497 }
498
499 /*
500 * Should be:
501 * if (pl->item[ITEM_MIRROR] > 0) return true; else return false;
502 */
Player_has_mirror(player_t * pl)503 static inline bool Player_has_mirror(player_t *pl)
504 {
505 if (BIT(pl->have, HAS_MIRROR))
506 return true;
507 return false;
508 }
509
510
511 /*
512 * Should be:
513 * if (pl->item[ITEM_TRACTOR_BEAM] > 0) return true; else return false;
514 */
Player_has_tractor_beam(player_t * pl)515 static inline bool Player_has_tractor_beam(player_t *pl)
516 {
517 if (BIT(pl->have, HAS_TRACTOR_BEAM))
518 return true;
519 return false;
520 }
521
Player_is_thrusting(player_t * pl)522 static inline bool Player_is_thrusting(player_t *pl)
523 {
524 if (BIT(pl->obj_status, THRUSTING))
525 return true;
526 return false;
527 }
528
Player_is_refueling(player_t * pl)529 static inline bool Player_is_refueling(player_t *pl)
530 {
531 if (BIT(pl->used, USES_REFUEL))
532 return true;
533 return false;
534 }
535
Player_is_repairing(player_t * pl)536 static inline bool Player_is_repairing(player_t *pl)
537 {
538 if (BIT(pl->used, USES_REPAIR))
539 return true;
540 return false;
541 }
542
Player_is_self_destructing(player_t * pl)543 static inline bool Player_is_self_destructing(player_t *pl)
544 {
545 return (pl->self_destruct_count > 0.0) ? true : false;
546 }
547
Player_self_destruct(player_t * pl,bool on)548 static inline void Player_self_destruct(player_t *pl, bool on)
549 {
550 if (on) {
551 if (Player_is_self_destructing(pl))
552 return;
553 pl->self_destruct_count = SELF_DESTRUCT_DELAY;
554 }
555 else
556 pl->self_destruct_count = 0.0;
557 }
558
Player_is_human(player_t * pl)559 static inline bool Player_is_human(player_t *pl)
560 {
561 return pl->pl_type == PL_TYPE_HUMAN ? true : false;
562 }
563
Player_is_robot(player_t * pl)564 static inline bool Player_is_robot(player_t *pl)
565 {
566 return pl->pl_type == PL_TYPE_ROBOT ? true : false;
567 }
568
Player_is_tank(player_t * pl)569 static inline bool Player_is_tank(player_t *pl)
570 {
571 return pl->pl_type == PL_TYPE_TANK ? true : false;
572 }
573
Player_owns_tank(player_t * pl,player_t * tank)574 static inline bool Player_owns_tank(player_t *pl, player_t *tank)
575 {
576 if (Player_is_tank(tank)
577 && tank->lock.pl_id != NO_ID /* kps - probably redundant */
578 && tank->lock.pl_id == pl->id)
579 return true;
580 return false;
581 }
582
583 /*
584 * Used where we wish to know if a player is simply on the same team.
585 */
Players_are_teammates(player_t * pl1,player_t * pl2)586 static inline bool Players_are_teammates(player_t *pl1, player_t *pl2)
587 {
588 if (BIT(world->rules->mode, TEAM_PLAY)
589 && pl1->team != TEAM_NOT_SET
590 && pl1->team == pl2->team)
591 return true;
592 return false;
593 }
594
595 /*
596 * Used where we wish to know if two players are members of the same alliance.
597 */
Players_are_allies(player_t * pl1,player_t * pl2)598 static inline bool Players_are_allies(player_t *pl1, player_t *pl2)
599 {
600 if (pl1->alliance != ALLIANCE_NOT_SET
601 && pl1->alliance == pl2->alliance)
602 return true;
603 return false;
604 }
605
Player_uses_autopilot(player_t * pl)606 static inline bool Player_uses_autopilot(player_t *pl)
607 {
608 if (BIT(pl->used, USES_AUTOPILOT))
609 return true;
610 return false;
611 }
612
Player_uses_compass(player_t * pl)613 static inline bool Player_uses_compass(player_t *pl)
614 {
615 if (BIT(pl->used, USES_COMPASS))
616 return true;
617 return false;
618 }
619
Player_uses_connector(player_t * pl)620 static inline bool Player_uses_connector(player_t *pl)
621 {
622 if (BIT(pl->used, USES_CONNECTOR))
623 return true;
624 return false;
625 }
626
Player_uses_tractor_beam(player_t * pl)627 static inline bool Player_uses_tractor_beam(player_t *pl)
628 {
629 if (BIT(pl->used, USES_TRACTOR_BEAM))
630 return true;
631 return false;
632 }
633
Player_uses_emergency_shield(player_t * pl)634 static inline bool Player_uses_emergency_shield(player_t *pl)
635 {
636 if (BIT(pl->used, (HAS_SHIELD|HAS_EMERGENCY_SHIELD)) ==
637 (HAS_SHIELD|HAS_EMERGENCY_SHIELD))
638 return true;
639 return false;
640 }
641
Player_has_emergency_thrust(player_t * pl)642 static inline bool Player_has_emergency_thrust(player_t *pl)
643 {
644 #if 0
645 if (pl->item[ITEM_EMERGENCY_THRUST] > 0
646 || pl->emergency_thrust_left > 0.0)
647 return true;
648 return false;
649 #else
650 if (BIT(pl->have, HAS_EMERGENCY_THRUST))
651 return true;
652 return false;
653 #endif
654 }
655
Player_uses_emergency_thrust(player_t * pl)656 static inline bool Player_uses_emergency_thrust(player_t *pl)
657 {
658 if (BIT(pl->used, USES_EMERGENCY_THRUST))
659 return true;
660 return false;
661 }
662
Player_has_phasing_device(player_t * pl)663 static inline bool Player_has_phasing_device(player_t *pl)
664 {
665 #if 0
666 if (pl->item[ITEM_PHASING] > 0
667 || pl->phasing_left > 0.0)
668 return true;
669 #else
670 if (BIT(pl->have, HAS_PHASING_DEVICE))
671 return true;
672 return false;
673 #endif
674 return false;
675 }
676
Player_is_phasing(player_t * pl)677 static inline bool Player_is_phasing(player_t *pl)
678 {
679 if (BIT(pl->used, USES_PHASING_DEVICE))
680 return true;
681 return false;
682 }
683
Player_is_cloaked(player_t * pl)684 static inline bool Player_is_cloaked(player_t *pl)
685 {
686 if (BIT(pl->used, USES_CLOAKING_DEVICE))
687 return true;
688 return false;
689 }
690
Player_is_active(player_t * pl)691 static inline bool Player_is_active(player_t *pl)
692 {
693 if (Player_is_alive(pl)
694 || Player_is_killed(pl))
695 return true;
696 return false;
697 }
698
699 /* kps - add id.h ? */
Is_player_id(int id)700 static inline bool Is_player_id(int id)
701 {
702 if (id >= 1 && id <= NUM_IDS)
703 return true;
704 return false;
705 }
706
Is_cannon_id(int id)707 static inline bool Is_cannon_id(int id)
708 {
709 if (id >= MIN_CANNON_ID && id <= MAX_CANNON_ID)
710 return true;
711 return false;
712 }
713
714 /*
715 * Prototypes for player.c
716 */
717
718 void Pick_startpos(player_t *pl);
719 void Go_home(player_t *pl);
720 Item_t Item_by_option_name(const char *name);
721 void Base_set_option(base_t *base, const char *name, const char *value);
722 void Compute_sensor_range(player_t *pl);
723 void Player_add_tank(player_t *pl, double tank_fuel);
724 void Player_remove_tank(player_t *pl, int which_tank);
725 void Player_hit_armor(player_t *pl);
726 void Player_used_kill(player_t *pl);
727 void Player_set_mass(player_t *pl);
728 void Player_init_items(player_t *pl);
729 int Init_player(int ind, shipshape_t *ship, int type);
730 void Alloc_players(int number);
731 void Free_players(void);
732 void Update_score_table(void);
733 void Reset_all_players(void);
734 void Check_team_members(int);
735 void Compute_game_status(void);
736 void Delete_player(player_t *pl);
737 void Add_spectator(player_t *pl);
738 void Delete_spectator(player_t *pl);
739 void Detach_ball(player_t *pl, ballobject_t *ball);
740 void Kill_player(player_t *pl, bool add_rank_death);
741 void Player_death_reset(player_t *pl, bool add_rank_death);
742 void Count_rounds(void);
743 void Team_game_over(int winning_team, const char *reason);
744 void Individual_game_over(int winner);
745 bool Team_immune(int id1, int id2);
746
Player_set_float_dir(player_t * pl,double new_float_dir)747 static inline void Player_set_float_dir(player_t *pl, double new_float_dir)
748 {
749 if (options.ngControls && new_float_dir != pl->float_dir) {
750 pl->float_dir = new_float_dir;
751 pl->float_dir_cos = cos(pl->float_dir * 2.0 * PI / RES);
752 pl->float_dir_sin = sin(pl->float_dir * 2.0 * PI / RES);
753 } else
754 pl->float_dir = new_float_dir;
755 }
756
757 void Player_print_state(player_t *pl, const char *funcname);
758 void Player_set_state(player_t *pl, int state);
759 void Player_set_modbank(player_t *pl, int bank, const char *str);
760
761 #endif
762