Mercurial > ~darius > hgwebdir.cgi > paradise_server
view src/dutil.c @ 18:1424868939a8
Indenting
author | darius |
---|---|
date | Wed, 24 Dec 1997 12:38:35 +0000 |
parents | 65de6eb6861a |
children |
line wrap: on
line source
/*-------------------------------------------------------------------------- NETREK II -- Paradise Permission to use, copy, modify, and distribute this software and its documentation, or any derivative works thereof, for any NON-COMMERCIAL purpose and without fee is hereby granted, provided that this copyright notice appear in all copies. No representations are made about the suitability of this software for any purpose. This software is provided "as is" without express or implied warranty. Xtrek Copyright 1986 Chris Guthrie Netrek (Xtrek II) Copyright 1989 Kevin P. Smith Scott Silvey Paradise II (Netrek II) Copyright 1993 Larry Denys Kurt Olsen Brandon Gillespie --------------------------------------------------------------------------*/ #include "config.h" #include <stdio.h> #include <math.h> #include <signal.h> #include <string.h> #include "defs.h" #include "struct.h" #include "data.h" #include "daemonII.h" #include "shmem.h" #define friendly(fred, bart) \ (!(fred->p_team & (bart->p_swar|bart->p_hostile)) && \ !(bart->p_team & (fred->p_swar|fred->p_hostile))) /*--------------------------------KILLMESS--------------------------------*/ /* * This function prints to the messages who killed who. This function now * adds the way of death onto the end of the kill message. */ extern void pmessage(); int get_explode_views(); #ifndef SYSV /* this is barfing on HP/UX */ extern int fprintf(); #endif extern void killerstats(); extern void checkmaxkills(); #ifdef LEAGUE_SUPPORT extern void tlog_plkill(); #else #define tlog_plkill(a,b,c) #endif extern void loserstats(); void killmess(victim, killer) struct player *victim, *killer; /* killee and killer */ { char buf[80]; /* to sprintf into */ sprintf(buf, "%s (%s", victim->p_name, twoletters(victim)); if (victim->p_armies) { if ((victim->p_ship.s_nflags & SFNHASFIGHTERS) && (victim->p_ship.s_type != STARBASE)) sprintf(buf + strlen(buf), "+%d fighters", victim->p_ship.s_missilestored); else sprintf(buf + strlen(buf), "+%d armies", victim->p_armies); } strcat(buf, ")"); if (killer) { sprintf(buf + strlen(buf), " was kill %0.2f for %s (%s)", killer->p_kills, killer->p_name, twoletters(killer)); if (friendly(victim, killer)) strcat(buf, "[no credit]"); } else { if (victim->p_whydead == KPLANET) { sprintf(buf + strlen(buf), " was %s by %s (%s)", PL_TYPE(planets[victim->p_whodead]) == PLSTAR ? "burned to a crisp" : "shot down", planets[victim->p_whodead].pl_name, teams[planets[victim->p_whodead].pl_owner].shortname); } else if (victim->p_whydead == KASTEROID) sprintf(buf + strlen(buf), " was crushed by an asteroid"); else { strcat(buf, " was killed"); } } switch (victim->p_whydead) { /* determine why player died */ case KTORP: strcat(buf, "[torp]"); break; case KPHASER: strcat(buf, "[phaser]"); break; case KSHIP: strcat(buf, "[explosion]"); break; case KPLASMA: strcat(buf, "[plasma]"); break; case KASTEROID: strcat(buf, "[asteroid]"); break; case KPLANET: switch (PL_TYPE(planets[victim->p_whodead])) { case PLSTAR: strcat(buf, "[star]"); break; case PLPLANET: strcat(buf, "[planet]"); break; default: strcat(buf, "[space rock]"); break; } break; default: strcat(buf, "[unknown]"); } pmessage(buf, 0, MALL | MKILLA, "GOD->ALL"); } /*-------------------------------VISIBLE FUNCTIONS------------------------*/ /*-------------------------------CAUSE_KABOOM------------------------------*/ /* * This function sets the victim to explode and sets the counter for the * explosion views. */ void cause_kaboom(victim) struct player *victim; /* which ship to blast to tiny fragments */ { victim->p_status = PEXPLODE; /* set player as exploding */ victim->p_explode = (short) get_explode_views(victim->p_ship.s_type); } /*------------------------------GET_EXPLODE_VIEWS--------------------------*/ /* returns the number of ship views for the given ship type */ int get_explode_views(stype) short stype; { switch (stype) { case STARBASE: case WARBASE: case JUMPSHIP: return 2 * SBEXPVIEWS / PLAYERFUSE; /* big kablooey */ } return 10 / PLAYERFUSE; /* small kablooey */ } /*------------------------------INFLICT_DAMAGE-----------------------------*/ /* * This function is used to inflict damage on a player. If the player dies * as a result he will be made to explode. The function returns a 1 if the * victim was killed and a 0 otherwise. If the sp parameter is a zero then * the victim was damaged by something other than a ship. It is the * responsibil- ity of the caller to set the whydead field of the victim. */ int inflict_damage(sp, op, victim, damage, why) struct player *sp; /* player that inflicted the damage */ struct player *op; /* other player that could be responsible */ struct player *victim; /* which ship to victimize */ int damage; /* how much damage, should be positive */ int why; /* the source of the damage */ { if (damage < 0) { /* should not be called with - damage */ fprintf(stderr, "Attempt to inflict negative damage\n"); return 0; } if (victim->p_flags & PFSHIELD) { /* shields up? */ int penetrated; float factor; /* * if the server is configured for damage penetration then the shields * will not absorb all the damage */ /* Holds the initial penetration factor */ factor = configvals->penetration; /* Are we in nebulous terrain? */ if ((terrain_grid[(int) (victim->p_x) / TGRID_GRANULARITY * TGRID_SIZE + (int) (victim->p_y) / TGRID_GRANULARITY].types & T_NEBULA) && neb_effect[SS_SHIELD]) factor += drand48(); /* Yes - add something to the penetration factor */ if(factor > 1) /* Check for overflow */ factor = 1; penetrated = damage * factor * (victim->p_ship.s_maxshield - victim->p_shield) / (victim->p_ship.s_maxshield); damage -= penetrated; victim->p_shield -= damage; /* damage shields */ if (victim->p_shield < 0) { /* we punched through the shield */ damage = -victim->p_shield; /* excess damage will apply to hull */ victim->p_shield = 0; /* and zero the shields */ } else damage = 0; damage += penetrated; /* some of the damage got through the shields */ } if (damage > 0) { victim->p_damage += damage; /* all damage to hull */ if (configvals->erosion > 0) { float chance = damage * configvals->erosion; while (chance >= 0.5) { /* no matter how much you suffer there's a * chance you can avoid permanent damage */ if (lrand48() & 0x40) { victim->p_ship.s_maxdamage--; /* apply damage to maximum */ victim->p_damage--; /* instead of current */ } chance -= 0.5; } if (drand48() < chance) { victim->p_ship.s_maxdamage--; /* apply damage to maximum */ victim->p_damage--; /* instead of current */ } } } if (victim->p_damage >= victim->p_ship.s_maxdamage) { /* victim dead? */ cause_kaboom(victim); /* make him explode */ if (sp) { victim->p_whydead = why; if (!friendly(sp, victim) && sp != victim /* hozers were getting credit for killing * themselves because they were at war with their own race */ ) { /* if a hostile player was responsible */ tlog_plkill(victim, sp, op); if (victim->p_ship.s_type == PATROL) sp->p_kills += .5 + ((float) victim->p_armies + victim->p_kills) / 10.0; else sp->p_kills += 1.0 + ((float) victim->p_armies + victim->p_kills) / 10.0; killerstats(sp->p_no, victim); /* adjust everyones stats */ checkmaxkills(sp->p_no); killmess(victim, sp); victim->p_whodead = sp->p_no; } else if (op && !friendly(op, victim) && op != victim) { /* the primary assassin was friendly, check auxiliary killer */ tlog_plkill(victim, op, sp); if (victim->p_ship.s_type == PATROL) op->p_kills += .5 + ((float) victim->p_armies + victim->p_kills) / 10.0; else op->p_kills += 1.0 + ((float) victim->p_armies + victim->p_kills) / 10.0; killerstats(op->p_no, victim); /* adjust everyones stats */ checkmaxkills(op->p_no); killmess(victim, op); victim->p_whodead = op->p_no; } else { /* * give no credit since it was friendly and the auxiliary murderer * was friendly too */ tlog_plkill(victim, sp, (struct player *) 0); killmess(victim, sp); victim->p_whodead = sp->p_no; } } loserstats(victim->p_no); return 1; /* victim died */ } else return 0; /* victim lived */ } /*-------------------------------------------------------------------------*/ struct ranksorter { int pno; int rank; float di; int teammates; }; static struct ranksorter admirals[MAXTEAM]; int enemy_admiral(tno) int tno; { int teammates; int pno; int i; for (i = 0; i < MAXTEAM; i++) { admirals[i].teammates = 0; admirals[i].rank = -1; } for (i = 0; i < MAXPLAYER; i++) { int team; struct player *pl; pl = &players[i]; if (pl->p_status == PFREE || pl->p_team == tno) continue; team = pl->p_team; admirals[team].teammates++; if (pl->p_stats.st_rank < admirals[team].rank) continue; if (pl->p_stats.st_rank > admirals[team].rank || pl->p_stats.st_di > admirals[team].di) { admirals[team].pno = i; admirals[team].rank = pl->p_stats.st_rank; admirals[team].di = pl->p_stats.st_di; } } teammates = -1; pno = 0; for (i = 0; i < MAXTEAM; i++) { if (admirals[i].teammates > teammates) { pno = admirals[i].pno; teammates = admirals[i].teammates; } } return pno; } /*--------END OF FILE-------*/