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