Mercurial > ~darius > hgwebdir.cgi > paradise_server
view src/phaser.c @ 5:054275999194
Initial revision
author | darius |
---|---|
date | Sat, 06 Dec 1997 04:37:03 +0000 |
parents | aa38447a4b21 |
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 "defs.h" #include "struct.h" #include "data.h" #include "weapons.h" #include "shmem.h" /*-----------------------------VISIBLE FUNCTIONS---------------------------*/ /*----------------------------------PHASER---------------------------------*/ /* * This function shoots a phaser for a player. Various conditions are * checked to see if the phaser should be allowed to fire. If the player can * fire then, a player is found in the direction the phaser was fired. */ extern int angdist(); void phaser(course) unsigned char course; { int i; /* looping var */ struct player *j, *target = 0;/* to hold player found */ struct plasmatorp *k, *target2 = 0; /* to hold plasma torp found */ struct missile *d, *target3 = 0; struct phaser *mine; /* to pnt to player's phaser */ int whichtarget; /* to hold type of target */ int target_x = 0, target_y = 0; /* target's x and y coords */ unsigned char dir; /* to get direction of phasr */ int range, trange; /* range of target */ int maxangle; /* potential target range */ int myphrange; /* angle to hit potentl targ */ char buf[80]; /* to sprintf warnings into */ mine = &phasers[me->p_no]; /* get phaser struct */ if (!(myship->s_nflags & SFNHASPHASERS)) { /* do we have phasers? */ warning("Weapons Officer: This ship is not armed with phasers, captain!"); return; } if (mine->ph_status != PHFREE) { /* is phaser currently being */ warning("Phasers have not recharged"); /* fired */ return; } if (me->p_fuel < myship->s_phaser.cost) { /* do we have enough fuel */ warning("Not enough fuel for phaser"); return; } if (me->p_flags & PFREPAIR) { /* cannot fire while in */ warning("Can't fire while repairing"); /* repair mode */ return; } if (me->p_flags & PFWEP) { /* cannot fire while weapon */ warning("Weapons overheated"); /* temped */ return; } if ((me->p_cloakphase) && (me->p_ship.s_type != ATT)) { warning("Cannot fire while cloaked"); /* cannot fire while cloaked */ return; } if (!check_fire_warp() || !check_fire_warpprep() || !check_fire_docked()) return; me->p_fuel -= myship->s_phaser.cost; /* subtract off fuel cost */ me->p_wtemp += myship->s_phaser.wtemp; /* add to w temp */ mine->ph_dir = course; /* get direction of phaser */ whichtarget = 0; /* no target fount yet */ range = 1000000; /* Sufficiently big. */ /* check the players */ for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) { /* loop all players */ if (((j->p_status != PALIVE) #ifdef PFBIRD && !(j->p_flags & PFBIRD) #endif ) || (j == me)) /* only check alive players */ continue; if ((!((j->p_swar | j->p_hostile) & me->p_team)) && (!((me->p_swar | me->p_hostile) & j->p_team)) && #ifdef PFBIRD !(j->p_flags & PFBIRD) #endif ) continue; /* only check at war with */ dir = (unsigned char) (int) (atan2((double) (j->p_x - me->p_x), (double) (me->p_y - j->p_y)) / 3.14159 * 128.); /* get range of target */ trange = ihypot(j->p_x - me->p_x, j->p_y - me->p_y); if (trange == 0) /* don't want zero in atan */ trange = 1; maxangle = atan((float) EXPDIST / trange) / 3.14159 * 128.0; if (angdist(dir, course) <= maxangle) { /* if angle within tolerance */ if (range > trange) { /* then check to see if */ whichtarget = 1; /* this is the closest target */ target = j; /* found yet */ range = trange; /* record if it is */ } } } /* check the plasmas */ for (i = 0, k = &plasmatorps[i]; i < MAXPLASMA * MAXPLAYER; i++, k++) { if ((k->pt_status != PTMOVE) || (k->pt_owner == me->p_no)) continue; /* only check live plasmas */ if ((!(k->pt_war & me->p_team)) && /* and unfriendly ones */ (!((me->p_swar | me->p_hostile) & k->pt_team))) continue; dir = (unsigned char) (int) (atan2((double) (k->pt_x - me->p_x), (double) (me->p_y - k->pt_y)) / 3.14159 * 128.); /* find direction */ trange = ihypot(k->pt_x - me->p_x, k->pt_y - me->p_y); if (trange == 0) /* no zeroes in math funcs */ trange = 1; maxangle = atan((float) EXPDIST / 4 / trange) / 3.14159 * 128.0; if (angdist(dir, course) <= (maxangle + 1)) { /* if we can hit it */ if (range > trange) { /* then check to see if this */ target_x = k->pt_x; /* is the closest plasma */ target_y = k->pt_y; /* found yet */ whichtarget = 2; /* and record it if it is */ target2 = k; range = trange; } } } /* check the fighters */ for (i = 0, d = &missiles[i]; i < NPTHINGIES * MAXPLAYER; i++, d++) { if ((d->ms_owner == me->p_no) || (d->ms_type != FIGHTERTHINGY)) continue; /* only check live fighters */ if ((!(d->ms_war & me->p_team)) && /* and unfriendly ones */ (!((me->p_swar | me->p_hostile) & d->ms_team))) continue; dir = (unsigned char) (atan2((double) (d->ms_x - me->p_x), (double) (me->p_y - d->ms_y)) / 3.14159 * 128.); /* find direction */ trange = ihypot(d->ms_x - me->p_x, d->ms_y - me->p_y); if (trange == 0) /* no zeroes in math funcs */ trange = 1; maxangle = atan((float) EXPDIST / 8 / trange) / 3.14159 * 128.0; if (angdist(dir, course) <= (maxangle + 1)) { /* if we can hit it */ if (range > trange) { /* then check to see if this */ target_x = d->ms_x; /* is the closest fighter */ target_y = d->ms_y; /* found yet */ whichtarget = 3; /* and record it if it is */ target3 = d; range = trange; } } } mine->ph_fuse = me->p_ship.s_phaser.fuse; /* set phaser fuse */ myphrange = me->p_ship.s_phaser.speed; /* phaser range */ if ((whichtarget == 0) || /* if no target found or all */ (range > myphrange)) { /* targets too long */ mine->ph_status = PHMISS; /* then we missed */ warning("Phaser missed!!!"); } else if (whichtarget == 2) { /* if we hit a plasma then */ warning("You destroyed the plasma torpedo!"); mine->ph_x = target_x; /* the set point to shoot at */ mine->ph_y = target_y; mine->ph_status = PHHIT2; /* we hit a plasma */ target2->pt_status = PTEXPLODE; /* Plasmas hurt everyone */ target2->pt_whodet = me->p_no; } else if (whichtarget == 3) { /* if we hit a fighter then */ warning("You shot a fighter!"); mine->ph_x = target_x; /* the set point to shoot at */ mine->ph_y = target_y; mine->ph_status = PHHIT2; /* we hit the fighter */ target3->ms_status = TDET; /* det the fighter */ target3->ms_whodet = me->p_no; } else { /* else if we hit player */ mine->ph_target = target->p_no; /* set the player number */ mine->ph_damage = me->p_ship.s_phaser.damage * /* get damage */ (1.0 - (range / (float) myphrange)); if (mine->ph_damage < 0) /* if damage inflicted */ mine->ph_damage = -mine->ph_damage; /* set the phaser damage */ mine->ph_status = PHHIT; /* status is a hit */ #ifdef PFBIRD if (target->p_flags & PFBIRD) { /* change to PHHIT2 so phaser won't follow bird */ mine->ph_status = PHHIT2; mine->ph_x = target->p_x; mine->ph_y = target->p_y; /* xx: slight misuse of fields here */ target->p_damage = mine->ph_damage; target->p_whodead = me->p_no; (void) sprintf(buf, "\"AAWWK!\""); } #endif (void) sprintf(buf, "Phaser burst hit %s for %d points", target->p_name, mine->ph_damage); warning(buf); } } /*------------------------------------------------------------------------*/ /*-------END OF FILE-------*/