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