Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -2013,10 +2013,21 @@ does match, then the top value is removed and it pushes false instead. VolumeAt ( x y -- volume ) Finds the greatest volume among objects at the specified location. +Walkable ( x y -- bool ) + Tells if the current object could walk on the specified coordinates, + according to Height, Climb, and CollisionLayers. This object is not + counted, even if it is at the specified coordinates. Shoving, hit bits, + Volume, etc are not checked. + +,Walkable ( obj x y -- bool ) + Similar to Walkable but for a specified object instead of this one. You + may also specify a class, in which case it uses the default values of + that class instead of the current values of an object. + WinLevel ( -- ) Ends all execution and accepts the input sequence that resulted in the current game state as a valid solution. (In other words, the goal of the game is to find a sequence of inputs that result in the execution of a WinLevel instruction, without causing any errors or executing LoseLevel.) Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -2739,10 +2739,53 @@ } pconn=nconn=first; StackReq(0,1); return v; } + +static Uint32 v_walkable(Uint32 obj,Uint32 x,Uint32 y) { + Uint32 r=0; + Object*o; + Uint32 n; + Uint8 lay; + if(obj==VOIDLINK) return 0; + o=objects[obj]; + if(o->oflags&OF_DESTROYED) return 0; + lay=classes[o->class]->collisionLayers; + if(x<1 || x>pfwidth || y<1 || y>pfheight) return 0; + n=playfield[x+y*64-65]; + while(n!=VOIDLINK) { + if(n!=obj) { + if(lay&classes[objects[n]->class]->collisionLayers) return 0; + if(!(objects[n]->oflags&(OF_VISUALONLY|OF_DESTROYED))) { + if(o->climbheight) return 0; + r=1; + } + } + n=objects[n]->up; + } + return r; +} + +static Uint32 v_walkable_c(Uint32 c,Uint32 x,Uint32 y) { + Class*cl=classes[c]; + Uint32 r=0; + Uint8 lay=cl->collisionLayers; + Uint32 n; + if(cl->cflags&CF_NOCLASS2) Throw("Invalid class number"); + if(x<1 || x>pfwidth || y<1 || y>pfheight) return 0; + n=playfield[x+y*64-65]; + while(n!=VOIDLINK) { + if(lay&classes[objects[n]->class]->collisionLayers) return 0; + if(!(objects[n]->oflags&(OF_VISUALONLY|OF_DESTROYED))) { + if(cl->climbheight) return 0; + r=1; + } + n=objects[n]->up; + } + return r; +} // 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))) @@ -3185,10 +3228,12 @@ case OP_VOLUME_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->volume=t1.u; break; case OP_VOLUME_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->volume=t1.u&0xFFFF; break; case OP_VOLUME_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->volume=t1.u; break; case OP_VOLUME_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->volume=t1.u&0xFFFF; break; case OP_VOLUMEAT: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(volume_at(t1.u,t2.u))); break; + case OP_WALKABLE: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=v_walkable(obj,t1.u,t2.u); Push(NVALUE(i)); break; + case OP_WALKABLE_C: StackReq(3,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); t3=Pop(); i=(t3.t==TY_CLASS?v_walkable_c(t3.u,t1.u,t2.u):v_walkable(v_object(t3),t1.u,t2.u)); Push(NVALUE(i)); break; case OP_WEIGHT: StackReq(0,1); Push(NVALUE(o->weight)); break; case OP_WEIGHT_C: StackReq(1,1); Push(GetVariableOrAttributeOf(weight,NVALUE)); break; case OP_WEIGHT_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->weight=t1.u; break; case OP_WEIGHT_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->weight=t1.u&0xFFFF; break; case OP_WEIGHT_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->weight=t1.u; break; Index: instruc ================================================================== --- instruc +++ instruc @@ -287,10 +287,11 @@ Trace ,TraceStack Trigger TriggerAt VolumeAt +,Walkable ,WinLevel ,XDir ,XStep XYDir ,YDir Index: instruc.h ================================================================== --- instruc.h +++ instruc.h @@ -428,68 +428,70 @@ #define OP_TRACESTACK 32982 #define OP_TRACESTACK_C 35030 #define OP_TRIGGER 32983 #define OP_TRIGGERAT 32984 #define OP_VOLUMEAT 32985 -#define OP_WINLEVEL 32986 -#define OP_WINLEVEL_C 35034 -#define OP_XDIR 32987 -#define OP_XDIR_C 35035 -#define OP_XSTEP 32988 -#define OP_XSTEP_C 35036 -#define OP_XYDIR 32989 -#define OP_YDIR 32990 -#define OP_YDIR_C 35038 -#define OP_YSTEP 32991 -#define OP_YSTEP_C 35039 -#define OP_MARK 32992 -#define OP_TMARK 32993 -#define OP_IN 32994 -#define OP_NIN 32995 -#define OP_MBEGIN 32996 -#define OP_FLIP 32997 -#define OP_COUNT 32998 -#define OP_CLEAR 32999 -#define OP_UNIQ 33000 -#define OP_ARRAY 33001 -#define OP_GETARRAY 33002 -#define OP_INITARRAY 33003 -#define OP_SETARRAY 33004 -#define OP_ARRAYCELL 33005 -#define OP_ARRAYSLICE 33006 -#define OP_COPYARRAY 33007 -#define OP_DOTPRODUCT 33008 -#define OP_PATTERN 33009 -#define OP_PATTERN_C 35057 -#define OP_PATTERN_E 37105 -#define OP_PATTERN_EC 39153 -#define OP_PATTERNS 33010 -#define OP_PATTERNS_C 35058 -#define OP_PATTERNS_E 37106 -#define OP_PATTERNS_EC 39154 -#define OP_ROOK 33011 -#define OP_BISHOP 33012 -#define OP_QUEEN 33013 -#define OP_CUT 33014 -#define OP_BIZARRO 33015 -#define OP_BIZARRO_C 35063 -#define OP_BIZARRO_E 37111 -#define OP_BIZARRO_EC 39159 -#define OP_BIZARROSWAP 33016 -#define OP_BIZARROSWAP_D 41208 -#define OP_SWAPWORLD 33017 -#define OP_ABSTRACT 33018 -#define OP_SUPER 33019 -#define OP_SUPER_C 35067 -#define OP_FUNCTION 33020 -#define OP_LOCAL 33021 -#define OP_LABEL 33022 -#define OP_STRING 33023 -#define OP_INT16 33024 -#define OP_INT32 33025 -#define OP_DISPATCH 33026 -#define OP_USERFLAG 33027 +#define OP_WALKABLE 32986 +#define OP_WALKABLE_C 35034 +#define OP_WINLEVEL 32987 +#define OP_WINLEVEL_C 35035 +#define OP_XDIR 32988 +#define OP_XDIR_C 35036 +#define OP_XSTEP 32989 +#define OP_XSTEP_C 35037 +#define OP_XYDIR 32990 +#define OP_YDIR 32991 +#define OP_YDIR_C 35039 +#define OP_YSTEP 32992 +#define OP_YSTEP_C 35040 +#define OP_MARK 32993 +#define OP_TMARK 32994 +#define OP_IN 32995 +#define OP_NIN 32996 +#define OP_MBEGIN 32997 +#define OP_FLIP 32998 +#define OP_COUNT 32999 +#define OP_CLEAR 33000 +#define OP_UNIQ 33001 +#define OP_ARRAY 33002 +#define OP_GETARRAY 33003 +#define OP_INITARRAY 33004 +#define OP_SETARRAY 33005 +#define OP_ARRAYCELL 33006 +#define OP_ARRAYSLICE 33007 +#define OP_COPYARRAY 33008 +#define OP_DOTPRODUCT 33009 +#define OP_PATTERN 33010 +#define OP_PATTERN_C 35058 +#define OP_PATTERN_E 37106 +#define OP_PATTERN_EC 39154 +#define OP_PATTERNS 33011 +#define OP_PATTERNS_C 35059 +#define OP_PATTERNS_E 37107 +#define OP_PATTERNS_EC 39155 +#define OP_ROOK 33012 +#define OP_BISHOP 33013 +#define OP_QUEEN 33014 +#define OP_CUT 33015 +#define OP_BIZARRO 33016 +#define OP_BIZARRO_C 35064 +#define OP_BIZARRO_E 37112 +#define OP_BIZARRO_EC 39160 +#define OP_BIZARROSWAP 33017 +#define OP_BIZARROSWAP_D 41209 +#define OP_SWAPWORLD 33018 +#define OP_ABSTRACT 33019 +#define OP_SUPER 33020 +#define OP_SUPER_C 35068 +#define OP_FUNCTION 33021 +#define OP_LOCAL 33022 +#define OP_LABEL 33023 +#define OP_STRING 33024 +#define OP_INT16 33025 +#define OP_INT32 33026 +#define OP_DISPATCH 33027 +#define OP_USERFLAG 33028 #ifdef HEROMESH_CLASS static const Op_Names op_names[]={ {"*",8486943}, {"+",8421405}, {"+Move",10584252}, @@ -498,19 +500,19 @@ {"-rot",8421382}, {".",10518528}, {"/",8486944}, {"ANHH",8389394}, {"ARRIVED",8389124}, -{"Abstract",8683770}, +{"Abstract",8683771}, {"Animate",8552596}, {"AnimateDead",8552597}, {"Arg1",8552576}, {"Arg2",8552577}, {"Arg3",8552578}, -{"Array",8683753}, -{"ArrayCell",8421613}, -{"ArraySlice",8421614}, +{"Array",8683754}, +{"ArrayCell",8421614}, +{"ArraySlice",8421615}, {"Arrivals",8618092}, {"Arrived",8618090}, {"Assassinate",8487062}, {"B",9437196}, {"BANG",8389380}, @@ -523,13 +525,13 @@ {"BRRREEET",8389396}, {"BRRRT",8389395}, {"BUZZER",8389420}, {"BWEEP",8389397}, {"Background",8683655}, -{"Bishop",8683764}, -{"Bizarro",8618231}, -{"BizarroSwap",10518776}, +{"Bishop",8683765}, +{"Bizarro",8618232}, +{"BizarroSwap",10518777}, {"Broadcast",10518679}, {"BroadcastAnd",8421528}, {"BroadcastAndEx",8421529}, {"BroadcastEx",10518683}, {"BroadcastList",8421532}, @@ -555,11 +557,11 @@ {"Coloc",8487074}, {"Compatible",8487035}, {"Connect",8487075}, {"Connection",8618104}, {"Control",8421514}, -{"CopyArray",8421615}, +{"CopyArray",8421616}, {"Create",10518692}, {"DEEP_POP",8389417}, {"DEPARTED",8389125}, {"DESTROY",8389122}, {"DESTROYED",8389136}, @@ -577,11 +579,11 @@ {"Destroy",10584232}, {"Destroyed",8487033}, {"Dir",8618054}, {"Distance",9142346}, {"Done",8618103}, -{"DotProduct",8421616}, +{"DotProduct",8421617}, {"E",9437184}, {"END_TURN",8389139}, {"EditorHelp",8683665}, {"F",9437192}, {"FAROUT",8389421}, @@ -594,11 +596,11 @@ {"FlushClass",8421547}, {"FlushObj",8487084}, {"From",8421503}, {"GLASS",8389379}, {"GLISSANT",8389419}, -{"GetArray",8421610}, +{"GetArray",8421611}, {"GetInventory",8421549}, {"HAWK",8389425}, {"HEARTBEAT",8389407}, {"HIT",8389134}, {"HITBY",8389135}, @@ -610,11 +612,11 @@ {"INIT",8389120}, {"IgnoreKey",8421552}, {"Image",8618055}, {"InPlace",8683662}, {"Inertia",9142344}, -{"InitArray",8421611}, +{"InitArray",8421612}, {"Input",8683660}, {"IntMove",10584241}, {"Invisible",8618095}, {"JAYAYAYNG",8389416}, {"JUMPED",8389128}, @@ -674,28 +676,28 @@ {"ObjLayerAt",8421574}, {"ObjMovingTo",8421575}, {"ObjTopAt",8421576}, {"Order",8683657}, {"Others",8683666}, -{"P",8880369}, -{"P*",8880370}, +{"P",8880370}, +{"P*",8880371}, {"PLAYERMOVING",8389133}, {"POSTINIT",8389138}, {"POUR",8389377}, {"POWER",8389386}, {"Player",8487034}, {"PopUp",8421577}, -{"Queen",8683765}, +{"Queen",8683766}, {"Quiz",8683661}, {"R",9437198}, {"RATCHET1",8389418}, {"RATCHET2",8389412}, {"RATTLE",8389403}, {"RB",9437197}, {"RF",9437199}, {"Rel",8487115}, -{"Rook",8683763}, +{"Rook",8683764}, {"S",9437190}, {"SE",9437191}, {"SMALL_POP",8389389}, {"SPLASH",8389376}, {"STEAM",8389424}, @@ -705,21 +707,21 @@ {"SW",9437189}, {"Seek",8487116}, {"Self",8421501}, {"Send",10584269}, {"SendEx",10584270}, -{"SetArray",8421612}, +{"SetArray",8421613}, {"SetInventory",8421583}, {"Shape",8618051}, {"ShapeDir",8618074}, {"Sharp",8618073}, {"Shovable",8618075}, {"Sound",8421584}, {"Stealthy",8618100}, {"Strength",9142358}, -{"Super",8487163}, -{"SwapWorld",8421625}, +{"Super",8487164}, +{"SwapWorld",8421626}, {"Sweep",8421585}, {"SweepEx",8421586}, {"Synchronize",8421587}, {"TAHTASHH",8389409}, {"THMP_thmp",8389405}, @@ -741,21 +743,22 @@ {"Volume",9142350}, {"VolumeAt",8421593}, {"W",9437188}, {"WAHOO",8389400}, {"WHACK",8389423}, +{"Walkable",8487130}, {"Weight",9142352}, -{"WinLevel",8487130}, -{"XDir",8487131}, -{"XStep",8487132}, -{"XYDir",8421597}, +{"WinLevel",8487131}, +{"XDir",8487132}, +{"XStep",8487133}, +{"XYDir",8421598}, {"Xloc",8486980}, -{"YDir",8487134}, +{"YDir",8487135}, {"YEEHAW",8389401}, -{"YStep",8487135}, +{"YStep",8487136}, {"Yloc",8486981}, -{"_",8421600}, +{"_",8421601}, {"a?",8421439}, {"again",8683533}, {"and",8683544}, {"band",8421415}, {"begin",8683532}, @@ -796,26 +799,26 @@ {"bor",8421416}, {"bxor",8421417}, {"c?",8421433}, {"case",8683542}, {"chain",8421536}, -{"clear",8421607}, -{"count",8421606}, -{"cut",8683766}, +{"clear",8421608}, +{"count",8421607}, +{"cut",8683767}, {"cz?",8421434}, {"dup",8421377}, {"else",8683530}, {"eq",8421424}, {"eq2",8421425}, {"exec",8486940}, -{"flip",8421605}, +{"flip",8421606}, {"for",8683537}, {"fork",8683545}, {"ge",8486965}, {"gt",8486963}, {"if",8683529}, -{"in",8421602}, +{"in",8421603}, {"is",8421431}, {"land",8421420}, {"le",8486966}, {"link",8683547}, {"lnot",8421423}, @@ -823,18 +826,18 @@ {"lsh",8421413}, {"lt",8486964}, {"lxor",8421422}, {"m?",8421435}, {"max",8486948}, -{"mbegin",8683748}, +{"mbegin",8683749}, {"min",8486947}, {"mod",8486945}, {"n?",8421432}, {"ne",8421426}, {"neg",8421410}, {"next",8683538}, -{"nin",8421603}, +{"nin",8421604}, {"nip",8421379}, {"o?",8421437}, {"or",8683543}, {"over",8421384}, {"oz?",8421438}, @@ -845,13 +848,13 @@ {"rsh",8486950}, {"rtn",8683546}, {"s?",8421436}, {"swap",8421378}, {"then",8683531}, -{"tmark",8421601}, +{"tmark",8421602}, {"tuck",8421380}, -{"uniq",8421608}, +{"uniq",8421609}, {"until",8683534}, {"while",8683535}, }; -#define N_OP_NAMES 362 +#define N_OP_NAMES 363 #endif