/* puckmove.c
*/
/*
Modified for use with guzzler code by Michael Kantner (MK)
Base upon code ftp'd from hobbes.ksu.ksu.edu on 9-9-93
Please mail all bugs, patches, comments to kantner@hot.caltech.edu
Updated extensively
Credits to Terence Chang for writing the initial version of puck
to Brick Verser for maintaining and improving it
to numerous others for comments and criticism
*/
#include "copyright.h"
#include <stdio.h>
#include <signal.h>
#include <math.h>
#include "defs.h"
#include "struct.h"
#include "data.h"
#include "puckdefs.h"
#ifdef PUCK_FIRST
#include <sys/sem.h>
extern struct sembuf sem_puck_op[1];
extern int sem_puck;
#endif
#define WEAKER_STR 2 /* integer factor to divide tractstr down */
#define WEAKER_RNG 1.25 /* factor to divide tractrng down */
#define SIZEOF(s) (sizeof (s) / sizeof (*(s)))
#define AVOID_TIME 4
#define AVOID_CLICKS 200
#define NORMALIZE(d) (((d) + 256) % 256)
#define E_INTRUDER 0x01
#define E_TSHOT 0x02
#define E_PSHOT 0x04
#define E_TRACT 0x08
#define NOENEMY (struct Enemy *) -1
struct Enemy {
int e_info;
int e_dist;
unsigned char e_course; /* course to enemy */
unsigned char e_edir; /* enemy's current heading */
unsigned char e_tcourse; /* torpedo intercept course to enemy */
unsigned int e_flags;
int e_tractor; /* who he's tractoring/pressoring */
int e_phrange; /* his phaser range */
int e_trrange; /* his tractor range */
struct player *pstruct;
};
typedef struct Track { /* our record of this player */
int t_x;
int t_y;
int t_status;
unsigned int t_goals;
unsigned int t_assists;
unsigned int t_seconds;
unsigned int t_flags; /* MK - new, additional flags */
} Track;
#define PU_SITOUT 0x0001
Track tracks[MAXPLAYER];
/* puck junk */
#define END_OF_PERIOD 20*60*PERSEC
#define PERIODS_PER_GAME 3
#define FACEOFF (30+TELEPORT_DELAY)*PERSEC
#define DEFLECT_DIST 750
#define SHOTRANGE 3000
#define SHOTSPEED 40
#define DEFLECT_SPEED 25 /* ***BAV*** */
#define SHOOTABLE_FACTOR 3
#define DXDISPLACE 8000 /* ***BAV*** was 5000 */
#define DXOFFSET 7000 /* ***BAV*** was 10000 */
#define DYDISPLACE 2000
#define DISPLACE 5000 /* Used for offside and home planet entry */
#define OFFSET 10000
#define SITOUT_X 1000 /* Distance from edge for sitout */
int scores[MAXTEAM+1];
int currp[MAXTEAM+1];
int lastp[MAXTEAM+1];
int faceoff = FACEOFF; /* "faceoff" mode */
int period = 1;
int roboclock = 0;
int short_game = 0; /* 0 = long game, 1 = short game */
#define MESSFUSEVAL 50*PERSEC
static int messfuse = MESSFUSEVAL;
static char tmessage[110];
char* puckie_messages[] = {
"Look at $n work that biscuit!",
"Can $n shoot his way out of a paper bag?",
"$n has the puck at $w.",
"$n takes possession for the $ts at $w.",
"This rink isn't big enough for the two of us, $n.",
"The $ts are considering trading away $n.",
"$n is actually the $t mascot.",
"Look out, $n is racing by $w.",
"$n is looking tired.",
"Attention $t shoppers, Blue Light special at $w.",
"$n shows off some impressive stickwork at $w.",
"$n slices through $w!",
"$n takes command of the puck.",
"$n has turned in an impressive performance tonight.",
"You know, the $ts should have retired $n ages ago.",
"$n weaves through traffic...",
};
extern int debug;
extern int oldmctl;
extern int hostile;
extern int sticky;
extern int practice;
extern int polymorphic;
extern int target; /* robotII.c 7/27/91 TC */
extern int phrange; /* robotII.c 7/31/91 TC */
extern int trrange; /* robotII.c 8/2/91 TC */
extern int length;
extern struct planet *oldplanets;
void cleanup(void);
void do_teleport_home(void);
void do_peace(void);
void do_msg_check(void);
void do_war(void);
void place_anncer(void);
void do_offsides(void);
void puck_rules(void);
void do_goal(int);
void do_score(void);
void do_faceoff(void);
void woomp(void);
void player_maint(void);
void player_bounce(void);
void exitRobot(void);
void light_planets(void);
unsigned char getcourse();
char *robo_message();
char *puckie_message(); /* added 8/2/91 TC */
int get_shotage(float);
#ifdef HAVE_GOALIE
struct player *ori_goalie = NULL;
struct player *kli_goalie = NULL;
static int ori_old_ship_type, kli_old_ship_type;
#endif
#ifdef OFFSIDE
int team_offsides = 0;
#endif
#ifdef PUCK_FIRST
void _rmove(void);
void rmove(void)
{
_rmove();
semop(sem_puck, sem_puck_op, 1);
}
void _rmove(void)
#else
void rmove(void)
#endif
{
extern struct Enemy *get_nearest();
struct Enemy *enemy_buf;
static int lastx;
static int lasty;
static int shotage;
static int shotby;
static int pauseticks;
/***** Start The Code Here *****/
HANDLE_SIG(SIGALRM,rmove);
me->p_ghostbuster = 0; /* keep ghostbuster away */
anncer->p_ghostbuster = 0; /* keep ghostbuster away */
/* If the game is paused, do very little */
if (ispaused){
pauseticks++;
if ((pauseticks % (PERSEC)) == 0) do_msg_check();
if ((pauseticks % (10*PERSEC)) == 0)
messAll(me->p_no,roboname,"Game is Paused, unpause to continue");
return;
}
/* Make sure game/period has not ended */
/* This is done first to allow for a good short_game */
if (roboclock >= END_OF_PERIOD) {
if (period >= PERIODS_PER_GAME) {
messAll(anncer->p_no,roboname,"#############################");
messAll(anncer->p_no,roboname,"#");
messAll(me->p_no, roboname,"# END OF GAME.");
messAll(anncer->p_no,roboname,"#");
woomp();
} else {
messAll(anncer->p_no,roboname,"#");
messAll(me->p_no, roboname,"# END OF PERIOD.");
messAll(anncer->p_no,roboname,"#");
woomp();
}
do_score();
roboclock = 0;
#ifdef OFFSIDE
team_offsides = 0;
planet_offsides(0);
#endif
me->p_ship.s_type = STARBASE;
me->p_whydead=KPLASMA;
me->p_explode=10;
me->p_status=PEXPLODE;
me->p_whodead=0;
if (period >= PERIODS_PER_GAME) {
if (scores[KLI] > scores[ORI])
messAll(me->p_no, roboname,"# Klingons win!");
else if (scores[ORI] > scores[KLI])
messAll(me->p_no, roboname,"# Orions win!");
else messAll(me->p_no,roboname,"# Tie game!");
messAll(anncer->p_no, roboname,"#############################");
scores[ORI] = 0;
scores[KLI] = 0;
period = 0;
length--;
if (length == 0)
cleanup();
do_score();
}
period++;
}
/* Check that I'm alive */
/* Messages are not checked when puck is not alive! */
if (me->p_status != PALIVE){ /*So I'm not alive now...*/
if (short_game) roboclock++;
if (me->p_status == PEXPLODE) { /*Let Puck Go BOOM */
player_bounce();
player_maint();
return; /*Do nothing else until done exploding*/
}
if (me->p_whydead == KPLASMA) { /*assume due to goal scored*/
me->p_status = PALIVE;
me->p_ship.s_type = SCOUT;
do_faceoff();
#ifdef OFFSIDE
planet_offsides(0); /*RESET Planets, just in case*/
#endif
player_bounce();
player_maint();
return;
}
cleanup(); /*Puck is dead for some unpredicted reason like xsg */
}
/* first priority: is this faceoff mode? */
/* Messages are checked once per second here */
if (faceoff > 0) {
int ticks_left;
if (short_game){
roboclock++;
ticks_left = END_OF_PERIOD - roboclock - faceoff;
}
else
ticks_left = END_OF_PERIOD - roboclock;
if (ticks_left <= 10*PERSEC) {
roboclock = END_OF_PERIOD;
messAll(me->p_no,roboname," Less than 10 seconds to score, Period Ends!");
}
if ((faceoff % (PERSEC)) == 0) do_msg_check();
faceoff--;
if (faceoff == 0) {
int i;
do_war(); /* open hostilities */
do_offsides();
for (i = 0; i <= MAXTEAM; i++) {
currp[i] = -1; lastp[i] = -1;
}
messAll(me->p_no,roboname,"<thunk!>");
me->p_x = 45000 + random()%10000; /* reappear */
me->p_y = R_MID;
me->p_speed = 0; /* *** BAV *** */
me->p_desspeed = 0;
me->p_subspeed = 0;
lasty = R_MID; /* avoid boing problems */
lastx = me->p_x;
shotby = -1; /* to find winner of faceoff */
}
else if ((faceoff % (10*PERSEC)) == 0) {
/* maintain peace */
do_peace();
messAll(me->p_no,roboname,"Faceoff in %d seconds.", faceoff/PERSEC);
}
if (faceoff == FACEOFF-TELEPORT_DELAY*PERSEC) { /* move people home */
do_teleport_home();
}
player_bounce(); /* keep players where they belong */
player_maint(); /* update necessary stats and info */
return; /* Do nothing else during faceoff mode */
}
/* Announce Period Clock Countdown */
/* Some useful bookkeeping stuff here */
if ((roboclock % (PERSEC*2)) == 0) {
place_anncer(); /*Place the announcer */
do_msg_check(); /*Check msgs every 2 sec*/
}
if ((roboclock % (PERSEC*10)) == 0) do_war();
if ((roboclock % (PERSEC*120)) == 0) {
puck_rules();
do_score();
}
if (roboclock >= (END_OF_PERIOD - 30*PERSEC)){
int timetogo = END_OF_PERIOD - roboclock;
if ( (timetogo % (PERSEC*10)) == 0)
messAll(me->p_no,roboname," %2i seconds left in the %s",
(timetogo/PERSEC), period>=PERIODS_PER_GAME ? "game":"period");
if ( (timetogo < 10*PERSEC) && ((timetogo % PERSEC) == 0) )
messAll(anncer->p_no,roboname," %i second%s left in the %s",
(timetogo/PERSEC),timetogo==PERSEC ? "":"s",
period>=PERIODS_PER_GAME ? "game":"period");
}
/* So we get to here: Then puck is in play, alive, and not faceoff */
roboclock++; /* time updated PERSEC times per second */
/* second priority: is anyone offsides */
#ifdef OFFSIDE
if ((lasty >= KLI_B) && (me->p_y < KLI_B)){
messAll(me->p_no,roboname," The puck crosses the Kli blue line");
check_offsides(ORI,1);
}
else if ((lasty <= ORI_B) && (me->p_y > ORI_B)){
messAll(me->p_no,roboname," The puck crosses the Ori blue line");
check_offsides(KLI,1);
}
else if ((me->p_y >= KLI_B) && (lasty < KLI_B)){
messAll(me->p_no,roboname," The puck is in the neutral zone");
planet_offsides(0); team_offsides = 0;
}
else if ((me->p_y <= ORI_B) && (lasty > ORI_B)){
messAll(me->p_no,roboname," The puck is in the neutral zone");
planet_offsides(0); team_offsides = 0;
}
else if (team_offsides!=0){
check_offsides(team_offsides,2);
}
/* At this point, team_offsides is set to whichever team is offsides */
#endif
/* third priority: did we enter a goal? */
if ((me->p_y < KLI_G) && (me->p_x > G_LFT) && (me->p_x < G_RGT)
&& (lasty >= KLI_G)) {
#ifdef OFFSIDE
if (team_offsides==ORI){
messAll(me->p_no,roboname,"The ORIONS have committed an offsides violation");
penalty_offsides(team_offsides);
}
else{
#endif
do_goal(ORI);
#ifdef OFFSIDE
}
#endif
player_bounce();
player_maint();
return;
}
if ((me->p_y > ORI_G) && (me->p_x > G_LFT) && (me->p_x < G_RGT)
&& (lasty <= ORI_G)) {
#ifdef OFFSIDE
if (team_offsides==KLI){
messAll(me->p_no,roboname,"The KLINGONS have committed an offsides violation");
penalty_offsides(team_offsides);
}
else{
#endif
do_goal(KLI);
#ifdef OFFSIDE
}
#endif
player_bounce();
player_maint();
return;
}
/* do left/right bounce */
if (me->p_x < RINK_LEFT) {
me->p_x = RINK_LEFT + (RINK_LEFT - me->p_x);
me->p_dir = me->p_desdir = 64 - (me->p_dir - 192);
shotby = -2;
} else if (me->p_x > RINK_RIGHT) {
me->p_x = RINK_RIGHT - (me->p_x - RINK_RIGHT);
me->p_dir = me->p_desdir = 192 - (me->p_dir - 64);
shotby = -2;
}
/* do goal bounce */
if (((me->p_y > ORI_G) && (me->p_y < ORI_E)) ||
((me->p_y < KLI_G) && (me->p_y > KLI_E))) {
if ((me->p_x <= G_RGT) && (lastx >= G_RGT)) {
if (me->p_speed > 0)
messAll(anncer->p_no,roboname,"Boing! Off right side of goal.");
me->p_x = G_RGT + (G_RGT - me->p_x);
me->p_dir = me->p_desdir = 64 - (me->p_dir - 192);
shotby = -2;
} else if ((me->p_x >= G_LFT) && (lastx <= G_LFT)) {
if (me->p_speed > 0)
messAll(anncer->p_no,roboname,"Boing! Off left side of goal.");
me->p_x = G_LFT - (me->p_x - G_LFT);
me->p_dir = me->p_desdir = 192 - (me->p_dir - 64);
shotby = -2;
}
}
if ((me->p_x > G_LFT) && (me->p_x < G_RGT)) {
if ((me->p_y > KLI_E) && (lasty <= KLI_E)) {
if (me->p_speed > 0)
messAll(anncer->p_no,roboname,"Boing! Off back of Kli goal.");
me->p_dir = me->p_desdir = 0 - (me->p_dir - 128);
me->p_y = KLI_E - (me->p_y - KLI_E);
shotby = -2;
} else if ((me->p_y < ORI_E) && (lasty >= ORI_E)) {
if (me->p_speed > 0)
messAll(anncer->p_no,roboname,"Boing! Off back of Ori goal.");
me->p_dir = me->p_desdir = 128 - me->p_dir;
me->p_y = ORI_E + (ORI_E - me->p_y);
shotby = -2;
}
}
/* keep all players in the rink */
/* and do some other bouncing */
player_bounce();
player_maint();
lastx = me->p_x;
lasty = me->p_y;
/* inertia: slow down */
if (me->p_desspeed > 0) {
me->p_desspeed = ((float)SHOTSPEED) * (1.0/((float)(roboclock-shotage)*2/PERSEC/3.5+1.0));
me->p_speed = me->p_desspeed;
}
/* shots: track possession, check for close pressorers */
enemy_buf = get_nearest();
if ((enemy_buf == NULL) || (enemy_buf == NOENEMY)) {
me->puck_carrier = -1;
return;
}
/* Set puck_carrier, used in redraw.c to see ship stats of the ship
currently in possesion of the puck. Entertaining for observers
locked on to puck.
*/
me->puck_carrier = enemy_buf->pstruct->p_no;
if (isInPossession(enemy_buf)) {
#ifdef OFFSIDE
if (enemy_buf->pstruct->p_team == team_offsides){
messAll(me->p_no,roboname,"%s (%2s) committed an offsides violation.",
enemy_buf->pstruct->p_name,enemy_buf->pstruct->p_mapchars);
penalty_offsides(team_offsides);
}
#endif
/* random commentary */
if ((random() % messfuse) == 0) {
messAll(anncer->p_no,roboname,puckie_message(enemy_buf->pstruct));
messfuse = MESSFUSEVAL;
} else
if (--messfuse == 0)
messfuse = 1;
/* intercepts/deflects -- stop moving puck/change dir randomly */
if (me->p_desspeed < SHOTSPEED/SHOOTABLE_FACTOR)
me->p_desspeed = 0;
else { /* deflections */
if ((enemy_buf->e_dist < DEFLECT_DIST) &&
(angdist(enemy_buf->e_course, me->p_dir) < 64) &&
(shotby != enemy_buf->e_info) )
{
messAll(me->p_no,roboname," Deflected by %s (%2s)!",
enemy_buf->pstruct->p_name,
enemy_buf->pstruct->p_mapchars);
/* Deflect in any direction. */
me->p_desdir = me->p_desdir + random() % 256;
me->p_dir = me->p_desdir;
shotby = enemy_buf->e_info;
}
}
if (currp[enemy_buf->pstruct->p_team] != enemy_buf->e_info) {
/* new guy in possession */
lastp[enemy_buf->pstruct->p_team] = currp[enemy_buf->pstruct->p_team];
currp[enemy_buf->pstruct->p_team] = enemy_buf->e_info;
#ifdef ANNOUNCER
messAll(me->p_no,roboname," %s (%2s) takes possession of the puck.",
enemy_buf->pstruct->p_name,
enemy_buf->pstruct->p_mapchars);
#endif
}
}
if ((enemy_buf->e_dist < SHOTRANGE) &&
(me->p_desspeed < SHOTSPEED/SHOOTABLE_FACTOR)) { /* shootable */
if (isPressoringMe(enemy_buf)) {
/* I am being shot */
int shot_faceoff = (shotby == -1);
int shot_ongoal = 0;
enemy_buf->pstruct->p_flags &= ~PFTRACT;
enemy_buf->pstruct->p_flags &= ~PFPRESS;
shotage = roboclock;
shotby = enemy_buf->e_info;
me->p_desspeed = SHOTSPEED;
me->p_speed = SHOTSPEED;
#ifdef SOCCER_SHOOT
me->p_dir = enemy_buf->e_course + 128;
me->p_desdir = enemy_buf->e_course + 128 ;
#else
me->p_dir = enemy_buf->pstruct->p_dir;
me->p_desdir = enemy_buf->pstruct->p_dir;
#endif
/* find extra information to descirbe the shot */
/* i.e.: is it on goal,etc */
if ((enemy_buf->pstruct->p_team == KLI) &&
(enemy_buf->pstruct->p_y >= ORI_B) &&
(enemy_buf->pstruct->p_y <= ORI_G) &&
(me->p_dir<=getcourse2(me->p_x,me->p_y,G_LFT,ORI_G)) &&
(me->p_dir>=getcourse2(me->p_x,me->p_y,G_RGT,ORI_G)))
shot_ongoal = 1;
if ((enemy_buf->pstruct->p_team == ORI) &&
(enemy_buf->pstruct->p_y >= KLI_G) &&
(enemy_buf->pstruct->p_y <= KLI_B)){
u_char to_left, to_right;
to_left = getcourse2(me->p_x,me->p_y,G_LFT,KLI_G);
to_right = getcourse2(me->p_x,me->p_y,G_RGT,KLI_G);
if (((me->p_dir>=to_left) && (me->p_dir<=to_right)) ||
((to_right < to_left) &&
((me->p_dir>=to_left) || (me->p_dir<=to_right))))
shot_ongoal = 1;
}
#ifndef SHOT_DESC
/* Turn off extra shot descriptions */
shot_ongoal = 0;
#endif
/* Now announce the type of shot */
if (shot_faceoff)
messAll(me->p_no,roboname," %s (%2s) wins the faceoff.",
enemy_buf->pstruct->p_name,
enemy_buf->pstruct->p_mapchars);
else if (shot_ongoal)
messAll(me->p_no,roboname," %s (%2s) shoots on goal!",
enemy_buf->pstruct->p_name,
enemy_buf->pstruct->p_mapchars);
else
messAll(me->p_no,roboname," %s (%2s) shoots!",
enemy_buf->pstruct->p_name,
enemy_buf->pstruct->p_mapchars);
} else { /* no shot yet */
if (enemy_buf->e_trrange > enemy_buf->e_dist)
me->p_flags |= PFSHIELD; /* shield up */
else
me->p_flags &= ~PFSHIELD;
} /* end shot */
} else { /* not shootable */
me->p_flags &= ~PFSHIELD; /* shield down */
} /* end shootable */
} /* End of rmove, the main puck moving program */
/*
* Additional routine start here
*/
void cleanup(void)
{
register struct player *j;
register int i;
/* Free the held slots - MK 9-20-92 */
queues[QU_PICKUP].free_slots = queues[0].free_slots
+ (MAXPLAYER - TESTERS) - NUMSKATERS;
queues[QU_PICKUP].max_slots = MAXPLAYER - TESTERS;
queues[QU_PICKUP].tournmask = ALLTEAM;
queues[QU_PICKUP].high_slot = 0;
queues[QU_PICKUP].high_slot = MAXPLAYER - TESTERS;
if (!practice) {
MCOPY(oldplanets, planets, sizeof(struct planet) * MAXPLANETS);
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
if ((j->p_status != PALIVE) || (j == me)) continue;
getship(&(j->p_ship), j->p_ship.s_type);
}
}
exitRobot();
}
void do_teleport_home(void)
{
register int i;
register struct player *j;
int startplanet;
if (practice) return;
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
/*Cleaned up this routine for v2 - MK*/
tracks[i].t_x = 0; /* **BAV** Don't rewarp if player reenters */
if ((j->p_status != PALIVE) || (j == me)) continue;
if (j->p_team == KLI)
startplanet = 20;
else if (j->p_team == ORI)
startplanet = 30;
else
continue;
j->p_y = planets[startplanet].pl_y + (random() % (2*DISPLACE) - DISPLACE);
if (j->p_x >= RINK_LEFT && j->p_x <= RINK_RIGHT)
j->p_x = planets[startplanet].pl_x + (random() % (2*DISPLACE) - DISPLACE);
j->p_speed = 0;
j->p_desspeed = 0;
j->p_subspeed = 0;
j->p_flags = PFSHIELD;
j->p_fuel = j->p_ship.s_maxfuel;
j->p_shield = j->p_ship.s_maxshield;
j->p_damage = 0;
tracks[i].t_x = j->p_x;
tracks[i].t_y = j->p_y;
}
}
void do_peace(void)
{
register int i;
register struct player *j;
if (practice) return;
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
j->p_hostile = 0;
j->p_swar = 0;
j->p_war = 0;
j->p_ship.s_tractstr = 1;
}
}
void do_msg_check(void)
{
while (oldmctl!=mctl->mc_current) {
oldmctl++;
if (oldmctl==MAXMESSAGE) oldmctl=0;
if (messages[oldmctl].m_flags & MINDIV) {
if ( (messages[oldmctl].m_recpt == me->p_no) ||
(messages[oldmctl].m_recpt == anncer->p_no) ){
check_command(&messages[oldmctl]);
#ifdef HAVE_GOALIE
if (strstr(messages[oldmctl].m_data, "UNGOALIE") != NULL)
{
do_ungoalie(messages[oldmctl].m_from); /* ***RAY*** */
return; /* else we also will do the GOALIE test */
}
/* if (strstr(messages[oldmctl].m_data, "GOALIE") != NULL) */
if (strstr(messages[oldmctl].m_data, "GOALIE") != NULL)
do_goalie(messages[oldmctl].m_from); /* ***RAY*** */
#endif
}
} else if (messages[oldmctl].m_flags & MALL) {
if (strstr(messages[oldmctl].m_data, "help") != NULL)
messOne(me->p_no,roboname,messages[oldmctl].m_from,
"If you want help from me, send me the message 'help'.");
}
}
}
#ifdef HAVE_GOALIE
/* goalie/ungoalie functions ***RAY*** */
void do_goalie(int who)
{
if (players[who].p_team == ORI)
{
if (ori_goalie != NULL)
{
messOne(me->p_no,roboname,who, "Your team already has a goalie: O%c.", shipnos[ori_goalie->p_no]);
return;
}
if (players[who].p_y < ORI_B)
{
messOne(me->p_no,roboname,who, "You have to be behind your home planet to be the goalie.");
return;
}
ori_goalie = &(players[who]);
ori_old_ship_type = ori_goalie->p_ship.s_type;
getship(&(ori_goalie->p_ship), BATTLESHIP);
ori_goalie->p_ship.s_repair = 30000;
ori_goalie->p_ship.s_type = ASSAULT;
ori_goalie->p_ship.s_maxdamage = 999;
ori_goalie->p_ship.s_maxshield = 999;
/*ori_goalie->p_ship.s_maxspeed = 6;*/ /* Was 8 -JGR */
/*ori_goalie->p_ship.s_maxegntemp = 600;*/ /* Was 1000 -JGR */
/*ori_goalie->p_ship.s_egncoolrate = 3;*/ /* Was 6 -JGR */
messAll(me->p_no,roboname,"%s (O%c) comes in as goalie for the Orions.", players[who].p_name, shipnos[who]);
}
else
{
if (kli_goalie != NULL)
{
messOne(me->p_no,roboname,who, "Your team already has a goalie: K%c.", shipnos[kli_goalie->p_no]);
}
if (players[who].p_y > KLI_B)
{
messOne(me->p_no,roboname,who,"You have to be behind your home planet to be the goalie.");
return;
}
kli_goalie = &(players[who]);
kli_old_ship_type = kli_goalie->p_ship.s_type;
getship(&(kli_goalie->p_ship), BATTLESHIP);
kli_goalie->p_ship.s_repair = 30000;
kli_goalie->p_ship.s_type = ASSAULT;
kli_goalie->p_ship.s_maxdamage = 999;
kli_goalie->p_ship.s_maxshield = 999;
/*kli_goalie->p_ship.s_maxspeed = 6;*/ /* Was 8 -JGR */
/*kli_goalie->p_ship.s_maxegntemp = 600;*/ /* Was 1000 -JGR */
/*kli_goalie->p_ship.s_egncoolrate = 3;*/ /* Was 6 -JGR */
messAll(me->p_no,roboname,"%s (K%c) comes in as goalie for the Klingons.", players[who].p_name, shipnos[who]);
}
}
void do_ungoalie(int who)
{
if (players[who].p_team == ORI)
{
if ((ori_goalie == NULL) || (ori_goalie->p_no != who))
{
messOne(me->p_no,roboname,who,"You aren't the goalie!");
return;
}
messAll(me->p_no,roboname,"%s (O%c) is no longer guarding the net.", ori_goalie->p_name, shipnos[who]);
getship(&(ori_goalie->p_ship), ori_old_ship_type);
ori_goalie->p_shield = ori_goalie->p_ship.s_maxshield / 2;
ori_goalie->p_damage = ori_goalie->p_ship.s_maxdamage / 2;
ori_goalie->p_fuel = ori_goalie->p_ship.s_maxfuel / 2;
ori_goalie = NULL;
}
else
{
if ((kli_goalie == NULL) || (kli_goalie->p_no != who))
{
messOne(me->p_no,roboname,who,"You aren't the goalie!");
return;
}
messAll(me->p_no,roboname,"%s (K%c) is no longer guarding the net.", kli_goalie->p_name, shipnos[who]);
getship(&(kli_goalie->p_ship), kli_old_ship_type);
kli_goalie->p_shield = kli_goalie->p_ship.s_maxshield / 2;
kli_goalie->p_damage = kli_goalie->p_ship.s_maxdamage / 2;
kli_goalie->p_fuel = kli_goalie->p_ship.s_maxfuel / 2;
kli_goalie = NULL;
}
}
#endif
/* Added by MK */
/* ARGSUSED */
void do_version(char *comm, struct message *mess)
{
int who;
who = mess->m_from;
messOne(me->p_no,roboname,who, "Puck Version 2.6Bpl2 - Beta Release Version");
messOne(me->p_no,roboname,who, "Please mail bug/coments to kantner@hot.caltech.edu");
}
/* ARGSUSED */
void do_stats_msg(char *comm, struct message *mess)
{
int who;
register int i;
register Track *track;
register struct player *j;
who = mess->m_from;
for (i = 0, j = &players[i], track = &tracks[i];
i < MAXPLAYER; i++, j++, track++) {
if ((j->p_status != PFREE) && !(j->p_flags & PFROBOT)) {
messOne(me->p_no,roboname,who, " %2s: %-16s %2dG %2dA %3d min",
j->p_mapchars,
j->p_name,
track->t_goals,
track->t_assists,
track->t_seconds / 60);
}
}
}
/* ARGSUSED */
void do_change_timekeep(int who, int mflags, int sendto)
{
if (short_game){
short_game = 0;
messAll(me->p_no,roboname,"Changing Time Keeping Method to LONG game");
}
else{
short_game = 1;
messAll(me->p_no,roboname,"Changing Time Keeping Method to SHORT game");
}
}
/* ARGSUSED */
void do_force_newgame(int who, int mflags, int sendto)
{
register int i;
register Track *track;
register struct player *j;
roboclock = END_OF_PERIOD;
period = PERIODS_PER_GAME;
/****MK - stats are cleared*/
#ifdef NEWGAME_RESET
messAll(me->p_no,roboname,"Clearing Player Stats for the Newgame");
for (i = 0, j = &players[i], track = &tracks[i];
i < MAXPLAYER; i++, j++, track++) {
if ( !(j->p_flags & PFROBOT) ) {
track->t_goals = 0;
track->t_assists = 0;
track->t_seconds = 0;
}
}
#endif
/****End added code */
}
/* ARGSUSED */
void do_force_newscore(int who, int mflags, int sendto)
{
scores[ORI] = 0;
scores[KLI] = 0;
do_score();
}
void do_war(void)
{
register int i;
register struct player *j;
if (practice) return;
for (i = 0; i < 40; i++) { /* ***BAV*** */
planets[i].pl_armies = 2;
}
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
if ((j->p_status == PALIVE) && (j != me) && (j != anncer) ) {
tracks[i].t_seconds += 10;
j->p_hostile |= (KLI|ORI);
j->p_hostile &= ~j->p_team;
j->p_war = (j->p_swar | j->p_hostile);
j->p_armies = 0;
j->p_ship.s_egncoolrate = 12;
/* j->p_ship.s_tractstr = 2500; non-uniform tractor str? */
/* j->p_ship.s_tractrng = 0.9; */
switch (j->p_ship.s_type) {
case SCOUT:
j->p_ship.s_tractstr = 2000/WEAKER_STR; /* scout: */
j->p_ship.s_tractrng = 0.7/WEAKER_RNG;
break;
case DESTROYER:
j->p_ship.s_tractstr = 2500/WEAKER_STR; /* destroyer: */
j->p_ship.s_tractrng = 0.9/WEAKER_RNG;
break;
case BATTLESHIP:
case ASSAULT:
j->p_ship.s_tractstr = 3700/WEAKER_STR; /* btlship/assault: */
j->p_ship.s_tractrng = 1.2/WEAKER_RNG;
break;
case STARBASE:
j->p_ship.s_tractstr = 8000/WEAKER_STR; /* starbase */
j->p_ship.s_tractrng = 1.5/WEAKER_RNG;
break;
case ATT:
j->p_ship.s_tractstr = 32765/WEAKER_STR; /* att: */
break;
default:
j->p_ship.s_tractstr = 3000/WEAKER_STR; /* cruiser: */
j->p_ship.s_tractrng = 1.0/WEAKER_RNG;
break;
}
}
}
}
void place_anncer(void)
{
anncer->p_status = PALIVE;
anncer->p_speed = 0; /* keep the announcer in place */
anncer->p_desspeed = 0;
anncer->p_x = RINK_LEFT/4;
anncer->p_y = R_MID;
}
void place_sitout(int who)
{
struct player *j;
Track *track;
j = &players[who];
track = &tracks[who];
/*Place people on opposite sides of the rink*/
if (j->p_team == KLI){
j->p_x = track->t_x = SITOUT_X;
j->p_y = track->t_y = KLI_B + (random() % (2*DISPLACE) - DISPLACE);
}
else if (j->p_team == ORI){
j->p_x = track->t_x = GWIDTH - SITOUT_X;
j->p_y = track->t_y = ORI_B + (random() % (2*DISPLACE) - DISPLACE);
}
else
return; /*Not ORI, not KLI, so do nothing... Weird*/
}
/* ARGSUSED */
void do_sitout(char *comm, struct message *mess)
{
int who;
struct player *j;
Track *track;
who = mess->m_from;
j = &players[who];
track = &tracks[who];
/*If you are already sitting out, do nothing*/
if (track->t_flags & PU_SITOUT){
messOne(me->p_no,roboname,who,"You are already sitting out");
return;
}
place_sitout(who);
messAll(me->p_no,roboname,"%s (O%c) is sitting out.", players[who].p_name, shipnos[who]);
track->t_flags |= PU_SITOUT ;
j->p_speed = 0; /*So you don't move */
j->p_desspeed = 0;
j->p_subspeed = 0;
j->p_flags = PFSHIELD;
j->p_fuel = 0; /*Hah, you're hosed anyway */
j->p_damage = j->p_ship.s_maxdamage - 5;
j->p_shield = j->p_ship.s_maxshield; /*OK, a potential help */
}
void do_offsides(void)
{
register int i;
register struct player *j;
if (practice) return;
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
if ((j != me) && (j->p_status == PALIVE)) {
if (((j->p_team == KLI) && (j->p_y > GWIDTH/2)) ||
((j->p_team == ORI) && (j->p_y < GWIDTH/2))) {
int startplanet;
messAll(me->p_no,roboname,"%s (%2s) is offsides.", j->p_name,
j->p_mapchars);
j->p_flags &= ~(PFORBIT|PFPLOCK|PFPLLOCK|PFTRACT|PFPRESS); /* ***BAV*** */
if (j->p_team == KLI)
startplanet = 20;
else if (j->p_team == ORI)
startplanet = 30;
j->p_y = planets[startplanet].pl_y + (random() % (2*DISPLACE) - DISPLACE);
}
}
}
}
void puck_rules(void)
{
messAll(anncer->p_no,roboname,"This is Netrek hockey. Send me the message \"help\" for rules.");
}
char* team_names[MAXTEAM+1] = { "", "Federation", "Romulans", "", "Klingons",
"", "", "", "Orions" };
void do_goal(int team)
{
#ifdef NO_BRUTALITY
do_peace();
#endif
messAll(anncer->p_no,roboname,"*****************************************************************");
if (lastp[team] == -1) { /* unassisted */
if (currp[team] == -1) { /* untouched?! */
messAll(me->p_no,roboname,"* The %s score without touching the puck!?",
team_names[team]);
} else {
messAll(me->p_no,roboname,"* %s scores for the %s! Unassisted!",
players[currp[team]].p_name, team_names[team]);
tracks[currp[team]].t_goals++;
#ifndef LTD_STATS
if (status->tourn) {
players[currp[team]].p_stats.st_tplanets++;
status->planets++;
} else {
players[currp[team]].p_stats.st_planets++;
}
#endif
}
} else {
messAll(me->p_no,roboname, "* %s scores for the %s! %s assisting!",
players[currp[team]].p_name, team_names[team],
players[lastp[team]].p_name);
tracks[currp[team]].t_goals++;
tracks[lastp[team]].t_assists++;
#ifndef LTD_STATS
if (status->tourn) {
players[currp[team]].p_stats.st_tplanets++;
players[lastp[team]].p_stats.st_tarmsbomb++;
status->planets++;
status->armsbomb++;
} else {
players[currp[team]].p_stats.st_planets++;
players[lastp[team]].p_stats.st_armsbomb++;
}
#endif
}
switch (random()%11) {
case 0:
messAll(anncer->p_no,roboname,"* Get in the fast lane, Gramma, the bingo game is ready to roll!"); break;
case 1:
messAll(anncer->p_no,roboname,"* Scratch my back with hacksaw!"); break;
case 2:
messAll(anncer->p_no,roboname,"* He beat him like a rented mule!"); break;
case 3:
messAll(anncer->p_no,roboname,"* Book'em Danno!"); break;
case 4:
messAll(anncer->p_no,roboname,"* She wants to sell my monkey!"); break;
case 5:
messAll(anncer->p_no,roboname,"* Ladies and gentlemen, Elvis has just left the building!"); break;
case 6:
messAll(anncer->p_no,roboname,"* Look out Loretta!"); break;
case 7:
messAll(anncer->p_no,roboname,"* How now Eddie Spaghetti!"); break;
case 8:
messAll(anncer->p_no,roboname,"* Michael Michael motorcycle!"); break;
case 9:
messAll(anncer->p_no,roboname,"* Stop the press, it's over now!"); break;
case 10: /* *** BAV *** */
messAll(anncer->p_no,roboname,"* Looky, Looky! Here comes Cookie!"); break;
}
messAll(anncer->p_no,roboname,"*****************************************************************");
scores[team]++;
do_score();
me->p_ship.s_type = STARBASE;
me->p_whydead=KPLASMA;
me->p_explode=10;
me->p_status=PEXPLODE;
me->p_whodead=0;
/* do_faceoff();*/
}
void do_score(void)
{
int tempclock;
tempclock = roboclock/PERSEC;
messAll(me->p_no,roboname,"Score is Klis %d, Oris %d. Elapsed time %02d:%02d. Period %d.",
scores[KLI], scores[ORI], tempclock/60, tempclock%60, period);
#ifdef LIGHT_PLANETS
light_planets();
#endif
}
/* ARGSUSED */
void do_score_msg(char *comm, struct message *mess)
{
int who;
int tempclock;
who = mess->m_from;
tempclock = roboclock/PERSEC;
messOne(me->p_no,roboname,who, "Score is Klis %d, Oris %d. Elapsed time %02d:%02d. Period %d.",
scores[KLI], scores[ORI], tempclock/60, tempclock%60, period);
}
void do_faceoff(void)
{
register int i,l;
register struct player *j;
for (i = 0, j = &players[i];
i < MAXPLAYER; i++, j++) {
if (j == me) continue;
#ifdef VOTING
for (l=0; l < PV_TOTAL; l++)
j->voting[l] = -1;
#endif
}
me->p_speed = 0;
me->p_desspeed = 0;
me->p_x = RINK_LEFT; /* *** BAV *** */
me->p_y = R_MID;
place_anncer();
if (debug)
faceoff = 5;
else
faceoff = FACEOFF;
}
unsigned char getcourse(int x, int y)
{
return((unsigned char) nint((atan2((double) (x - me->p_x),
(double) (me->p_y - y)) / 3.14159 * 128.)));
}
int isInPossession(struct Enemy *enemy_buf)
{
return ((enemy_buf->pstruct->p_flags & PFTRACT) &&
(enemy_buf->pstruct->p_tractor == me->p_no));
}
int isTractoringMe(struct Enemy *enemy_buf)
{
return ((enemy_buf->pstruct->p_flags & PFTRACT) &&
!(enemy_buf->pstruct->p_flags & PFPRESS) &&
(enemy_buf->pstruct->p_tractor == me->p_no));
}
int isPressoringMe(struct Enemy *enemy_buf)
{
return ((enemy_buf->pstruct->p_flags & PFTRACT) &&
(enemy_buf->pstruct->p_flags & PFPRESS) &&
(enemy_buf->pstruct->p_tractor == me->p_no));
}
void woomp(void)
{
register int i;
register struct player *j;
/* avoid dead slots, me, other robots (which aren't hostile) */
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
if (j == me || j->p_status==PFREE) /* Last clause *** BAV *** */
continue;
j->p_ship.s_type = STARBASE;
j->p_whydead=KPLASMA;
j->p_explode=10;
j->p_status=PEXPLODE;
j->p_whodead=me->p_no;
}
}
/* by MK */
void player_maint(void)
{
register int i,l;
register struct player *j;
register Track *track;
/* avoid dead slots, me, other robots (which aren't hostile) */
for (i = 0, j = &players[i], track = &tracks[i];
i < MAXPLAYER; i++, j++, track++) {
/* */
/*RESURRECTION code is in here!!!*/
/* */
if ((j == me) || (j == anncer))/* ignore puck */
continue;
if (j->p_status != PALIVE) { /*for dead people*/
track->t_status = j->p_status;
if (j->p_status == PFREE) {
track->t_goals = 0;
track->t_assists = 0;
track->t_seconds = 0;
track->t_x = 0;
track->t_y = 0;
#ifdef VOTING
for (l = 0; l < PV_TOTAL; l++) {
j->voting[l]=-1;
}
#endif
track->t_flags = 0;
}
continue; /* do nothing else for dead players */
}
/*At this point, the player is alive*/
/*Place players who just came back to life*/
if ((track->t_status != PALIVE) && (track->t_x != 0)) {
if (!practice) {
if (random() % 2 == 0) /* step to the left */
j->p_x = track->t_x - ((random() % DXDISPLACE) + DXOFFSET);
else /* step to the right */
j->p_x = track->t_x + ((random() % DXDISPLACE) + DXOFFSET);
/* and shake it all around */
j->p_y = track->t_y + random()%(2*DYDISPLACE) - DYDISPLACE;
}
}
/*If you were sitting out and died, you are still sitting out*/
if ((track->t_status != PALIVE) && (track->t_flags & PU_SITOUT)) {
if (!practice) {
place_sitout(i);
}
}
if (track->t_flags & PU_SITOUT){
if ( (j->p_x >= RINK_LEFT) && (j->p_x <= RINK_RIGHT) ){
track->t_flags &= ~PU_SITOUT;
messAll(me->p_no,roboname,"%s (O%c) is back on the ice.",
players[i].p_name, shipnos[i]);
}
}
/* Save current info */
track->t_status = j->p_status;
track->t_x = j->p_x;
track->t_y = j->p_y;
/* Note: track->t_seconds is updated in do_war */
}
}
void player_bounce(void)
{
register int i;
register struct player *j;
register Track *track;
/* avoid dead slots, me, other robots (which aren't hostile) */
for (i = 0, j = &players[i], track = &tracks[i];
i < MAXPLAYER; i++, j++, track++) {
if ( (j == me) || (j == anncer) || (j->p_status!=PALIVE) ||
(j->p_flags & PFORBIT) )
continue; /*Don't do this for dead and for puck*/
if (track->t_flags & PU_SITOUT)
continue; /*Don't do this if sitting out */
#ifdef WALL_BOUNCE
/* Hit/bounce off the boards */
if (j->p_x < RINK_LEFT) {
j->p_x = RINK_LEFT;
} else if (j->p_x > RINK_RIGHT) {
j->p_x = RINK_RIGHT;
}
#endif
#ifdef GOAL_CLEAR
/* do goal bounce? */
/* is player "inside a goal?" */
if ( ((j->p_x > G_LFT) && (j->p_x < G_RGT)) &&
( ((j->p_y > ORI_G) && (j->p_y < ORI_E)) ||
((j->p_y < KLI_G) && (j->p_y > KLI_E)) ) ) {
if (track->t_x >= G_RGT) {
j->p_x = G_RGT; /*Hits right side of goal*/
} else if (track->t_x <= G_LFT) {
j->p_x = G_LFT; /*Hits left side of goal*/
}
if ((j->p_y > KLI_E) && (track->t_y <= KLI_E)) {
j->p_y = KLI_E; /*Hits back of Kli goal*/
} else if ((j->p_y < ORI_E) && (track->t_y >= ORI_E)) {
j->p_y = ORI_E; /*Hits back of Ori goal*/
} else if ((j->p_y < KLI_G) && (track->t_y >= KLI_G)) {
j->p_y = KLI_G; /*Hits front of Kli goal*/
} else if ((j->p_y > ORI_G) && (track->t_y <= ORI_G)) {
j->p_y = ORI_G; /*Hits front of Ori goal*/
}
} /*End big inside goal if */
#endif
} /*end for loop*/
#ifdef HAVE_GOALIE
/* check goalies ***RAY*** */
if (ori_goalie != NULL)
{
if (ori_goalie->p_y < ORI_B)
ori_goalie->p_y = ORI_B;
if (ori_goalie->p_status != PALIVE)
{
ori_goalie->p_ship.s_type = ori_old_ship_type;
ori_goalie = NULL;
}
}
if (kli_goalie != NULL)
{
if (kli_goalie->p_y > KLI_B)
kli_goalie->p_y = KLI_B;
if (kli_goalie->p_status != PALIVE)
{
kli_goalie->p_ship.s_type = kli_old_ship_type;
kli_goalie = NULL;
}
}
#endif
}
#ifdef OFFSIDE
void check_offsides(int team, int offside_msg)
{
register int i;
register struct player *j;
register Track *track;
team_offsides = 0;
for (i=0, j=&players[i]; i < MAXPLAYER; i++, j++){
if ( (j->p_status != PALIVE) || (j==me) ) continue;
if ( (team==ORI) && (j->p_y < KLI_B) && (j->p_team==ORI) ||
(team==KLI) && (j->p_y > ORI_B) && (j->p_team==KLI) ){
team_offsides = team;
if (offside_msg==1)
messAll(me->p_no,roboname,"%s (%2s) is offsides.", j->p_name,j->p_mapchars);
}
}
if ( (offside_msg==2) && (team!=team_offsides) )
messAll(me->p_no,roboname,"The %s are longer offsides!",team==ORI?"Orions":"Klingons");
planet_offsides(team_offsides);
}
void penalty_offsides(int team)
{
do_teleport_home(); /*Send everyone back to start*/
planet_offsides(0); team_offsides = 0; /*Clear Offsides*/
/*Place Puck in Neutral Zone*/
if (me->p_x > G_MID) me->p_x = RED_4;
else me->p_x = RED_1;
if (team == ORI) me->p_y = (R_MID + KLI_B)/2;
else me->p_y = (R_MID + ORI_B)/2;
me->p_speed=me->p_desspeed=0;
}
void planet_offsides(int team)
{
#define IND 0
register int i;
if (team == KLI){ /*Klingons are offsides*/
planets[37].pl_owner = ORI; /* Urs */
planets[38].pl_owner = ORI; /* Her */
for (i=7; i<10; i++){
planets[i].pl_owner = ORI;
planets[i+10].pl_owner = ORI;
}
}else if (team == ORI){ /*Orions are offsides*/
planets[23].pl_owner = KLI; /* Lal */
planets[29].pl_owner = KLI; /* Cas */
for (i=0; i<3; i++){
planets[i].pl_owner = KLI;
planets[i+10].pl_owner = KLI;
}
}else { /*No one is offsides now*/
planets[37].pl_owner = IND;
planets[38].pl_owner = IND;
planets[23].pl_owner = IND;
planets[29].pl_owner = IND;
for (i=0; i<10; i++){
planets[i].pl_owner = IND;
planets[i+10].pl_owner = IND;
}
}
}
#endif
struct Enemy ebuf;
struct Enemy *get_nearest(void)
{
int pcount = 0;
register int i;
register struct player *j;
int intruder = 0;
int tdist;
double dx, dy;
/* Find an enemy */
ebuf.e_info = me->p_no;
ebuf.e_dist = GWIDTH + 1;
pcount = 0; /* number of human players in game */
/* avoid dead slots, me, other robots (which aren't hostile) */
for (i = 0, j = &players[i];
i < MAXPLAYER; i++, j++) {
/*skip me, announcer, and the not-alive players */
if ( (j==me) || (j==anncer) || (j->p_status != PALIVE) ) continue;
pcount++; /* Other players in the game */
/* We have an enemy */
/* Get his range */
dx = j->p_x - me->p_x;
dy = j->p_y - me->p_y;
tdist = hypot(dx, dy);
if (tdist < ebuf.e_dist) {
ebuf.e_info = i;
ebuf.e_dist = tdist;
if (intruder)
ebuf.e_flags |= E_INTRUDER;
else
ebuf.e_flags &= ~(E_INTRUDER);
}
} /* end for */
if (pcount == 0) {
return (NOENEMY); /* no players in game */
} else if (ebuf.e_info == me->p_no) {
return (0); /* no hostile players in the game */
} else {
j = &players[ebuf.e_info];
ebuf.pstruct = j;
/* Get torpedo course to nearest enemy */
ebuf.e_flags &= ~(E_TSHOT);
/* Get phaser shot status */
if (ebuf.e_dist < 0.8 * phrange)
ebuf.e_flags |= E_PSHOT;
else
ebuf.e_flags &= ~(E_PSHOT);
/* Get tractor/pressor status */
if (ebuf.e_dist < trrange)
ebuf.e_flags |= E_TRACT;
else
ebuf.e_flags &= ~(E_TRACT);
/* get his phaser and tractor range */
ebuf.e_phrange = PHASEDIST * j->p_ship.s_phaserdamage / 100;
ebuf.e_trrange = TRACTDIST * j->p_ship.s_tractrng;
/* get course info */
ebuf.e_course = getcourse(j->p_x, j->p_y);
ebuf.e_edir = j->p_dir;
ebuf.e_tractor = j->p_tractor;
/*
if (debug)
ERROR(1,( "Set course to enemy is %d (%d)\n",
(int)ebuf.e_course,
(int) ebuf.e_course * 360 / 256));
*/
return (&ebuf);
}
}
char* puckie_message(struct player* enemy)
{
int i;
char *s,*t;
i=(random() % (sizeof(puckie_messages)/sizeof(puckie_messages[0])));
for (t=puckie_messages[i], s=tmessage; *t!='\0'; s++, t++) {
switch(*t) {
case '$':
switch(*(++t)) {
case '$':
*s = *t;
break;
case 'T': /* "a Fed" or "a Klingon" ... */
if (enemy->p_team != me->p_team &&
enemy->p_team == ORI) {
strcpy(s, "an ");
} else {
strcpy(s, "a ");
}
s=s+strlen(s);
case 't': /* "Fed" or "Orion" */
if (enemy->p_team != me->p_team) {
switch (enemy->p_team) {
case FED:
strcpy(s, "Fed");
break;
case ROM:
strcpy(s, "Romulan");
break;
case KLI:
strcpy(s, "Klingon");
break;
case ORI:
strcpy(s, "Orion");
break;
}
} else {
strcpy(s, "TRAITOR");
}
s=s+strlen(s)-1;
break;
case 'n': /* name 8/2/91 TC */
strcpy(s, enemy->p_name);
s=s+strlen(s)-1;
break;
case 'w': /* where on the rink */
if (me->p_y < KLI_G)
strcpy(s, "the Klingon goal end");
else if (me->p_y < KLI_B)
strcpy(s, "the Klingon zone");
else if (me->p_y < ORI_B)
strcpy(s, "the neutral zone");
else if (me->p_y < ORI_G)
strcpy(s, "the Orion zone");
else
strcpy(s, "the Orion goal end");
s=s+strlen(s)-1;
break;
default:
*s = *t;
}
break;
default:
*s = *t;
break;
}
}
*s='\0';
return(tmessage);
}
void exitRobot(void)
{
SIGNAL(SIGALRM, SIG_IGN);
#ifdef PUCK_FIRST
if (sem_puck > -1) {
semop(sem_puck, sem_puck_op, 1);
}
#endif
if (me != NULL && me->p_team != ALLTEAM) {
if (target >= 0) {
messAll(me->p_no,roboname, "I'll be back.");
}
else {
messAll(me->p_no,roboname,"#############################");
messAll(me->p_no,roboname,"#");
messAll(me->p_no,roboname,"# The puck is tired. Hockey is over for now");
messAll(me->p_no,roboname,"#");
}
}
freeslot(me);
freeslot(anncer);
exit(0);
}
#ifdef LIGHT_PLANETS
/*
* light_planets changes ownership of planets to indicate the score.
* Some people really like this feature, and no one objects to it.
*/
#define IND 0
void light_planets(void)
{
int pln_light,extra;
int i;
int kli_light= ROM, ori_light = FED;
if (scores[KLI] > 0) {
pln_light=scores[KLI]%5;
switch(pln_light) {
case 1:
planets[10].pl_owner=kli_light;
for (i=11; i<15; i++) {
planets[i].pl_owner = IND;}
extra = scores[KLI]/5;
if (extra > 0) { planets[extra-1].pl_owner = kli_light;}
break;
case 2:
planets[11].pl_owner=kli_light; break;
case 3:
planets[12].pl_owner=kli_light; break;
case 4:
planets[13].pl_owner=kli_light; break;
case 0:
planets[14].pl_owner=kli_light; break;
default:
break;
}
}else{
for (i=0; i<5; i++) {
planets[i].pl_owner = IND;
planets[10+i].pl_owner = IND; }
}
if (scores[ORI] > 0) {
pln_light=scores[ORI]%5;
switch(pln_light) {
case 1:
planets[9].pl_owner=ori_light;
for (i=5; i<9; i++) {
planets[i].pl_owner = IND;}
extra = scores[ORI]/5;
if (extra > 0) {
planets[20-extra].pl_owner = ori_light;}
break;
case 2:
planets[8].pl_owner=ori_light; break;
case 3:
planets[7].pl_owner=ori_light; break;
case 4:
planets[6].pl_owner=ori_light; break;
case 0:
planets[5].pl_owner=ori_light; break;
default:
break;
}
}else{
for (i=0; i<5; i++) {
planets[5+i].pl_owner = IND;
planets[15+i].pl_owner = IND; }
}
}
#endif /* LIGHT_PLANETS */