1 1.2 kamil /* Header: weapon.c,v 7.0.1.2 86/10/20 14:36:33 lwall Exp */ 2 1.1 kamil 3 1.2 kamil /* Log: weapon.c,v 4 1.1 kamil * Revision 7.0.1.2 86/10/20 14:36:33 lwall 5 1.1 kamil * Picked some lint. 6 1.4 rillig * 7 1.1 kamil * Revision 7.0.1.1 86/10/16 10:54:42 lwall 8 1.1 kamil * Added Damage. Fixed random bugs. 9 1.4 rillig * 10 1.1 kamil * Revision 7.0 86/10/08 15:18:08 lwall 11 1.1 kamil * Split into separate files. Added amoebas and pirates. 12 1.4 rillig * 13 1.1 kamil */ 14 1.1 kamil 15 1.1 kamil #include "EXTERN.h" 16 1.1 kamil #include "warp.h" 17 1.1 kamil #include "bang.h" 18 1.1 kamil #include "object.h" 19 1.1 kamil #include "move.h" 20 1.1 kamil #include "score.h" 21 1.1 kamil #include "sig.h" 22 1.1 kamil #include "term.h" 23 1.1 kamil #include "them.h" 24 1.1 kamil #include "us.h" 25 1.1 kamil #include "util.h" 26 1.1 kamil #include "INTERN.h" 27 1.1 kamil #include "weapon.h" 28 1.1 kamil 29 1.1 kamil void 30 1.3 christos weapon_init(void) 31 1.1 kamil { 32 1.1 kamil ; 33 1.1 kamil } 34 1.1 kamil 35 1.1 kamil void 36 1.3 christos fire_torp(OBJECT *from, int ydir, int xdir) 37 1.1 kamil { 38 1.3 christos OBJECT *to; 39 1.1 kamil 40 1.1 kamil if (from->type == Enemy || 41 1.1 kamil (from == ent && etorp > 0) || 42 1.1 kamil (from == base && btorp > 0)) { 43 1.1 kamil to = occupant[(from->posy+from->vely+ydir+YSIZE00)%YSIZE] 44 1.1 kamil [(from->posx+from->velx+xdir+XSIZE00)%XSIZE]; 45 1.1 kamil if (from->type != Enemy || !to || to->vely || to->velx) { 46 1.1 kamil if (from->type != Enemy && 47 1.1 kamil (to = isatorp[from==base][ydir+1][xdir+1])) { 48 1.1 kamil to->vely += ydir; 49 1.1 kamil to->velx += xdir; 50 1.1 kamil } 51 1.1 kamil else { 52 1.1 kamil if (from == ent) { 53 1.1 kamil to = make_object(Torp, '+', from->posy,from->posx, 54 1.1 kamil from->vely+ydir,from->velx+xdir, 0L, 1L,&root); 55 1.1 kamil aretorps++; 56 1.1 kamil isatorp[0][ydir+1][xdir+1] = to; 57 1.1 kamil etorp--; 58 1.1 kamil } 59 1.1 kamil else if (from == base) { 60 1.1 kamil to = make_object(Torp, '+', from->posy,from->posx, 61 1.1 kamil from->vely+ydir,from->velx+xdir, 0L, 1L,&root); 62 1.1 kamil aretorps++; 63 1.1 kamil isatorp[1][ydir+1][xdir+1] = to; 64 1.1 kamil btorp--; 65 1.1 kamil } 66 1.1 kamil else if (from->image == 'G') { 67 1.1 kamil numos++; 68 1.1 kamil to = make_object(Torp, 'o', from->posy,from->posx, 69 1.1 kamil from->vely+ydir,from->velx+xdir, 100L, 1L,&root); 70 1.1 kamil if (madgorns) { 71 1.1 kamil possiblescore += 35; 72 1.1 kamil to->image = '0'; 73 1.1 kamil to->mass = 2000; 74 1.1 kamil to->energy = 2000; 75 1.1 kamil } 76 1.1 kamil else if (rand_mod(120)+10 > smarts) 77 1.1 kamil possiblescore += 100; 78 1.1 kamil else { 79 1.1 kamil possiblescore += 200; 80 1.1 kamil to->image = 'O'; 81 1.1 kamil } 82 1.1 kamil } 83 1.1 kamil else { 84 1.1 kamil to = make_object(Torp, 'x', from->posy,from->posx, 85 1.1 kamil from->vely+ydir,from->velx+xdir, 0L, 1L,&root); 86 1.1 kamil if (rand_mod(160)+10 > smarts) 87 1.1 kamil possiblescore += 10; 88 1.1 kamil else { 89 1.1 kamil possiblescore += 100; 90 1.1 kamil to->image = 'X'; 91 1.1 kamil to->mass = 1000+super*20; 92 1.1 kamil numxes++; 93 1.1 kamil } 94 1.1 kamil } 95 1.1 kamil } 96 1.1 kamil } 97 1.1 kamil } 98 1.1 kamil } 99 1.1 kamil 100 1.1 kamil void 101 1.3 christos attack(OBJECT *attackee) 102 1.1 kamil { 103 1.3 christos int dx; 104 1.3 christos int dy; 105 1.3 christos int curx; 106 1.3 christos int cury; 107 1.3 christos int prob; 108 1.3 christos OBJECT *obj; 109 1.3 christos bool torps; 110 1.3 christos bool webnear = false; 111 1.3 christos bool thru_stars; 112 1.1 kamil int nukey; 113 1.1 kamil int nukex; 114 1.1 kamil int nukedist; 115 1.1 kamil 116 1.1 kamil if (attackee) { 117 1.1 kamil if (attackee == nuke) { 118 1.1 kamil if (amb[attackee->posy][attackee->posx] != '~') 119 1.1 kamil return; 120 1.1 kamil nukey = nukex = 0; 121 1.1 kamil nukedist = 100; 122 1.1 kamil } 123 1.1 kamil for (dx= -1; dx<=1 ; dx++) { 124 1.1 kamil for (dy= -1; dy<=1; dy++) { 125 1.1 kamil if (dx||dy) { 126 1.1 kamil cury = attackee->posy; 127 1.1 kamil curx = attackee->posx; 128 1.3 christos torps = thru_stars = false; 129 1.1 kamil if (massacre || madgorns || !rand_mod(53-super) ) 130 1.1 kamil webnear += rand_mod(2); 131 1.1 kamil else 132 1.3 christos webnear = false; 133 1.1 kamil for (prob = scandist;prob;prob--) { 134 1.1 kamil cury = (cury + dy + YSIZE00) % YSIZE; 135 1.1 kamil curx = (curx + dx + XSIZE00) % XSIZE; 136 1.3 christos if ((obj = occupant[cury][curx]) != NULL) { 137 1.1 kamil switch (obj->image) { 138 1.1 kamil case 'P': case 'K': case 'R': case ' ': 139 1.1 kamil pot_shot: 140 1.1 kamil if (attackee == nuke) { 141 1.1 kamil if (rand_mod(2+scandist-prob) < 142 1.1 kamil rand_mod(smarts/40+1)) 143 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1); 144 1.1 kamil } 145 1.1 kamil if (rand_mod(51 - sm50) <= prob) { 146 1.1 kamil switch (obj->strategy||thru_stars?0: 147 1.1 kamil rand_mod(ent?4:2)) { 148 1.1 kamil case 1: case 2: 149 1.1 kamil if (-dy + attackee->vely == obj->vely 150 1.1 kamil && -dx + attackee->velx == obj->velx) 151 1.1 kamil fire_torp(obj, 152 1.1 kamil -dy + attackee->vely, 153 1.1 kamil -dx + attackee->velx); 154 1.1 kamil else 155 1.1 kamil fire_torp(obj, 156 1.1 kamil -dy + attackee->vely - obj->vely, 157 1.1 kamil -dx + attackee->velx - obj->velx); 158 1.1 kamil if (obj->image == ' ') 159 1.1 kamil setimage(obj, 160 1.1 kamil obj->flags & PIRATE ? 'P' : 'R'); 161 1.1 kamil break; 162 1.1 kamil case 3: { 163 1.1 kamil int newspeed = 164 1.1 kamil rand_mod(prob<5&&smarts>70?4:3)-1; 165 1.4 rillig 166 1.1 kamil obj->vely = -dy * newspeed; 167 1.1 kamil obj->velx = -dx * newspeed; 168 1.1 kamil if (newspeed >= 0 && 169 1.1 kamil !rand_mod(82-sm80)) { 170 1.1 kamil obj->vely += attackee->vely; 171 1.1 kamil obj->velx += attackee->velx; 172 1.1 kamil } 173 1.1 kamil break; 174 1.1 kamil } 175 1.1 kamil case 0: 176 1.1 kamil if (!torps && obj->energy > 1000) { 177 1.1 kamil fire_phaser(obj, -dy, -dx); 178 1.1 kamil if (smarts > 40 && 179 1.1 kamil (scandist-prob > 5 180 1.1 kamil || attackee==base) && 181 1.1 kamil (massacre || obj->strategy || 182 1.1 kamil rand_mod(2))) 183 1.1 kamil while (rand_mod(2)) 184 1.1 kamil fire_phaser(obj, -dy, -dx); 185 1.1 kamil if (obj->image == ' ') 186 1.1 kamil setimage(obj, 187 1.1 kamil obj->flags&PIRATE ? 'P':'R'); 188 1.1 kamil } 189 1.1 kamil if (obj->strategy) { 190 1.1 kamil obj->velx = obj->vely = 0; 191 1.1 kamil if (obj->energy < 1000 || 192 1.1 kamil bvely || bvelx) 193 1.1 kamil obj->strategy = 0; 194 1.1 kamil } 195 1.1 kamil else if ((attackee==base || 196 1.1 kamil (cloaking && attackee==ent) 197 1.1 kamil ) && 198 1.1 kamil scandist-prob > 5 && 199 1.1 kamil !(rand_mod( 200 1.1 kamil ent?antibase*2:antibase)) ) 201 1.1 kamil obj->strategy = 1; 202 1.1 kamil break; 203 1.1 kamil } 204 1.1 kamil } 205 1.1 kamil goto bombout; 206 1.1 kamil case 'G': 207 1.1 kamil if (thru_stars && obj->strategy < 7) 208 1.1 kamil goto bombout; 209 1.1 kamil if (attackee == nuke) { 210 1.1 kamil if (rand_mod(2+scandist-prob) < 211 1.1 kamil rand_mod(smarts/40+1)) 212 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1); 213 1.1 kamil goto bombout; 214 1.1 kamil } 215 1.1 kamil if (obj->strategy) { 216 1.1 kamil if (madgorns || !rand_mod(4)) { 217 1.1 kamil obj->vely = attackee->vely; 218 1.1 kamil obj->velx = attackee->velx; 219 1.1 kamil } 220 1.1 kamil obj->strategy += (!torps && deados > 10); 221 1.1 kamil if (obj->strategy > 4) 222 1.3 christos madgorns = true; 223 1.1 kamil if (!torps && obj->strategy > 5) { 224 1.1 kamil do { 225 1.1 kamil fire_phaser(obj, -dy, -dx); 226 1.1 kamil } while (rand_mod(2)); 227 1.1 kamil } 228 1.1 kamil } 229 1.1 kamil else if (numgorns >= numenemies-1 && 230 1.1 kamil deados > 15+numgorns*5) 231 1.1 kamil obj->strategy = 1; 232 1.1 kamil if (madgorns || rand_mod(51 - sm50) <= prob) { 233 1.1 kamil if (-dy + attackee->vely == obj->vely 234 1.1 kamil && -dx + attackee->velx == obj->velx) 235 1.1 kamil fire_torp(obj, 236 1.1 kamil -dy + attackee->vely, 237 1.1 kamil -dx + attackee->velx); 238 1.1 kamil else 239 1.1 kamil fire_torp(obj, 240 1.1 kamil -dy + attackee->vely - obj->vely, 241 1.1 kamil -dx + attackee->velx - obj->velx); 242 1.1 kamil } 243 1.1 kamil goto bombout; 244 1.1 kamil case 'T': 245 1.1 kamil if (attackee == nuke) { 246 1.1 kamil if (rand_mod(2+scandist-prob) < 247 1.1 kamil rand_mod(smarts/40+1)) 248 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1); 249 1.1 kamil } 250 1.1 kamil if (thru_stars) 251 1.1 kamil goto bombout; 252 1.1 kamil if (webnear && scandist-prob > 5) { 253 1.1 kamil if (massacre || rand_mod(50) < super) { 254 1.1 kamil if (!torps && obj->energy > 1000) { 255 1.1 kamil fire_phaser(obj, -dy, -dx); 256 1.1 kamil while (!rand_mod(57-sm55)) 257 1.1 kamil fire_phaser(obj, -dy, -dx); 258 1.1 kamil } 259 1.1 kamil } 260 1.1 kamil } 261 1.1 kamil goto bombout; 262 1.1 kamil case 'C': case 'c': 263 1.1 kamil if (thru_stars) 264 1.1 kamil goto bombout; 265 1.1 kamil break; 266 1.1 kamil case 'Q': case 'W': case 'Y': case 'U': 267 1.1 kamil case 'I': case 'S': case 'D': case 'H': case 'J': 268 1.1 kamil case 'L': case 'Z': case 'V': case 'M': case 'F': 269 1.1 kamil if (attackee == nuke) { 270 1.1 kamil if (rand_mod(2+scandist-prob) < 271 1.1 kamil rand_mod(smarts/40+1)) 272 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1); 273 1.1 kamil if (rand_mod(2)) 274 1.1 kamil goto pot_shot; 275 1.1 kamil } 276 1.1 kamil if (madfriends > 1000) { 277 1.1 kamil madfriends -= 200; 278 1.1 kamil goto pot_shot; 279 1.1 kamil } 280 1.1 kamil /* FALL THROUGH */ 281 1.1 kamil case '+': 282 1.1 kamil if (attackee == nuke) { 283 1.1 kamil if (smarts > 70) { 284 1.1 kamil if ( 285 1.1 kamil (obj->posx + obj->velx + XSIZE00)%XSIZE 286 1.1 kamil == attackee->posx && 287 1.1 kamil (obj->posy + obj->vely + YSIZE00)%YSIZE 288 1.1 kamil == attackee->posy ) { 289 1.3 christos tract(nuke,dy,dx,-1); 290 1.1 kamil } 291 1.1 kamil else 292 1.1 kamil while (!rand_mod(82-sm80)) 293 1.3 christos tract(nuke,dy,dx,-1); 294 1.1 kamil } 295 1.1 kamil else if (smarts > 60 || 296 1.1 kamil rand_mod(2+scandist-prob) < 297 1.1 kamil rand_mod(smarts/20+1)) 298 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1); 299 1.1 kamil } 300 1.3 christos torps = false; 301 1.3 christos thru_stars = false; 302 1.1 kamil break; 303 1.1 kamil case '|': case '-': case '/': case '\\': 304 1.1 kamil if (thru_stars) 305 1.1 kamil goto bombout; 306 1.1 kamil webnear = (scandist-prob < 3); 307 1.3 christos torps = false; 308 1.1 kamil break; 309 1.1 kamil case 'x': 310 1.1 kamil if (attackee == nuke) { 311 1.1 kamil if (rand_mod(2+scandist-prob) < 312 1.1 kamil rand_mod(smarts/20+1)) 313 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1); 314 1.1 kamil } 315 1.1 kamil if (thru_stars) 316 1.1 kamil goto bombout; 317 1.3 christos torps = true; 318 1.1 kamil break; 319 1.1 kamil case 'o': case 'O': case '0': 320 1.1 kamil if (attackee == nuke) { 321 1.1 kamil if (rand_mod(2+scandist-prob) < 322 1.1 kamil rand_mod(smarts/20+1)) 323 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1); 324 1.1 kamil } 325 1.1 kamil if (thru_stars) 326 1.1 kamil goto bombout; 327 1.3 christos torps = true; 328 1.1 kamil if (rand_mod(99+3*scandist) < smarts+3*prob) { 329 1.1 kamil obj->vely = -dy + attackee->vely; 330 1.1 kamil obj->velx = -dx + attackee->velx; 331 1.1 kamil if (obj->flags & STATIC) {/* not a mover? */ 332 1.1 kamil obj->flags &= ~STATIC; 333 1.1 kamil obj->prev->next = obj->next; 334 1.1 kamil obj->next->prev = obj->prev; 335 1.1 kamil root.prev->next = obj; 336 1.1 kamil obj->prev = root.prev; 337 1.1 kamil root.prev = obj; 338 1.1 kamil obj->next = &root; 339 1.1 kamil } 340 1.1 kamil } 341 1.1 kamil if (obj->image != '0') 342 1.1 kamil break; 343 1.3 christos /*FALLTHROUGH*/ 344 1.1 kamil case 'X': 345 1.1 kamil if (attackee == nuke) { 346 1.1 kamil if (rand_mod(2+scandist-prob) < 347 1.1 kamil rand_mod(smarts/20+1)) 348 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1); 349 1.1 kamil } 350 1.3 christos torps = true; 351 1.1 kamil if (thru_stars) 352 1.1 kamil goto bombout; 353 1.1 kamil if (prob == scandist) { 354 1.1 kamil int y, x; 355 1.1 kamil 356 1.1 kamil blast[y=(obj->posy+obj->vely+YSIZE00)%YSIZE] 357 1.1 kamil [x=(obj->posx+obj->velx+XSIZE00)%XSIZE] 358 1.1 kamil += (obj->image == '0' ? 2000 : 200); 359 1.1 kamil yblasted[y] |= 1; 360 1.1 kamil xblasted[x] |= 1; 361 1.3 christos blasted = true; 362 1.1 kamil } 363 1.1 kamil break; 364 1.1 kamil case 'A': 365 1.1 kamil if (attackee != nuke) { 366 1.1 kamil if (scandist-prob>1 && !rand_mod(51-super)) 367 1.3 christos tract(obj,-dy,-dx,1); 368 1.1 kamil } 369 1.1 kamil /* FALL THROUGH */ 370 1.1 kamil case '*': case '@': 371 1.1 kamil if (attackee == nuke) { 372 1.1 kamil if (amb[cury][curx] != '~') { 373 1.1 kamil if (scandist-prob < nukedist) { 374 1.1 kamil nukedist = scandist-prob; 375 1.1 kamil nukey = dy; /* nearest food in */ 376 1.1 kamil nukex = dx; /* this direction */ 377 1.1 kamil } 378 1.1 kamil if (smarts > 55 && scandist-prob > 8) { 379 1.1 kamil if (rand_mod(30+scandist-prob) < 380 1.1 kamil rand_mod(smarts/20+1)) 381 1.3 christos tract(nuke,dy,dx,1); 382 1.1 kamil } 383 1.1 kamil } 384 1.1 kamil else if (obj->vely || obj->velx) { 385 1.3 christos tract(nuke,dy,dx,1); /* for looks */ 386 1.1 kamil obj->vely = obj->velx = 0; 387 1.1 kamil } 388 1.1 kamil } 389 1.3 christos if (!thru_stars) { 390 1.1 kamil if (rand_mod(97-sm95)) 391 1.1 kamil goto bombout; 392 1.1 kamil else 393 1.3 christos thru_stars = true; 394 1.3 christos } 395 1.1 kamil break; 396 1.1 kamil case '<': case '>': 397 1.1 kamil if (attackee == nuke) { 398 1.1 kamil if ((!dy && scandist-prob < 8) || 399 1.1 kamil rand_mod(2+scandist-prob) < 400 1.1 kamil rand_mod(smarts/20+1) ) { 401 1.1 kamil nuke->mass += 10000; 402 1.3 christos tract(nuke,dy,dx,-1); 403 1.1 kamil nuke->mass -= 10000; 404 1.1 kamil } 405 1.1 kamil } 406 1.1 kamil goto bombout; 407 1.1 kamil case 'E': case 'B': 408 1.1 kamil if (attackee == nuke) { 409 1.1 kamil if (rand_mod(2+scandist-prob) < 410 1.1 kamil rand_mod(smarts/40+1)) 411 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1); 412 1.1 kamil } 413 1.1 kamil goto bombout; 414 1.1 kamil default: 415 1.1 kamil goto bombout; 416 1.1 kamil } 417 1.1 kamil } 418 1.1 kamil else { 419 1.1 kamil if (thru_stars) 420 1.1 kamil goto bombout; 421 1.4 rillig } 422 1.1 kamil } 423 1.1 kamil bombout: ; /* end of loop */ 424 1.1 kamil } 425 1.1 kamil } 426 1.1 kamil } 427 1.1 kamil if (attackee == nuke && nukedist < 100) {/* aim amoeba at nearest */ 428 1.1 kamil if (nukey < 0) /* free star */ 429 1.1 kamil nukey = 2; 430 1.1 kamil if (nukex < 0) 431 1.1 kamil nukex = 2; 432 1.1 kamil nuke->strategy = nukey + (nukex << 2); 433 1.1 kamil } 434 1.1 kamil } 435 1.1 kamil } 436 1.1 kamil 437 1.1 kamil void 438 1.3 christos fire_phaser(OBJECT *obj, int dy, int dx) 439 1.1 kamil { 440 1.3 christos int y; 441 1.3 christos int x; 442 1.3 christos int skipping; 443 1.3 christos int size=5000; 444 1.1 kamil int decr = 50, oldy, oldx; 445 1.1 kamil static char curchar[] = "@* "; 446 1.1 kamil 447 1.1 kamil if (obj == ent) 448 1.1 kamil decr = 100; 449 1.1 kamil else if (obj == base) { 450 1.1 kamil decr = 1000; 451 1.1 kamil size = 200; 452 1.1 kamil } 453 1.1 kamil if (!dy) 454 1.1 kamil curchar[2] = '-'; 455 1.1 kamil else if (!dx) 456 1.1 kamil curchar[2] = '!'; 457 1.1 kamil else if (dy == dx) 458 1.1 kamil curchar[2] = '\\'; 459 1.1 kamil else 460 1.1 kamil curchar[2] = '/'; 461 1.1 kamil if (obj->energy >= decr) { 462 1.1 kamil obj->energy -= decr; 463 1.1 kamil for ( 464 1.1 kamil /* initialize */ 465 1.1 kamil skipping = (obj != base), 466 1.1 kamil y = (obj->posy+(obj==base?dy*2:dy)+YSIZE00)%YSIZE, 467 1.1 kamil x = (obj->posx+(obj==base?dx*2:dx)+XSIZE00)%XSIZE; 468 1.1 kamil /* while */ 469 1.1 kamil size && (!occupant[y][x]||(skipping && occupant[y][x]->type==Star)); 470 1.1 kamil /* at end of loop */ 471 1.1 kamil y = (y+dy+YSIZE00) % YSIZE, 472 1.1 kamil x = (x+dx+XSIZE00) % XSIZE, 473 1.1 kamil size = size * 3 / 4 ) { 474 1.1 kamil move(y+1,x*2,0); 475 1.1 kamil beg_qwrite(); 476 1.1 kamil if (obj == base || obj->image == 'T') { 477 1.1 kamil *filler = '@'; 478 1.1 kamil qwrite(); 479 1.1 kamil *filler = '#'; 480 1.1 kamil qwrite(); 481 1.1 kamil *filler = '~'; 482 1.1 kamil qwrite(); 483 1.1 kamil *filler = '%'; 484 1.1 kamil qwrite(); 485 1.1 kamil *filler = ':'; 486 1.1 kamil qwrite(); 487 1.1 kamil *filler = '@'; 488 1.1 kamil } 489 1.1 kamil else { 490 1.1 kamil *filler = size >= 500 ? 491 1.1 kamil *curchar : (size >= 50 ? 492 1.1 kamil curchar[1] : 493 1.1 kamil curchar[2]); 494 1.1 kamil } 495 1.1 kamil qwrite(); 496 1.1 kamil if (occupant[y][x]) 497 1.1 kamil qaddc(occupant[y][x]->image); 498 1.1 kamil else { 499 1.1 kamil if (numamoebas) 500 1.1 kamil qaddc(amb[y][x]); 501 1.1 kamil else 502 1.1 kamil qaddspace(); 503 1.1 kamil if (skipping) 504 1.1 kamil skipping = 0; 505 1.1 kamil } 506 1.1 kamil end_qwrite(); 507 1.1 kamil } 508 1.1 kamil if (size) { 509 1.1 kamil char img; 510 1.1 kamil 511 1.1 kamil assert(occupant[y][x]); 512 1.1 kamil img = occupant[y][x]->image; 513 1.1 kamil if (occupant[y][x]->type == Crusher) { 514 1.1 kamil if (dy) 515 1.1 kamil return; 516 1.1 kamil if (dx==(img == '<' ? 1 : -1) ) { 517 1.1 kamil occupant[y][x]->image = 518 1.1 kamil (occupant[y][x]->velx *= -1) < 0 ? '>' : '<'; 519 1.1 kamil return; 520 1.1 kamil } 521 1.1 kamil } 522 1.1 kamil else if (occupant[y][x]->flags & FRIENDLY) 523 1.1 kamil madfriends += 200; 524 1.1 kamil if (numamoebas && amb[y][x] == '~' && smarts % 3 && 525 1.1 kamil (smarts > 70 || rand_mod(smarts) > rand_mod(20)) ) { 526 1.1 kamil if (size > 10000) 527 1.1 kamil modify_amoeba(y,x,1,'~',10); 528 1.1 kamil else if (size > 1000) 529 1.1 kamil modify_amoeba(y,x,1,'~',7); 530 1.1 kamil else if (size > 50) 531 1.1 kamil modify_amoeba(y,x,1,'~',5); 532 1.1 kamil else 533 1.1 kamil modify_amoeba(y,x,1,'~',2); 534 1.1 kamil if (occupant[y][x] == nuke) { 535 1.1 kamil nuke->strategy = rand_mod(30); 536 1.1 kamil nuke->flags |= COUNTDOWN; 537 1.1 kamil } 538 1.1 kamil return; 539 1.1 kamil } 540 1.1 kamil else { 541 1.1 kamil move(y+1,x*2,0); 542 1.1 kamil beg_qwrite(); 543 1.1 kamil if (img == ' ') { 544 1.1 kamil *filler = occupant[y][x]->flags & PIRATE ? 'P' : 'R'; 545 1.1 kamil occupant[y][x]->image = *filler; 546 1.1 kamil occupant[y][x]->strategy = 0; 547 1.1 kamil qwrite(); 548 1.1 kamil qwrite(); 549 1.1 kamil } 550 1.1 kamil else if (img == 'C' || img == 'c') { 551 1.1 kamil cloaked = 0; 552 1.1 kamil img += 2; 553 1.1 kamil occupant[y][x]->image = img; 554 1.1 kamil *filler = img; 555 1.1 kamil qwrite(); 556 1.1 kamil qwrite(); 557 1.1 kamil } 558 1.1 kamil else if (img == 'K' && size > 50) 559 1.1 kamil occupant[y][x]->strategy = 0; 560 1.1 kamil *filler = '@'; 561 1.1 kamil qwrite(); 562 1.1 kamil *filler = '#'; 563 1.1 kamil qwrite(); 564 1.1 kamil *filler = '@'; 565 1.1 kamil qwrite(); 566 1.1 kamil *filler = '#'; 567 1.1 kamil qwrite(); 568 1.1 kamil *filler = '@'; 569 1.1 kamil qwrite(); 570 1.1 kamil qaddc(img); 571 1.1 kamil end_qwrite(); 572 1.1 kamil oldy = y; 573 1.1 kamil oldx = x; 574 1.1 kamil y = (occupant[oldy][oldx]->posy + occupant[oldy][oldx]->vely + 575 1.1 kamil YSIZE00) % YSIZE; 576 1.1 kamil x = (occupant[oldy][oldx]->posx + occupant[oldy][oldx]->velx + 577 1.1 kamil XSIZE00) % XSIZE; 578 1.1 kamil if (occupant[y][x] && occupant[y][x]->type == Star) { 579 1.1 kamil y = occupant[oldy][oldx]->posy; 580 1.1 kamil x = occupant[oldy][oldx]->posx; 581 1.1 kamil } 582 1.1 kamil if (obj==base) 583 1.1 kamil blast[y][x] += size>50 ? 15000 : (size>15 ? 1500 : 150); 584 1.1 kamil else if (obj==ent) 585 1.1 kamil blast[y][x] += size*4; 586 1.1 kamil else if (obj->image=='T') 587 1.1 kamil blast[y][x] += 15000; 588 1.1 kamil else 589 1.1 kamil blast[y][x] += size*smarts/25; 590 1.1 kamil yblasted[y] |= 1; 591 1.1 kamil xblasted[x] |= 1; 592 1.3 christos blasted = true; 593 1.1 kamil } 594 1.1 kamil } 595 1.1 kamil } 596 1.1 kamil } 597 1.1 kamil 598 1.1 kamil int 599 1.3 christos tract(OBJECT *obj, int dy, int dx, int to_or_fro) 600 1.1 kamil { 601 1.3 christos int y; 602 1.3 christos int x; 603 1.3 christos int size=10; 604 1.1 kamil static char ch; 605 1.3 christos OBJECT *tractee; 606 1.1 kamil 607 1.1 kamil if (!dy) 608 1.1 kamil ch = '|'; 609 1.1 kamil else if (!dx) 610 1.1 kamil ch = '-'; 611 1.1 kamil else if (dy == dx) 612 1.1 kamil ch = '/'; 613 1.1 kamil else 614 1.1 kamil ch = '\\'; 615 1.1 kamil { 616 1.1 kamil for ( 617 1.1 kamil y = (obj->posy+dy+YSIZE00)%YSIZE, 618 1.1 kamil x = (obj->posx+dx+XSIZE00)%XSIZE; 619 1.1 kamil size && (!occupant[y][x]); 620 1.1 kamil y = (y+dy+YSIZE00) % YSIZE, x = (x+dx+XSIZE00) % XSIZE, size--) { 621 1.1 kamil move(y+1,x*2,0); 622 1.1 kamil beg_qwrite(); 623 1.1 kamil *filler = ch; 624 1.1 kamil qwrite(); 625 1.1 kamil qwrite(); 626 1.1 kamil if (numamoebas) 627 1.1 kamil qaddch(amb[y][x]); 628 1.1 kamil else 629 1.1 kamil qaddspace(); 630 1.1 kamil end_qwrite(); 631 1.1 kamil } 632 1.1 kamil tractee = occupant[y][x]; 633 1.1 kamil if (size) { 634 1.1 kamil assert(tractee); 635 1.1 kamil if (numamoebas && obj != nuke && amb[y][x] == '~') { 636 1.1 kamil if (to_or_fro > 0) 637 1.1 kamil modify_amoeba(y,x,2,'~',size); 638 1.1 kamil else 639 1.1 kamil modify_amoeba(y,x,1,' ',size); 640 1.1 kamil } 641 1.1 kamil if (tractee->type != Web && 642 1.1 kamil (tractee->mass < obj->mass * 5 || 643 1.1 kamil (tractee->type == Crusher && !dx) ) ) { 644 1.1 kamil if (tractee == ent) { 645 1.1 kamil evely -= dy * to_or_fro; 646 1.1 kamil evelx -= dx * to_or_fro; 647 1.1 kamil } 648 1.1 kamil else if (tractee == base) { 649 1.1 kamil bvely -= dy * to_or_fro; 650 1.1 kamil bvelx -= dx * to_or_fro; 651 1.1 kamil } 652 1.1 kamil else { 653 1.1 kamil tractee->vely -= dy * to_or_fro; 654 1.1 kamil tractee->velx -= dx * to_or_fro; 655 1.1 kamil } 656 1.1 kamil if (tractee->type == Torp || 657 1.1 kamil tractee->type == Star) { 658 1.1 kamil if (tractee->flags & STATIC) { /* not a mover? */ 659 1.1 kamil tractee->flags &= ~STATIC; 660 1.1 kamil tractee->prev->next = tractee->next; 661 1.1 kamil tractee->next->prev = tractee->prev; 662 1.1 kamil root.prev->next = tractee; 663 1.1 kamil tractee->prev = root.prev; 664 1.1 kamil root.prev = tractee; 665 1.1 kamil tractee->next = &root; 666 1.1 kamil } 667 1.1 kamil } 668 1.1 kamil } 669 1.1 kamil else if (tractee->type == Crusher && !dy && 670 1.1 kamil dx==(tractee->image == '<' ? 1 : -1) ) { 671 1.1 kamil setimage(tractee, (tractee->velx *= -1) < 0 ? '>' : '<'); 672 1.1 kamil } 673 1.1 kamil if (tractee->mass * 5 > obj->mass) 674 1.1 kamil return(1); 675 1.1 kamil } 676 1.1 kamil } 677 1.1 kamil return(0); 678 1.1 kamil } 679