|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T o
Length: 12543 (0x30ff)
Types: TextFile
Names: »order.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Gb/order.c«
/*
* Galactic Bloodshed (Robert Chansky, smq@b)
* order.c -- give orders to ship
*/
#include "vars.h"
#include "ships.h"
#include <curses.h>
#include <ctype.h>
#include <setjmp.h>
#include <signal.h>
#include <math.h>
extern jmp_buf main_jenv;
char *prin_aimed_at(), *prin_ship_dest();
extern int Ignore_filelocks;
int order_shdata,order_pdata,order_stardata;
static bool first,prerror,was_obj = 0;
order(APcount, argn,args)
int APcount;
int argn;
char args[MAXARGS][COMMANDSIZE];
{
int i,shipno,Sdatamod=0;
int order_handler();
bool err;
order_shdata = order_pdata = order_stardata = NEUTRAL_FD;
signal(SIGINT, order_handler);
first = 1;
prerror = 0;
clear(); move(0,0);
if (argn>=2) {
if (args[1][0]=='#') {
/* a ship was specified, order only that ship */
if (sscanf(args[1],"#%d",&shipno)!=1)
DontOwnErr(shipno);
else
give_orders(APcount, shipno, 1);
} else {
printf("usage: order [#shipnum]\n");
return;
}
} else {
/* no ship specified, order all ships,planets in scope */
switch (Dir.level) {
case LEVEL_UNIV:
for (i=0; i<MAXUSHIPS; i++)
if (Sdata.shipnums[i] && enufAP(Sdata.AP, APcount))
Sdatamod |= give_orders(APcount, Sdata.shipnums[i], 0);
for (i=0; i<Sdata.numstars; i++)
star_give_orders(APcount, i);
if (Sdatamod)
deductAPs(APcount, 0, 1);
break;
case LEVEL_STAR:
if (enufAP(Stars[Dir.snum]->AP, APcount)) {
if (star_give_orders(APcount, Dir.snum))
deductAPs(APcount, Stars[Dir.snum], 1);
}
break;
case LEVEL_PLAN:
if (enufAP(Stars[Dir.snum]->AP, APcount)) {
if (plan_give_orders(APcount, Stars[Dir.snum]->planetpos[Dir.pnum]))
deductAPs(APcount, Stars[Dir.snum], 1);
}
break;
case LEVEL_SHIP:
give_orders(APcount, Dir.shipno, 1); /* 1 == objects are ok */
break;
}
}
/* move to bottom of screen */
move(stdscr->_maxy-2,0);
refresh();
}
/* various prompt locations so we don't have to remember the #'s */
#define Opromptx 19
#define Oprompty 7
#define Erry (Oprompty+1)
#define Spromptx (25+PLACENAMESIZE)
#define Sprompty 2
#define Tpromptx Spromptx
#define Tprompty 4
#define Dprompty 2
#define Dpromptx 15
#define SWprompty 4
#define SWpromptx 2
#define Bprompty 6
int give_orders(APcount, shipno, obj)
int APcount;
int shipno,obj;
{
bool Mod=0,q=0,redraw=1;
placetype where,pl;
int i = 0;
shiptype *ship, *oldship, ship2;
char c,s[PLACENAMESIZE];
openshdata(&order_shdata);
if (!getship(order_shdata,&ship,shipno)) {
order_handler();
}
ship2 = *ship; /* copy for ESC command */
oldship = &ship2;
/* cannot order docked ships */
/* or objects, when object option is on */
if (ship->owner==Playernum) {
if (is_object(ship) && !obj) {
printw("%s #%d is not a ship. (order with ``order #%d'')\n",
Shipnames[ship->type], shipno, shipno);
i = 1;
}
if (ship->is_docked && !is_object(ship)) {
printw("%s #%d is docked.\n",Shipnames[ship->type], shipno);
i = 1;
}
if (ship->rad) {
printw("%s #%d has been irradiated; it cannot respond to orders.\n",
Shipnames[ship->type], shipno);
i = 1;
}
if (!ship->popn && Shipdata[ship->type][ABIL_MAXCREW] > 0) {
printw("%s #%d has no crew and is not a robotic ship.\n",
Shipnames[ship->type], shipno);
i = 1;
}
if (i) {
free(ship); close(order_shdata);
printw("\nhit a key to continue: ");
refresh();
tty_on(); getchr(); tty_off();
putchr('\n');
return;
}
do {
if (redraw) {
redraw = 0;
if (first || was_obj!=is_object(ship)) {
clear();
first = 0;
} else if (prerror) {
move(Oprompty,Opromptx); /* clear error message */
clrtoeol();
}
move(0,0);
printw("%13s #%-4d at '%s'. (%2d APs)",
Shipnames[ship->type], shipno, prin_ship_orbits(ship),
ship->whatorbits==LEVEL_UNIV ? Sdata.AP[Playernum] :
Stars[ship->storbits]->AP[Playernum]);
if (can_move(ship)) {
move(2,0);
printw("(d)estination: %*s", -PLACENAMESIZE, prin_ship_dest(ship));
if (ship->type!=STYPE_POD) {
move(Sprompty,Spromptx-9);
printw("(s)peed: %d\n",ship->speed);
}
}
if (ship->type==STYPE_MIRROR) {
was_obj = 1;
move(4,0);
printw("(a)imed at: %s", prin_aimed_at(ship));
printw("\n (i)ntensity: %3d",ship->orders.aimed_at.intensity);
} else if (ship->type==STYPE_MINE) {
move(Tprompty,Tpromptx-18);
printw("(t)rigger radius: %d", ship->orders.object.number);
} else if (can_move(ship) && Shipdata[ship->type][ABIL_DESTCAP]) {
was_obj = 0;
move(Bprompty,0); clrtoeol();
if (ship->orders.o.bombard)
if (ship->whatdest==LEVEL_PLAN)
printw("(b)OMBARD planet %s",
ship->whatdest==LEVEL_PLAN ?
prin_ship_dest(ship) : "" );
else
printw("(b)OMBARD ON (no planet specified)");
else
printw("(b)ombard off");
}
if (has_switch(ship)) {
move(SWprompty,SWpromptx);
printw("(o)%s", ship->orders.object.on ? "n" : "ff");
}
move(Oprompty,0);
printw("orders (");
if (can_move(ship))
printw("dsi%s ESC?):",ship->type==STYPE_MIRROR ? "a" : "tm");
else
printw("O%s ESC?):",ship->type==STYPE_MINE?"t":"");
}
move(Oprompty,Opromptx);
clrtoeol();
refresh();
tty_on();
do {
c = getchr();
} while (iscntrl(c) && c!='');
switch (c) {
case '': { shiptype *tempship;
tempship = oldship;
ship = oldship;
oldship = tempship;
redraw = 1;
Mod=0;
touchwin();
} break;
case 'o':
/* on/off switch */
if (has_switch(ship)) {
move(SWprompty,SWpromptx);
ship->orders.object.on = !ship->orders.object.on;
printw("(o)%s", ship->orders.object.on ? "n " : "ff");
Mod = 1;
if (ship->orders.object.on) {
move(SWprompty+1,SWpromptx);
switch (ship->type) {
case STYPE_MINE:
printw("Mine armed and ready.");
break;
case OTYPE_TRANSDEV:
printw("Ready to receive.");
break;
default: break;
}
}
}
break;
case 'd':
if (can_move(ship)) {
move(Dprompty,Dpromptx);
printw("%*s", PLACENAMESIZE-1, " ");
move(Dprompty,Dpromptx);
refresh();
tty_off();
if ((c = getchr())!='\n') {
ungetc(c,stdin);
scanw("%43s",s);
move(Erry,0); refresh();
Ignore_filelocks = 1;
where = Getplace(s, 1);
Ignore_filelocks = 0;
if (!where.err) {
if (where.level==LEVEL_SHIP) {
/*if (sqrt(Distsq(ship->xpos, ship->ypos, where.shipptr->xpos,where.shipptr->ypos))<SYSTEMSIZE*2.0) {*/
ship->destshipno = where.shipno;
ship->whatdest = LEVEL_SHIP;
/*} else { move(Erry,0); printw("Ship #%d can't find ship #%d.", shipno, where.shipno); }*/
} else {
ship->whatdest = where.level;
ship->deststar = where.snum;
ship->destpnum = where.pnum;
}
}
}
tty_on();
move(Dprompty,Dpromptx);
printw("%*s", -PLACENAMESIZE, prin_ship_dest(ship) );
Mod=1;
} else
makerr(c);
break;
case 's':
if (can_move(ship) && ship->type!=STYPE_POD) {
do {
mvaddch(Sprompty, Spromptx, '?');
move(Sprompty, Spromptx);
refresh();
c = getchr();
if (c=='?') {
move(10,0);
clrtobot();
printw("Speed:\n 0 -- Full stop\n 1 -- Slow (fuel efficient)\n 2 -- Standard\n 3 -- Flank (wastes fuel)\n 4 -- RAMMING SPEED, MR. SULU!!");
move(Sprompty, Spromptx);
refresh();
} else if (isspace(c)) {
c = ship->speed + '0';
} else if (c<'0' || c>'4') {
move(Sprompty,Spromptx);
printw("Bad value %c.",c);
refresh();
c = '?';
}
} while (c=='?');
ship->speed = c - '0';
Mod=1;
} else
makerr(c);
break;
case 't':
if (ship->type==STYPE_MINE) {
move(Tprompty,Tpromptx);
refresh(); tty_off();
scanw("%hd", &ship->orders.object.number);
tty_on();
if (ship->orders.object.number > 200)
ship->orders.object.number = 200;
else if (ship->orders.object.number < 0)
ship->orders.object.number = 0;
move(Tprompty,Tpromptx);
printw("%d ",ship->orders.object.number);
} else
makerr(c);
break;
case 'a':
if (ship->type==STYPE_MIRROR) {
if (ship->fuel >= 0.3) {
move(4,12);
printw("%*s", PLACENAMESIZE-1, " ");
refresh();
tty_off();
if ((c=getchr())!='\n') {
ungetc(c,stdin);
scanw("%43s", s);
move(Erry,0);
refresh();
pl = Getplace(s,1);
if (pl.err) {
break;
} else {
ship->orders.aimed_at.level = pl.level;
ship->orders.aimed_at.pnum = pl.pnum;
ship->orders.aimed_at.snum = pl.snum;
ship->orders.aimed_at.shipno = pl.shipno;
ship->fuel -= 0.3;
Mod=1;
}
}
move(4,12);
printw("%*s", -PLACENAMESIZE, prin_aimed_at(ship) );
} else {
move(Erry,0);
printw("Not enough fuel (%.2f).",ship->fuel);
}
}
break;
case 'i':
if (ship->type==STYPE_MIRROR) { unsigned i;
move(5,14); refresh();
tty_off(); /* unset cbreak */
if ((c=getchr())!='\n') {
ungetc(c,stdin);
scanw("%u",&i);
ship->orders.aimed_at.intensity = i;
Mod=1;
if (ship->orders.aimed_at.intensity>100)
ship->orders.aimed_at.intensity=100;
else if (ship->orders.aimed_at.intensity<0)
ship->orders.aimed_at.intensity=0;
}
move(5,14);
printw("%3d",ship->orders.aimed_at.intensity);
tty_on();
} else
makerr(c);
break;
case 'b':
if (!is_object(ship) && ship->type!=STYPE_MIRROR && ship->type!=STYPE_MINE && Shipdata[ship->type][ABIL_DESTCAP]) {
move(Bprompty,0);
clrtoeol();
ship->orders.o.bombard = !ship->orders.o.bombard;
Mod=1;
if (ship->orders.o.bombard)
if (ship->whatdest==LEVEL_PLAN)
printw("(b)OMBARD planet %s",
ship->whatdest==LEVEL_PLAN ?
prin_ship_dest(ship) : "" );
else
printw("(b)OMBARD ON (no planet specified)");
else
printw("(b)ombard off");
} else
makerr(c);
break;
case '?':
move(10,0); clrtobot();
if (can_move(ship))
printw(" d -- destination\n s -- speed\n");
if (ship->type==STYPE_MIRROR)
printw(" a -- object aimed at\n i -- intensity\n");
else if (has_switch(ship))
printf(" o -- turn object on/off\n");
if (ship->type==STYPE_MINE)
printf(" t -- trigger radius\n");
printw("ESC-- reset all orders\n");
printw("' '-- adv to next ship/object\n");
printw(" ? -- help\n");
printw("^C -- quit order\n");
break;
case ' ': /* no orders */
break;
default:
makerr(c);
break;
}
} while (c!=' ');
putship(order_shdata,ship,shipno);
}
close(order_shdata);
free(ship);
free(oldship);
return Mod;
}
int plan_give_orders(APcount, filepos)
int APcount;
register int filepos; /* filepos of planet */
{
register int i;
planettype *p;
int plan_give_orders_pdata,Planmod=0;
openpdata(&plan_give_orders_pdata);
getplanet(plan_give_orders_pdata,&p,filepos);
close(plan_give_orders_pdata);
for (i=0; i<MAXPSHIPS; i++)
if (p->shipnums[i])
Planmod |= give_orders(APcount, p->shipnums[i]);
free(p);
return Planmod;
}
int star_give_orders(APcount, num)
int APcount;
register int num;
{
register int i=0,Starmod=0;
while (i<MAXSSHIPS)
if (Stars[num]->shipnums[i++])
Starmod |= give_orders(APcount, Stars[num]->shipnums[i-1]);
for (i=0; i<Stars[num]->numplanets; i++)
Starmod |= plan_give_orders(APcount, Stars[num]->planetpos[i]);
return Starmod;
}
/*
* return what the ship is aimed at, if it's a mirror
*/
char *prin_aimed_at(ship)
shiptype *ship;
{
placetype targ;
targ.level = ship->orders.aimed_at.level;
targ.snum = ship->orders.aimed_at.snum;
targ.pnum = ship->orders.aimed_at.pnum;
targ.shipno = ship->orders.aimed_at.shipno;
return Dispplace(&targ);
}
char *prin_ship_dest(ship)
shiptype *ship;
{
placetype dest;
dest.level = ship->whatdest;
dest.snum = ship->deststar;
dest.pnum = ship->destpnum;
dest.shipno = ship->destshipno;
return Dispplace(&dest);
}
makerr(c)
char c;
{
move(Oprompty,Opromptx);
printw("'%c':illegal order.",c);
move(Oprompty,Opromptx);
refresh();
}
order_handler(sig, code, scp)
int sig,code;
struct sigcontext *scp;
{
Ignore_filelocks = 0;
close(order_shdata);
close(order_pdata);
close(order_stardata);
longjmp(main_jenv,1);
}