diff src/phaser.c @ 4:aa38447a4b21

First entry of Paradise Server 2.9 patch 10 Beta
author darius
date Sat, 06 Dec 1997 04:37:03 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/phaser.c	Sat Dec 06 04:37:03 1997 +0000
@@ -0,0 +1,247 @@
+/*--------------------------------------------------------------------------
+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-------*/