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