#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/file.h>
#include <math.h>
#include <sys/ipc.h>
#include <errno.h>
#include <pwd.h>
#include <ctype.h>
#include "defs.h"
#include "struct.h"
#include "data.h"

void getship();

char *names[] = { "Neutral", "Fed", "Rom", "", "Kli", "", "", "", "Ori"};

main(argc, argv)
int argc;
char **argv;
{
    int player;
    char buf[1000];
    int c;

    if (argc < 2)
	Usage();
    getpath();

    openmem(0);

    getshipdefaults();

    player=atoi(argv[1]);
    if ((player == 0) && (*argv[1] != '0')) {
	c = *argv[1];
	if (c >= 'a' && c <= 'j')
	    player = c - 'a' + 10;
	else {
	    Usage();
	}
    }
    if (players[player].p_status != PALIVE) {
	if (argc > 2)
	    if (*argv[2] == 'F') 
             /* forceShutdown the ntserv, which triggers freeslot */
             if (players[player].p_process > 1) {
                  ERROR(1,("xtkilling player %i, process %i\n",player,players[player].p_process));
                  if (kill (players[player].p_process, SIGTERM) < 0) 
		    freeslot(&players[player]);
		  exit(0); 
             } else {
 	        freeslot(&players[player]);
		exit(0);
	      }
	printf("Slot is not alive.\n");
	exit(1);
      }
    if (argc > 2)
	switch (*argv[2]) {
	  case 'T': {
	      int team;
	      
	      switch (argv[2][1]) {
		case 'f': team = 1; break;
		case 'r': team = 2; break;
		case 'k': team = 4; break;
		case 'o': team = 8; break;
		default:  team = 0;
	      }	    
	      players[player].p_team = team;
	      players[player].p_hostile &= ~team;
	      players[player].p_swar &= ~team;
	      players[player].p_war &= ~team;
	      sprintf(buf, "GOD->ALL Change:  %2s is now a %s.",
		      players[player].p_mapchars,
		      names[team]);
	      pmessage(buf, 0, MALL);
	      sprintf(players[player].p_mapchars, "%c%c", 
		      teamlet[players[player].p_team], shipnos[player]);
	      sprintf(players[player].p_longname, "%s (%s)", 
		      players[player].p_name, players[player].p_mapchars);
	  }
	    break;
	  case 'e':
	    sprintf(buf, "GOD->ALL %s has been ejected from the game.", 
		    players[player].p_longname);		    
	    players[player].p_whydead=KQUIT;
	    players[player].p_explode=10;
	    players[player].p_status=3;
	    players[player].p_whodead=0;
	    pmessage(buf, 0, MALL);
	    break;
	  case 't':
	    switch(argv[2][1]) {
	      case 'f':
		players[player].p_x = planets[0].pl_x;
		players[player].p_y = planets[0].pl_y;
		break;
	      case 'r':
		players[player].p_x = planets[10].pl_x;
		players[player].p_y = planets[10].pl_y;
		break;
	      case 'k':
		players[player].p_x = planets[20].pl_x;
		players[player].p_y = planets[20].pl_y;
		break;
	      case 'o':
		players[player].p_x = planets[30].pl_x;
		players[player].p_y = planets[30].pl_y;
		break;
	      case 'c':
		players[player].p_x = GWIDTH/2;
		players[player].p_y = GWIDTH/2;
		break;
	      default:
		printf("Valid teleports: frkoc.\n");
		exit(1);
	    }
	    break;
	  case 's':
	     switch (argv[2][1]) {
	       case 'a': getship(&players[player].p_ship, ASSAULT); break;
	       case 'b': getship(&players[player].p_ship, BATTLESHIP); break;
	       case 'c': getship(&players[player].p_ship, CRUISER); break;
	       case 'd': getship(&players[player].p_ship, DESTROYER); break;
	       case 's': getship(&players[player].p_ship, SCOUT); break;
	       case 'o': getship(&players[player].p_ship, STARBASE); break;
	       case 'A': getship(&players[player].p_ship, ATT); break;
	       default:
		 printf("Valid ship types: abcdsoA.\n");
		 exit(1);
		 break;
	    }
	    players[player].p_damage = 0;
	    players[player].p_shield = players[player].p_ship.s_maxshield;
	    players[player].p_wtemp = 0;
	    players[player].p_etemp = 0;
	    players[player].p_fuel = players[player].p_ship.s_maxfuel;
	    break;
	  case 'p':		/* puck? */
	    players[player].p_ship.s_tractstr = 1;
	    players[player].p_ship.s_torpdamage = -1;
	    players[player].p_ship.s_plasmadamage = -1;
	    players[player].p_ship.s_phaserdamage = -1;
	    players[player].p_hostile = 0;
	    players[player].p_swar = 0;
	    players[player].p_war = 0;
	    players[player].p_team = 0;	/* indep */
	    players[player].p_ship.s_type = STARBASE;
	    players[player].p_ship.s_mass = 200;
	    players[player].p_ship.s_repair = 30000;
	    players[player].p_ship.s_maxspeed = 0;
	  case 'S':		/* super ship */
	    players[player].p_ship.s_maxshield = 750;
	    players[player].p_shield = 750;
	    players[player].p_ship.s_maxdamage = 750;
	    players[player].p_ship.s_maxegntemp = 5000;
	    break;
	  case 'D':		/* demote */
	    --players[player].p_stats.st_rank;
	    sprintf(buf, "GOD->ALL %2s was (temporarily) demoted for rank normalization purposes.",
		    players[player].p_mapchars);
	    pmessage(buf, 0, MALL);
	    break;
	  case 'P':
	    ++players[player].p_stats.st_rank;
	    break;
	  case 'k':
	    players[player].p_kills += 1.0;
	    break;
	  case 'a':
	    players[player].p_armies += 6;
	    break;
	  case 'C':
	    teams[players[player].p_team].s_surrender = 6;
	    break;
	  case 'h':
	    players[player].p_shield = 0;
	    players[player].p_damage = players[player].p_ship.s_maxdamage/2;
	    break;
	  case 'R':
	    if (players[player].p_flags & PFROBOT) {
		players[player].p_ship.s_type = STARBASE;
		players[player].p_whydead=KPROVIDENCE;
		players[player].p_explode=10;
		players[player].p_status=3;
		players[player].p_whodead=0;
	    }
	    break;
	  case 'L':
	    players[player].p_stats.st_sblosses--;
	    break;
	  default:
	    Usage();
	}			/* end switch */
    else {
	sprintf(buf, "GOD->ALL %s was utterly obliterated.", 
		players[player].p_longname);
	players[player].p_ship.s_type = STARBASE;
	players[player].p_whydead=KPROVIDENCE;
	players[player].p_explode=10;
	players[player].p_status=3;
	players[player].p_whodead=0;
	pmessage(buf, 0, MALL);
    }
    return 1;		/* satisfy lint */
}

