Home | History | Annotate | Line # | Download | only in warp
us.c revision 1.1
      1 /* $Header: /tank/opengrok/rsync2/NetBSD/src/games/warp/us.c,v 1.1 2020/11/09 23:37:05 kamil Exp $ */
      2 
      3 /* $Log: us.c,v $
      4 /* Revision 1.1  2020/11/09 23:37:05  kamil
      5 /* Add Warp Kit, Version 7.0 by Larry Wall
      6 /*
      7 /* Warp is a real-time space war game that doesn't get boring very quickly.
      8 /* Read warp.doc and the manual page for more information.
      9 /*
     10 /* games/warp originally distributed with 4.3BSD-Reno, is back to the BSD
     11 /* world via NetBSD. Its remnants were still mentioned in games/Makefile.
     12 /*
     13 /* Larry Wall, the original author and the copyright holder, generously
     14 /* donated the game and copyright to The NetBSD Foundation, Inc.
     15 /*
     16 /* Import the game sources as-is from 4.3BSD-Reno, with the cession
     17 /* of the copyright and license to BSD-2-clause NetBSD-style.
     18 /*
     19 /* Signed-off-by: Larry Wall <larry (at) wall.org>
     20 /* Signed-off-by: Kamil Rytarowski <kamil (at) netbsd.org>
     21 /*
     22  * Revision 7.0.1.3  87/01/13  17:13:21  lwall
     23  * Partially fixed ^S behavior.  It now just ignores ^S.
     24  *
     25  * Revision 7.0.1.2  86/12/12  17:06:09  lwall
     26  * Baseline for net release.
     27  *
     28  * Revision 7.0.1.1  86/10/16  10:53:50  lwall
     29  * Added Damage.  Fixed random bugs.
     30  *
     31  * Revision 7.0  86/10/08  15:14:21  lwall
     32  * Split into separate files.  Added amoebas and pirates.
     33  *
     34  */
     35 
     36 #include "EXTERN.h"
     37 #include "warp.h"
     38 #include "bang.h"
     39 #include "object.h"
     40 #include "play.h"
     41 #include "sig.h"
     42 #include "term.h"
     43 #include "util.h"
     44 #include "weapon.h"
     45 #include "INTERN.h"
     46 #include "us.h"
     47 
     48 void
     49 us_init()
     50 {
     51     ;
     52 }
     53 
     54 void
     55 do_direction(dy,dx)
     56 int dy, dx;
     57 {
     58     Reg1 int decr;
     59     Reg2 OBJECT *obj;
     60 
     61     if (status < 2) {
     62 	if (cloaking) {
     63 	    char ch;
     64 
     65 	    cloaked = FALSE;
     66 	    ch = (ent->energy >= 500?'E':'e');
     67 	    if (ch != ent->image) {
     68 		setimage(ent, ch);
     69 	    }
     70 	}
     71 	decr = 5+abs(evely)+abs(evelx)+tractor*tractor;
     72 	if (ent->energy >= decr) {
     73 	    ent->energy -= decr;
     74 	    if (tractor) {
     75 		if (!damage || !damflag[NOTRACTORS]) {
     76 		    if (!rand_mod(50)) {
     77 			damage++;
     78 			damflag[NOTRACTORS] = rand_mod(smarts+10)+2;
     79 		    }
     80 		    if (tract(ent,dy,dx,tractor)) {
     81 			evely += tractor*dy;
     82 			evelx += tractor*dx;
     83 		    }
     84 		}
     85 	    }
     86 	    else if (!damage ||
     87 	      (!entmode && !damflag[NOIMPULSE]) ||
     88 	      (entmode && !damflag[NOWARP]) ) {
     89 		if (!rand_mod(30+500/(abs(evely)+abs(evelx)+1))) {
     90 		    damage++;
     91 		    damflag[entmode?NOWARP:NOIMPULSE] = rand_mod(smarts+10)+2;
     92 		}
     93 		evely += dy;
     94 		evelx += dx;
     95 	    }
     96 	    if (inumthols &&
     97 	      (obj=occupant[(ent->posy+evely+YSIZE00)%YSIZE]
     98 			   [(ent->posx+evelx+XSIZE00)%XSIZE] ) &&
     99 	      obj->type == Web)
    100 		evely = evelx = 0;
    101 	}
    102     }
    103     else if (status == 2) {
    104 	decr = 500+abs(bvely)*5+abs(bvelx)*5+tractor*tractor*100;
    105 	if (base->energy >= decr) {
    106 	    base->energy -= decr;
    107 	    if (tractor) {
    108 		if (tract(base,dy,dx,tractor)) {
    109 		    bvely += tractor*dy;
    110 		    bvelx += tractor*dx;
    111 		}
    112 	    }
    113 	    else {
    114 		bvely += dy;
    115 		bvelx += dx;
    116 	    }
    117 	    if (inumthols &&
    118 	      (obj=occupant[(base->posy+bvely+YSIZE00)%YSIZE]
    119 			   [(base->posx+bvelx+XSIZE00)%XSIZE] ) &&
    120 	      obj->type == Web)
    121 		bvely = bvelx = 0;
    122 	}
    123     }
    124     tractor = 0;
    125 }
    126 
    127 void
    128 ctrl_direction(dy,dx)
    129 int dy, dx;
    130 {
    131     if (status < 2) {
    132 	if (cloaking) {
    133 	    char ch;
    134 
    135 	    cloaked = FALSE;
    136 	    ch = (ent->energy >= 500?'E':'e');
    137 	    if (ch != ent->image) {
    138 		setimage(ent, ch);
    139 	    }
    140 	}
    141 	if (!damage || !damflag[NOPHASERS]) {
    142 	    if (!rand_mod(200)) {
    143 		damage++;
    144 		damflag[NOPHASERS] = rand_mod(smarts+10)+2;
    145 	    }
    146 	    fire_phaser(ent, dy, dx);
    147 	}
    148     }
    149     else if (status == 2)
    150 	fire_phaser(base, dy, dx);
    151 }
    152 
    153 void
    154 shift_direction(dy,dx)
    155 int dy, dx;
    156 {
    157     if (status < 2) {
    158 	if (cloaking) {
    159 	    char ch;
    160 
    161 	    cloaked = FALSE;
    162 	    ch = (ent->energy >= 500?'E':'e');
    163 	    if (ch != ent->image) {
    164 		setimage(ent, ch);
    165 	    }
    166 	}
    167 	if (!damage || !damflag[NOTORPS]) {
    168 	    if (!rand_mod(300)) {
    169 		damage++;
    170 		damflag[NOTORPS] = rand_mod(smarts+10)+2;
    171 	    }
    172 	    fire_torp(ent, dy, dx);
    173 	}
    174     }
    175     else if (status == 2)
    176 	fire_torp(base, dy, dx);
    177 }
    178 
    179 void
    180 get_commands(done)
    181 bool *done;
    182 {
    183     static char ch[80];
    184     Reg1 int i;
    185     Reg2 int count;
    186     Reg3 bool ctrla = FALSE;
    187     char numdestructs = 0, numzaps = 0;
    188 
    189 top:
    190     while (count = read_nd(ch,(sizeof ch))) {
    191 	for (i=0; i<count; i++) {
    192 	    if (ch[i] == 'Q') {
    193 		bombed_out = TRUE;
    194 		*done = TRUE;
    195 		keepgoing = FALSE;
    196 		return;
    197 	    }
    198 	    if (ch[i] == 'q' || ch[i] == BREAKCH || ch[i] == INTRCH) {
    199 		int x;
    200 		static char quest[] = "Do you wish to escape from reality? ";
    201 
    202 		if (timer >= whenok) {
    203 		    mvaddstr(12,22,quest);
    204 		    do {
    205 			getcmd(&ch[i]);
    206 		    } while (ch[i] != 'y' && ch[i] != 'n');
    207 		    if (ch[i] == 'y') {
    208 			bombed_out = TRUE;
    209 			*done = TRUE;
    210 			return;
    211 		    }
    212 		    else {
    213 			for (x=11; x<=28; x++) {
    214 			    mvaddch(12,x*2,
    215 				occupant[11][x]
    216 				   ? occupant[11][x]->image
    217 				   : numamoebas
    218 				      ? amb[11][x]
    219 				      : ' ');
    220 			    addspace();
    221 			}
    222 			roundsleep(2);
    223 			whenok = timer + 10;
    224 			goto top;
    225 		    }
    226 		}
    227 		else {
    228 		    write(1,"\07",1);
    229 		    goto top;
    230 		}
    231 	    }
    232 	}
    233 	for (i=0; i<count; i++) {
    234 	    if (ctrla) {
    235 		switch (ch[i]) {
    236 		case '1': case 'b':
    237 		    ctrl_direction(1, -1);
    238 		    break;
    239 		case '2': case 'j':
    240 		    ctrl_direction(1, 0);
    241 		    break;
    242 		case '3': case 'n':
    243 		    ctrl_direction(1, 1);
    244 		    break;
    245 		case '4': case 'h':
    246 		    ctrl_direction(0, -1);
    247 		    break;
    248 		case '6': case 'l':
    249 		    ctrl_direction(0, 1);
    250 		    break;
    251 		case '7': case 'y':
    252 		    ctrl_direction(-1, -1);
    253 		    break;
    254 		case '8': case 'k':
    255 		    ctrl_direction(-1, 0);
    256 		    break;
    257 		case '9': case 'u':
    258 		    ctrl_direction(-1, 1);
    259 		    break;
    260 		case 'r':
    261 		    rewrite();
    262 		    roundsleep(3);
    263 		    ctrla = FALSE;
    264 		    goto top;
    265 		case 'w':
    266 		    clear();
    267 		    while (!input_pending())
    268 			sleep(1);
    269 		    rewrite();
    270 		    roundsleep(3);
    271 		    ctrla = FALSE;
    272 		    goto top;
    273 #ifdef SIGTSTP
    274 		case 'z':
    275 		    clear();
    276 		    mytstp();
    277 		    sleep(4);
    278 		    ctrla = FALSE;
    279 		    goto top;
    280 #endif
    281 		default:
    282 		    break;
    283 		}
    284 		ctrla = FALSE;
    285 	    }
    286 	    else {
    287 		switch (ch[i]) {
    288 		case 'Z':
    289 		    clear();
    290 		    mytstp();
    291 		    sleep(4);
    292 		    goto top;
    293 		case 'i':
    294 		    if (ent && (!damage || !damflag[NOIMPULSE])) {
    295 			entmode = 0;
    296 			status = 0;
    297 		    }
    298 		    break;
    299 		case 'w':
    300 		    if (ent && (!damage || !damflag[NOWARP])) {
    301 			entmode = 1;
    302 			status = 1;
    303 		    }
    304 		    break;
    305 		case 'p':
    306 		    if (base) {
    307 			status = 2;
    308 		    }
    309 		    break;
    310 		case 'o':
    311 		    if (status < 2) {
    312 			if (base)
    313 			    status = 2;
    314 		    }
    315 		    else if (status == 2) {
    316 			if (ent)
    317 			    status = entmode;
    318 		    }
    319 		    break;
    320 		case 'v':
    321 		    if (ent) {
    322 			status = entmode;
    323 		    }
    324 		    cloaking=FALSE;
    325 		    cloaked=FALSE;
    326 		    break;
    327 		case 'c':
    328 		    if (ent) {
    329 			status = entmode;
    330 			if (ent->energy >= 250)
    331 			    cloaking = TRUE;
    332 		    }
    333 		    break;
    334 		case 'z':
    335 		    if (ent && (!damage || !damflag[NOZAPPER])) {
    336 			++numzaps;
    337 			if (!rand_mod(100/numzaps)) {
    338 			    damage++;
    339 			    damflag[NOZAPPER] = rand_mod(smarts+10)+2;
    340 			}
    341 			if (nxtbang && bangm[nxtbang-1] < 0)
    342 			    --nxtbang;	/* consolidate zaps */
    343 			make_blast(evely*2+ent->posy,evelx*2+ent->posx,
    344 			    -5000000L, 3*numzaps);
    345 			ent->energy /= 2;
    346 		    }
    347 		    break;
    348 		case 'D':
    349 		    if (status < 2 && (!damage || !damflag[NODESTRUCT])) {
    350 			if (ent && !rand_mod(10)) {
    351 			    damage++;
    352 			    damflag[NODESTRUCT] = rand_mod(smarts+10)+2;
    353 			}
    354 			if (++numdestructs <= 2)
    355 			    make_blast(evely*2+ent->posy,evelx*2+ent->posx,
    356 				15000L, 3);
    357 			ent->energy /= 4;
    358 		    }
    359 		    else if (status == 2) {
    360 			if (numdestructs)
    361 			    base->energy = base->energy / 2;
    362 			if (++numdestructs <= 2)
    363 			    make_blast(base->posy, base->posx, 15000L, 5);
    364 		    }
    365 		    break;
    366 		case 'd':
    367 		    if ((!damage || !damflag[NODESTRUCT]) && (base||ent)) {
    368 			Reg4 OBJECT *obj;
    369 			int x, y;
    370 
    371 			if (ent && !rand_mod(200)) {
    372 			    damage++;
    373 			    damflag[NODESTRUCT] = rand_mod(smarts+10)+2;
    374 			}
    375 			for (obj = root.prev;
    376 			  obj != &root;
    377 			  obj = obj->prev) {
    378 			    if (obj->image == '+') {
    379 				blast[y=(obj->posy+obj->vely+YSIZE00)%YSIZE]
    380 				     [x=(obj->posx+obj->velx+XSIZE00)%XSIZE]
    381 				     += 1;
    382 				yblasted[y] |= 1;
    383 				xblasted[x] |= 1;
    384 				blasted = TRUE;
    385 				obj->mass = (massacre?3000:4000);
    386 			    }
    387 			}
    388 		    }
    389 		    break;
    390 		case 's':
    391 		    if ((!damage || !damflag[NODESTRUCT]) && (base||ent)) {
    392 			Reg4 OBJECT *obj;
    393 			if (ent && !rand_mod(200)) {
    394 			    damage++;
    395 			    damflag[NODESTRUCT] = rand_mod(smarts+10)+2;
    396 			}
    397 			for (obj = root.prev;
    398 			  obj->type == Torp || obj->type == Web ||
    399 			  obj->type == Star;
    400 			  obj = obj->prev) {
    401 			    if (obj->image == '+')
    402 				obj->vely = obj->velx = 0;
    403 			}
    404 		    }
    405 		    break;
    406 		case '\001':
    407 		    ctrla = TRUE;
    408 		    break;
    409 		case '\002':
    410 		case '\003':
    411 		case '\004':
    412 		case '\005':
    413 		case '\006':
    414 		case '\007':
    415 		case '\010':
    416 		case '\011':
    417 		case '\012':
    418 		case '\013':
    419 		case '\014':
    420 		case '\015':
    421 		case '\016':
    422 		case '\017':
    423 		case '\020':
    424 		case '\021':
    425 		case '\022':
    426 		case '\023':
    427 		case '\024':
    428 		case '\025':
    429 		case '\026':
    430 		case '\027':
    431 		case '\030':
    432 		case '\031':
    433 		case '\032':
    434 		    ch[i] += 96;
    435 		    i--;
    436 		    ctrla = TRUE;
    437 		    break;
    438 		case '\033':
    439 		    tractor = 0;
    440 		    break;
    441 		case 'a':
    442 		    tractor++;
    443 		    break;
    444 		case 'r':
    445 		    tractor--;
    446 		    break;
    447 		case '1': case 'b':
    448 		    do_direction(1,-1);
    449 		    break;
    450 		case '2': case 'j':
    451 		    do_direction(1,0);
    452 		    break;
    453 		case '3': case 'n':
    454 		    do_direction(1,1);
    455 		    break;
    456 		case '4': case 'h':
    457 		    do_direction(0,-1);
    458 		    break;
    459 		case '6': case 'l':
    460 		    do_direction(0,1);
    461 		    break;
    462 		case '7': case 'y':
    463 		    do_direction(-1,-1);
    464 		    break;
    465 		case '8': case 'k':
    466 		    do_direction(-1,0);
    467 		    break;
    468 		case '9': case 'u':
    469 		    do_direction(-1,1);
    470 		    break;
    471 		case '0': case 'S':
    472 		    if (status < 2) {
    473 			evely = 0;
    474 			evelx = 0;
    475 		    }
    476 		    break;
    477 		case '-':
    478 		    if (status < 2 && ent->energy >= 10) {
    479 			evely *= -1;
    480 			evelx *= -1;
    481 			ent->energy -= 10;
    482 		    }
    483 		    break;
    484 		case '%': case '\177': case '_':
    485 		    shift_direction(0, -1);
    486 		    shift_direction(0, 1);
    487 		    shift_direction(-1, 0);
    488 		    shift_direction(1, 0);
    489 		    shift_direction(-1, -1);
    490 		    shift_direction(-1, 1);
    491 		    shift_direction(1, -1);
    492 		    shift_direction(1, 1);
    493 		    break;
    494 		case '!': case 'B':
    495 		    shift_direction(1, -1);
    496 		    break;
    497 		case '@': case 'J':
    498 		    shift_direction(1, 0);
    499 		    break;
    500 		case '#': case 'N':
    501 		    shift_direction(1, 1);
    502 		    break;
    503 		case '$': case 'H':
    504 		    shift_direction(0, -1);
    505 		    break;
    506 		case '^': case 'L':
    507 		    shift_direction(0, 1);
    508 		    break;
    509 		case '&': case 'Y':
    510 		    shift_direction(-1, -1);
    511 		    break;
    512 		case '*': case 'K':
    513 		    shift_direction(-1, 0);
    514 		    break;
    515 		case '(': case 'U':
    516 		    shift_direction(-1, 1);
    517 		    break;
    518 		case '?':
    519 		    helper();
    520 		    roundsleep(3);
    521 		    goto top;
    522 		default:
    523 		    break;
    524 		}
    525 	    }
    526 	}
    527     }
    528 }
    529