Index: class.c ================================================================== --- class.c +++ class.c @@ -1158,10 +1158,11 @@ case OP_LOC: case OP_MARK: case OP_SUB: case OP_QUEEN: case OP_ROOK: case OP_BISHOP: case OP_DIR: case OP_DIR_C: case OP_DIR_E: case OP_DIR_EC: case OP_OBJTOPAT: case OP_OBJBOTTOMAT: case OP_CUT: case OP_MUL: case OP_OBJABOVE: case OP_OBJBELOW: case OP_TRACE: case OP_NEXT: + case OP_IMAGE: case OP_IMAGE_C: case 0x0200 ... 0x02FF: // message case 0x4000 ... 0x7FFF: // class case 0xC000 ... 0xFFFF: // message cl->codes[ptr++]=tokenv; break; Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -2731,10 +2731,22 @@ Fail the match if the height here is greater than this number. cut Discards the most recent choice point. +Dir + Set the direction to the origin object's direction. + +,Dir + Set the direction to the matched object's direction. + +=Dir + Change the origin object's direction to the current direction. + +=,Dir + Change the matched object's direction to the current direction. + else Delimits alternatives within a block. Height Fail the match if the origin object can climb here. @@ -2743,10 +2755,17 @@ Fail the match if the height here isn't greater than this number. if Begin a block that can optionally match. +Image + Match an object with the remembered class and image (if none is + remembered, use the origin object's class and image). + +,Image + Remember the class and image of the currently matched object. + next Unconditionally fail the current attempt and try the next choice. ObjAbove Match the object above the currently matched object. Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -2215,12 +2215,14 @@ Uint8 d=objects[obj]->dir; Uint32 n=VOIDLINK; Uint32 m; Uint16 g; Value v; - static ChoicePoint cp[MAXCHOICE]; + ChoicePoint cp[MAXCHOICE]; Uint8 cpi=0; + Uint16 ccl=objects[obj]->class; + Uint8 cim=objects[obj]->image; if(!x) return VOIDLINK; cp->depth=vstackptr; again: switch(code[ptr++]) { case 0 ... 7: n=VOIDLINK; @@ -2373,10 +2375,24 @@ cp[cpi].y=y; cp[cpi].dir=d; cp[cpi].depth=vstackptr; cp[cpi].ptr=code[ptr++]; break; + case OP_IMAGE: + if(n!=VOIDLINK && ccl==objects[n]->class && cim==objects[n]->image) break; + n=playfield[x+y*64-65]; + while(n!=VOIDLINK) { + if(objects[n]->class==ccl && objects[n]->image==cim && !(objects[n]->oflags&OF_DESTROYED)) break; + m=objects[n]->up; + } + if(n==VOIDLINK) goto fail; + break; + case OP_IMAGE_C: + if(n==VOIDLINK) Throw("No object specified in pattern"); + ccl=objects[n]->class; + cim=objects[n]->image; + break; case OP_LOC: if(vstackptr>=VSTACKSIZE-2) Throw("Stack overflow"); Push(NVALUE(x)); Push(NVALUE(y)); break; @@ -2392,20 +2408,24 @@ case OP_NEXT: goto fail; case OP_OBJABOVE: if(n==VOIDLINK) Throw("No object specified in pattern"); n=obj_above(n); + if(n==VOIDLINK) goto fail; break; case OP_OBJBELOW: if(n==VOIDLINK) Throw("No object specified in pattern"); n=obj_below(n); + if(n==VOIDLINK) goto fail; break; case OP_OBJBOTTOMAT: n=obj_bottom_at(x,y); + if(n==VOIDLINK) goto fail; break; case OP_OBJTOPAT: n=obj_top_at(x,y); + if(n==VOIDLINK) goto fail; break; case OP_QUEEN: if(cpi>=MAXCHOICE-8) Throw("Choice overflow"); d=0; cpi+=7;