Index: class.c ================================================================== --- class.c +++ class.c @@ -1339,11 +1339,11 @@ if(tokent!=TF_CLOSE) ParseError("Close parentheses expected\n"); return n; } for(;;) { if(tokent==TF_CLOSE) return n; - if(!Tokenf(TF_DIR) || tokenv>7 || (tokenv&1)) ParseError("Expected even absolute direction\n"); + if(!Tokenf(TF_DIR) || tokenv>7) ParseError("Expected absolute direction\n"); n|=1<) Set this object to be shovable in the specified directions, which can be - E, N, W, or S (diagonals are not allowed). + any absolute direction. (Shovable ) Set the Shovable variable to the specified 8-bit number. (You cannot set the initial value of any other bits; they are always clear.) @@ -1835,11 +1835,12 @@ This section describes the bits of the return value of the HIT and HITBY messages; these values are also used as the Arg3 of those messages. Some descriptions below are marked with an asterisk. If the Compatible flag is set for the object that returned this value, then all bits with -the asterisk in the below descriptions are masked out. +the asterisk in the below descriptions are masked out (bit15 is only +masked out for Compatible objects for diagonal movement). bit0 Do not send the HITBY message to the target object. bit1 @@ -1890,11 +1891,11 @@ Abort before actually moving the object and before trying sliding. bit14 * Do not set the Moved flag even if successful. -bit15 +bit15 (*) Try again after trying shoving (whether or not the shoving is successful). If it tries to shove an object and it is successful, then it will automatically set this bit and automatically try again. bit16 @@ -1985,6 +1986,8 @@ * Moving objects is not allowed during LASTIMAGE processing. * The way that the trigger phase works is different. * In the ARRIVED and DEPARTED messages, Arg1 is always zero. + +* Diagonal shoving is not possible. Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -837,22 +837,34 @@ oE=objects[objE]; if(oE->height>0) { hit&=0xFC287000; v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(hit)); if(v.t) Throw("Type mismatch in HIT/HITBY"); - hit|=v.u&(classes[o->class]->cflags&CF_COMPATIBLE?0xC0098F7F:-1L); + hit|=v.u&(classes[o->class]->cflags&CF_COMPATIBLE?0xC0090F7F:-1L); if(hit&8) goto fail; if(!(hit&0x11)) { v=send_message(obj,objE,MSG_HITBY,NVALUE(oW->x),NVALUE(oW->y),NVALUE(hit)); if(v.t>TY_MAXTYPE) goto warp; if(v.t) Throw("Type mismatch in HIT/HITBY"); - hit|=v.u&(classes[oE->class]->cflags&CF_COMPATIBLE?0xC0098F7F:-1L); + hit|=v.u&(classes[oE->class]->cflags&CF_COMPATIBLE?0xC0090F7F:-1L); if(hit&8) goto fail; } + } + // Shoving + if(!(classes[o->class]->cflags&CF_COMPATIBLE)) { + if(!(hit&0x44) && (oE->shovable&(1<inertia>=oE->weight && !(oE->oflags&OF_VISUALONLY)) { + oE->inertia=o->inertia; + if(move_dir(obj,objE,dir)) { + if(!(oE->oflags&OF_DESTROYED)) o->inertia=oE->inertia; + hit|=0x8000; + if(hit&0x800000) goto restart; + } + } } objE=obj_below(objE); } + if((hit&0x48000)==0x8000) goto restart; if((hit&0x200000) && !(hit&0x402008)) { if(hit&0x20000) goto success; if(!oF) goto fail; if(move_to(from,obj,oF->x,oF->y)) goto success; else goto fail; }