Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -2114,11 +2114,14 @@ 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) + or for multiple collisions with the same objects. The return value has + bit0 to allow the move, bit1 to handle sharpness, and bit2 to retry if + the move fails. The bit16 and higher bits will have the similar effect + for the other object instead. 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 Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -1201,16 +1201,19 @@ static int defer_move(Uint32 obj,Uint32 dir,Uint8 plus) { Object*o; Object*q; Uint32 n; + Uint8 x,y; Value v; if(StackProtection()) Throw("Call stack overflow during movement"); if(obj==VOIDLINK || obj==control_obj) return 0; o=objects[obj]; if(o->oflags&(OF_DESTROYED|OF_BIZARRO)) return 0; dir=resolve_dir(obj,dir); + x=o->x+x_delta[dir]; y=o->y+y_delta[dir]; + if(x<1 || x>pfwidth || y<1 || y>pfheight) return 0; 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; @@ -1220,14 +1223,14 @@ } 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]; + n=playfield[x+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))) { + if(!(q->oflags&(OF_DESTROYED|OF_VISUALONLY|OF_MOVING)) && ((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; } @@ -3051,11 +3054,11 @@ } } objE=oE->up; } } - return ~h; + return h; } static void do_deferred_moves(void) { Object*o; Object*p; @@ -3079,12 +3082,11 @@ o->oflags=(o->oflags|OF_MOVED)&~OF_MOVING; i-=65; if(i<0) i=0; goto retry; } - stop: - if((h&5)!=4) o->oflags&=~OF_MOVING; + if((h&5)!=4) stop: o->oflags&=~OF_MOVING; } skip: n=o->up; } }