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