/* 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 #include #include #include "defs.h" #include "struct.h" #include "data.h" #include "puckdefs.h" char* team_names[MAXTEAM+1] = { "", "Federation", "Romulans", "", "Klingons", "", "", "", "Orions" }; #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 #ifdef OFFSIDE struct Coord { int p_x,p_y; }; #endif 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 */ #if defined(REAL_FACEOFF) && defined(NEW_OFFSIDE) && defined(OFFSIDE) #define SHORT_FACEOFF (5+TELEPORT_DELAY/2)*PERSEC #endif #ifdef OFFSIDE /* RBB 10.17.96 */ #define FACEOFF_CIRCLE TENTH #define FACEOFF_BUFFER TENTH/3 /* Face_off constants */ #define FACEOFF_DIST TENTH/4 /* Distance from puck on faceoff */ #define OFFSIDES_BUFFER TENTH/4 /* Distance of allowance for offsides call*/ #endif int scores[MAXTEAM+1]; int period_scores[4][MAXTEAM+1]; /* RBB 10.12.96 */ int tie_game = 0; /* An OT bit of code */ int current_team; /* An offsides bit of code */ #ifdef DUAL_ASS int lastp[2][MAXTEAM+1]; #else int lastp[MAXTEAM+1]; #endif int currp[MAXTEAM+1]; int faceoff = FACEOFF; /* "faceoff" mode */ int period = 1; int roboclock = 0; int short_game = 1; /* 0 = long game, 1 = short game */ int short_face = 0; #ifdef OFFSIDE /* Offsides can become a votable option */ int offsides_on = 1; /* 0 = No offsides, 1 = offsides */ struct Coord face_place; /* Place of faceoff */ #endif #ifdef STREAK int strk_team; int strk_goals; #endif #define MESSFUSEVAL 50*PERSEC static int messfuse = MESSFUSEVAL; static char tmessage[110]; char* puckie_messages[] = { "You can't really dust for vomit.", "What you got back home, little sisters, to play your fuzzy yarbles on?", "I don't know where you get you delusions, laser brain!", "Uh-oh. I smell another cheap cartoon-crossover.", "Cool...a Ruckus!", "Silly customer, you can not hurt a twinkie.", "Wow, nothing for 16 years and then twice in one day.", "It happens sometimes. People just explode. Natural causes.", "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...", }; char* passing_messages[] = { /* cool passing messages */ "Nice passing by the %s!", "Outstanding passing by the %s!", "Nice puck work by the %s!", "The %s have been rehearsing that maneuver.", "What teamwork by the %s!", }; const int numpassingmsg = sizeof(passing_messages)/sizeof(passing_messages[0]); char* goal_messages[] = { "* Looks like I picked the wrong week to stop sniffing glue!", "* Looks like I picked the wrong week to quit drinking!", "* Get in the fast lane, Gramma, the bingo game is ready to roll!", "* Scratch my back with hacksaw!", "* He beat him like a rented mule!", "* Book'em Danno!", "* She wants to sell my monkey!", "* Ladies and gentlemen, Elvis has just left the building!", "* Look out Loretta!", "* How now Eddie Spaghetti!", "* Michael Michael motorcycle!", "* Stop the press, it's over now!", "* Looky, Looky! Here comes Cookie!" }; const int numgoalmsg = sizeof(goal_messages)/sizeof(goal_messages[0]); 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; unsigned char getcourse(); char *robo_message(); char *puckie_message(); /* added 8/2/91 TC */ #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 rmove() { extern struct Enemy *get_nearest(); struct Enemy *enemy_buf; int i; #ifdef OT register Track *track; int pcount; register struct player *j; #endif static int lastx; static int lasty; static int shotage; static int shotby; static int lastteamtoshoot=-1; /* used for coolpassing */ static int coolpassing=0; /* used for coolpassing */ static int lastshotby; /* used for coolpassing */ static int pauseticks; static int shot_toward = NOBODY; // non struct player* saved_by; // non /***** 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) { #ifdef OT /* If the score is tied and there is a player in the game, overtime */ if (period >= PERIODS_PER_GAME) { tie_game = (scores[ORI] == scores[KLI]); if (tie_game) { /* Count number of players */ pcount = 0; for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) { if ( (j==me) || (j==anncer) || (j->p_status != PALIVE) ) continue; pcount++; } if (pcount < 2) { messAll(anncer->p_no,roboname,"Not enough players for overtime."); messAll(anncer->p_no,roboname,"Only %d players.",pcount); tie_game = 0; messAll(anncer->p_no, roboname,"# END OF GAME."); woomp(); } else { messAll(anncer->p_no, roboname,"# END OF REGULATION."); woomp(); } }else{ messAll(anncer->p_no, roboname,"# END OF GAME."); woomp(); } } else { messAll(anncer->p_no,roboname," END OF PERIOD %d",period); woomp(); } #else /* OVERTIME */ 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(); } #endif /* End of OT section (for now) */ #ifdef DUAL_ASS /* Part of Dual Assists */ period_totals(); #else do_score(); #endif 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; #ifdef OT if (period >= PERIODS_PER_GAME) { if (!tie_game) { /* Is the game tie? */ if (scores[ORI] > scores[KLI]) { /* No, tell who won. */ messAll(anncer->p_no, roboname, " **** Orions win ****"); }else if (scores[KLI] > scores[ORI]) { messAll(anncer->p_no, roboname, " **** Klingons win ****"); }else messAll(anncer->p_no,roboname, " **** Tie game ****"); /* A tie game */ scores[KLI] = 0; scores[ORI] = 0; for (i=1 ; i<5 ; i++ ) { period_scores[i][ORI] = 0; period_scores[i][KLI] = 0;} #ifdef PLANET_LIGHT lightPlanets(); #endif period = 0; #ifdef STREAK strk_goals=0; #endif #ifdef NEWGAME_RESET messAll(me->p_no,roboname,"Clearing Game Stats."); 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 length--; if (length == 0) cleanup(); } else { /* It is a tie game. */ messAll(anncer->p_no,roboname," Tie game!"); messAll(anncer->p_no,roboname," Overtime!"); messAll(anncer->p_no,roboname," First goal wins!"); period_scores[4][KLI] = 0; period_scores[4][ORI] = 0; } } period++; if (period >4) period=4; #else /* No Overtime Code */ 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++; #endif } /* 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 */ } #if defined(REAL_FACEOFF) && defined(OFFSIDE) if (short_face > 0){ if ( (END_OF_PERIOD - roboclock) <= short_face){ roboclock=END_OF_PERIOD; messAll(me->p_no,roboname," Period Ends before faceoff!"); } if ((short_face % (PERSEC)) == 0) do_msg_check(); short_face--; if (short_face == 0) { do_war(); /* open hostilities */ encrouchment(face_place.p_y); me->p_speed = 0; /* *** BAV *** */ me->p_desspeed = 0; me->p_subspeed = 0; me->p_x = face_place.p_x; me->p_y = face_place.p_y; for (i = 0; i <= MAXTEAM; i++) { currp[i] = -1; current_team = -1; #ifdef DUAL_ASS lastp[1][i] = -1; lastp[2][i] = -1; #else lastp[i] = -1; #endif } messAll(me->p_no,roboname," Play!"); lastx = me->p_x; lasty = me->p_y; /* avoid boing problems */ shotby = -1; /* to find winner of faceoff */ }else{ if (short_face == 2*PERSEC) messAll(me->p_no,roboname,"Ready"); if (short_face == PERSEC) { messAll(me->p_no,roboname," Set"); do_war(); /* open before faceoff hostilities */ } } } #endif /* first priority: is this faceoff mode? */ /* Messages are checked once per second here */ if (faceoff > 0) { if (short_game){ roboclock++; if ( (END_OF_PERIOD - roboclock) <= faceoff){ roboclock=END_OF_PERIOD; messAll(me->p_no,roboname," Period Ends before faceoff!"); } } 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; current_team = -1; #ifdef DUAL_ASS lastp[1][i] = -1; lastp[1][i] = -1; #else lastp[i] = -1; #endif } messAll(me->p_no,roboname,""); 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 period",(timetogo/PERSEC)); if ( (timetogo < 10*PERSEC) && ((timetogo % PERSEC) == 0) ) messAll(anncer->p_no,roboname," %i second%s left in the period",(timetogo/PERSEC), timetogo==PERSEC ? "":"s"); } /* 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 (offsides_on) { if ((lasty >= KLI_B) && (me->p_y < KLI_B)){ messAll(anncer->p_no,roboname, "-->The puck crosses the %s blue line<--",team_names[KLI]); if (current_team == ORI) check_offsides(ORI); } else if ((lasty <= ORI_B) && (me->p_y > ORI_B)){ messAll(anncer->p_no,roboname, "-->The puck crosses the %s blue line<--",team_names[ORI]); if (current_team == KLI) check_offsides(KLI); } else if ((me->p_y >= KLI_B) && (lasty < KLI_B) && !(shotby == -1)){ messAll(me->p_no,roboname, " "); planet_offsides(0); team_offsides = 0; } else if ((me->p_y <= ORI_B) && (lasty > ORI_B) && !(shotby == -1)){ messAll(me->p_no,roboname, " <%s clear the puck.>",team_names[ORI]); planet_offsides(0); team_offsides = 0; } else if (team_offsides!=0) check_onsides(team_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 ((offsides_on) && (team_offsides==ORI)){ messAll(me->p_no,roboname, "The ORIONS have committed an offsides violation"); penalty_offsides(team_offsides); #if defined(NEW_FACEOFF) && defined(OFFSIDE) shotby= -1; #endif } else{ #endif do_goal(ORI, roboclock); #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 ((offsides_on) && (team_offsides==KLI)){ messAll(me->p_no,roboname, "The KLINGONS have committed an offsides violation"); penalty_offsides(team_offsides); #if defined(NEW_FACEOFF) && defined(OFFSIDE) shotby= -1; #endif } else{ #endif do_goal(KLI, roboclock); #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(); /* "saved shot" stat tracking by non 8-may-97 */ /* check for a saved shot */ saved_by = 0; if( shot_toward == ORI ) { /* are we no longer flying toward goal? */ if( me->p_desspeed == 0 || !(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))) { /* the save goes to the closest tractor/pressoring defender */ float distance = 0; int i; struct player *j; shot_toward = NOBODY; for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) { /* skip me, announcer, and the not-alive players */ if ( j->p_status != PALIVE || j==me || j==anncer ) continue; /* if the player is tractor/pressoring me and is on the defending team */ if( (j->p_flags & PFTRACT) && j->p_tractor == me->p_no && j->p_team == ORI ) { int deltaX = j->p_x - me->p_x; int deltaY = j->p_y - me->p_y; float jDist = (float) deltaX*deltaX + deltaY*deltaY; /* and if he's the closest defender */ if( saved_by == NULL || jDist < distance ) { /* give him the save */ saved_by = j; distance = jDist; } } } } } else if( shot_toward == KLI ) { 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); /* are we no longer flying toward goal? */ if( me->p_desspeed == 0 || !( ((me->p_dir>=to_left) && (me->p_dir<=to_right)) || ((to_right < to_left) && ((me->p_dir>=to_left) || (me->p_dir<=to_right))) )) { /* the save goes to the closest tractor/pressoring defender */ float distance = 0; int i; struct player *j; shot_toward = NOBODY; for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) { /* skip me, announcer, and the not-alive players */ if ( j->p_status != PALIVE || j==me || j==anncer ) continue; /* if the player is tractor/pressoring me and is on the defending team */ if( (j->p_flags & PFTRACT) && j->p_tractor == me->p_no && j->p_team == KLI ) { int deltaX = j->p_x - me->p_x; int deltaY = j->p_y - me->p_y; float jDist = (float) deltaX*deltaX + deltaY*deltaY; /* and if he's the closest defender */ if( saved_by == NULL || jDist < distance ) { /* give him the save */ saved_by = j; distance = jDist; } } } } } if( saved_by ) { messAll( anncer->p_no,roboname, " %s (%2s) makes the save!", saved_by->p_name, saved_by->p_mapchars); /* update the statistics here (currently disabled) if (status->tourn) { saved_by->p_stats.st_tarmsbomb++; status->armsbomb++; } else { saved_by->p_stats.st_armsbomb++; } */ } /* end "saved shot" stats */ /* find extra information to descirbe the shot */ /* i.e.: is it on goal,etc */ if ((enemy_buf == NULL) || (enemy_buf == NOENEMY)) return; 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) ) { /* If close and within 90 (?) degrees of course, and the deflector is not the last guy to shoot it. */ messAll(me->p_no,roboname," Deflected by %s (%2s)!", enemy_buf->pstruct->p_name, enemy_buf->pstruct->p_mapchars); me->p_desdir = me->p_desdir + random() % 192 - 96; me->p_dir = me->p_desdir; shotby = enemy_buf->e_info; coolpassing=0; /* no deflects in cool passing */ } } if (currp[enemy_buf->pstruct->p_team] != enemy_buf->e_info) { /* new guy in possession */ #ifdef DUAL_ASS int tmp = enemy_buf->pstruct->p_team; lastp[2][tmp] = lastp[1][tmp]; lastp[1][tmp] = currp[tmp]; currp[tmp] = enemy_buf->e_info; #else lastp[enemy_buf->pstruct->p_team] = currp[enemy_buf->pstruct->p_team]; currp[enemy_buf->pstruct->p_team] = enemy_buf->e_info; #endif #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; shotby = enemy_buf->e_info; #ifdef OFFSIDE current_team = enemy_buf->pstruct->p_team; /* RBB */ #endif /* more stuff for announcer, by critter, may97 */ if ((lastshotby!=enemy_buf->e_info) && (roboclock-shotage<75) && (lastteamtoshoot== enemy_buf->pstruct->p_team)) { if(coolpassing++>0) /* after 3 quick passes */ messAll( anncer->p_no,roboname, passing_messages[random()%numpassingmsg], lastteamtoshoot==KLI ? "Klingons" : "Orions"); } else coolpassing=0; lastteamtoshoot=enemy_buf->pstruct->p_team; lastshotby=shotby; /* end of more announcer stuff */ 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))) { // non shot_toward = ORI; // non shot_ongoal = 1; //non } 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_toward = KLI; // non 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 */ cleanup() { 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(); } do_teleport_home() { 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*/ if (tracks[i].t_flags & PU_SITOUT) /* fix stuck-on-wall - critter */ continue; /*Don't do this if sitting out */ 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; } } do_peace() { 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; } } do_msg_check() { 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*** */ do_goalie(who) 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]); } } do_ungoalie(who) 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 */ do_version(comm,mess) 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 */ do_stats_msg(comm,mess) 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 */ do_change_timekeep(who, mflags, sendto) int who, mflags, 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 */ do_force_newgame(who, mflags, sendto) int who, mflags, 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 */ } do_war() { 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; } } } } place_anncer() { 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; } place_sitout(who) 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 */ do_sitout(comm,mess) 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 */ } do_offsides() { 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); } } } } puck_rules() { messAll(anncer->p_no,roboname,"This is Netrek hockey. Send me the message \"help\" for rules."); } #ifdef DUAL_ASS /* All the goals and scoring message are here */ #include "goals_n_scores.h" #else /* Old goals and scoring messages are here */ do_goal(team) 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++; if (status->tourn) { players[currp[team]].p_stats.st_tplanets++; status->planets++; } else { players[currp[team]].p_stats.st_planets++; } } } 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++; 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++; } } #ifdef OT if (tie_game) { messAll(anncer->p_no,roboname, "* Game winner!! %s win!!!",team_names[team]); roboclock = END_OF_PERIOD; } else { messAll(anncer->p_no,roboname,goal_messages[random()%numgoalmsg]); } #else messAll(anncer->p_no,roboname,goal_messages[random()%numgoalmsg]); #endif messAll(anncer->p_no,roboname,"*****************************************************************"); scores[team]++; period_scores[period][team]++; if (!tie_game) do_score(); #ifdef PLANET_LIGHT lightPlanets(); #endif me->p_ship.s_type = STARBASE; me->p_whydead=KPLASMA; me->p_explode=10; me->p_status=PEXPLODE; me->p_whodead=0; /* do_faceoff();*/ } do_score() { 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); } /* ARGSUSED */ do_score_msg(comm,mess) 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); } #endif /* End of standard goal messages */ do_faceoff() { 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(x, y) int x, y; { return((unsigned char) nint((atan2((double) (x - me->p_x), (double) (me->p_y - y)) / 3.14159 * 128.))); } isInPossession(enemy_buf) struct Enemy *enemy_buf; { return ((enemy_buf->pstruct->p_flags & PFTRACT) && (enemy_buf->pstruct->p_tractor == me->p_no)); } isTractoringMe(enemy_buf) 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)); } isPressoringMe(enemy_buf) 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)); } woomp() { 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 */ player_maint() { 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; } #ifdef OFFSIDES /* If the player is offsides and the team is offsides move him back behind the blue line. */ if ((offsides_on) && (j->p_team == team_offsides)) { if (j->p_team == ORI) j->p_y = KLI_B + DYDISPLACE; else j->p_y = ORI_B - DYDISPLACE; } #endif } /*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 */ } } player_bounce() { 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) ) 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 check_offsides(team) int team; { register int i; register struct player *j; register Track *track; int dribbled; float diff_x,diff_y,dist; team_offsides = 0; for (i=0, j=&players[i]; i < MAXPLAYER; i++, j++){ if ( (j->p_status != PALIVE) || (j==me) || (j->p_team != team)) continue; if ( ((team==ORI) && (j->p_y < KLI_B)) || ((team==KLI) && (j->p_y > ORI_B)) ) { if (i == currp[j->p_team]) { diff_x = (float)(j->p_x - me->p_x) ; if (team==ORI) diff_y = (float)(j->p_y - KLI_B) ; else diff_y = (float)(j->p_y - ORI_B) ; dist = sqrt(diff_x*diff_x + diff_y*diff_y); dribbled = (dist < OFFSIDES_BUFFER); if (dribbled) continue; /* dribbler not offsides */ } team_offsides = team; /* Someone is offsides */ messAll(anncer->p_no,roboname," ***Delayed Call: %s (%2s) is offsides .", j->p_name,j->p_mapchars); /* I have not added messTeam yet to this version yet. messTeam(anncer->p_no,roboname,team,"WARNING!!! %s (%2s) is offsides.", j->p_name,j->p_mapchars); */ } /* end of offsides if-then */ } /*end of player loop */ #ifdef PLANET_LIGHT planet_offsides(team_offsides); #endif } check_onsides(team) int team; { 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) || (j->p_team != team)) continue; /* Check if anyone is still offsides */ if ( ((team==ORI) && (j->p_y < KLI_B)) || ((team==KLI) && (j->p_y > ORI_B)) ) team_offsides = team; } /* End of loop */ if (team_offsides==0) { messAll(me->p_no,roboname, " ***The %s are back onsides!",team_names[team]); /* messTeam(me->p_no,roboname,team,"Your team is back on sides."); */ #ifdef PLANET_LIGHT planet_offsides(team_offsides); #endif } } #if defined(NEW_FACEOFF) && defined(OFFSIDE) #include "drop_puck.h" penalty_offsides(team) int team; { /*Place Puck in Neutral Zone*/ if (me->p_x > G_MID) { face_place.p_x = RED_4; me->p_x = RINK_RIGHT; }else{ face_place.p_x = RED_1; me->p_x = RINK_LEFT; } if (team == ORI) face_place.p_y = (R_MID + KLI_B)/2; else face_place.p_y = (R_MID + ORI_B)/2; me->p_y = face_place.p_y; me->p_speed=me->p_desspeed=0; drop_puck(team); /*Send everyone back to start*/ planet_offsides(0); team_offsides = 0; /*Clear Offsides*/ } #else /* Old penalty for OFFSIDE */ penalty_offsides(team) 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; } #endif /* NEW FACEOFF */ #ifdef PLANET_LIGHT planet_offsides(team) int team; { #define IND 0 register int i; if (team == KLI){ /*Klingons are offsides*/ planets[37].pl_owner = ROM; /* Urs */ planets[38].pl_owner = ROM; /* Her */ planets[30].pl_owner = ROM; /* ORI */ }else if (team == ORI){ /*Orions are offsides*/ planets[23].pl_owner = ROM; /* Lal */ planets[29].pl_owner = ROM; /* Cas */ planets[20].pl_owner = ROM; /* KLI */ }else { /*No one is offsides now*/ planets[30].pl_owner = ORI; planets[37].pl_owner = IND; planets[38].pl_owner = IND; planets[20].pl_owner = KLI; planets[23].pl_owner = IND; planets[29].pl_owner = IND; } } #else /* Planet lights */ planet_offsides(team) 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 /* Planet lights */ #endif /* OFFSIDES */ struct Enemy ebuf; struct Enemy * get_nearest() { 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(enemy) 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); } exitRobot() { SIGNAL(SIGALRM, SIG_IGN); 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 PLANET_LIGHT lightPlanets() { #define IND 0 int pln_light,extra; int i; int kli_light,ori_light; kli_light = ROM; ori_light = FED; /* Modification to light up planets for each goal */ 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