6
|
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 #include "config.h"
|
|
20 #include <math.h>
|
|
21
|
|
22 #include "plutil.h"
|
|
23 #include "data.h"
|
|
24 #include "shmem.h"
|
|
25
|
|
26 int
|
|
27 idx_to_mask(i)
|
|
28 int i;
|
|
29 {
|
|
30 if (i >= 0)
|
|
31 return 1 << i;
|
|
32 else
|
|
33 return 0;
|
|
34 }
|
|
35
|
|
36 int
|
|
37 mask_to_idx(m)
|
|
38 int m;
|
|
39 {
|
|
40 int i;
|
|
41 if (!m)
|
|
42 return -1;
|
|
43 for (i = 0; m > 1; i++, m >>= 1);
|
|
44 return i;
|
|
45 }
|
|
46
|
|
47 /*
|
|
48 */
|
|
49
|
|
50 int
|
|
51 in_warp(pl)
|
|
52 struct player *pl;
|
|
53 {
|
|
54 if (pl->p_flags & PFDOCK)
|
|
55 {
|
|
56 /* if we are docked, then we have the same state as our base */
|
|
57 return in_warp(&players[pl->p_docked]);
|
|
58 }
|
|
59 return (pl->p_flags & PFWARP) || pl->p_warptime;
|
|
60 }
|
|
61
|
|
62
|
|
63 int
|
|
64 undock_player(pl)
|
|
65 struct player *pl;
|
|
66 {
|
|
67 struct player *base;
|
|
68
|
|
69 if (!(pl->p_flags & PFDOCK))
|
|
70 return 0;
|
|
71
|
|
72 base = &players[pl->p_docked];
|
|
73 base->p_docked--; /* base no longer has as many docked */
|
|
74 base->p_port[pl->p_port[0]] = VACANT; /* the port is vacant */
|
|
75
|
|
76 /* what if the player is being undocked because he died? */
|
|
77 if (base->p_ship.s_type == JUMPSHIP)
|
|
78 {
|
|
79 pl->p_jsdock = 1;
|
|
80 pl->p_lastjs = pl->p_docked;
|
|
81 }
|
|
82 pl->p_flags &= ~PFDOCK;
|
|
83 pl->p_docked = -1;
|
|
84 pl->p_port[0] = VACANT;
|
|
85
|
|
86 return 1;
|
|
87 }
|
|
88
|
|
89 int
|
|
90 base_undock(base, port_id)
|
|
91 struct player *base;
|
|
92 int port_id;
|
|
93 {
|
|
94 struct player *pl;
|
|
95
|
|
96 if (base->p_port[port_id] < 0)
|
|
97 return 0;
|
|
98
|
|
99 pl = &players[base->p_port[port_id]];
|
|
100
|
|
101 base->p_docked--;
|
|
102 base->p_port[port_id] = VACANT;
|
|
103
|
|
104 /* if the jumpship kicks you off, he doesn't get credited. -RF */
|
|
105
|
|
106 pl->p_flags &= ~PFDOCK;
|
|
107 pl->p_docked = -1;
|
|
108 pl->p_port[0] = VACANT;
|
|
109 return 1;
|
|
110 }
|
|
111
|
|
112 void
|
|
113 enforce_dock_position(pl)
|
|
114 struct player *pl;
|
|
115 {
|
|
116 struct player *base;
|
|
117 unsigned char angle;
|
|
118 int port_id;
|
|
119
|
|
120 if (!(pl->p_flags & PFDOCK))
|
|
121 return;
|
|
122
|
|
123 base = &players[pl->p_docked];
|
|
124 port_id = pl->p_port[0];
|
|
125
|
|
126 if ((base->p_ship.s_type == STARBASE) || (base->p_ship.s_type == WARBASE) ||
|
|
127 (base->p_ship.s_type == JUMPSHIP))
|
|
128 angle = (port_id * 2 + 1) * 128 / base->p_ship.s_numports;
|
|
129 else
|
|
130 angle = base->p_dir + 64 + (128 * port_id); /* max of two ports, really */
|
|
131 move_player(pl->p_no, (int) (base->p_x + DOCKDIST * Cos[angle]),
|
|
132 (int) (base->p_y + DOCKDIST * Sin[angle]), 1);
|
|
133
|
|
134 pl->p_speed = pl->p_desspeed = 0;
|
|
135 if ((base->p_ship.s_type == STARBASE) || (base->p_ship.s_type == WARBASE) ||
|
|
136 (base->p_ship.s_type == JUMPSHIP))
|
|
137 pl->p_dir = pl->p_desdir = angle + 64;
|
|
138 else
|
|
139 pl->p_dir = pl->p_desdir = base->p_dir;
|
|
140 }
|
|
141
|
|
142 void
|
|
143 dock_to(pl, base_num, port_id)
|
|
144 struct player *pl;
|
|
145 int base_num, port_id;
|
|
146 {
|
|
147 struct player *base = &players[base_num];
|
|
148
|
|
149 undock_player(pl);
|
|
150
|
|
151 base->p_docked++;
|
|
152 base->p_port[port_id] = pl->p_no;
|
|
153
|
|
154 pl->p_flags |= PFDOCK; /* we are docked */
|
|
155 pl->p_docked = base_num; /* to this base */
|
|
156 pl->p_port[0] = port_id; /* in this docking bay */
|
|
157
|
|
158 enforce_dock_position(pl);
|
|
159 }
|
|
160
|
|
161 void
|
|
162 scout_planet(p_no, pl_no)
|
|
163 int p_no;
|
|
164 int pl_no;
|
|
165 {
|
|
166 struct player *fred = &players[p_no];
|
|
167 struct planet *mars = &planets[pl_no];
|
|
168 int oldness = status->clock - mars->pl_tinfo[fred->p_team].timestamp;
|
|
169
|
|
170 if (!status->tourn)
|
|
171 return;
|
|
172
|
|
173 if ((mars->pl_owner != fred->p_team) &&
|
|
174 (oldness > 2))
|
|
175 {
|
|
176 #define LOG2OFe 1.442695
|
|
177 double scoutdi = log((double) oldness) * LOG2OFe / 100;
|
|
178 if (scoutdi > 0.1)
|
|
179 scoutdi = 0.1;
|
|
180 fred->p_stats.st_di += scoutdi;
|
|
181 }
|
|
182 mars->pl_hinfo |= fred->p_team;
|
|
183 if (mars->pl_owner != fred->p_team)
|
|
184 {
|
|
185 mars->pl_tinfo[fred->p_team].flags = mars->pl_flags;
|
|
186 mars->pl_tinfo[fred->p_team].armies = mars->pl_armies;
|
|
187 mars->pl_tinfo[fred->p_team].owner = mars->pl_owner;
|
|
188 mars->pl_tinfo[fred->p_team].timestamp = status->clock;
|
|
189 }
|
|
190 }
|
|
191
|
|
192 /*
|
|
193 * */
|
|
194
|
|
195 void
|
|
196 evaporate(pl)
|
|
197 struct player *pl;
|
|
198 {
|
|
199 /* put someone on the outfit screen with no ill effects */
|
|
200
|
|
201 undock_player(pl); /* if docked then undock me */
|
|
202
|
|
203 if (allows_docking(pl->p_ship))
|
|
204 { /* if ships can dock */
|
|
205 int k;
|
|
206 for (k = 0; k < pl->p_ship.s_numports; k++)
|
|
207 base_undock(pl, k); /* remove all docked ships */
|
|
208 pl->p_docked = 0; /* no ships docked anymore */
|
|
209 }
|
|
210 if (pl->p_flags & PFORBIT)
|
|
211 { /* if orbiting then */
|
|
212 pl->p_flags &= ~PFORBIT; /* eject from orbit */
|
|
213 }
|
|
214
|
|
215 pl->p_status = POUTFIT;
|
|
216 pl->p_whydead = KPROVIDENCE;
|
|
217 }
|
|
218
|
|
219 void
|
|
220 explode_everyone(whydead, minlive)
|
|
221 int whydead;
|
|
222 int minlive;
|
|
223 {
|
|
224 int i;
|
|
225 for (i = 0; i < MAXPLAYER; i++)
|
|
226 {
|
|
227 if (players[i].p_status != PALIVE
|
|
228 && players[i].p_status != POBSERVE)
|
|
229 continue;
|
|
230
|
|
231 if (players[i].p_updates < minlive)
|
|
232 continue;
|
|
233
|
|
234 players[i].p_whydead = whydead;
|
|
235 players[i].p_whodead = 0;
|
|
236 players[i].p_status = PEXPLODE;
|
|
237 players[i].p_explode = 10;
|
|
238 players[i].p_ntorp = 0; /* no torps shot */
|
|
239 players[i].p_nplasmatorp = 0; /* no plasmas shot */
|
|
240 }
|
|
241 }
|
|
242
|
|
243
|
|
244 /* round randomly, but weighted by the fractional part */
|
|
245
|
|
246 int
|
|
247 random_round(d)
|
|
248 double d;
|
|
249 {
|
|
250 int rval = floor(d);
|
|
251 if (drand48() < d - rval)
|
|
252 rval++;
|
|
253 return rval;
|
|
254 }
|
|
255
|
|
256
|
|
257 char *
|
|
258 twoletters(pl)
|
|
259 struct player *pl;
|
|
260 /* calculate the two letters that form the players designation (e.g. R4) */
|
|
261 {
|
|
262 #define RINGSIZE MAXPLAYER+3
|
|
263 static char buf[RINGSIZE][3]; /* ring of buffers so that this */
|
|
264 static int idx; /* proc can be called several times before
|
|
265 * the results are used */
|
|
266 if (idx >= RINGSIZE)
|
|
267 idx = 0;
|
|
268 buf[idx][0] = teams[pl->p_team].letter;
|
|
269 buf[idx][1] = shipnos[pl->p_no];
|
|
270 buf[idx][2] = 0;
|
|
271 return buf[idx++];
|
|
272 }
|