Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -1760,10 +1760,26 @@ Trace ( obj arg1 arg2 -- ) If tracing is enabled, sends the three values and some other information on stdout. If tracing is disabled, does nothing. This is intended to be used for debugging class codes. + +Trigger ( obj message -- ) ** + Call a message for a pending trigger for the specified object immediately + instead of waiting for its turn in the trigger phase. Only has an effect + if the object does not have the Compatible flag. The message must be + MOVED, DEPARTED, or ARRIVED; otherwise it is an error. If that trigger is + pending, it will clear the trigger and send it like it does during the + trigger phase, setting Arg1 as appropriate, but From is set to the object + calling it instead of 0, and Arg2 and Arg3 will be inherited from the + current values of those variables. The return value is ignored. Since the + trigger is cleared before it is sent, it is safe for objects to call the + triggers of objects in a loop. + +TriggerAt ( x ymessage -- ) ** + Works like Trigger on all objects at the specified location, from the + bottom to the top. tuck ( x y -- y x y ) uniq ( mark ... value -- mark ... value true | mark ... false ) Check if the top value matches any others in the list above the mark. If Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -2004,10 +2004,52 @@ } } else { Throw("Type mismatch"); } } + +static void v_trigger(Uint32 from,Uint32 to,Value v) { + Object*o; + Uint32 n; + if(v.t!=TY_MESSAGE) Throw("Type mismatch"); + o=objects[to]; + if(classes[o->class]->cflags&CF_COMPATIBLE) return; + switch(v.u) { + case MSG_MOVED: + if(o->oflags&OF_MOVED2) { + o->oflags&=~OF_MOVED2; + send_message(from,to,MSG_MOVED,NVALUE(0),msgvars.arg2,msgvars.arg3); + } + break; + case MSG_DEPARTED: + if(o->departed2) { + n=o->departed2; + o->departed2=0; + send_message(from,to,MSG_DEPARTED,NVALUE(n),msgvars.arg2,msgvars.arg3); + } + break; + case MSG_ARRIVED: + if(o->arrived2) { + n=o->arrived2; + o->arrived2=0; + send_message(from,to,MSG_ARRIVED,NVALUE(n),msgvars.arg2,msgvars.arg3); + } + break; + default: Throw("Invalid message for Trigger"); + } +} + +static void v_trigger_at(Uint32 from,Uint32 x,Uint32 y,Value v) { + Uint32 m,n; + if(x<1 || x>pfwidth || y<1 || y>pfheight) return; + n=playfield[x+y*64-65]; + while(n!=VOIDLINK) { + m=objects[n]->up; + v_trigger(from,n,v); + n=m; + } +} // 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))) @@ -2393,10 +2435,12 @@ case OP_TEMPERATURE_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->temperature=t1.u&0xFFFF; break; case OP_TEMPERATURE_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->temperature=t1.u; break; case OP_TEMPERATURE_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->temperature=t1.u&0xFFFF; break; case OP_TMARK: StackReq(1,2); t1=Pop(); if(t1.t==TY_MARK) { Push(NVALUE(0)); } else { Push(t1); Push(NVALUE(1)); } break; case OP_TRACE: StackReq(3,0); trace_stack(obj); break; + case OP_TRIGGER: NoIgnore(); StackReq(2,0); t1=Pop(); i=v_object(Pop()); if(i!=VOIDLINK) v_trigger(obj,i,t1); break; + case OP_TRIGGERAT: NoIgnore(); StackReq(3,0); t3=Pop(); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); v_trigger_at(obj,t1.u,t2.u,t3); break; case OP_TUCK: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t2); Push(t1); Push(t2); break; case OP_UNIQ: StackReq(2,3); t1=Pop(); i=v_uniq(t1); if(i) Push(t1); Push(NVALUE(i)); break; case OP_USERSIGNAL: StackReq(0,1); if(o->oflags&OF_USERSIGNAL) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_USERSIGNAL_C: StackReq(1,1); GetFlagOf(OF_USERSIGNAL); break; case OP_USERSIGNAL_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_USERSIGNAL; else o->oflags&=~OF_USERSIGNAL; break; Index: instruc ================================================================== --- instruc +++ instruc @@ -266,10 +266,12 @@ SetInventory Sound Synchronize ,Target Trace +Trigger +TriggerAt VolumeAt WinLevel ,XDir XYDir ,YDir Index: instruc.h ================================================================== --- instruc.h +++ instruc.h @@ -396,57 +396,59 @@ #define OP_SOUND 32963 #define OP_SYNCHRONIZE 32964 #define OP_TARGET 32965 #define OP_TARGET_C 35013 #define OP_TRACE 32966 -#define OP_VOLUMEAT 32967 -#define OP_WINLEVEL 32968 -#define OP_XDIR 32969 -#define OP_XDIR_C 35017 -#define OP_XYDIR 32970 -#define OP_YDIR 32971 -#define OP_YDIR_C 35019 -#define OP_MARK 32972 -#define OP_TMARK 32973 -#define OP_IN 32974 -#define OP_NIN 32975 -#define OP_MBEGIN 32976 -#define OP_FLIP 32977 -#define OP_COUNT 32978 -#define OP_CLEAR 32979 -#define OP_UNIQ 32980 -#define OP_ARRAY 32981 -#define OP_GETARRAY 32982 -#define OP_INITARRAY 32983 -#define OP_SETARRAY 32984 -#define OP_ARRAYCELL 32985 -#define OP_ARRAYSLICE 32986 -#define OP_COPYARRAY 32987 -#define OP_DOTPRODUCT 32988 -#define OP_PATTERN 32989 -#define OP_PATTERN_C 35037 -#define OP_PATTERN_E 37085 -#define OP_PATTERN_EC 39133 -#define OP_PATTERNS 32990 -#define OP_PATTERNS_C 35038 -#define OP_PATTERNS_E 37086 -#define OP_PATTERNS_EC 39134 -#define OP_ROOK 32991 -#define OP_BISHOP 32992 -#define OP_QUEEN 32993 -#define OP_CUT 32994 -#define OP_ABSTRACT 32995 -#define OP_SUPER 32996 -#define OP_SUPER_C 35044 -#define OP_FUNCTION 32997 -#define OP_LOCAL 32998 -#define OP_LABEL 32999 -#define OP_STRING 33000 -#define OP_INT16 33001 -#define OP_INT32 33002 -#define OP_DISPATCH 33003 -#define OP_USERFLAG 33004 +#define OP_TRIGGER 32967 +#define OP_TRIGGERAT 32968 +#define OP_VOLUMEAT 32969 +#define OP_WINLEVEL 32970 +#define OP_XDIR 32971 +#define OP_XDIR_C 35019 +#define OP_XYDIR 32972 +#define OP_YDIR 32973 +#define OP_YDIR_C 35021 +#define OP_MARK 32974 +#define OP_TMARK 32975 +#define OP_IN 32976 +#define OP_NIN 32977 +#define OP_MBEGIN 32978 +#define OP_FLIP 32979 +#define OP_COUNT 32980 +#define OP_CLEAR 32981 +#define OP_UNIQ 32982 +#define OP_ARRAY 32983 +#define OP_GETARRAY 32984 +#define OP_INITARRAY 32985 +#define OP_SETARRAY 32986 +#define OP_ARRAYCELL 32987 +#define OP_ARRAYSLICE 32988 +#define OP_COPYARRAY 32989 +#define OP_DOTPRODUCT 32990 +#define OP_PATTERN 32991 +#define OP_PATTERN_C 35039 +#define OP_PATTERN_E 37087 +#define OP_PATTERN_EC 39135 +#define OP_PATTERNS 32992 +#define OP_PATTERNS_C 35040 +#define OP_PATTERNS_E 37088 +#define OP_PATTERNS_EC 39136 +#define OP_ROOK 32993 +#define OP_BISHOP 32994 +#define OP_QUEEN 32995 +#define OP_CUT 32996 +#define OP_ABSTRACT 32997 +#define OP_SUPER 32998 +#define OP_SUPER_C 35046 +#define OP_FUNCTION 32999 +#define OP_LOCAL 33000 +#define OP_LABEL 33001 +#define OP_STRING 33002 +#define OP_INT16 33003 +#define OP_INT32 33004 +#define OP_DISPATCH 33005 +#define OP_USERFLAG 33006 #ifdef HEROMESH_CLASS static const Op_Names op_names[]={ {"*",8486939}, {"+",8421401}, {"+Move",10584239}, @@ -455,19 +457,19 @@ {"-rot",8421382}, {".",10518528}, {"/",8486940}, {"ANHH",8389394}, {"ARRIVED",8389124}, -{"Abstract",8683747}, +{"Abstract",8683749}, {"Animate",8421516}, {"AnimateDead",8421517}, {"Arg1",8552571}, {"Arg2",8552572}, {"Arg3",8552573}, -{"Array",8683733}, -{"ArrayCell",8421593}, -{"ArraySlice",8421594}, +{"Array",8683735}, +{"ArrayCell",8421595}, +{"ArraySlice",8421596}, {"Arrivals",8618088}, {"Arrived",8618086}, {"Assassinate",8487054}, {"B",9437196}, {"BANG",8389380}, @@ -480,11 +482,11 @@ {"BRRREEET",8389396}, {"BRRRT",8389395}, {"BUZZER",8389420}, {"BWEEP",8389397}, {"Background",8683650}, -{"Bishop",8683744}, +{"Bishop",8683746}, {"Broadcast",10518671}, {"BroadcastAnd",8421520}, {"BroadcastAndEx",8421521}, {"BroadcastEx",10518675}, {"BroadcastList",8421524}, @@ -506,11 +508,11 @@ {"Climb",9142352}, {"CodePage",8683651}, {"CollisionLayers",8487031}, {"Coloc",8487066}, {"Compatible",8487030}, -{"CopyArray",8421595}, +{"CopyArray",8421597}, {"Create",10518683}, {"DEEP_POP",8389417}, {"DEPARTED",8389125}, {"DESTROY",8389122}, {"DESTROYED",8389136}, @@ -528,11 +530,11 @@ {"Destroy",10584223}, {"Destroyed",8487028}, {"Dir",8618050}, {"Distance",9142342}, {"Done",8618099}, -{"DotProduct",8421596}, +{"DotProduct",8421598}, {"E",9437184}, {"END_TURN",8389139}, {"EditorHelp",8683657}, {"F",9437192}, {"FAROUT",8389421}, @@ -543,11 +545,11 @@ {"FlushClass",8421536}, {"FlushObj",8487073}, {"From",8421498}, {"GLASS",8389379}, {"GLISSANT",8389419}, -{"GetArray",8421590}, +{"GetArray",8421592}, {"GetInventory",8421538}, {"HAWK",8389425}, {"HEARTBEAT",8389407}, {"HIT",8389134}, {"HITBY",8389135}, @@ -558,11 +560,11 @@ {"INIT",8389120}, {"IgnoreKey",8421540}, {"Image",8618051}, {"InPlace",8683654}, {"Inertia",9142340}, -{"InitArray",8421591}, +{"InitArray",8421593}, {"Input",8683652}, {"IntMove",10584229}, {"Invisible",8618091}, {"JAYAYAYNG",8389416}, {"JUMPED",8389128}, @@ -618,28 +620,28 @@ {"ObjDir",8487096}, {"ObjLayerAt",8421561}, {"ObjMovingTo",8421562}, {"ObjTopAt",8421563}, {"Others",8683658}, -{"P",8880349}, -{"P*",8880350}, +{"P",8880351}, +{"P*",8880352}, {"PLAYERMOVING",8389133}, {"POSTINIT",8389138}, {"POUR",8389377}, {"POWER",8389386}, {"Player",8487029}, {"PopUp",8421564}, -{"Queen",8683745}, +{"Queen",8683747}, {"Quiz",8683653}, {"R",9437198}, {"RATCHET1",8389418}, {"RATCHET2",8389412}, {"RATTLE",8389403}, {"RB",9437197}, {"RF",9437199}, {"Rel",8487102}, -{"Rook",8683743}, +{"Rook",8683745}, {"S",9437190}, {"SE",9437191}, {"SMALL_POP",8389389}, {"SPLASH",8389376}, {"STEAM",8389424}, @@ -649,49 +651,51 @@ {"SW",9437189}, {"Seek",8487103}, {"Self",8421496}, {"Send",10584256}, {"SendEx",10584257}, -{"SetArray",8421592}, +{"SetArray",8421594}, {"SetInventory",8421570}, {"Shape",8618047}, {"ShapeDir",8618070}, {"Sharp",8618069}, {"Shovable",8618071}, {"Sound",8421571}, {"Stealthy",8618096}, {"Strength",9142354}, -{"Super",8487140}, +{"Super",8487142}, {"Synchronize",8421572}, {"TAHTASHH",8389409}, {"THMP_thmp",8389405}, {"THWIT",8389384}, {"TICK",8389391}, {"Target",8487109}, {"Temperature",9142333}, {"Trace",8421574}, +{"Trigger",8421575}, +{"TriggerAt",8421576}, {"UH_OH",8389382}, {"UNCORK",8389414}, {"UNHH",8389381}, {"UserSignal",8618093}, {"UserState",8618094}, {"VACUUM",8389411}, {"VisualOnly",8618095}, {"Volume",9142346}, -{"VolumeAt",8421575}, +{"VolumeAt",8421577}, {"W",9437188}, {"WAHOO",8389400}, {"WHACK",8389423}, {"Weight",9142348}, -{"WinLevel",8421576}, -{"XDir",8487113}, -{"XYDir",8421578}, +{"WinLevel",8421578}, +{"XDir",8487115}, +{"XYDir",8421580}, {"Xloc",8486976}, -{"YDir",8487115}, +{"YDir",8487117}, {"YEEHAW",8389401}, {"Yloc",8486977}, -{"_",8421580}, +{"_",8421582}, {"a?",8421435}, {"again",8683533}, {"and",8683544}, {"band",8421411}, {"begin",8683532}, @@ -732,24 +736,24 @@ {"bor",8421412}, {"bxor",8421413}, {"c?",8421429}, {"case",8683542}, {"chain",8421528}, -{"clear",8421587}, -{"count",8421586}, -{"cut",8683746}, +{"clear",8421589}, +{"count",8421588}, +{"cut",8683748}, {"cz?",8421430}, {"dup",8421377}, {"else",8683530}, {"eq",8421420}, {"eq2",8421421}, -{"flip",8421585}, +{"flip",8421587}, {"for",8683537}, {"ge",8486961}, {"gt",8486959}, {"if",8683529}, -{"in",8421582}, +{"in",8421584}, {"is",8421427}, {"land",8421416}, {"le",8486962}, {"lnot",8421419}, {"lor",8421417}, @@ -756,18 +760,18 @@ {"lsh",8421409}, {"lt",8486960}, {"lxor",8421418}, {"m?",8421431}, {"max",8486944}, -{"mbegin",8683728}, +{"mbegin",8683730}, {"min",8486943}, {"mod",8486941}, {"n?",8421428}, {"ne",8421422}, {"neg",8421406}, {"next",8683538}, -{"nin",8421583}, +{"nin",8421585}, {"nip",8421379}, {"o?",8421433}, {"or",8683543}, {"over",8421384}, {"oz?",8421434}, @@ -777,13 +781,13 @@ {"rot",8421381}, {"rsh",8486946}, {"s?",8421432}, {"swap",8421378}, {"then",8683531}, -{"tmark",8421581}, +{"tmark",8421583}, {"tuck",8421380}, -{"uniq",8421588}, +{"uniq",8421590}, {"until",8683534}, {"while",8683535}, }; -#define N_OP_NAMES 337 +#define N_OP_NAMES 339 #endif