From a931697f3be302466855163a7e216ffee7766445 Mon Sep 17 00:00:00 2001 From: kamil Date: Mon, 9 Nov 2020 23:37:05 +0000 Subject: Add Warp Kit, Version 7.0 by Larry Wall Warp is a real-time space war game that doesn't get boring very quickly. Read warp.doc and the manual page for more information. games/warp originally distributed with 4.3BSD-Reno, is back to the BSD world via NetBSD. Its remnants were still mentioned in games/Makefile. Larry Wall, the original author and the copyright holder, generously donated the game and copyright to The NetBSD Foundation, Inc. Import the game sources as-is from 4.3BSD-Reno, with the cession of the copyright and license to BSD-2-clause NetBSD-style. Signed-off-by: Larry Wall Signed-off-by: Kamil Rytarowski --- warp/move.c | 698 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 698 insertions(+) create mode 100644 warp/move.c (limited to 'warp/move.c') diff --git a/warp/move.c b/warp/move.c new file mode 100644 index 00000000..5c6123ee --- /dev/null +++ b/warp/move.c @@ -0,0 +1,698 @@ +/* $Header: /cvsroot/src/games/warp/move.c,v 1.1 2020/11/09 23:37:05 kamil Exp $ */ + +/* $Log: move.c,v $ +/* Revision 1.1 2020/11/09 23:37:05 kamil +/* Add Warp Kit, Version 7.0 by Larry Wall +/* +/* Warp is a real-time space war game that doesn't get boring very quickly. +/* Read warp.doc and the manual page for more information. +/* +/* games/warp originally distributed with 4.3BSD-Reno, is back to the BSD +/* world via NetBSD. Its remnants were still mentioned in games/Makefile. +/* +/* Larry Wall, the original author and the copyright holder, generously +/* donated the game and copyright to The NetBSD Foundation, Inc. +/* +/* Import the game sources as-is from 4.3BSD-Reno, with the cession +/* of the copyright and license to BSD-2-clause NetBSD-style. +/* +/* Signed-off-by: Larry Wall +/* Signed-off-by: Kamil Rytarowski +/* + * Revision 7.0.1.2 86/10/20 14:37:06 lwall + * Picked some lint. + * + * Revision 7.0.1.1 86/10/16 10:52:09 lwall + * Added Damage. Fixed random bugs. + * + * Revision 7.0 86/10/08 15:12:40 lwall + * Split into separate files. Added amoebas and pirates. + * + */ + +#include "EXTERN.h" +#include "warp.h" +#include "bang.h" +#include "object.h" +#include "move.h" +#include "play.h" +#include "score.h" +#include "term.h" +#include "them.h" +#include "us.h" +#include "util.h" +#include "weapon.h" +#include "INTERN.h" +#include "move.h" + +void +move_init() +{ + ; +} + +void +bounce(obj) +Reg4 OBJECT *obj; +{ + Reg1 int x; + Reg2 int y; + Reg3 int count=0; + + y = (obj->posy - sgn(obj->vely) + YSIZE00) % YSIZE; + x = (obj->posx - sgn(obj->velx) + XSIZE00) % XSIZE; + while (occupant[y][x]) { + y = (y + rand_mod(3) - 1 + YSIZE00) % YSIZE; + x = (x + rand_mod(3) - 1 + XSIZE00) % XSIZE; + if (++count > 10000) { /* if universe full, get out of it fast */ + unmake_object(obj); + if (ent) unmake_object(ent); + if (base) unmake_object(base); + finish = 1; + return; + } + } + obj->posy = y; + obj->posx = x; + obj->vely = 0; + obj->velx = 0; + occupant[y][x] = obj; + if (numamoebas && obj->image == ' ') + mvaddc(y+1, x*2, amb[y][x]); + else + mvaddc(y+1, x*2, obj->image); +} + +void +move_universe() +{ + Reg1 OBJECT *curobj; + Reg2 int x; + Reg3 int y; + Reg4 OBJECT *temp; + OBJECT *thenext; + + for (curobj = movers; curobj != &root; curobj = curobj->next) { + x = curobj->posx; + y = curobj->posy; + if (curobj == occupant[y][x]) { + occupant[y][x] = 0; + } + else if (curobj->type != Torp && curobj->type != Web) { + resetty(); + abort(); + } + } + for (curobj = movers; curobj != &root; curobj = thenext) { + thenext = curobj->next; + if (curobj->vely || curobj->velx) { + y = curobj->posy; + x = curobj->posx; + if (curobj->image != ' ' && + (!(temp=occupant[y][x]) || temp->image==' ') ) { + move(y+1, x*2, numamoebas ? amb[y][x] : ' '); + } + y = (y + curobj->vely + YSIZE00) % YSIZE; + x = (x + curobj->velx + XSIZE00) % XSIZE; + if (!(temp=occupant[y][x]) || temp->type != Star || + curobj->type != Torp || curobj->image == '+' || + curobj->image == 'x') { + curobj->posy = y; + curobj->posx = x; + } + else { + if (curobj->image == '0') { + curobj->vely = rand_mod(3)-1; + curobj->velx = rand_mod(3)-1; + } + else + curobj->vely = curobj->velx = 0; + y = curobj->posy; + x = curobj->posx; + } + } + else { /* not moving */ + y = curobj->posy; + x = curobj->posx; + if (curobj->type == Torp || + curobj->type == Star || + curobj->type == Web) { + curobj->flags |= STATIC; + curobj->next->prev = curobj->prev; + curobj->prev->next = curobj->next; + curobj->prev = movers->prev; + curobj->next = movers; + movers->prev->next = curobj; + movers->prev = curobj; + } + } + if (temp = occupant[y][x]) { /* already occupied? */ + if (!temp->contend) { + if (temp->type == Torp) { + if (temp->image == '+') + blast[y][x] += 1250; + else if (temp->image == 'o' && (base||ent)) + blast[y][x] += 500+super*20; + else if (temp->image == 'O' && (base||ent)) + blast[y][x] += 5000+super*100; + } + } + yblasted[y] |= 1; + xblasted[x] |= 1; + blasted = TRUE; + curobj->contend = temp; + occupant[y][x] = curobj; + switch (curobj->type) { + case Enemy: + if (numamoebas && curobj == nuke && temp->image == '+') + blast[y][x] += 80000; + else if (temp->type == Enemy) + blast[y][x] += 10; + else + goto defblast; + break; + case Crusher: + if (curobj->velx) + blast[y][x] += 100000; + else + goto defblast; + break; + case Torp: + if (curobj->image == '+') + blast[y][x] += (temp==nuke ? 80000 : 1250); + else if (curobj->image == 'o') + blast[y][x] += 500+super*20; + else if (curobj->image == 'O') + blast[y][x] += 5000+super*100; + goto defblast; + case Star: + if (temp == ent) + goto damshield; + goto defblast; + case Enterprise: + if (temp->type == Star) { + damshield: + if (!rand_mod(10)) { + if (!damflag[NOSHIELDS]) + damage++; + if (damflag[NOSHIELDS] < 100) + damflag[NOSHIELDS] += rand_mod(smarts)/5+2; + } + } + goto defblast; + default: + defblast: + blast[y][x] += rand_mod(751)+1; + break; + } + } + else { + occupant[y][x] = curobj; + if (curobj->image != ' ' && + (curobj->velx || curobj->vely || + curobj->type == Torp || curobj->type == Web) ) { + mvaddc(y+1, x*2, curobj->image); + } + if (curobj->type == Crusher && curobj->velx) { + blast[y][x] += 100000; + yblasted[y] |= 1; + xblasted[x] |= 1; + blasted = TRUE; + } + } + } + if (blasted) { + Reg7 int minxblast = -1; + Reg8 int maxxblast = -2; + Reg5 long tmpblast; + + blasted = numamoebas; + for (x=0; ximage == '&') + tmpblast >>= 1; + else if (temp->type == Web) + tmpblast = 100000; + else + tmpblast += 50 + temp->energy/100; + if (tmpblast > 250 && !rand_mod(5+(inumstars>>4))) + modify_amoeba(y,x,1,'~',5); + } + xblasted[x] = 2; + yblasted[y] = 2; + } + if (tmpblast) { + Reg6 OBJECT *biggie = 0; + + blast[y][x] = 0; + temp = occupant[y][x]; + if (tmpblast < 0) { + if (numamoebas && tmpblast < -1000000 && + amb[y][x] == '~' && temp != nuke) { + amb[y][x] = ' '; + if (!temp) + make_plink(y,x); + ambsize--; + } + tmpblast = 0; + } + if (temp) { + if ((!numamoebas || amb[y][x]==' ') && + tmpblast < 100000) + make_plink(y,x); + for ( ;temp; + temp = curobj->contend,curobj->contend = 0){ + curobj = temp; + switch (curobj->type) { + case Enterprise: { + long tmp = curobj->energy; + + if (ent->energy>500 || apolloflag & 1) + curobj->energy -= tmpblast / + ((apolloflag & 1) + ? 20 + : (5+abs(ent->velx)+abs(ent->vely)) + / ((damflag[NOSHIELDS]>>3)+1)+1); + else + curobj->energy -= tmpblast; + if (rand_mod(1 + tmp - curobj->energy) > 100 + || ent->energy < (entmax>>1)) { + if (debug & 128 || + (damage <= smarts/10 && + !rand_mod(6-smarts/20-massacre) )) { + tmp = rand_mod(MAXDAMAGE); + if (damflag[tmp]) { + if (damflag[tmp] < 60) + damflag[tmp] += rand_mod(60); + } + else { + damflag[tmp] = + rand_mod(smarts+10)+2; + damage++; + } + } + } + break; + } + case Base: + if (base->energy > 1000 || apolloflag & 2) + curobj->energy -= tmpblast / + ((apolloflag & 2)?20:5); + else + curobj->energy -= tmpblast; + break; + case Crusher: + if (tmpblast > 132767) + curobj->energy -= (tmpblast - 100000); + else if (tmpblast >= 100000) { + curobj->energy += (tmpblast - 100000); + if (curobj->energy > 32767) + curobj->energy = 32767; + } + else /* vulnerable while feeding */ + curobj->energy -= tmpblast; + break; + case Enemy: + curobj->energy -= tmpblast*10/enemshields; + break; + default: + curobj->energy -= tmpblast; + break; + } + if (curobj->energy < 0) { /* killed it? */ + switch (curobj->image) { + case 'A': + tmpblast = 100000; + make_blast(y,x,8192L,1); + numapollos = apolloflag = 0; + numstars--; + numenemies--; + curscore += 5000; + deados = 0; + break; + case 'E': case 'e': case 'C': case 'c': + ent = 0; + numents--; + if (base) + status = 2; + else + status = 3; + deados = 0; + break; + case 'B': case 'b': + base = 0; + numbases--; + if (ent) + status = entmode; + else + status = 3; + deados = 0; + break; + case '&': { + int i, xxx, yyy; + + for (i = 0; i < YSIZE; i++) + yblasted[i] &= 1; + for (i = 0; i < XSIZE; i++) + xblasted[i] &= 1; + numamoebas = 0; /* ignore amb[][] now */ + for (yyy = 0; yyy < YSIZE; yyy++) { + for (xxx = 0; xxx < XSIZE; xxx++) { + if (amb[yyy][xxx] == '~' && + !occupant[yyy][xxx]) { + mvaddch(yyy+1,xxx*2,' '); + } + } + } + numenemies--; + curscore += 10000; + if (curobj == enemies) + enemies = curobj->next; + deados = 0; + break; + } + case '<': case '>': { + int i; + + numenemies--; + numcrushes = 0; + curscore += 10000; + if (curobj == movers) + movers = curobj->next; + if (curobj == enemies) + enemies = curobj->next; + deados = 0; + + tmpblast = 100000; + make_blast(y,(x+XSIZE00)%XSIZE,10000L,0); + if (curobj->image == '<') { + for (i=XSIZE00; i<=XSIZE01; i++) + make_blast(y,(x+i)%XSIZE, + 10000L,0); + for (i=XSIZE00; i<=XSIZE02; i++) + make_blast(y,(x+i)%XSIZE, + 10000L,0); + make_blast(y,(x+XSIZE03)%XSIZE, + 10000L,1); + for (i=XSIZE00; i<=XSIZE08; i++) + make_blast(y,(x+i)%XSIZE, + 10000L,0); + } + else { + for (i=XSIZE00; i>=XSIZE99; i--) + make_blast(y,(x+i)%XSIZE, + 10000L,0); + for (i=XSIZE00; i>=XSIZE98; i--) + make_blast(y,(x+i)%XSIZE, + 10000L,0); + make_blast(y,(x+XSIZE97)%XSIZE, + 10000L,1); + for (i=XSIZE00; i>=XSIZE92; i--) + make_blast(y,(x+i)%XSIZE, + 10000L,0); + } + } + break; + case 'K': + numenemies--; + curscore += curobj->mass; + if (curobj == enemies) + enemies = curobj->next; + deados = 0; + break; + case 'T': + numenemies--; + curscore += curobj->mass*3/2; + if (curobj == enemies) + enemies = curobj->next; + deados = 0; + break; + case 'R': case ' ': case 'P': + numenemies--; + if (curobj->flags & PIRATE) + curscore += curobj->mass; + else + curscore += curobj->mass*3; + if (curobj == enemies) + enemies = curobj->next; + deados = 0; + break; + case 'G': + numenemies--; + numgorns--; + tmpblast = 100000; + if (madgorns) + curscore += curobj->mass/2; + else + curscore += curobj->mass*2; + if (curobj == enemies) + enemies = curobj->next; + { + int xxx,yyy; + + for (xxx = -1; xxx<=1; xxx++) + for (yyy = -1; yyy<=1; yyy++) + if (rand_mod(2+massacre)) + fire_torp(curobj, + yyy,xxx); + } + deados = 0; + break; + case '@': + numinhab--; + /* FALL THROUGH */ + case '*': + banging = TRUE; + numstars--; + break; + case '|': case '-': case '/': case '\\': + tmpblast = 100000; + make_blast(y,x,curobj->mass,1); + banging = TRUE; + deados = 0; + break; + case 'x': + curscore += 10; + deados = 0; + break; + case 'X': + curscore += 100; + numxes--; + deados = 0; + break; + case '0': + curscore += 35; + numos--; + deados += 3; + break; + case 'o': + curscore += 100; + numos--; + deados++; + break; + case 'O': + curscore += 200; + numos--; + deados += 2; + break; + case 'M': + deadmudds++; + inumfriends--; + numfriends--; + if (curobj == enemies) + enemies = curobj->next; + break; + case 'Q': case 'W': case 'Y': case 'U': + case 'I': case 'S': case 'D': case 'H': + case 'J': case 'L': case 'Z': case 'V': + case 'F': + numfriends--; + if (curobj == enemies) + enemies = curobj->next; + if (inumfriends < 10) + madfriends += 500; + else + madfriends += 10000/inumfriends; + break; + } + if (tmpblast < 100000) + make_blast(y,x,curobj->mass,1); + unmake_object(curobj); + } + else { /* didn't kill anything */ + if (!biggie) + biggie = curobj; + else { + if (biggie->mass > curobj->mass) + bounce(curobj); + else { + bounce(biggie); + biggie = curobj; + } + } + } + } + if (biggie) { + occupant[y][x] = biggie; + if (numamoebas && biggie->image == ' ') + mvaddch(y+1,x*2, amb[y][x]); + else + mvaddch(y+1,x*2, biggie->image); + } + else { + occupant[y][x] = 0; + mvaddch(y+1, x*2, numamoebas ? amb[y][x] : ' '); + } + } + } + } + } + } + } + do_bangs(); + if (numcrushes && movers->type == Crusher) + movers->vely = 0; + if (curobj = base) { + char ch; + + curobj->velx = 0; + curobj->vely = 0; + curobj->energy += 25*lookaround(curobj->posy,curobj->posx,Star); + if (curobj->energy > basemax) + curobj->energy = basemax; + if (curobj->energy >= 1000) + ch = 'B'; + else + ch = 'b'; + if (ch != curobj->image) { + setimage(curobj, ch); + } + } + if (curobj = ent) { + char ch; + + if (entmode == 0) { + curobj->velx = 0; + curobj->vely = 0; + } + if (base && !cloaking && !curobj->velx && !curobj->vely && + lookfor(curobj->posy,curobj->posx,Base)) { + int tmp; + +#ifdef lint + tmp = 0; +#else + tmp = (int) (base->energy - 1000 < entmax - curobj->energy ? + base->energy - 1000 : entmax - curobj->energy); +#endif + if (tmp < 0) + tmp = 0; + curobj->energy += tmp; + base->energy -= tmp; + tmp = (btorp < 50 - etorp ? + btorp : 50 - etorp); + etorp += tmp; + btorp -= tmp; + if (damage) { + tmp = rand_mod(MAXDAMAGE); + if (damflag[tmp] > 5) { + damflag[tmp] = rand_mod(5)+1; + } + } + } + if (curobj->energy >= 500 && (!damage || !damflag[NOSHIELDS])) + ch = cloaked?'C':'E'; + else + ch = cloaked?'c':'e'; + if (ch != curobj->image) { + setimage(curobj, ch); + } + } +} + +int +lookaround(y, x, what) +Reg1 int y; +Reg2 int x; +Reg4 char what; +{ + Reg3 OBJECT *obj; + Reg5 int count=0; + Reg6 int xp; + Reg7 int xm; + + if ((obj=occupant[y][xp=(x+XSIZE01)%XSIZE])&&obj->type == what) /* 0, 1 */ + count++; + if ((obj=occupant[y][xm=(x+XSIZE99)%XSIZE])&&obj->type == what) /* 0, -1 */ + count++; + if ((obj=occupant[y=(y+YSIZE99)%YSIZE][xp])&&obj->type == what) /* -1, 1 */ + count++; + if ((obj=occupant[y][x])&&obj->type == what) /* -1, 0 */ + count++; + if ((obj=occupant[y][xm])&&obj->type == what) /* -1, -1 */ + count++; + if ((obj=occupant[y=(y+2)%YSIZE][xp])&&obj->type == what) /* 1, 1 */ + count++; + if ((obj=occupant[y][x])&&obj->type == what) /* 1, 0 */ + count++; + if ((obj=occupant[y][xm])&&obj->type == what) /* 1, -1 */ + count++; + return (count); +} + +int +lookfor(y, x, what) +Reg1 int y; +Reg2 int x; +Reg4 char what; +{ + Reg3 OBJECT *obj; + Reg5 int xp; + Reg6 int xm; + + if ((obj=occupant[y][xp=(x+XSIZE01)%XSIZE])&&obj->type == what ||/* 0, 1 */ + (obj=occupant[y][xm=(x+XSIZE99)%XSIZE])&&obj->type == what ||/* 0, -1 */ + (obj=occupant[y=(y+YSIZE99)%YSIZE][xp])&&obj->type == what ||/* -1, 1 */ + (obj=occupant[y][x])&&obj->type == what ||/* -1, 0 */ + (obj=occupant[y][xm])&&obj->type == what ||/* -1,-1 */ + (obj=occupant[y=(y+2)%YSIZE][xp])&&obj->type == what ||/* 1, 1 */ + (obj=occupant[y][x])&&obj->type == what ||/* 1, 0 */ + (obj=occupant[y][xm])&&obj->type == what) /* 1, -1 */ + return(1); + return (0); +} + +OBJECT* +lookimg(y, x, what) +Reg1 int y; +Reg2 int x; +Reg4 char what; +{ + Reg3 OBJECT *obj; + Reg5 int xp; + Reg6 int xm; + + if ((obj=occupant[y][xp=(x+XSIZE01)%XSIZE])&&obj->image==what ||/* 0, 1 */ + (obj=occupant[y][xm=(x+XSIZE99)%XSIZE])&&obj->image==what ||/* 0, -1 */ + (obj=occupant[y=(y+YSIZE99)%YSIZE][xp])&&obj->image==what ||/* -1, 1 */ + (obj=occupant[y][x])&&obj->image==what ||/* -1, 0 */ + (obj=occupant[y][xm])&&obj->image==what ||/* -1,-1 */ + (obj=occupant[y=(y+2)%YSIZE][xp])&&obj->image==what ||/* 1, 1 */ + (obj=occupant[y][x])&&obj->image==what ||/* 1, 0 */ + (obj=occupant[y][xm])&&obj->image==what) /* 1, -1 */ + return obj; + return Null(OBJECT*); +} -- cgit v1.2.3-56-ge451