diff options
author | kamil <kamil@NetBSD.org> | 2020-11-09 23:37:05 +0000 |
---|---|---|
committer | kamil <kamil@NetBSD.org> | 2020-11-09 23:37:05 +0000 |
commit | a931697f3be302466855163a7e216ffee7766445 (patch) | |
tree | 0ac2ab10bd68f8317dcf403536f0d612730ef35c /warp/them.c | |
parent | 6d16c3b48f5f1f377e2be346c1189d9f8edac22d (diff) | |
download | bsdgames-darwin-a931697f3be302466855163a7e216ffee7766445.tar.gz bsdgames-darwin-a931697f3be302466855163a7e216ffee7766445.tar.zst bsdgames-darwin-a931697f3be302466855163a7e216ffee7766445.zip |
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 <larry@wall.org>
Signed-off-by: Kamil Rytarowski <kamil@netbsd.org>
Diffstat (limited to 'warp/them.c')
-rw-r--r-- | warp/them.c | 424 |
1 files changed, 424 insertions, 0 deletions
diff --git a/warp/them.c b/warp/them.c new file mode 100644 index 00000000..da52e04f --- /dev/null +++ b/warp/them.c @@ -0,0 +1,424 @@ +/* $Header: /cvsroot/src/games/warp/them.c,v 1.1 2020/11/09 23:37:05 kamil Exp $ */ + +/* $Log: them.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 <larry@wall.org> +/* Signed-off-by: Kamil Rytarowski <kamil@netbsd.org> +/* + * Revision 7.0.1.5 86/12/12 17:05:41 lwall + * Baseline for net release. + * + * Revision 7.0.1.4 86/10/20 12:32:38 lwall + * Wasn't clearing FRIENDLY flag on pirate creation. + * + * Revision 7.0.1.3 86/10/20 12:15:33 lwall + * Was trying to create pirates from cloaked pirates. + * + * Revision 7.0.1.2 86/10/17 10:03:44 lwall + * Fixed Romulan writing spaces while cloaked. + * + * Revision 7.0.1.1 86/10/16 10:53:39 lwall + * Added Damage. Fixed random bugs. + * + * Revision 7.0 86/10/08 15:14:15 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 "score.h" +#include "term.h" +#include "us.h" +#include "util.h" +#include "weapon.h" +#include "INTERN.h" +#include "them.h" + +void +them_init() +{ + ; +} + +void +their_smarts() +{ + Reg1 OBJECT *curkl; + Reg2 OBJECT *obj; + Reg3 int prob; + Reg4 int count; + Reg5 int y; + Reg6 int x; + + if (numcrushes && (obj=movers)->type == Crusher) { + if (numamoebas) { + y = obj->posy; + x = (obj->posx+(obj->image=='<'?1:-1)+XSIZE00)%XSIZE; + if (amb[y][x] == '~') { + obj->velx = 0; /* stop and munch amoeba */ + modify_amoeba(y,x,1,' ',(int)rand_mod(5+ambsize/10)+1); + if (occupant[y][x] == nuke) /* except go for nucleus */ + obj->velx = (obj->image=='<' ? 1 : -1); + } + else if (!obj->velx) { + if (!rand_mod(4)) + obj->image = rand_mod(2) ? '<' : '>'; + obj->velx = obj->image == '<' ? 1 : -1; + } + } + obj->vely += (rand_mod(222) - 111) / 100; + if (!(rand_mod(100))) { + setimage(obj, (obj->velx *= -1) < 0 ? '>' : '<'); + } + } + if (numamoebas) { + if (!rand_mod(3)) + nuke->velx = nuke->vely = 0; + if (nuke->strategy && ambsize < 90 && !rand_mod(200-smarts)) + modify_amoeba(0,0,0,'~',(int)rand_mod(10)); + if (ambsize > 200 || (ambsize > 100 && !rand_mod(15))) + modify_amoeba(yamblast,xamblast,2,' ',(ambsize-100)/5); + } + for (curkl = enemies; curkl->type == Enemy; curkl = curkl->next) { + if ((curkl->flags & (CLOAKS|FRIENDLY)) == CLOAKS && + (curkl->image != ' ') && + (curkl->energy > 300 || massacre) ) { + setimage(curkl, ' '); + } + if (madgorns) + prob = 3; + else if (curkl->vely || curkl->velx) + prob = massacre?10:20; + else if ((curkl->flags & (PIRATE|FRIENDLY)) == PIRATE) { + /* pirates want to sit sometimes */ + if (curkl->strategy) { + if ((obj = lookimg(curkl->posy, curkl->posx, '@')) || + (obj = lookimg(curkl->posy, curkl->posx, 'B')) ) { + make_plink(obj->posy, obj->posx); + if (!--curkl->strategy) { /* clock ran down */ + if (obj->image == '@') { + obj->image = '*'; + numinhab--; + if (obj->flags & STATIC) + mvaddch(obj->posy+1,obj->posx*2,obj->image); + if (curkl->energy < 20000) + curkl->energy += 5000; + } + prob = 2; /* our work here is done */ + } + else if (obj->image == 'B') { + btorp -= rand_mod(50); + if (btorp < 0) + btorp = 0; + obj->energy -= rand_mod(500); + if (obj->energy < 0) + obj->energy = 0; + prob = 10000; /* stay here */ + } + else + prob = 10000; + } + else { /* it went away--go elsewhere */ + prob = 4; + curkl->strategy = 0; + } + } + else if (lookimg(curkl->posy, curkl->posx, '@') || + lookimg(curkl->posy, curkl->posx, 'B')) { + curkl->strategy = rand_mod(15)+5; + prob = 10000; + } + else + prob = 4; + } + else if (curkl->image == 'M') { /* Mudd wants to sit sometimes */ + if ((obj = lookimg(curkl->posy, curkl->posx, 'E')) || + (obj = lookimg(curkl->posy, curkl->posx, 'B')) ) { + if (obj->image == 'B') { + btorp -= rand_mod(40); + if (btorp < 0) + btorp = 0; + obj->energy -= rand_mod(100); + if (obj->energy < 0) + obj->energy = 0; + } + else if (!obj->vely && !obj->velx) { + etorp -= rand_mod(10); + if (etorp < 0) + etorp = 0; + obj->energy -= rand_mod(20); + if (obj->energy < 0) + obj->energy = 0; + } + prob = 10000; /* stay here */ + } + else /* it went away--go elsewhere */ + prob = 4; + } + else if (curkl->flags & FRIENDLY) { + if (curkl->energy < 10000 && + lookimg(curkl->posy, curkl->posx, '@') ) { + curkl->energy += 100; + prob = 20; /* do some loading */ + } + else + prob = 4; + } + else if (curkl->image == '&') { + if (curkl->flags & COUNTDOWN) { + if (curkl->strategy) + curkl->strategy--; + else + curkl->flags &= ~COUNTDOWN; + prob = 100; /* someone's feeding us, so sit still */ + } + else + prob = 4; + } + else + prob = 4; /* don't sit still too long */ + count = 11; + for (;;) { + if (--count <= 0) /* no opening, just ram something */ + break; + +#ifdef lint + prob = prob; +#endif + if (!(rand_mod(prob))) /* turn randomly occasionally */ + goto accell; + + y=(curkl->posy+curkl->vely+YSIZE00)%YSIZE; /* find prospective */ + x=(curkl->posx+curkl->velx+XSIZE00)%XSIZE; /* new position */ + + if (numamoebas) { + if (curkl == nuke) { + if (amb[y][x] != '~') + goto accell; /* never move nucleus from protoplasm */ + } + else { + if (amb[y][x] == '~' && rand_mod(2)) { + yamblast = y; + xamblast = x; + goto accell; + } + } + } + + obj = occupant[y][x]; + if (!obj) break; /* is anyone there? */ + + switch (obj->type) { + case Star: + if (obj->image == '@' && (curkl->flags & PIRATE)) { + if (curkl->image != 'P' && curkl->image != ' ') { + if (curkl->flags & FRIENDLY) { + curkl->flags &= ~FRIENDLY; + curkl->energy += 1000; + possiblescore += curkl->mass; + inumfriends--; + numfriends--; + inumenemies++; + numenemies++; + } + curkl->image = 'P'; + } + break; /* go ahead and ram the star */ + } + goto accell; /* try not to ram stars */ + case Torp: + if (!obj->vely && !obj->velx && (rand_mod(100) <= smarts) && + (obj->image == 'o' || obj->image == 'O' || obj->image == 'X')) + goto accell; /* try not to ram "friendly" torps */ + break; + case Web: + if (curkl->image != 'T') + goto accell; /* non-Tholians shouldn't ram web */ + if (count <= 5) + break; /* Tholians retrace web if desperate */ + if (obj->image == + (curkl->vely? + (curkl->velx? + (curkl->velx==curkl->vely? + '\\' + : + '/' + ) + : + '|' + ) + : + '-' + ) + ) goto accell; /* Tholians try not to retrace web */ + break; /* No problem with crossing web */ + } + break; /* okay to move over object */ + + accell: + /* determine maximum velocity */ + if (massacre && curkl->image != 'T') { + curkl->vely = rand_mod(7) - 3; + curkl->velx = rand_mod(7) - 3; + } + else if (curkl->image == '&') { + if (rand_mod(2)) { + curkl->vely = rand_mod(3) - 1; + curkl->velx = rand_mod(3) - 1; + } + else { + curkl->vely = curkl->strategy & 3; + if (curkl->vely & 2) + curkl->vely = -1; + curkl->velx = (curkl->strategy >> 2) & 3; + if (curkl->velx & 2) + curkl->velx = -1; + } + } + else if (curkl->energy >= 2500 && curkl->image != 'T') { + curkl->vely = rand_mod(5) - 2; + curkl->velx = rand_mod(5) - 2; + } + else { + curkl->vely = rand_mod(3) - 1; + curkl->velx = rand_mod(3) - 1; + } + } + if (count != 10) { + if (curkl->image == ' ') { + setimage(curkl, curkl->flags & PIRATE ? 'P' : 'R'); + } + if (!count) { + curkl->vely = 0; + curkl->velx = 0; + } + } + if (curkl->image == 'G' && (base||ent) && + !rand_mod((103-smarts)*10) ) { + int xxx,yyy; + + for (xxx = -1; xxx<=1; xxx++) + for (yyy = -1; yyy<=1; yyy++) + if ((xxx||yyy) && rand_mod(2)) + fire_torp(curkl,yyy,xxx); + } + else if (curkl->image == 'T' && (curkl->velx || curkl->vely)) { + Make_object(Web, + curkl->vely? + (curkl->velx? + (curkl->velx==curkl->vely? + '\\' + : + '/' + ) + : + '|' + ) + : + '-', + curkl->posy,curkl->posx,0,0,32767L,32767L,&root); + if (obj && obj->type == Web) { + unmake_object(obj); + occupant[y][x] = Null(OBJECT*); + } + } + } + /* klingon-style fighting */ + if (numamoebas) + attack(nuke); + attack(base); + if (ent && (!cloaked || ent->image=='E' || ent->image=='e')) + attack(ent); +} + +void +modify_amoeba(y,x,where,ch,quant) +Reg1 int y; +Reg2 int x; +int where; +Reg6 int ch; +Reg7 int quant; +{ + Reg3 int dy; + Reg4 int dx; + Reg5 int count = 15; + + if (!numamoebas) + return; + if (!where || (where==1 && rand_mod(2))) { + y = nuke->posy; + x = nuke->posx; + } + if (nuke->strategy && rand_mod(3)) { + dy = nuke->strategy & 3; + if (dy & 2) + dy = -1; + dx = (nuke->strategy >> 2) & 3; + if (dx & 2) + dx = -1; + if (ch == ' ') { /* take from the tail */ + dy = -dy; + dx = -dx; + } + if (!rand_mod(100)) + nuke->strategy = rand_mod(256); + } + else { + dy = rand_mod(3) - 1; + dx = rand_mod(3) - 1; + } + if (!dy && !dx) + return; + do { + if (--count < 0) + return; + y = (y + dy + YSIZE00) % YSIZE; + x = (x + dx + XSIZE00) % XSIZE; + } while (amb[y][x] != ' '); + if (ch == ' ') { + y = (y - dy + YSIZE00) % YSIZE; + x = (x - dx + XSIZE00) % XSIZE; + } + if (ambsize > 100 && quant > 2) { + quant >>= (ambsize/100); + } + if ((nuke->energy += quant << 6) > 32767) + nuke->energy = 32767; + count = quant << 3; /* endless loop catcher */ + while (count-- > 0 && quant > 0) { + if (amb[y][x] != ch) { + quant--; + amb[y][x] = ch; + if (ch == '~') { + ambsize++; + yblasted[y] |= 2; + xblasted[x] |= 2; + blasted = TRUE; + } + else + ambsize--; + if (!occupant[y][x]) + mvaddch(y+1,x*2,ch); + } + y = (y + rand_mod(3) + YSIZE99) % YSIZE; + x = (x + rand_mod(3) + XSIZE99) % XSIZE; + } +} |