pmessage(str, recip, group)
char *str;
int recip;
int group;
{
    struct message *cur;
    if (++(mctl->mc_current) >= MAXMESSAGE)
	mctl->mc_current = 0;
    cur = &messages[mctl->mc_current];
    cur->m_no = mctl->mc_current;
    cur->m_flags = group;
    cur->m_time = 0;
    cur->m_from = 255; /* change 3/30/91 TC */
    cur->m_recpt = recip;
    (void) sprintf(cur->m_data, "%s", str);
    cur->m_flags |= MVALID;
}

Usage()
{
    printf("\
    xtkill [0-9a-j] <mode><mode option>\n\
\n\
    where <mode> is one of :\n\
      e(ject from game)             (simulates self-destruct)\n\
      s(hip class change)[abcdosA]  (A = ATT)\n\
      t(eleport to quadrant)[frkoc] (c = center of galaxy)\n\
      S(uper)                       (big shields/max damage/max etmp)\n\
      T(eam change)[frko]           (no team == independent)\n\
      D(emote)                      (-1 to rank)\n\
      P(romote)                     (+1 to rank)\n\
      F(ree slot)                   (bypasses 6 minute ghostbuster timeout)\n\
      k(ills increment)             (+1 kill)\n\
      h(arm)                        (no shields, 50%% damage)\n\
      a(rmies increment)            (+6 armies)\n\
      C(lock, surrender -- set it)  (to 6 minutes (debugging aid))\n\
      L(oss adjust, SB (-1))        (in case you toast an SB accidentally)\n\
      R(obot obliterate)            (like obliterate, but only for robots)\n\
      (no mode == obliterate)\n\
");
    exit(1);
}
