Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -880,10 +880,14 @@ this flag. During the trigger phase, it will send the MOVED message to all objects which have moved; you can set or clear this flag by yourself if you want to cause it to trigger even though it didn't move or to not trigger even though it did move. +Moving : bool + This flag indicates that a deferred movement is scheduled for this + object. The direction of movement is specified by the Dir variable. + Player : bool [c] [ro] If this object is the player. This is used implicitly as the From of some messages sent by the game engine, and has a few other purposes. (Normally, a level should have exactly one object of such a class, although this is not mandatory; any number (including zero) is allowed.) @@ -907,12 +911,12 @@ with insufficient Hardness is destroyed. Shovable : int16 [c] Defines what directions the object may be shoved, where bit0 means east, bit2 means north, bit4 means west, and bit6 means south. Bit1, bit3, - bit5, and bit7 can be used for diagonal shoving; the high 8-bits are - currently unused but may be used in future. + bit5, and bit7 can be used for diagonal shoving. Higher bits are + reserved for future and should not be used. Stealthy : bool [c] If this flag is set, then the Arrived and Departed variables of other objects are not automatically set when this object moves. @@ -1352,10 +1356,29 @@ Mesh; you probably do not need to use this yourself.) ,Move+ ( obj dir -- bool ) ** As Move+ but for a specified object. ++Move ( dir -- bool ) ** + Schedules a deferred move for this object in the specified direction + (which may be absolute or relative). Some things are checked at this + time, while other things are checked at the time that the movement will + be made; its working is different from non-deferred movements. The + result is true if the move was scheduled or false if it isn't. (Note: + Do not confuse +Move with Move+; they are unrelated.) + +,+Move ( obj dir -- bool ) ** + As +Move but for a specified object rather than necessarily this one. + +-Move ( dir -- bool ) ** + Cancel a deferred move in the specified direction, and possibly also + other things that are shoved by it. The result will be true if it was + scheduled and successfully removed, or false otherwise. + +,-Move ( obj dir -- bool ) ** + As -Move but for a specified object rather than necessarily this one. + MoveNumber ( -- number ) The current move number. This is initially zero, and is advanced after each input phase (before the beginning phase). MoveTo ( x y -- bool ) ** @@ -1438,10 +1461,16 @@ ObjLayerAt ( layers x y -- obj ) Find an object with the given CollisionLayers bits set at that location. If you specify multiple bits, it finds one with any of those bits. (It is not possible for there to be more than one such object.) +ObjMovingTo ( x y -- ... ) + Push on the stack all objects scheduled to move to the specified X and Y + coordinates. There may be zero or more such objects; you can add a mark + to the stack in order to delimit this list (it won't do so automatically, + since you may be putting multiple lists together). + ObjTopAt ( x y -- obj ) Find the object on the top at the specified location. The result will be zero if that location is vacant or out of range. over ( x y -- x y x ) @@ -1666,11 +1695,12 @@ === Messages === This section describes when the various standard messages are sent to objects, and what return values are expected. (Do not confuse CREATE with -CREATED or DESTROY with DESTROYED; they have different purposes.) +CREATED, or DESTROY with DESTROYED, or COLLIDE with COLLIDING; they have +different purposes.) (Some standard messages are in the names.js file but not used; do not use them in your own code, since their names and meaning may change later. The ones listed here are (probably) considered stable, and their numeric value (used in level files) will (probably) remain unchanged.) @@ -1685,10 +1715,18 @@ input phase). From is an object with the Player flag (if there is any), Arg1 and Arg2 are the X and Y coordinates of that object, and Arg3 is the most recent return value from a KEY message. The beginning phase may be suppressed; if it is, then the ending phase is also suppressed. +BLOCKED + When scheduling deferred movement, if the moving object is blocked by + another object, then the moving object sends this message to the object + which is blocking it. From is the object attempting to move, Arg1 and + Arg2 are that object's coordinates, and Arg3 is 1 for +Move or 0 for + -Move. Of the return value, bit0 clears the Moving flag (causing the + move to fail), and bit1 causes it to not send any more BLOCKED messages. + COLLIDE Received when this object is trying to move into a location where there is a collision, so it can't move there. Of the return value, bit0 means to prevent the movement (even if the objects are moved out of the way or destroyed in order to make room), bit1 means to not send any COLLIDEBY @@ -1709,10 +1747,28 @@ necessary, it will try to destroy this object to make room. From is the object attempting to move here, and Arg1 and Arg2 are its location (if attempting to create an object, then From, Arg1, and Arg2 are all zero). Arg3 is the class of the object being moved or created. +COLLIDING + Called when deferred movement is being performed if the move cannot + occur due to a collision with some other object. From is the object + that it is colliding with, Arg1 and Arg2 are its location, and Arg3 + is the type of collision (0 if this object is trying to move into a + stationary object, 1 if another object is trying to move into this + stationary object, 2 if two objects are trying to move into the same + space, or 3 if two or more objects forming a loop are trying to move + into each other). There is no guarantee that this will only be called + once; sometimes it will be called multiple times for a single collision + or for multiple collisions with the same objects. (TODO) + +CONFLICT + Called during scheduling of a deferred move if it is already currently + scheduled to move but in a different direction. Arg1 is the direction + that it is trying to schedule the move in. If the return value is false + then the schedule fails; if true, then it succeeds. + CREATE Sent when the object is created by the Create instruction. This is done after the object is created, but before sending any other messages. The From is the object that created it. The return value will be used as the Arg3 of the SUNK and CREATED messages it might send if appropriate. From Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -1043,10 +1043,47 @@ yy=objects[n]->y; if(!move_to(from,n,x,y)) return 0; send_message(VOIDLINK,n,MSG_JUMPED,NVALUE(xx),NVALUE(yy),OVALUE(from)); return 1; } + +static int defer_move(Uint32 obj,Uint32 dir,Uint8 plus) { + Object*o; + Object*q; + Uint32 n; + Value v; + if(StackProtection()) Throw("Call stack overflow during movement"); + if(obj==VOIDLINK) return 0; + o=objects[obj]; + if(o->oflags&(OF_DESTROYED|OF_BIZARRO)) return 0; + dir=resolve_dir(obj,dir); + if(plus) { + if(o->oflags&OF_MOVING) { + if(o->dir==dir) return 1; + v=send_message(VOIDLINK,obj,MSG_CONFLICT,NVALUE(dir),NVALUE(0),NVALUE(0)); + if(!v_bool(v)) return 0; + } + o->oflags|=OF_MOVING; + o->dir=dir; + } else { + if(!(o->oflags&OF_MOVING)) return 0; + if(o->dir!=dir) return 0; + o->oflags&=~OF_MOVING; + } + n=playfield[o->x+o->y*64-65]; + while(n!=VOIDLINK) { + q=objects[n]; + if(!(q->oflags&(OF_DESTROYED|OF_VISUALONLY)) && ((q->height>0 && q->height>=o->climb) || (classes[q->class]->collisionLayers&classes[o->class]->collisionLayers))) { + v=send_message(obj,n,MSG_BLOCKED,NVALUE(o->x),NVALUE(o->y),NVALUE(plus)); + if(v.t) Throw("Type mismatch"); + if(v.u&1) o->oflags&=~OF_MOVING; + if(v.u&2) break; + } + n=q->up; + } + return plus?(o->oflags&OF_MOVING?1:0):1; +} static void trace_stack(Uint32 obj) { Value t2=Pop(); Value t1=Pop(); Value t0=Pop(); @@ -1068,11 +1105,11 @@ } static void flush_object(Uint32 n) { Object*o=objects[n]; o->arrived=o->departed=0; - o->oflags&=~(OF_MOVED|OF_BUSY|OF_USERSIGNAL); + o->oflags&=~(OF_MOVED|OF_BUSY|OF_USERSIGNAL|OF_MOVING); o->inertia=0; } static void flush_class(Uint16 c) { Uint32 n,p; @@ -1081,11 +1118,11 @@ n=lastobj; while(o=objects[n]) { p=o->prev; if(!c || o->class==c) { o->arrived=o->departed=0; - o->oflags&=~(OF_MOVED|OF_BUSY|OF_USERSIGNAL); + o->oflags&=~(OF_MOVED|OF_BUSY|OF_USERSIGNAL|OF_MOVING); o->inertia=0; } if(p==VOIDLINK) break; n=p; } @@ -1440,10 +1477,30 @@ v=vstack[p+n]; vstack[p+n]=vstack[vstackptr-n-1]; vstack[vstackptr-n-1]=v; } } + +static inline void v_obj_moving_to(Uint32 x,Uint32 y) { + int d; + Uint32 n,xx,yy; + Object*o; + for(d=0;d<8;d++) { + xx=x-x_delta[d]; + yy=y-y_delta[d]; + if(xx<1 || xx>pfwidth || yy<1 || yy>pfheight) continue; + n=playfield[xx+yy*64-65]; + while(n!=VOIDLINK) { + o=objects[n]; + if((o->oflags&OF_MOVING) && !(o->oflags&(OF_DESTROYED|OF_VISUALONLY)) && o->dir==d) { + if(vstackptr>=VSTACKSIZE-2) Throw("Stack overflow"); + Push(OVALUE(n)); + } + n=o->up; + } + } +} // Here is where the execution of a Free Hero Mesh bytecode subroutine is executed. #define NoIgnore() do{ changed=1; }while(0) #define GetVariableOf(a,b) (i=v_object(Pop()),i==VOIDLINK?NVALUE(0):b(objects[i]->a)) #define GetVariableOrAttributeOf(a,b) (t2=Pop(),t2.t==TY_CLASS?NVALUE(classes[t2.u]->a):(i=v_object(t2),i==VOIDLINK?NVALUE(0):b(objects[i]->a))) @@ -1673,10 +1730,14 @@ case OP_LXOR: StackReq(2,1); t1=Pop(); t2=Pop(); if(v_bool(t1)?!v_bool(t2):v_bool(t2)) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_MANHATTAN: StackReq(1,1); t1=Pop(); i=manhattan(obj,v_object(t1)); Push(NVALUE(i)); break; case OP_MANHATTAN_C: StackReq(2,1); t2=Pop(); t1=Pop(); i=manhattan(v_object(t1),v_object(t2)); Push(NVALUE(i)); break; case OP_MARK: StackReq(0,1); Push(UVALUE(0,TY_MARK)); break; case OP_MAXINVENTORY: StackReq(1,0); t1=Pop(); Numeric(t1); if(ninventory>t1.u) Throw("Inventory overflow"); break; + case OP_MINUSMOVE: StackReq(1,1); t1=Pop(); Numeric(t1); i=defer_move(obj,t1.u,0); Push(NVALUE(i)); break; + case OP_MINUSMOVE_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); i=defer_move(i,t1.u,0); Push(NVALUE(i)); break; + case OP_MINUSMOVE_D: StackReq(1,0); t1=Pop(); Numeric(t1); defer_move(obj,t1.u,0); break; + case OP_MINUSMOVE_CD: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); defer_move(i,t1.u,0); break; case OP_MOD: StackReq(2,1); t2=Pop(); DivideBy(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u%t2.u)); break; case OP_MOD_C: StackReq(2,1); t2=Pop(); DivideBy(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.s%t2.s)); break; case OP_MOVE: NoIgnore(); StackReq(1,1); t1=Pop(); Numeric(t1); o->inertia=o->strength; Push(NVALUE(move_dir(obj,obj,t1.u))); break; case OP_MOVE_C: NoIgnore(); StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else { objects[i]->inertia=o->strength; Push(NVALUE(move_dir(obj,i,t1.u))); } break; case OP_MOVE_D: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=o->strength; move_dir(obj,obj,t1.u); break; @@ -1692,10 +1753,14 @@ case OP_MOVEPLUS_CD: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) { objects[i]->inertia+=o->strength; move_dir(obj,i,t1.u); } break; case OP_MOVETO: NoIgnore(); StackReq(2,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); Push(NVALUE(move_to(obj,obj,t2.u,t3.u))); break; case OP_MOVETO_C: NoIgnore(); StackReq(3,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); i=v_object(Pop()); Push(NVALUE(move_to(obj,i,t2.u,t3.u))); break; case OP_MOVETO_D: NoIgnore(); StackReq(2,0); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); move_to(obj,obj,t2.u,t3.u); break; case OP_MOVETO_CD: NoIgnore(); StackReq(3,0); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); i=v_object(Pop()); move_to(obj,i,t2.u,t3.u); break; + case OP_MOVING: StackReq(0,1); if(o->oflags&OF_MOVING) Push(NVALUE(1)); else Push(NVALUE(0)); break; + case OP_MOVING_C: StackReq(1,1); GetFlagOf(OF_MOVING); break; + case OP_MOVING_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_MOVING; else o->oflags&=~OF_MOVING; break; + case OP_MOVING_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_MOVING); break; case OP_MSG: StackReq(0,1); Push(MVALUE(msgvars.msg)); break; case OP_MUL: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u*t2.u)); break; case OP_MUL_C: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.s*t2.s)); break; case OP_NE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?0:1)); break; case OP_NEG: StackReq(1,1); t1=Pop(); Numeric(t1); t1.s=-t1.s; Push(t1); break; @@ -1712,15 +1777,20 @@ case OP_OBJBOTTOMAT: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_bottom_at(t1.u,t2.u); Push(OVALUE(i)); break; case OP_OBJCLASSAT: StackReq(3,1); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_obj_class_at(t1,t2,t3)); break; case OP_OBJDIR: StackReq(1,1); t2=Pop(); Numeric(t2); i=obj_dir(obj,t2.u); Push(OVALUE(i)); break; case OP_OBJDIR_C: StackReq(2,1); t2=Pop(); Numeric(t2); i=obj_dir(v_object(Pop()),t2.u); Push(OVALUE(i)); break; case OP_OBJLAYERAT: StackReq(3,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_layer_at(t1.u,t2.u,t3.u); Push(OVALUE(i)); break; + case OP_OBJMOVINGTO: StackReq(2,0); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); v_obj_moving_to(t1.u,t2.u); break; case OP_OBJTOPAT: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_top_at(t1.u,t2.u); Push(OVALUE(i)); break; case OP_OVER: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t1); Push(t2); Push(t1); break; case OP_PICK: StackReq(0,1); t1=Pop(); Numeric(t1); if(t1.u>=vstackptr) Throw("Stack index out of range"); t1=vstack[vstackptr-t1.u-1]; Push(t1); break; case OP_PLAYER: StackReq(0,1); if(classes[o->class]->cflags&CF_PLAYER) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_PLAYER_C: StackReq(1,1); GetClassFlagOf(CF_PLAYER); break; + case OP_PLUSMOVE: StackReq(1,1); t1=Pop(); Numeric(t1); i=defer_move(obj,t1.u,1); Push(NVALUE(i)); break; + case OP_PLUSMOVE_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); i=defer_move(i,t1.u,1); Push(NVALUE(i)); break; + case OP_PLUSMOVE_D: StackReq(1,0); t1=Pop(); Numeric(t1); defer_move(obj,t1.u,1); break; + case OP_PLUSMOVE_CD: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); defer_move(i,t1.u,1); break; case OP_POPUP: StackReq(1,0); v_set_popup(obj,0); break; case OP_POPUPARGS: i=code[ptr++]; StackReq(i+1,0); v_set_popup(obj,i); break; case OP_QA: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_ARRAY) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_QC: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_CLASS) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_QCZ: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_CLASS || (t1.t==TY_NUMBER && !t1.u)) Push(NVALUE(1)); else Push(NVALUE(0)); break; @@ -1939,10 +2009,120 @@ nlevelstrings=0; free(deadanim); deadanim=0; ndeadanim=0; } + +static inline int try_sharp(Uint32 n1,Uint32 n2) { + Object*o=objects[n1]; + Object*p=objects[n2]; + if((o->oflags|p->oflags)&OF_DESTROYED) return 0; + if(o->dir&1) return 0; + if(p->x!=o->x+x_delta[o->dir] || p->y!=o->y+y_delta[o->dir]) return 0; + if(p->hard[(o->dir^4)>>1]<=o->sharp[o->dir>>1]) return 0; + return !v_bool(destroy(n1,n2,o->oflags&OF_MOVING?2:1)); +} + +static Uint32 handle_colliding(Uint32 n1,Uint32 n2,Uint8 r1,Uint8 r2) { + // n1 = the object trying to move + // n2 = the object it is colliding with (which might also be trying to move, or might not) + Value v; + Uint32 h; + v=send_message(n1,n2,MSG_COLLIDING,NVALUE(objects[n1]->x),NVALUE(objects[n1]->y),NVALUE(r1)); + if(v.t) Throw("Type mismatch"); + h=(v.u>>16)|(v.u<<16); + v=send_message(n2,n1,MSG_COLLIDING,NVALUE(objects[n2]->x),NVALUE(objects[n2]->y),NVALUE(r2)); + if(v.t) Throw("Type mismatch"); + h|=v.u; + if((h&0x0002) && try_sharp(n1,n2)) h|=0x0004; + if((h&0x00020000) && try_sharp(n2,n1)) h|=0x00040000; + return h; +} + +static Uint32 deferred_colliding(Uint32 obj,int x,int y) { + Object*o=objects[obj]; + Object*oE; + Uint32 h=0xFFFFFFFF; + Uint32 objE=playfield[x+y*64-65]; + Uint8 d; + int xx,yy; + while(objE!=VOIDLINK) { + oE=objects[objE]; + if(!(oE->oflags&(OF_DESTROYED|OF_VISUALONLY))) { + if(oE->oflags&OF_MOVING) { + // At this point, it is necessary to check for a loop, which may be like the diagram below: + // >>>>>>>v + // ^<<<< + // The loop may also have a different shape. + // If a loop is found, call the handle_colliding function to determine what to do next. + // If there is no loop, allow the move to be retried later, trying objE's location next. + + } + if(oE->height>o->climb || (classes[o->class]->collisionLayers&classes[oE->class]->collisionLayers)) { + h&=handle_colliding(obj,objE,1,0); + + } + } + objE=oE->up; + } + + // Find other objects trying to move to the same place + if(h&8) for(d=0;d<8;d++) { + xx=x-x_delta[d]; + yy=y-y_delta[d]; + if(xx<1 || xx>pfwidth || yy<1 || yy>pfheight) continue; + objE=playfield[xx+yy*64-65]; + while(objE!=VOIDLINK) { + oE=objects[objE]; + if(obj!=objE && (oE->oflags&OF_MOVING) && oE->dir==d && !(oE->oflags&OF_DESTROYED)) { + if(o->height>oE->climb || oE->height>o->climb || (classes[o->class]->collisionLayers&classes[oE->class]->collisionLayers)) { + h&=handle_colliding(obj,objE,2,2); + + } + } + objE=oE->up; + } + + } + + return ~h; +} + +static void do_deferred_moves(void) { + Object*o; + Object*p; + Uint32 h,n; + int i,x,y; + Uint8 re; + restart: + re=0; + for(i=0;i<64*pfheight;i++) { + retry: + n=playfield[i]; + while(n!=VOIDLINK) { + o=objects[n]; + if((o->oflags&(OF_MOVING|OF_DESTROYED))==OF_MOVING) { + x=o->x+x_delta[o->dir]; + y=o->y+y_delta[o->dir]; + if(x<1 || x>pfwidth || y<1 || y>pfheight || playfield[x+y*64-65]==VOIDLINK) goto stop; + h=deferred_colliding(n,x,y); + if((h&1) && (o->oflags&OF_MOVING) && move_to(VOIDLINK,n,x,y)) { + re=1; + o->oflags=(o->oflags|OF_MOVED)&~OF_MOVING; + i-=65; + if(i<0) i=0; + goto retry; + } + stop: + if(!(h&4)) o->oflags&=~OF_MOVING; + } + skip: + n=o->up; + } + } + if(re) goto restart; +} static void execute_animation(Uint32 obj) { Object*o=objects[obj]; Animation*a=o->anim; if(!(a->step[a->lstep].flag&ANI_ONCE)) return; @@ -1988,11 +2168,11 @@ vstackptr=0; current_key=key; tc=0; for(n=0;ndistance=0; - o->oflags&=~(OF_KEYCLEARED|OF_DONE); + o->oflags&=~(OF_KEYCLEARED|OF_DONE|OF_MOVING); if(o->anim) { o->anim->count=0; if(o->anim->status==ANISTAT_VISUAL) o->anim->status=0; } } @@ -2059,10 +2239,14 @@ busy=1; } if(o->anim && (o->anim->status&ANISTAT_LOGICAL)) execute_animation(n); if(o->oflags&(OF_BUSY|OF_USERSIGNAL)) busy=1; } else { + if(o->oflags&OF_MOVING) { + do_deferred_moves(); + goto trig; + } o->departed2|=o->departed; o->arrived2|=o->arrived; o->departed=o->arrived=0; if(o->oflags&OF_MOVED) o->oflags=(o->oflags|OF_MOVED2)&~OF_MOVED; } @@ -2087,11 +2271,11 @@ if(!busy && !all_flushed) { n=lastobj; while(n!=VOIDLINK) { v=send_message(VOIDLINK,n,MSG_END_TURN,NVALUE(turn),NVALUE(0),NVALUE(0)); if(v_bool(v) || objects[n]->arrived || objects[n]->departed) busy=1; - if(objects[n]->oflags&(OF_BUSY|OF_USERSIGNAL|OF_MOVED)) busy=1; + if(objects[n]->oflags&(OF_BUSY|OF_USERSIGNAL|OF_MOVED|OF_MOVING)) busy=1; n=objects[n]->prev; } turn++; if(!busy) all_flushed=1; } @@ -2108,11 +2292,11 @@ n=o->prev; } n=lastobj; while(n!=VOIDLINK) { o=objects[n]; - if(o->oflags&(OF_BUSY|OF_USERSIGNAL|OF_MOVED)) busy=1; + if(o->oflags&(OF_BUSY|OF_USERSIGNAL|OF_MOVED|OF_MOVING)) busy=1; if(o->arrived || o->departed) busy=1; if(o->anim && (o->anim->status&ANISTAT_LOGICAL) && (o->anim->step[o->anim->lstep].flag&ANI_ONCE)) { i=o->anim->ltime+clock; o->anim->ltime=i>255?255:i; busy=1; Index: heromesh.h ================================================================== --- heromesh.h +++ heromesh.h @@ -35,11 +35,11 @@ #define ZVALUE(x) UVALUE(x,TY_STRING) #define OVALUE(x) ((x)==VOIDLINK?NVALUE(0):UVALUE(x,objects[x]->generation)) #define ValueTo64(v) (((sqlite3_int64)((v).u))|(((sqlite3_int64)((v).t))<<32)) #define ValueEq(x,y) ((x).t==(y).t && (x).u==(y).u) -#define N_MESSAGES 24 +#define N_MESSAGES 25 extern const char*const standard_message_names[]; extern const char*const standard_sound_names[]; extern const char*const heromesh_key_names[256]; extern sqlite3*userdb; @@ -137,10 +137,11 @@ #define OF_DONE 0x0080 #define OF_KEYCLEARED 0x0100 #define OF_DESTROYED 0x0200 #define OF_BIZARRO 0x0400 #define OF_MOVED2 0x0800 +#define OF_MOVING 0x1000 typedef struct { const char*name; const char*edithelp; // not present if CF_GROUP const char*gamehelp; // not present if CF_GROUP Index: instruc ================================================================== --- instruc +++ instruc @@ -172,10 +172,11 @@ ,=UserSignal ,=UserState ,=VisualOnly ,=Stealthy ,=Moved +,=Moving ,=Done ,Destroyed ,Player ,Compatible ,CollisionLayers @@ -228,19 +229,22 @@ ,Manhattan MaxInventory ; error if more than that many slots in inventory .,Move .,MovePlus "Move+" ; obj.Inertia+=Strength instead of obj.Inertia=Strength .,MoveTo ; the internal MoveTo() function +.,PlusMove "+Move" +.,MinusMove "-Move" NewX NewXY NewY ,ObjAbove ,ObjBelow ObjBottomAt ObjClassAt ,ObjDir ObjLayerAt +ObjMovingTo ObjTopAt PopUp *PopUpArgs ; for (PopUp [number]) ,Rel ,Seek Index: instruc.h ================================================================== --- instruc.h +++ instruc.h @@ -245,377 +245,395 @@ #define OP_STEALTHY_EC 39019 #define OP_MOVED 32876 #define OP_MOVED_C 34924 #define OP_MOVED_E 36972 #define OP_MOVED_EC 39020 -#define OP_DONE 32877 -#define OP_DONE_C 34925 -#define OP_DONE_E 36973 -#define OP_DONE_EC 39021 -#define OP_DESTROYED 32878 -#define OP_DESTROYED_C 34926 -#define OP_PLAYER 32879 -#define OP_PLAYER_C 34927 -#define OP_COMPATIBLE 32880 -#define OP_COMPATIBLE_C 34928 -#define OP_COLLISIONLAYERS 32881 -#define OP_COLLISIONLAYERS_C 34929 -#define OP_SELF 32882 -#define OP_MSG 32883 -#define OP_FROM 32884 -#define OP_ARG1 32885 -#define OP_ARG1_E 36981 -#define OP_ARG2 32886 -#define OP_ARG2_E 36982 -#define OP_ARG3 32887 -#define OP_ARG3_E 36983 -#define OP_MOVENUMBER 32888 -#define OP_LEVEL 32889 -#define OP_KEY 32890 -#define OP_FINISHED 32891 -#define OP_FINISHED_E 36987 -#define OP_BACKGROUND 32892 -#define OP_INPUT 32893 -#define OP_QUIZ 32894 -#define OP_INPLACE 32895 -#define OP_DEFAULTIMAGE 32896 -#define OP_HELP 32897 -#define OP_EDITORHELP 32898 -#define OP_SUBS 32899 -#define OP_ANIMATE 32900 -#define OP_ANIMATEDEAD 32901 -#define OP_ASSASSINATE 32902 -#define OP_ASSASSINATE_C 34950 -#define OP_BROADCAST 32903 -#define OP_BROADCAST_D 41095 -#define OP_BROADCASTCLASS 32904 -#define OP_BROADCASTEX 32905 -#define OP_BROADCASTEX_D 41097 -#define OP_BROADCASTSUM 32906 -#define OP_BROADCASTSUMEX 32907 -#define OP_CHAIN 32908 -#define OP_CHEBYSHEV 32909 -#define OP_CHEBYSHEV_C 34957 -#define OP_CREATE 32910 -#define OP_CREATE_D 41102 -#define OP_DELINVENTORY 32911 -#define OP_DELTA 32912 -#define OP_DESTROY 32913 -#define OP_DESTROY_C 34961 -#define OP_DESTROY_D 41105 -#define OP_DESTROY_CD 43153 -#define OP_FLUSHCLASS 32914 -#define OP_FLUSHOBJ 32915 -#define OP_FLUSHOBJ_C 34963 -#define OP_GETINVENTORY 32916 -#define OP_HEIGHTAT 32917 -#define OP_IGNOREKEY 32918 -#define OP_INTMOVE 32919 -#define OP_INTMOVE_C 34967 -#define OP_INTMOVE_D 41111 -#define OP_INTMOVE_CD 43159 -#define OP_JUMPTO 32920 -#define OP_JUMPTO_C 34968 -#define OP_JUMPTO_D 41112 -#define OP_JUMPTO_CD 43160 -#define OP_LOC 32921 -#define OP_LOC_C 34969 -#define OP_LOCATEME 32922 -#define OP_LOSELEVEL 32923 -#define OP_MANHATTAN 32924 -#define OP_MANHATTAN_C 34972 -#define OP_MAXINVENTORY 32925 -#define OP_MOVE 32926 -#define OP_MOVE_C 34974 -#define OP_MOVE_D 41118 -#define OP_MOVE_CD 43166 -#define OP_MOVEPLUS 32927 -#define OP_MOVEPLUS_C 34975 -#define OP_MOVEPLUS_D 41119 -#define OP_MOVEPLUS_CD 43167 -#define OP_MOVETO 32928 -#define OP_MOVETO_C 34976 -#define OP_MOVETO_D 41120 -#define OP_MOVETO_CD 43168 -#define OP_NEWX 32929 -#define OP_NEWXY 32930 -#define OP_NEWY 32931 -#define OP_OBJABOVE 32932 -#define OP_OBJABOVE_C 34980 -#define OP_OBJBELOW 32933 -#define OP_OBJBELOW_C 34981 -#define OP_OBJBOTTOMAT 32934 -#define OP_OBJCLASSAT 32935 -#define OP_OBJDIR 32936 -#define OP_OBJDIR_C 34984 -#define OP_OBJLAYERAT 32937 -#define OP_OBJTOPAT 32938 -#define OP_POPUP 32939 -#define OP_POPUPARGS 32940 -#define OP_REL 32941 -#define OP_REL_C 34989 -#define OP_SEEK 32942 -#define OP_SEEK_C 34990 -#define OP_SEND 32943 -#define OP_SEND_C 34991 -#define OP_SEND_D 41135 -#define OP_SEND_CD 43183 -#define OP_SENDEX 32944 -#define OP_SENDEX_C 34992 -#define OP_SENDEX_D 41136 -#define OP_SENDEX_CD 43184 -#define OP_SETINVENTORY 32945 -#define OP_SOUND 32946 -#define OP_SYNCHRONIZE 32947 -#define OP_TRACE 32948 -#define OP_VOLUMEAT 32949 -#define OP_WINLEVEL 32950 -#define OP_XDIR 32951 -#define OP_XDIR_C 34999 -#define OP_XYDIR 32952 -#define OP_YDIR 32953 -#define OP_YDIR_C 35001 -#define OP_MARK 32954 -#define OP_TMARK 32955 -#define OP_IN 32956 -#define OP_NIN 32957 -#define OP_MBEGIN 32958 -#define OP_FLIP 32959 -#define OP_ARRAY 32960 -#define OP_GETARRAY 32961 -#define OP_INITARRAY 32962 -#define OP_SETARRAY 32963 -#define OP_ARRAYCELL 32964 -#define OP_FUNCTION 32965 -#define OP_LOCAL 32966 -#define OP_LABEL 32967 -#define OP_STRING 32968 -#define OP_INT16 32969 -#define OP_INT32 32970 -#define OP_DISPATCH 32971 -#define OP_USERFLAG 32972 +#define OP_MOVING 32877 +#define OP_MOVING_C 34925 +#define OP_MOVING_E 36973 +#define OP_MOVING_EC 39021 +#define OP_DONE 32878 +#define OP_DONE_C 34926 +#define OP_DONE_E 36974 +#define OP_DONE_EC 39022 +#define OP_DESTROYED 32879 +#define OP_DESTROYED_C 34927 +#define OP_PLAYER 32880 +#define OP_PLAYER_C 34928 +#define OP_COMPATIBLE 32881 +#define OP_COMPATIBLE_C 34929 +#define OP_COLLISIONLAYERS 32882 +#define OP_COLLISIONLAYERS_C 34930 +#define OP_SELF 32883 +#define OP_MSG 32884 +#define OP_FROM 32885 +#define OP_ARG1 32886 +#define OP_ARG1_E 36982 +#define OP_ARG2 32887 +#define OP_ARG2_E 36983 +#define OP_ARG3 32888 +#define OP_ARG3_E 36984 +#define OP_MOVENUMBER 32889 +#define OP_LEVEL 32890 +#define OP_KEY 32891 +#define OP_FINISHED 32892 +#define OP_FINISHED_E 36988 +#define OP_BACKGROUND 32893 +#define OP_INPUT 32894 +#define OP_QUIZ 32895 +#define OP_INPLACE 32896 +#define OP_DEFAULTIMAGE 32897 +#define OP_HELP 32898 +#define OP_EDITORHELP 32899 +#define OP_SUBS 32900 +#define OP_ANIMATE 32901 +#define OP_ANIMATEDEAD 32902 +#define OP_ASSASSINATE 32903 +#define OP_ASSASSINATE_C 34951 +#define OP_BROADCAST 32904 +#define OP_BROADCAST_D 41096 +#define OP_BROADCASTCLASS 32905 +#define OP_BROADCASTEX 32906 +#define OP_BROADCASTEX_D 41098 +#define OP_BROADCASTSUM 32907 +#define OP_BROADCASTSUMEX 32908 +#define OP_CHAIN 32909 +#define OP_CHEBYSHEV 32910 +#define OP_CHEBYSHEV_C 34958 +#define OP_CREATE 32911 +#define OP_CREATE_D 41103 +#define OP_DELINVENTORY 32912 +#define OP_DELTA 32913 +#define OP_DESTROY 32914 +#define OP_DESTROY_C 34962 +#define OP_DESTROY_D 41106 +#define OP_DESTROY_CD 43154 +#define OP_FLUSHCLASS 32915 +#define OP_FLUSHOBJ 32916 +#define OP_FLUSHOBJ_C 34964 +#define OP_GETINVENTORY 32917 +#define OP_HEIGHTAT 32918 +#define OP_IGNOREKEY 32919 +#define OP_INTMOVE 32920 +#define OP_INTMOVE_C 34968 +#define OP_INTMOVE_D 41112 +#define OP_INTMOVE_CD 43160 +#define OP_JUMPTO 32921 +#define OP_JUMPTO_C 34969 +#define OP_JUMPTO_D 41113 +#define OP_JUMPTO_CD 43161 +#define OP_LOC 32922 +#define OP_LOC_C 34970 +#define OP_LOCATEME 32923 +#define OP_LOSELEVEL 32924 +#define OP_MANHATTAN 32925 +#define OP_MANHATTAN_C 34973 +#define OP_MAXINVENTORY 32926 +#define OP_MOVE 32927 +#define OP_MOVE_C 34975 +#define OP_MOVE_D 41119 +#define OP_MOVE_CD 43167 +#define OP_MOVEPLUS 32928 +#define OP_MOVEPLUS_C 34976 +#define OP_MOVEPLUS_D 41120 +#define OP_MOVEPLUS_CD 43168 +#define OP_MOVETO 32929 +#define OP_MOVETO_C 34977 +#define OP_MOVETO_D 41121 +#define OP_MOVETO_CD 43169 +#define OP_PLUSMOVE 32930 +#define OP_PLUSMOVE_C 34978 +#define OP_PLUSMOVE_D 41122 +#define OP_PLUSMOVE_CD 43170 +#define OP_MINUSMOVE 32931 +#define OP_MINUSMOVE_C 34979 +#define OP_MINUSMOVE_D 41123 +#define OP_MINUSMOVE_CD 43171 +#define OP_NEWX 32932 +#define OP_NEWXY 32933 +#define OP_NEWY 32934 +#define OP_OBJABOVE 32935 +#define OP_OBJABOVE_C 34983 +#define OP_OBJBELOW 32936 +#define OP_OBJBELOW_C 34984 +#define OP_OBJBOTTOMAT 32937 +#define OP_OBJCLASSAT 32938 +#define OP_OBJDIR 32939 +#define OP_OBJDIR_C 34987 +#define OP_OBJLAYERAT 32940 +#define OP_OBJMOVINGTO 32941 +#define OP_OBJTOPAT 32942 +#define OP_POPUP 32943 +#define OP_POPUPARGS 32944 +#define OP_REL 32945 +#define OP_REL_C 34993 +#define OP_SEEK 32946 +#define OP_SEEK_C 34994 +#define OP_SEND 32947 +#define OP_SEND_C 34995 +#define OP_SEND_D 41139 +#define OP_SEND_CD 43187 +#define OP_SENDEX 32948 +#define OP_SENDEX_C 34996 +#define OP_SENDEX_D 41140 +#define OP_SENDEX_CD 43188 +#define OP_SETINVENTORY 32949 +#define OP_SOUND 32950 +#define OP_SYNCHRONIZE 32951 +#define OP_TRACE 32952 +#define OP_VOLUMEAT 32953 +#define OP_WINLEVEL 32954 +#define OP_XDIR 32955 +#define OP_XDIR_C 35003 +#define OP_XYDIR 32956 +#define OP_YDIR 32957 +#define OP_YDIR_C 35005 +#define OP_MARK 32958 +#define OP_TMARK 32959 +#define OP_IN 32960 +#define OP_NIN 32961 +#define OP_MBEGIN 32962 +#define OP_FLIP 32963 +#define OP_ARRAY 32964 +#define OP_GETARRAY 32965 +#define OP_INITARRAY 32966 +#define OP_SETARRAY 32967 +#define OP_ARRAYCELL 32968 +#define OP_FUNCTION 32969 +#define OP_LOCAL 32970 +#define OP_LABEL 32971 +#define OP_STRING 32972 +#define OP_INT16 32973 +#define OP_INT32 32974 +#define OP_DISPATCH 32975 +#define OP_USERFLAG 32976 #ifdef HEROMESH_CLASS static const Op_Names op_names[]={ {"*",8486937}, {"+",8421399}, +{"+Move",10584226}, {"-",8421400}, +{"-Move",10584227}, {"-rot",8421382}, {".",10518528}, {"/",8486938}, {"ANHH",8389394}, {"ARRIVED",8389124}, -{"Animate",8421508}, -{"AnimateDead",8421509}, -{"Arg1",8552565}, -{"Arg2",8552566}, -{"Arg3",8552567}, -{"Array",8683712}, -{"ArrayCell",8421572}, +{"Animate",8421509}, +{"AnimateDead",8421510}, +{"Arg1",8552566}, +{"Arg2",8552567}, +{"Arg3",8552568}, +{"Array",8683716}, +{"ArrayCell",8421576}, {"Arrivals",8618083}, {"Arrived",8618081}, -{"Assassinate",8487046}, +{"Assassinate",8487047}, {"B",9437196}, {"BANG",8389380}, {"BEDOINGNG",8389406}, {"BEEDEEP",8389404}, {"BEGIN_TURN",8389123}, -{"BIZARRO_SWAP",8389143}, +{"BLOCKED",8389144}, {"BOOOM",8389410}, {"BOUNCE",8389415}, {"BRRREEET",8389396}, {"BRRRT",8389395}, {"BUZZER",8389420}, {"BWEEP",8389397}, -{"Background",8683644}, -{"Broadcast",10518663}, -{"BroadcastEx",10518665}, -{"BroadcastSum",8421514}, -{"BroadcastSumEx",8421515}, +{"Background",8683645}, +{"Broadcast",10518664}, +{"BroadcastEx",10518666}, +{"BroadcastSum",8421515}, +{"BroadcastSumEx",8421516}, {"Busy",8618085}, {"CHEEP",8389393}, {"CHYEW",8389392}, -{"CLEANUP",8389140}, {"CLICK",8389388}, {"COLLIDE",8389142}, {"COLLIDEBY",8389141}, +{"COLLIDING",8389143}, +{"CONFLICT",8389140}, {"CREATE",8389121}, {"CREATED",8389137}, -{"Chebyshev",8487053}, +{"Chebyshev",8487054}, {"Class",8486967}, {"Climb",9142347}, -{"CollisionLayers",8487025}, -{"Compatible",8487024}, -{"Create",10518670}, +{"CollisionLayers",8487026}, +{"Compatible",8487025}, +{"Create",10518671}, {"DEEP_POP",8389417}, {"DEPARTED",8389125}, {"DESTROY",8389122}, {"DESTROYED",8389136}, {"DINK",8389390}, {"DOOR",8389378}, {"DRLRLRINK",8389398}, {"DYUPE",8389413}, -{"DefaultImage",8683648}, -{"DelInventory",8421519}, -{"Delta",8421520}, +{"DefaultImage",8683649}, +{"DelInventory",8421520}, +{"Delta",8421521}, {"Density",9142339}, {"Departed",8618082}, {"Departures",8618084}, -{"Destroy",10584209}, -{"Destroyed",8487022}, +{"Destroy",10584210}, +{"Destroyed",8487023}, {"Dir",8618045}, {"Distance",9142337}, -{"Done",8618093}, +{"Done",8618094}, {"E",9437184}, {"END_TURN",8389139}, -{"EditorHelp",8683650}, +{"EditorHelp",8683651}, {"F",9437192}, {"FAROUT",8389421}, {"FFFFTT",8389399}, {"FLOATED",8389132}, {"FROG",8389383}, -{"Finished",8552571}, -{"FlushClass",8421522}, -{"FlushObj",8487059}, -{"From",8421492}, +{"Finished",8552572}, +{"FlushClass",8421523}, +{"FlushObj",8487060}, +{"From",8421493}, {"GLASS",8389379}, {"GLISSANT",8389419}, -{"GetArray",8421569}, -{"GetInventory",8421524}, +{"GetArray",8421573}, +{"GetInventory",8421525}, {"HAWK",8389425}, {"HEARTBEAT",8389407}, {"HIT",8389134}, {"HITBY",8389135}, {"Hard",8618063}, {"Height",9142345}, -{"HeightAt",8421525}, -{"Help",8683649}, +{"HeightAt",8421526}, +{"Help",8683650}, {"INIT",8389120}, -{"IgnoreKey",8421526}, +{"IgnoreKey",8421527}, {"Image",8618046}, -{"InPlace",8683647}, +{"InPlace",8683648}, {"Inertia",9142335}, -{"InitArray",8421570}, -{"Input",8683645}, -{"IntMove",10584215}, +{"InitArray",8421574}, +{"Input",8683646}, +{"IntMove",10584216}, {"Invisible",8618086}, {"JAYAYAYNG",8389416}, {"JUMPED",8389128}, -{"JumpTo",10584216}, +{"JumpTo",10584217}, {"KEWEL",8389422}, {"KEY",8389129}, {"KLECK",8389387}, {"KLINKK",8389385}, -{"Key",8421498}, +{"Key",8421499}, {"KeyCleared",8618087}, {"L",9437194}, {"LASTIMAGE",8389126}, {"LB",9437195}, {"LF",9437193}, {"LOCK",8389408}, {"LOOP",8388610}, -{"Level",8421497}, -{"Loc",8487065}, -{"LocateMe",8421530}, -{"LoseLevel",8421531}, +{"Level",8421498}, +{"Loc",8487066}, +{"LocateMe",8421531}, +{"LoseLevel",8421532}, {"MOVED",8389127}, {"MOVING",8389130}, -{"Manhattan",8487068}, -{"MaxInventory",8421533}, +{"Manhattan",8487069}, +{"MaxInventory",8421534}, {"Misc1",9142355}, {"Misc2",9142357}, {"Misc3",9142359}, {"Misc4",9142361}, {"Misc5",9142363}, {"Misc6",9142365}, {"Misc7",9142367}, -{"Move",10584222}, -{"Move+",10584223}, -{"MoveNumber",8421496}, -{"MoveTo",10584224}, +{"Move",10584223}, +{"Move+",10584224}, +{"MoveNumber",8421497}, +{"MoveTo",10584225}, {"Moved",8618092}, -{"Msg",8421491}, +{"Moving",8618093}, +{"Msg",8421492}, {"N",9437186}, {"NE",9437185}, {"NW",9437187}, -{"NewX",8421537}, -{"NewXY",8421538}, -{"NewY",8421539}, +{"NewX",8421540}, +{"NewXY",8421541}, +{"NewY",8421542}, {"OLDPHONE",8389402}, {"ONCE",8388609}, {"OSC",8388616}, {"OSCLOOP",8388618}, -{"ObjAbove",8487076}, -{"ObjBelow",8487077}, -{"ObjBottomAt",8421542}, -{"ObjClassAt",8421543}, -{"ObjDir",8487080}, -{"ObjLayerAt",8421545}, -{"ObjTopAt",8421546}, +{"ObjAbove",8487079}, +{"ObjBelow",8487080}, +{"ObjBottomAt",8421545}, +{"ObjClassAt",8421546}, +{"ObjDir",8487083}, +{"ObjLayerAt",8421548}, +{"ObjMovingTo",8421549}, +{"ObjTopAt",8421550}, {"PLAYERMOVING",8389133}, {"POSTINIT",8389138}, {"POUR",8389377}, {"POWER",8389386}, -{"Player",8487023}, -{"PopUp",8421547}, -{"Quiz",8683646}, +{"Player",8487024}, +{"PopUp",8421551}, +{"Quiz",8683647}, {"R",9437198}, {"RATCHET1",8389418}, {"RATCHET2",8389412}, {"RATTLE",8389403}, {"RB",9437197}, {"RF",9437199}, -{"Rel",8487085}, +{"Rel",8487089}, {"S",9437190}, {"SE",9437191}, {"SMALL_POP",8389389}, {"SPLASH",8389376}, {"STEAM",8389424}, {"STOP",8388608}, -{"SUBS",8683651}, +{"SUBS",8683652}, {"SUNK",8389131}, {"SW",9437189}, -{"Seek",8487086}, -{"Self",8421490}, -{"Send",10584239}, -{"SendEx",10584240}, -{"SetArray",8421571}, -{"SetInventory",8421553}, +{"Seek",8487090}, +{"Self",8421491}, +{"Send",10584243}, +{"SendEx",10584244}, +{"SetArray",8421575}, +{"SetInventory",8421557}, {"Shape",8618042}, {"ShapeDir",8618065}, {"Sharp",8618064}, {"Shovable",8618066}, -{"Sound",8421554}, +{"Sound",8421558}, {"Stealthy",8618091}, {"Strength",9142349}, -{"Synchronize",8421555}, +{"Synchronize",8421559}, {"TAHTASHH",8389409}, {"THMP_thmp",8389405}, {"THWIT",8389384}, {"TICK",8389391}, {"Temperature",9142328}, -{"Trace",8421556}, +{"Trace",8421560}, {"UH_OH",8389382}, {"UNCORK",8389414}, {"UNHH",8389381}, {"UserSignal",8618088}, {"UserState",8618089}, {"VACUUM",8389411}, {"VisualOnly",8618090}, {"Volume",9142341}, -{"VolumeAt",8421557}, +{"VolumeAt",8421561}, {"W",9437188}, {"WAHOO",8389400}, {"WHACK",8389423}, {"Weight",9142343}, -{"WinLevel",8421558}, -{"XDir",8487095}, -{"XYDir",8421560}, +{"WinLevel",8421562}, +{"XDir",8487099}, +{"XYDir",8421564}, {"Xloc",8486971}, -{"YDir",8487097}, +{"YDir",8487101}, {"YEEHAW",8389401}, {"Yloc",8486972}, -{"_",8421562}, +{"_",8421566}, {"a?",8421430}, {"again",8683534}, {"band",8421407}, {"begin",8683533}, {"bit",8683555}, @@ -653,38 +671,38 @@ {"bit9",8423401}, {"bnot",8421410}, {"bor",8421408}, {"bxor",8421409}, {"c?",8421424}, -{"chain",8421516}, +{"chain",8421517}, {"cz?",8421425}, {"dup",8421377}, {"el",8683532}, {"else",8683530}, {"eq",8421416}, -{"flip",8421567}, +{"flip",8421571}, {"for",8683538}, {"ge",8486956}, {"gt",8486954}, {"if",8683529}, -{"in",8421564}, +{"in",8421568}, {"is",8421422}, {"land",8421412}, {"le",8486957}, {"lnot",8421415}, {"lor",8421413}, {"lsh",8421405}, {"lt",8486955}, {"lxor",8421414}, {"m?",8421426}, -{"mbegin",8683710}, +{"mbegin",8683714}, {"mod",8486939}, {"n?",8421423}, {"ne",8421417}, {"neg",8421404}, {"next",8683539}, -{"nin",8421565}, +{"nin",8421569}, {"nip",8421379}, {"o?",8421428}, {"over",8421384}, {"oz?",8421429}, {"pick",8421383}, @@ -693,12 +711,12 @@ {"rot",8421381}, {"rsh",8486942}, {"s?",8421427}, {"swap",8421378}, {"then",8683531}, -{"tmark",8421563}, +{"tmark",8421567}, {"tuck",8421380}, {"until",8683535}, {"while",8683536}, }; -#define N_OP_NAMES 304 +#define N_OP_NAMES 309 #endif Index: names.h ================================================================== --- names.h +++ names.h @@ -17,14 +17,15 @@ #define MSG_HITBY 15 #define MSG_DESTROYED 16 #define MSG_CREATED 17 #define MSG_POSTINIT 18 #define MSG_END_TURN 19 -#define MSG_CLEANUP 20 +#define MSG_CONFLICT 20 #define MSG_COLLIDEBY 21 #define MSG_COLLIDE 22 -#define MSG_BIZARRO_SWAP 23 +#define MSG_COLLIDING 23 +#define MSG_BLOCKED 24 #ifdef HEROMESH_MAIN const char*const standard_message_names[]={ "INIT", "CREATE", "DESTROY", @@ -43,14 +44,15 @@ "HITBY", "DESTROYED", "CREATED", "POSTINIT", "END_TURN", - "CLEANUP", + "CONFLICT", "COLLIDEBY", "COLLIDE", - "BIZARRO_SWAP", + "COLLIDING", + "BLOCKED", }; #endif #define SND_SPLASH 0 #define SND_POUR 1 #define SND_DOOR 2 Index: names.js ================================================================== --- names.js +++ names.js @@ -22,14 +22,15 @@ 16 = DESTROYED 17 = CREATED 18 = POSTINIT 19 = END_TURN // New - 20 = CLEANUP + 20 = CONFLICT 21 = COLLIDEBY 22 = COLLIDE - 23 = BIZARRO_SWAP + 23 = COLLIDING + 24 = BLOCKED `.split("\n").map(x=>/^ *([0-9]+) = ([^ ]*) *$/.exec(x)).filter(x=>x); const standard_sound_names=[]; ` SPLASH POUR