diff src/redraw.c @ 6:8c6d5731234d

First entry of Paradise Server 2.9 patch 10 Beta
author darius
date Sat, 06 Dec 1997 04:37:04 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/redraw.c	Sat Dec 06 04:37:04 1997 +0000
@@ -0,0 +1,689 @@
+/*--------------------------------------------------------------------------
+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 <signal.h>
+#include <setjmp.h>		/* change 4/14/91 TC */
+#include <string.h>
+#include <time.h>
+
+#include <math.h>
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "shmem.h"
+
+extern char start_login[], start_name[];	/* change 4/14/91 TC */
+extern int goAway;		/* change 4/14/91 TC */
+extern jmp_buf env;		/* change 4/14/91 TC */
+
+
+#ifdef AUTHORIZE
+extern int makeReservedPacket();
+#endif
+extern int sendClientPacket();
+#ifndef	IRIX
+extern int fprintf();
+#endif
+extern void death();
+void auto_features();
+extern int set_speed();
+extern int orbit();
+extern int set_course();
+int newcourse();
+extern void imm_warning();
+
+#ifdef AUTHORIZE
+void
+check_authentication()
+{
+  /* if (!configvals->binconfirm) testtime=0; */
+  if (testtime == -1)
+  {
+    struct reserved_spacket sp;
+
+#ifdef RSA_EXEMPTION_FILE
+    if (site_rsa_exempt())
+    {
+      printf("site exempt from RSA authentication\n");
+      strcpy(RSA_client_type, "site/player is RSA exempt");
+      testtime = 0;
+    }
+    else
+#endif				/* RSA_EXEMPTION_FILE */
+    {
+      /*
+       * Give reasonable period of time to respond to query (and test code if
+       * they need to)
+       */
+
+      testtime = 200;
+      makeReservedPacket(&sp);
+      memcpy(testdata, sp.data, KEY_SIZE);
+      sendClientPacket((struct player_spacket *) & sp);
+    }				/* RSA EXEMPTION */
+  }
+  else if (testtime != 0)
+  {
+    testtime--;
+    if (testtime == 0)
+    {
+      /* User failed to respond to verification query.  Bye! */
+      if (!configvals->binconfirm)
+	me->p_stats.st_flags |= ST_CYBORG;	/* mark for reference 7/27/91
+						 * TC */
+      else
+      {
+	me->p_explode = 10;
+	me->p_whydead = KQUIT;
+	me->p_status = PEXPLODE;
+	fprintf(stderr, "User binary failed to verify\n");
+	if (RSA_Client == 1)
+	  warning("No customized binaries.  Please use a blessed one.");
+	else if (RSA_Client == 2)
+	  warning("Wrong Client Version Number!");
+	else
+	  warning("You need a spiffy new RSA client for this server!");
+      }
+    }
+  }
+}
+#endif				/* AUTHORIZE */
+
+void
+intrupt()
+{
+#ifdef AUTHORIZE
+  check_authentication();
+#endif
+
+  if (me->p_status == PFREE)
+  {
+    me->p_ghostbuster = 0;
+    me->p_status = PDEAD;
+  }
+  /* Change 4/14/91 TC: fixing 2 players/1 slot bug here, since this is */
+  /* where the ghostbust check is */
+
+#if 0
+  if ((strcmp(me->p_login, start_login) != 0) ||
+      (strcmp(me->p_name, start_name) != 0))
+  {
+    struct pstatus_spacket pstatus;
+    goAway = 1;			/* get rid of this client! */
+    warning("Sorry, your slot has been taken by another player.");
+    pstatus.type = SP_PSTATUS;
+    pstatus.pnum = 0;
+    pstatus.status = PDEAD;
+    sendClientPacket(&pstatus);
+    longjmp(env, 0);
+  }
+#endif
+
+  if (me->p_status == PEXPLODE || me->p_status == PDEAD)
+  {
+    inputMask = 0;
+  }
+  if (((me->p_status == PDEAD) || (me->p_status == POUTFIT))
+      && (me->p_ntorp <= 0) && (me->p_nplasmatorp <= 0))
+  {
+    death();
+  }
+  auto_features();
+  updateClient();
+}
+
+
+static void
+selfdestruct_countdown()
+{
+  char buf[180];
+  if (!(me->p_flags & PFSELFDEST))
+    return;
+
+  if ((me->p_updates >= selfdest) ||
+      ((me->p_flags & PFGREEN) && (me->p_damage == 0)
+       && (me->p_shield == me->p_ship.s_maxshield)))
+  {
+    me->p_flags &= ~PFSELFDEST;
+    me->p_explode = 10;
+    me->p_whydead = KQUIT;
+    me->p_status = PEXPLODE;
+  }
+  else
+  {
+    switch ((selfdest - me->p_updates) / 10)
+    {
+     case 5:
+     case 4:
+      imm_warning("You notice everyone on the bridge is staring at you.");
+      break;
+     default:
+      sprintf(buf, "Stand by ... Self destruct in %d seconds",
+	      (selfdest - me->p_updates) / 10);
+      imm_warning(buf);
+      break;
+    }
+  }
+}
+
+static void
+warp_powerup()
+{
+  static int sequence = 0;
+  int time = myship->s_warpinittime;
+
+  if (me->p_warptime <= 0 && sequence == 0)
+    return;
+
+  if (me->p_speed > myship->s_warpprepspeed && !(me->p_flags & PFWARP))
+  {
+    if (sequence < 1)
+    {
+      warning("Prepping for warp jump");
+      sequence = 1;
+    }
+  }
+  else if (me->p_warptime >= time * 9 / 10 /* 37 */ )
+  {
+    if (sequence < 2)
+    {
+      warning("Starting power buildup for warp");
+      sequence = 2;
+    }
+  }
+  else if (me->p_warptime >= time * 3 / 4 /* 30 */ )
+  {
+    if (sequence < 3)
+    {
+      imm_warning("Warp power buildup at 30%");
+      sequence = 3;
+    }
+  }
+  else if (me->p_warptime >= time * 3 / 5 /* 23 */ )
+  {
+    if (sequence < 4)
+    {
+      imm_warning("Warp power buildup at 60%");
+      sequence = 4;
+    }
+  }
+  else if (me->p_warptime >= time * 2 / 5 /* 16 */ )
+  {
+    if (sequence < 5)
+    {
+      imm_warning("Warp power buildup at 90%");
+      sequence = 5;
+    }
+  }
+  else if (me->p_warptime >= time * 1 / 5 /* 8 */ )
+  {
+    if (sequence < 6)
+    {
+      imm_warning("Commander Hoek: `Prepare to surge to sub-light speed'");
+      sequence = 6;
+    }
+  }
+  else if (me->p_warptime == 0)
+  {
+    warning((me->p_flags & PFWARP) ? "Engage" : "Warp drive aborted");
+    sequence = 0;
+  }
+}
+
+static void
+refit_countdown()
+{
+  char buf[120];
+  static int lastRefitValue = 0;/* for smooth display */
+
+  if (!(me->p_flags & PFREFITTING))
+    return;
+
+  if (lastRefitValue != (rdelay - me->p_updates) / 10)
+  {
+    lastRefitValue = (rdelay - me->p_updates) / 10;	/* CSE to the rescue? */
+    switch (lastRefitValue)
+    {
+     case 3:
+     case 2:
+      sprintf(buf, "Engineering:  Energizing transporters in %d seconds", lastRefitValue);
+      warning(buf);
+      break;
+     case 1:
+      warning("Engineering:  Energize. [ SFX: chimes ]");
+      break;
+     case 0:
+      switch (lrand48() % 5)
+      {
+       case 0:
+	warning("Wait, you forgot your toothbrush!");
+	break;
+       case 1:
+	warning("Nothing like turning in a used ship for a new one.");
+	break;
+       case 2:
+	warning("First officer:  Oh no, not you again... we're doomed!");
+	break;
+       case 3:
+	warning("First officer:  Uh, I'd better run diagnostics on the escape pods.");
+	break;
+       case 4:
+	warning("Shipyard controller:  `This time, *please* be more careful, okay?'");
+	break;
+      }
+      break;
+    }
+  }
+}
+
+static void
+backstab_countdown()
+{
+  static int lastWarValue = 0;
+
+  if (!(me->p_flags & PFWAR))
+    return;
+
+  if (lastWarValue != (delay - me->p_updates) / 10)
+  {
+    char *str = 0;
+    lastWarValue = (delay - me->p_updates) / 10;	/* CSE to the rescue? */
+    if (lastWarValue == 0)
+    {
+      static char buf[1024];
+      static char *msgs[7] = {
+	"tires on the ether",
+	"Klingon bitmaps are ugly",
+	"Federation bitmaps are gay",
+	"all admirals have scummed",
+	"Mucus Pig exists",
+	"guests advance 5x faster",
+	"Iggy has infinite fuel",
+      };
+      sprintf(buf, "First Officer: laws of the universe, like '%s'.",
+	      msgs[lrand48() % 7]);
+      str = buf;
+    }
+    else if (lastWarValue <= 9)
+    {
+      static char *msgs[10] = {
+	"First Officer:  Easy, big guy... it's just one of those mysterious",
+	"Weapons officer:  Bah! [ bangs fist on inoperative console ]",
+	"Weapons officer:  Just to twiddle a few bits of the ship's memory?",
+	"Weapons officer:  ...the whole ship's computer is down?",
+	"Weapons officer:  Not again!  This is absurd...",
+      };
+      str = msgs[(lastWarValue - 1) / 2];
+    }
+    else
+    {
+      str = "urk";
+    }
+    if (str)
+    {
+      warning(str);
+    }
+  }
+}
+
+static void
+bombing_info()
+{
+  char buf[120];
+
+  if (!(me->p_flags & PFBOMB))
+    return;
+
+  if (planets[me->p_planet].pl_armies < 5)
+  {
+    if (configvals->facilitygrowth)
+      imm_warning("Weapons Officer: Bombing resources off planet, sir.");
+    else
+    {
+      sprintf(buf, "Weapons Officer: Bombing is ineffective. Sensor read %d armies left.",
+	      planets[me->p_planet].pl_armies);
+      imm_warning(buf);
+    }
+  }
+  else
+  {
+    sprintf(buf, "Weapons Officer: Bombarding %s...  Sensors read %d armies left.",
+	    planets[me->p_planet].pl_name,
+	    planets[me->p_planet].pl_armies);
+    imm_warning(buf);
+  }
+}
+
+
+static void
+operate_transporters()
+{
+  char buf[120];
+  int troop_capacity = 0;
+
+  if ((me->p_ship.s_nflags & SFNARMYNEEDKILL) &&
+      (me->p_kills * myship->s_armyperkill) < myship->s_maxarmies)
+  {
+    troop_capacity = (int) (me->p_kills * myship->s_armyperkill);
+  }
+  else
+    troop_capacity = me->p_ship.s_maxarmies;
+
+  if (me->p_flags & PFBEAMUP)
+  {
+    if (me->p_flags & PFORBIT)
+    {
+      if (planets[me->p_planet].pl_armies < 1)
+      {
+	sprintf(buf, "%s: Too few armies to beam up",
+		planets[me->p_planet].pl_name);
+	warning(buf);
+	me->p_flags &= ~PFBEAMUP;
+      }
+      else if ((planets[me->p_planet].pl_armies <= 4) &&
+	       (me->p_lastman != 2))
+      {
+	strcpy(buf, "Hit beam again to beam up all armies.");
+	warning(buf);
+	me->p_flags &= ~PFBEAMUP;
+      }
+      else if (me->p_armies == troop_capacity)
+      {
+	sprintf(buf, "No more room on board for armies");
+	warning(buf);
+	me->p_flags &= ~PFBEAMUP;
+      }
+      else
+      {
+	sprintf(buf, "Beaming up.  (%d/%d)", me->p_armies, troop_capacity);
+	imm_warning(buf);
+      }
+    }
+    else if (me->p_flags & PFDOCK)
+    {
+      if (players[me->p_docked].p_armies == 0)
+      {
+	sprintf(buf, "Starbase %s: Too few armies to beam up",
+		players[me->p_docked].p_name);
+	warning(buf);
+	me->p_flags &= ~PFBEAMUP;
+      }
+      else if (me->p_armies >= troop_capacity)
+      {
+	sprintf(buf, "No more room on board for armies");
+	warning(buf);
+	me->p_flags &= ~PFBEAMUP;
+      }
+      else
+      {
+	sprintf(buf, "Beaming up.  (%d/%d)", me->p_armies, troop_capacity);
+	imm_warning(buf);
+      }
+    }
+  }
+  if (me->p_flags & PFBEAMDOWN)
+  {
+    if (me->p_armies == 0)
+    {
+      if (me->p_flags & PFDOCK)
+      {
+	sprintf(buf, "No more armies to beam down to Starbase %s.",
+		players[me->p_docked].p_name);
+	warning(buf);
+      }
+      else
+      {
+	sprintf(buf, "No more armies to beam down to %s.",
+		planets[me->p_planet].pl_name);
+	warning(buf);
+      }
+      me->p_flags &= ~PFBEAMDOWN;
+    }
+    else if (me->p_flags & PFORBIT)
+    {
+      sprintf(buf, "Beaming down.  (%d/%d) %s has %d armies left",
+	      me->p_armies,
+	      troop_capacity,
+	      planets[me->p_planet].pl_name,
+	      planets[me->p_planet].pl_armies);
+      imm_warning(buf);
+    }
+    else if (me->p_flags & PFDOCK)
+    {
+      if (players[me->p_docked].p_armies ==
+	  players[me->p_docked].p_ship.s_maxarmies)
+      {
+	sprintf(buf, "Transporter Room:  Starbase %s reports all troop bunkers are full!",
+		players[me->p_docked].p_name);
+	warning(buf);
+	me->p_flags &= ~PFBEAMDOWN;
+      }
+      else
+      {
+	sprintf(buf, "Transfering ground units.  (%d/%d) Starbase %s has %d armies left",
+		me->p_armies,
+		troop_capacity,
+		players[me->p_docked].p_name,
+		players[me->p_docked].p_armies);
+	imm_warning(buf);
+      }
+    }
+  }
+}
+
+#if 0
+static void
+reduce_speed()
+{
+  if (me->p_desspeed > myship->s_imp.maxspeed)
+  {
+    /* drop out of warp */
+    me->p_desspeed = myship->s_imp.maxspeed + 1;
+    me->p_flags &= ~(PFWARP | PFAFTER);
+    warning("Approaching planet, dropping out of warp");
+  }
+  set_speed(me->p_desspeed - 1, 0);
+}
+#endif
+
+static void
+decelerate_at_range(dist)
+  int dist;
+{
+  int speed;
+  int maximp = myship->s_imp.maxspeed;
+
+#define FUDGEFACT	1.15
+
+  if (me->p_flags & PFWARP)
+  {
+    if (configvals->warpdecel)
+    {
+      /*
+       * int impdist = 1000*(maximp*10*WARP1*maximp*10*WARP1)/ (2 *
+       * myship->s_imp.dec*10*10*warp1);
+       */
+
+      int impdist = FUDGEFACT * (maximp * maximp - 2 * 2) * 500 * WARP1 / myship->s_imp.dec;
+
+      for (speed = maximp;
+	   speed < me->p_desspeed && speed < me->p_speed;
+	   speed++)
+      {
+	int decdist;
+	decdist = FUDGEFACT * 500 * ((speed * speed) - (maximp * maximp)) * WARP1 /
+	  myship->s_warp.dec;
+	if (dist - impdist - ENTORBDIST < decdist)
+	  break;
+      }
+      if (speed == maximp && speed < me->p_speed)
+	warning("Approaching planet, dropping out of warp");
+      if (speed < me->p_desspeed &&
+	  speed < me->p_speed)
+      {
+	/* printf("(W) curr: %d, ideal %d\n", me->p_speed, speed); */
+	me->p_desspeed = speed;
+      }
+    }
+    else
+    {
+      int impdist;
+      maximp = (3 * maximp + myship->s_warp.maxspeed) / 4;
+      impdist = FUDGEFACT * ((maximp) * (maximp) - 2 * 2) *
+	500 * WARP1 / myship->s_imp.dec;
+      if (dist - impdist - ENTORBDIST < 0)
+	me->p_flags &= ~PFWARP;
+    }
+  }
+  else
+  {
+    for (speed = 2; speed < me->p_desspeed && speed < me->p_speed; speed++)
+    {
+      int decdist;
+      decdist = FUDGEFACT * 500 * (speed * speed - 2 * 2) * WARP1 / myship->s_imp.dec;
+      if (dist - ENTORBDIST < decdist)
+	break;
+    }
+    if (speed < me->p_desspeed &&
+	speed < me->p_speed)
+    {
+      /* printf("(I) curr: %d, ideal %d\n", me->p_speed, speed); */
+      me->p_desspeed = speed;
+    }
+  }
+}
+
+static void
+follow_player()
+{
+  struct player *pl;
+  int dist;
+
+  if (!(me->p_flags & PFPLOCK))
+    return;
+
+  /* set course to player x */
+
+  pl = &players[me->p_playerl];
+  if (pl->p_status != PALIVE)
+    me->p_flags &= ~PFPLOCK;
+  if (allows_docking(pl->p_ship))
+  {
+    dist = ihypot(me->p_x - pl->p_x, me->p_y - pl->p_y);
+
+    decelerate_at_range(dist);
+
+    if ((dist < DOCKDIST) && (me->p_speed <= 2))
+    {
+      orbit();
+      me->p_flags &= ~PFPLOCK;
+    }
+  }
+  if (me->p_flags & PFPLOCK)
+    set_course(newcourse(pl->p_x, pl->p_y));
+
+}
+
+static void
+follow_planet()
+{				/* follow a planet?  How silly. Will it
+				 * perhaps outmaneuver you? */
+  struct planet *pln;
+  int dist;
+  /* int speed = me->p_speed; */
+
+  if (!(me->p_flags & PFPLLOCK))
+    return;
+
+  /* set course to planet x */
+
+  pln = &planets[me->p_planet];
+  dist = ihypot(me->p_x - pln->pl_x, me->p_y - pln->pl_y);
+
+  decelerate_at_range(dist);
+
+  if ((dist < ENTORBDIST) && (me->p_speed <= 2))
+  {
+    orbit();
+    me->p_flags &= ~PFPLLOCK;
+  }
+  else
+  {
+    int course = newcourse(pln->pl_x, pln->pl_y);
+    set_course(course);
+  }
+}
+
+/*
+ * These are routines that need to be done on interrupts but don't belong in
+ * the redraw routine and particularly don't belong in the daemon.
+ */
+
+void
+auto_features()
+{
+  selfdestruct_countdown();
+
+  warp_powerup();
+
+  /* provide a refit countdown 4/6/92 TC */
+  refit_countdown();
+
+  /* provide a war declaration countdown 4/6/92 TC */
+  backstab_countdown();
+
+  /* give certain information about bombing or beaming */
+  bombing_info();
+
+  operate_transporters();
+
+  if (me->p_flags & PFREPAIR)
+  {
+    if ((me->p_damage == 0) && (me->p_shield == me->p_ship.s_maxshield))
+      me->p_flags &= ~PFREPAIR;
+  }
+  if (me->p_status != POBSERVE)
+  {
+    /* these mess up the observer mode */
+    follow_player();
+    follow_planet();
+  }
+
+#if defined(CLUECHECK1) || defined(CLUECHECK2)
+  if (
+#ifdef LEAGUE_SUPPORT
+      !status2->league &&
+#endif
+      configvals->cluecheck)
+    countdown_clue();
+#endif
+}
+
+int
+newcourse(x, y)
+  int x, y;
+{
+  if (x == me->p_x && y == me->p_y)
+    return 0;
+
+  return (int) (atan2((double) (x - me->p_x),
+		      (double) (me->p_y - y)) / 3.14159 * 128.);
+}