1/* Header: them.c,v 7.0.1.5 86/12/12 17:05:41 lwall Exp */ 2 3/* Log: them.c,v 4 * Revision 7.0.1.5 86/12/12 17:05:41 lwall 5 * Baseline for net release. 6 * 7 * Revision 7.0.1.4 86/10/20 12:32:38 lwall 8 * Wasn't clearing FRIENDLY flag on pirate creation. 9 * 10 * Revision 7.0.1.3 86/10/20 12:15:33 lwall 11 * Was trying to create pirates from cloaked pirates. 12 * 13 * Revision 7.0.1.2 86/10/17 10:03:44 lwall 14 * Fixed Romulan writing spaces while cloaked. 15 * 16 * Revision 7.0.1.1 86/10/16 10:53:39 lwall 17 * Added Damage. Fixed random bugs. 18 * 19 * Revision 7.0 86/10/08 15:14:15 lwall 20 * Split into separate files. Added amoebas and pirates. 21 * 22 */ 23 24#include "EXTERN.h" 25#include "warp.h" 26#include "bang.h" 27#include "object.h" 28#include "move.h" 29#include "score.h" 30#include "term.h" 31#include "us.h" 32#include "util.h" 33#include "weapon.h" 34#include "INTERN.h" 35#include "them.h" 36 37void 38them_init(void) 39{ 40 ; 41} 42 43void 44their_smarts(void) 45{ 46 OBJECT *curkl; 47 OBJECT *obj = NULL; 48 int prob; 49 int count; 50 int y = 0; 51 int x = 0; 52 53 if (numcrushes && (obj=movers)->type == Crusher) { 54 if (numamoebas) { 55 y = obj->posy; 56 x = (obj->posx+(obj->image=='<'?1:-1)+XSIZE00)%XSIZE; 57 if (amb[y][x] == '~') { 58 obj->velx = 0; /* stop and munch amoeba */ 59 modify_amoeba(y,x,1,' ',(int)rand_mod(5+ambsize/10)+1); 60 if (occupant[y][x] == nuke) /* except go for nucleus */ 61 obj->velx = (obj->image=='<' ? 1 : -1); 62 } 63 else if (!obj->velx) { 64 if (!rand_mod(4)) 65 obj->image = rand_mod(2) ? '<' : '>'; 66 obj->velx = obj->image == '<' ? 1 : -1; 67 } 68 } 69 obj->vely += (rand_mod(222) - 111) / 100; 70 if (!(rand_mod(100))) { 71 setimage(obj, (obj->velx *= -1) < 0 ? '>' : '<'); 72 } 73 } 74 if (numamoebas) { 75 if (!rand_mod(3)) 76 nuke->velx = nuke->vely = 0; 77 if (nuke->strategy && ambsize < 90 && !rand_mod(200-smarts)) 78 modify_amoeba(0,0,0,'~',(int)rand_mod(10)); 79 if (ambsize > 200 || (ambsize > 100 && !rand_mod(15))) 80 modify_amoeba(yamblast,xamblast,2,' ',(ambsize-100)/5); 81 } 82 for (curkl = enemies; curkl->type == Enemy; curkl = curkl->next) { 83 if ((curkl->flags & (CLOAKS|FRIENDLY)) == CLOAKS && 84 (curkl->image != ' ') && 85 (curkl->energy > 300 || massacre) ) { 86 setimage(curkl, ' '); 87 } 88 if (madgorns) 89 prob = 3; 90 else if (curkl->vely || curkl->velx) 91 prob = massacre?10:20; 92 else if ((curkl->flags & (PIRATE|FRIENDLY)) == PIRATE) { 93 /* pirates want to sit sometimes */ 94 if (curkl->strategy) { 95 if ((obj = lookimg(curkl->posy, curkl->posx, '@')) || 96 (obj = lookimg(curkl->posy, curkl->posx, 'B')) ) { 97 make_plink(obj->posy, obj->posx); 98 if (!--curkl->strategy) { /* clock ran down */ 99 if (obj->image == '@') { 100 obj->image = '*'; 101 numinhab--; 102 if (obj->flags & STATIC) 103 mvaddch(obj->posy+1,obj->posx*2,obj->image); 104 if (curkl->energy < 20000) 105 curkl->energy += 5000; 106 } 107 prob = 2; /* our work here is done */ 108 } 109 else if (obj->image == 'B') { 110 btorp -= rand_mod(50); 111 if (btorp < 0) 112 btorp = 0; 113 obj->energy -= rand_mod(500); 114 if (obj->energy < 0) 115 obj->energy = 0; 116 prob = 10000; /* stay here */ 117 } 118 else 119 prob = 10000; 120 } 121 else { /* it went away--go elsewhere */ 122 prob = 4; 123 curkl->strategy = 0; 124 } 125 } 126 else if (lookimg(curkl->posy, curkl->posx, '@') || 127 lookimg(curkl->posy, curkl->posx, 'B')) { 128 curkl->strategy = rand_mod(15)+5; 129 prob = 10000; 130 } 131 else 132 prob = 4; 133 } 134 else if (curkl->image == 'M') { /* Mudd wants to sit sometimes */ 135 if ((obj = lookimg(curkl->posy, curkl->posx, 'E')) || 136 (obj = lookimg(curkl->posy, curkl->posx, 'B')) ) { 137 if (obj->image == 'B') { 138 btorp -= rand_mod(40); 139 if (btorp < 0) 140 btorp = 0; 141 obj->energy -= rand_mod(100); 142 if (obj->energy < 0) 143 obj->energy = 0; 144 } 145 else if (!obj->vely && !obj->velx) { 146 etorp -= rand_mod(10); 147 if (etorp < 0) 148 etorp = 0; 149 obj->energy -= rand_mod(20); 150 if (obj->energy < 0) 151 obj->energy = 0; 152 } 153 prob = 10000; /* stay here */ 154 } 155 else /* it went away--go elsewhere */ 156 prob = 4; 157 } 158 else if (curkl->flags & FRIENDLY) { 159 if (curkl->energy < 10000 && 160 lookimg(curkl->posy, curkl->posx, '@') ) { 161 curkl->energy += 100; 162 prob = 20; /* do some loading */ 163 } 164 else 165 prob = 4; 166 } 167 else if (curkl->image == '&') { 168 if (curkl->flags & COUNTDOWN) { 169 if (curkl->strategy) 170 curkl->strategy--; 171 else 172 curkl->flags &= ~COUNTDOWN; 173 prob = 100; /* someone's feeding us, so sit still */ 174 } 175 else 176 prob = 4; 177 } 178 else 179 prob = 4; /* don't sit still too long */ 180 count = 11; 181 for (;;) { 182 if (--count <= 0) /* no opening, just ram something */ 183 break; 184 185#ifdef lint 186 prob = prob; 187#endif 188 if (!(rand_mod(prob))) /* turn randomly occasionally */ 189 goto accell; 190 191 y=(curkl->posy+curkl->vely+YSIZE00)%YSIZE; /* find prospective */ 192 x=(curkl->posx+curkl->velx+XSIZE00)%XSIZE; /* new position */ 193 194 if (numamoebas) { 195 if (curkl == nuke) { 196 if (amb[y][x] != '~') 197 goto accell; /* never move nucleus from protoplasm */ 198 } 199 else { 200 if (amb[y][x] == '~' && rand_mod(2)) { 201 yamblast = y; 202 xamblast = x; 203 goto accell; 204 } 205 } 206 } 207 208 obj = occupant[y][x]; 209 if (!obj) break; /* is anyone there? */ 210 211 switch (obj->type) { 212 case Star: 213 if (obj->image == '@' && (curkl->flags & PIRATE)) { 214 if (curkl->image != 'P' && curkl->image != ' ') { 215 if (curkl->flags & FRIENDLY) { 216 curkl->flags &= ~FRIENDLY; 217 curkl->energy += 1000; 218 possiblescore += curkl->mass; 219 inumfriends--; 220 numfriends--; 221 inumenemies++; 222 numenemies++; 223 } 224 curkl->image = 'P'; 225 } 226 break; /* go ahead and ram the star */ 227 } 228 goto accell; /* try not to ram stars */ 229 case Torp: 230 if (!obj->vely && !obj->velx && (rand_mod(100) <= smarts) && 231 (obj->image == 'o' || obj->image == 'O' || obj->image == 'X')) 232 goto accell; /* try not to ram "friendly" torps */ 233 break; 234 case Web: 235 if (curkl->image != 'T') 236 goto accell; /* non-Tholians shouldn't ram web */ 237 if (count <= 5) 238 break; /* Tholians retrace web if desperate */ 239 if (obj->image == 240 (curkl->vely? 241 (curkl->velx? 242 (curkl->velx==curkl->vely? 243 '\\' 244 : 245 '/' 246 ) 247 : 248 '|' 249 ) 250 : 251 '-' 252 ) 253 ) goto accell; /* Tholians try not to retrace web */ 254 break; /* No problem with crossing web */ 255 } 256 break; /* okay to move over object */ 257 258 accell: 259 /* determine maximum velocity */ 260 if (massacre && curkl->image != 'T') { 261 curkl->vely = rand_mod(7) - 3; 262 curkl->velx = rand_mod(7) - 3; 263 } 264 else if (curkl->image == '&') { 265 if (rand_mod(2)) { 266 curkl->vely = rand_mod(3) - 1; 267 curkl->velx = rand_mod(3) - 1; 268 } 269 else { 270 curkl->vely = curkl->strategy & 3; 271 if (curkl->vely & 2) 272 curkl->vely = -1; 273 curkl->velx = (curkl->strategy >> 2) & 3; 274 if (curkl->velx & 2) 275 curkl->velx = -1; 276 } 277 } 278 else if (curkl->energy >= 2500 && curkl->image != 'T') { 279 curkl->vely = rand_mod(5) - 2; 280 curkl->velx = rand_mod(5) - 2; 281 } 282 else { 283 curkl->vely = rand_mod(3) - 1; 284 curkl->velx = rand_mod(3) - 1; 285 } 286 } 287 if (count != 10) { 288 if (curkl->image == ' ') { 289 setimage(curkl, curkl->flags & PIRATE ? 'P' : 'R'); 290 } 291 if (!count) { 292 curkl->vely = 0; 293 curkl->velx = 0; 294 } 295 } 296 if (curkl->image == 'G' && (base||ent) && 297 !rand_mod((103-smarts)*10) ) { 298 int xxx,yyy; 299 300 for (xxx = -1; xxx<=1; xxx++) 301 for (yyy = -1; yyy<=1; yyy++) 302 if ((xxx||yyy) && rand_mod(2)) 303 fire_torp(curkl,yyy,xxx); 304 } 305 else if (curkl->image == 'T' && (curkl->velx || curkl->vely)) { 306 make_object(Web, 307 curkl->vely? 308 (curkl->velx? 309 (curkl->velx==curkl->vely? 310 '\\' 311 : 312 '/' 313 ) 314 : 315 '|' 316 ) 317 : 318 '-', 319 curkl->posy,curkl->posx,0,0,32767L,32767L,&root); 320 if (obj && obj->type == Web) { 321 unmake_object(obj); 322 occupant[y][x] = NULL; 323 } 324 } 325 } 326 /* klingon-style fighting */ 327 if (numamoebas) 328 attack(nuke); 329 attack(base); 330 if (ent && (!cloaked || ent->image=='E' || ent->image=='e')) 331 attack(ent); 332} 333 334void 335modify_amoeba(int y, int x, int where, int ch, int quant) 336{ 337 int dy; 338 int dx; 339 int count = 15; 340 341 if (!numamoebas) 342 return; 343 if (!where || (where==1 && rand_mod(2))) { 344 y = nuke->posy; 345 x = nuke->posx; 346 } 347 if (nuke->strategy && rand_mod(3)) { 348 dy = nuke->strategy & 3; 349 if (dy & 2) 350 dy = -1; 351 dx = (nuke->strategy >> 2) & 3; 352 if (dx & 2) 353 dx = -1; 354 if (ch == ' ') { /* take from the tail */ 355 dy = -dy; 356 dx = -dx; 357 } 358 if (!rand_mod(100)) 359 nuke->strategy = rand_mod(256); 360 } 361 else { 362 dy = rand_mod(3) - 1; 363 dx = rand_mod(3) - 1; 364 } 365 if (!dy && !dx) 366 return; 367 do { 368 if (--count < 0) 369 return; 370 y = (y + dy + YSIZE00) % YSIZE; 371 x = (x + dx + XSIZE00) % XSIZE; 372 } while (amb[y][x] != ' '); 373 if (ch == ' ') { 374 y = (y - dy + YSIZE00) % YSIZE; 375 x = (x - dx + XSIZE00) % XSIZE; 376 } 377 if (ambsize > 100 && quant > 2) { 378 quant >>= (ambsize/100); 379 } 380 if ((nuke->energy += quant << 6) > 32767) 381 nuke->energy = 32767; 382 count = quant << 3; /* endless loop catcher */ 383 while (count-- > 0 && quant > 0) { 384 if (amb[y][x] != ch) { 385 quant--; 386 amb[y][x] = ch; 387 if (ch == '~') { 388 ambsize++; 389 yblasted[y] |= 2; 390 xblasted[x] |= 2; 391 blasted = true; 392 } 393 else 394 ambsize--; 395 if (!occupant[y][x]) 396 mvaddch(y+1,x*2,ch); 397 } 398 y = (y + rand_mod(3) + YSIZE99) % YSIZE; 399 x = (x + rand_mod(3) + XSIZE99) % XSIZE; 400 } 401} 402