Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -49,19 +49,23 @@ #define Throw(x) (my_error=(x),longjmp(my_env,1)) #define StackReq(x,y) do{ if(vstackptr<(x)) Throw("Stack underflow"); if(vstackptr-(x)+(y)>=VSTACKSIZE) Throw("Stack overflow"); }while(0) #define Push(x) (vstack[vstackptr++]=(x)) #define Pop() (vstack[--vstackptr]) + +// For arrival/departure masks +#define Xbit(a) ((a)%5-2) +#define Ybit(a) (2-(a)/5) static Value send_message(Uint32 from,Uint32 to,Uint16 msg,Value arg1,Value arg2,Value arg3); static Uint32 broadcast(Uint32 from,int c,Uint16 msg,Value arg1,Value arg2,Value arg3,int s); const char*value_string_ptr(Value v) { switch(v.t) { case TY_STRING: return stringpool[v.u]; //TODO: Level strings - default: fatal("Trying to get string pointer for a non-string\n"); + default: fatal("Internal confusion: Trying to get string pointer for a non-string\n"); } } void pfunlink(Uint32 n) { Object*o=objects[n]; @@ -150,12 +154,12 @@ else objects[o->down]->up=o->up; if(o->up!=VOIDLINK) objects[o->up]->down=o->down; o->down=o->up=VOIDLINK; if(firstobj==n) firstobj=o->next; if(lastobj==n) lastobj=o->prev; - if(o->prev) objects[o->prev]->next=o->next; - if(o->next) objects[o->next]->prev=o->prev; + if(o->prev!=VOIDLINK) objects[o->prev]->next=o->next; + if(o->next!=VOIDLINK) objects[o->next]->prev=o->prev; free(o); objects[n]=0; generation_number_inc=1; } @@ -233,10 +237,43 @@ static inline int v_unsigned_greater(Value x,Value y) { if(x.t!=TY_NUMBER || y.t!=TY_NUMBER) Throw("Type mismatch"); return x.u>y.u; } + +static Value destroy(Uint32 from,Uint32 to,Uint32 why) { + Object*o; + Value v; + int i,x,y,xx,yy; + Uint32 n; + if(n==VOIDLINK) return NVALUE(0); + o=objects[to]; + // Not checking if it is already destroyed, since EKS Hero Mesh doesn't check. + v=send_message(from,to,MSG_DESTROY,NVALUE(0),NVALUE(0),NVALUE(why)); + if(!v_bool(v)) { + o->oflags|=OF_DESTROYED; + if(firstobj==to) firstobj=o->next; + if(lastobj==to) lastobj=o->prev; + if(o->prev!=VOIDLINK) objects[o->prev]->next=o->next; + if(o->next!=VOIDLINK) objects[o->next]->prev=o->prev; + if(!(o->oflags&OF_VISUALONLY)) { + // Not checking for stealth; that only applies to movement, not destruction + xx=o->x; yy=o->y; + for(i=25;i>=0;i--) { + x=xx+Xbit(i); y=yy+Ybit(i); + if(x<1 || x>pfwidth || y<1 || y>pfheight) continue; + n=playfield[x+y*64-65]; + while(n!=VOIDLINK) { + o=objects[n]; + if(o->departures&(1<up; + } + } + } + } + return v; +} static void trace_stack(Uint32 obj) { Value t2=Pop(); Value t1=Pop(); Value t0=Pop(); @@ -432,10 +469,11 @@ MessageVars saved=msgvars; Uint16 c=objects[to]->class; Uint16 p=get_message_ptr(c,msg); Uint16*code; int stackptr=vstackptr; + if(objects[to]->oflags&OF_DESTROYED) return NVALUE(0); if(p==0xFFFF) { p=get_message_ptr(0,msg); if(p==0xFFFF) return NVALUE(0); code=classes[0]->codes; } else { @@ -461,20 +499,15 @@ static Uint32 broadcast(Uint32 from,int c,Uint16 msg,Value arg1,Value arg2,Value arg3,int s) { Uint32 t=0; Uint32 n,p; Object*o; Value v; - if(c && !classes[c]->nmsg && (!classes[0] || !classes[0]->nmsg)) { - if(s) return 0; - for(n=0;nclass==c && o->generation) t++; - return t; - } if(lastobj==VOIDLINK) return; n=lastobj; while(o=objects[n]) { p=o->prev; - if((!c || o->class==c) && o->generation) { + if(!c || o->class==c) { v=send_message(from,n,msg,arg1,arg2,arg3); if(s>0) { switch(v.t) { case TY_NUMBER: t+=v.u; break; case TY_CLASS: t++; break;