Mercurial > ~darius > hgwebdir.cgi > paradise_server
comparison src/dutil.c @ 3:cafa94d86546
Initial revision
author | darius |
---|---|
date | Sat, 06 Dec 1997 04:37:01 +0000 |
parents | |
children | d28f3d01043c |
comparison
equal
deleted
inserted
replaced
2:2719a89505ba | 3:cafa94d86546 |
---|---|
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 <stdio.h> | |
21 #include <math.h> | |
22 #include <signal.h> | |
23 #include <string.h> | |
24 | |
25 #include "defs.h" | |
26 #include "struct.h" | |
27 #include "data.h" | |
28 #include "daemonII.h" | |
29 #include "shmem.h" | |
30 | |
31 #define friendly(fred, bart) \ | |
32 (!(fred->p_team & (bart->p_swar|bart->p_hostile)) && \ | |
33 !(bart->p_team & (fred->p_swar|fred->p_hostile))) | |
34 | |
35 /*--------------------------------KILLMESS--------------------------------*/ | |
36 | |
37 /* | |
38 * This function prints to the messages who killed who. This function now | |
39 * adds the way of death onto the end of the kill message. | |
40 */ | |
41 | |
42 | |
43 extern void pmessage(); | |
44 int get_explode_views(); | |
45 #ifndef SYSV /* this is barfing on HP/UX */ | |
46 extern int fprintf(); | |
47 #endif | |
48 extern void killerstats(); | |
49 extern void checkmaxkills(); | |
50 #ifdef LEAGUE_SUPPORT | |
51 extern void tlog_plkill(); | |
52 #else | |
53 #define tlog_plkill(a,b,c) | |
54 #endif | |
55 extern void loserstats(); | |
56 | |
57 void | |
58 killmess(victim, killer) | |
59 struct player *victim, *killer; /* killee and killer */ | |
60 { | |
61 char buf[80]; /* to sprintf into */ | |
62 | |
63 sprintf(buf, "%s (%s", victim->p_name, twoletters(victim)); | |
64 | |
65 if (victim->p_armies) | |
66 { | |
67 if ((victim->p_ship.s_nflags & SFNHASFIGHTERS) && (victim->p_ship.s_type != STARBASE)) | |
68 sprintf(buf + strlen(buf), "+%d fighters", | |
69 victim->p_ship.s_missilestored); | |
70 else | |
71 sprintf(buf + strlen(buf), "+%d armies", victim->p_armies); | |
72 } | |
73 strcat(buf, ")"); | |
74 if (killer) | |
75 { | |
76 sprintf(buf + strlen(buf), " was kill %0.2f for %s (%s)", | |
77 killer->p_kills, killer->p_name, | |
78 twoletters(killer)); | |
79 | |
80 if (friendly(victim, killer)) | |
81 strcat(buf, "[no credit]"); | |
82 | |
83 } | |
84 else | |
85 { | |
86 if (victim->p_whydead == KPLANET) | |
87 { | |
88 sprintf(buf + strlen(buf), " was %s by %s (%s)", | |
89 PL_TYPE(planets[victim->p_whodead]) == PLSTAR ? | |
90 "burned to a crisp" : "shot down", | |
91 planets[victim->p_whodead].pl_name, | |
92 teams[planets[victim->p_whodead].pl_owner].shortname); | |
93 } | |
94 else if (victim->p_whydead == KASTEROID) | |
95 sprintf(buf + strlen(buf), " was crushed by an asteroid"); | |
96 else | |
97 { | |
98 strcat(buf, " was killed"); | |
99 } | |
100 } | |
101 switch (victim->p_whydead) | |
102 { /* determine why player died */ | |
103 case KTORP: | |
104 strcat(buf, "[torp]"); | |
105 break; | |
106 case KPHASER: | |
107 strcat(buf, "[phaser]"); | |
108 break; | |
109 case KSHIP: | |
110 strcat(buf, "[explosion]"); | |
111 break; | |
112 case KPLASMA: | |
113 strcat(buf, "[plasma]"); | |
114 break; | |
115 case KASTEROID: | |
116 strcat(buf, "[asteroid]"); | |
117 break; | |
118 case KPLANET: | |
119 switch (PL_TYPE(planets[victim->p_whodead])) | |
120 { | |
121 case PLSTAR: | |
122 strcat(buf, "[star]"); | |
123 break; | |
124 case PLPLANET: | |
125 strcat(buf, "[planet]"); | |
126 break; | |
127 default: | |
128 strcat(buf, "[space rock]"); | |
129 break; | |
130 } | |
131 break; | |
132 default: | |
133 strcat(buf, "[unknown]"); | |
134 } | |
135 pmessage(buf, 0, MALL | MKILLA, "GOD->ALL"); | |
136 } | |
137 | |
138 | |
139 | |
140 | |
141 /*-------------------------------VISIBLE FUNCTIONS------------------------*/ | |
142 | |
143 /*-------------------------------CAUSE_KABOOM------------------------------*/ | |
144 /* | |
145 * This function sets the victim to explode and sets the counter for the | |
146 * explosion views. | |
147 */ | |
148 | |
149 void | |
150 cause_kaboom(victim) | |
151 struct player *victim; /* which ship to blast to tiny fragments */ | |
152 { | |
153 victim->p_status = PEXPLODE; /* set player as exploding */ | |
154 victim->p_explode = (short) get_explode_views(victim->p_ship.s_type); | |
155 } | |
156 | |
157 /*------------------------------GET_EXPLODE_VIEWS--------------------------*/ | |
158 /* returns the number of ship views for the given ship type */ | |
159 | |
160 int | |
161 get_explode_views(stype) | |
162 short stype; | |
163 { | |
164 switch (stype) | |
165 { | |
166 case STARBASE: | |
167 case WARBASE: | |
168 case JUMPSHIP: | |
169 return 2 * SBEXPVIEWS / PLAYERFUSE; /* big kablooey */ | |
170 } | |
171 return 10 / PLAYERFUSE; /* small kablooey */ | |
172 } | |
173 | |
174 /*------------------------------INFLICT_DAMAGE-----------------------------*/ | |
175 /* | |
176 * This function is used to inflict damage on a player. If the player dies | |
177 * as a result he will be made to explode. The function returns a 1 if the | |
178 * victim was killed and a 0 otherwise. If the sp parameter is a zero then | |
179 * the victim was damaged by something other than a ship. It is the | |
180 * responsibil- ity of the caller to set the whydead field of the victim. | |
181 */ | |
182 | |
183 int | |
184 inflict_damage(sp, op, victim, damage, why) | |
185 struct player *sp; /* player that inflicted the damage */ | |
186 struct player *op; /* other player that could be responsible */ | |
187 struct player *victim; /* which ship to victimize */ | |
188 int damage; /* how much damage, should be positive */ | |
189 int why; /* the source of the damage */ | |
190 { | |
191 if (damage < 0) | |
192 { /* should not be called with - damage */ | |
193 fprintf(stderr, "Attempt to inflict negative damage\n"); | |
194 return 0; | |
195 } | |
196 | |
197 if (victim->p_flags & PFSHIELD) | |
198 { /* shields up? */ | |
199 int penetrated; | |
200 /* | |
201 * if the server is configured for damage penetration then the shields | |
202 * will not absorb all the damage | |
203 */ | |
204 penetrated = damage * configvals->penetration | |
205 * (victim->p_ship.s_maxshield - victim->p_shield) | |
206 / (victim->p_ship.s_maxshield); | |
207 damage -= penetrated; | |
208 | |
209 victim->p_shield -= damage; /* damage shields */ | |
210 if (victim->p_shield < 0) | |
211 { /* we punched through the shield */ | |
212 damage = -victim->p_shield; /* excess damage will apply to hull */ | |
213 victim->p_shield = 0; /* and zero the shields */ | |
214 } | |
215 else | |
216 damage = 0; | |
217 damage += penetrated; /* some of the damage got through the shields */ | |
218 } | |
219 if (damage > 0) | |
220 { | |
221 victim->p_damage += damage; /* all damage to hull */ | |
222 if (configvals->erosion > 0) | |
223 { | |
224 float chance = damage * configvals->erosion; | |
225 while (chance >= 0.5) | |
226 { /* no matter how much you suffer there's a | |
227 * chance you can avoid permanent damage */ | |
228 if (lrand48() & 0x40) | |
229 { | |
230 victim->p_ship.s_maxdamage--; /* apply damage to maximum */ | |
231 victim->p_damage--; /* instead of current */ | |
232 } | |
233 chance -= 0.5; | |
234 } | |
235 if (drand48() < chance) | |
236 { | |
237 victim->p_ship.s_maxdamage--; /* apply damage to maximum */ | |
238 victim->p_damage--; /* instead of current */ | |
239 } | |
240 } | |
241 } | |
242 | |
243 if (victim->p_damage >= victim->p_ship.s_maxdamage) | |
244 { /* victim dead? */ | |
245 cause_kaboom(victim); /* make him explode */ | |
246 if (sp) | |
247 { | |
248 victim->p_whydead = why; | |
249 if (!friendly(sp, victim) | |
250 && sp != victim /* hozers were getting credit for killing | |
251 * themselves because they were at war with | |
252 their own race */ ) | |
253 { | |
254 /* if a hostile player was responsible */ | |
255 tlog_plkill(victim, sp, op); | |
256 if (victim->p_ship.s_type == PATROL) | |
257 sp->p_kills += .5 + ((float) victim->p_armies + victim->p_kills) / 10.0; | |
258 else | |
259 sp->p_kills += 1.0 + ((float) victim->p_armies + victim->p_kills) / 10.0; | |
260 killerstats(sp->p_no, victim); /* adjust everyones stats */ | |
261 checkmaxkills(sp->p_no); | |
262 killmess(victim, sp); | |
263 victim->p_whodead = sp->p_no; | |
264 } | |
265 else if (op && !friendly(op, victim) && op != victim) | |
266 { | |
267 /* the primary assassin was friendly, check auxiliary killer */ | |
268 tlog_plkill(victim, op, sp); | |
269 | |
270 if (victim->p_ship.s_type == PATROL) | |
271 op->p_kills += .5 + ((float) victim->p_armies + victim->p_kills) / 10.0; | |
272 else | |
273 op->p_kills += 1.0 + ((float) victim->p_armies + victim->p_kills) / 10.0; | |
274 killerstats(op->p_no, victim); /* adjust everyones stats */ | |
275 checkmaxkills(op->p_no); | |
276 killmess(victim, op); | |
277 victim->p_whodead = op->p_no; | |
278 } | |
279 else | |
280 { | |
281 /* | |
282 * give no credit since it was friendly and the auxiliary murderer | |
283 * was friendly too | |
284 */ | |
285 tlog_plkill(victim, sp, (struct player *) 0); | |
286 killmess(victim, sp); | |
287 victim->p_whodead = sp->p_no; | |
288 } | |
289 } | |
290 loserstats(victim->p_no); | |
291 return 1; /* victim died */ | |
292 } | |
293 else | |
294 return 0; /* victim lived */ | |
295 } | |
296 | |
297 /*-------------------------------------------------------------------------*/ | |
298 | |
299 | |
300 struct ranksorter | |
301 { | |
302 int pno; | |
303 int rank; | |
304 float di; | |
305 int teammates; | |
306 }; | |
307 | |
308 static struct ranksorter admirals[MAXTEAM]; | |
309 | |
310 int | |
311 enemy_admiral(tno) | |
312 int tno; | |
313 { | |
314 int teammates; | |
315 int pno; | |
316 int i; | |
317 | |
318 for (i = 0; i < MAXTEAM; i++) | |
319 { | |
320 admirals[i].teammates = 0; | |
321 admirals[i].rank = -1; | |
322 } | |
323 | |
324 for (i = 0; i < MAXPLAYER; i++) | |
325 { | |
326 int team; | |
327 struct player *pl; | |
328 pl = &players[i]; | |
329 | |
330 if (pl->p_status == PFREE || | |
331 pl->p_team == tno) | |
332 continue; | |
333 | |
334 team = pl->p_team; | |
335 admirals[team].teammates++; | |
336 | |
337 if (pl->p_stats.st_rank < admirals[team].rank) | |
338 continue; | |
339 if (pl->p_stats.st_rank > admirals[team].rank || | |
340 pl->p_stats.st_di > admirals[team].di) | |
341 { | |
342 admirals[team].pno = i; | |
343 admirals[team].rank = pl->p_stats.st_rank; | |
344 admirals[team].di = pl->p_stats.st_di; | |
345 } | |
346 } | |
347 | |
348 teammates = -1; | |
349 pno = 0; | |
350 for (i = 0; i < MAXTEAM; i++) | |
351 { | |
352 if (admirals[i].teammates > teammates) | |
353 { | |
354 pno = admirals[i].pno; | |
355 teammates = admirals[i].teammates; | |
356 } | |
357 } | |
358 return pno; | |
359 } | |
360 | |
361 | |
362 /*--------END OF FILE-------*/ |