Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -346,11 +346,11 @@ case OP_BROADCASTSUMEX: StackReq(5,1); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_broadcast(obj,t1,t2,t3,t4,t5,1)); break; case OP_BXOR: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u^t2.u)); break; case OP_CALLSUB: execute_program(code,code[ptr++],obj); break; case OP_CLASS: StackReq(0,1); Push(CVALUE(o->class)); break; case OP_CLASS_C: StackReq(1,1); Push(GetVariableOf(class,CVALUE)); break; - case OP_DIR: StackReq(0,1); Push(NVALUE(o->dir&7)); break; + case OP_DIR: StackReq(0,1); Push(NVALUE(o->dir)); break; case OP_DISTANCE: StackReq(0,1); Push(NVALUE(o->distance)); break; case OP_DROP: StackReq(1,0); Pop(); break; case OP_DROP_D: StackReq(2,0); Pop(); Pop(); break; case OP_DUP: StackReq(1,2); t1=Pop(); Push(t1); Push(t1); break; case OP_EQ: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?1:0)); break; @@ -463,18 +463,18 @@ 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) t++; + 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) { + if((!c || o->class==c) && o->generation) { 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; Index: function.c ================================================================== --- function.c +++ function.c @@ -254,11 +254,11 @@ if(sqlite3_value_type(*argv)==SQLITE_NULL) { sqlite3_result_int(cxt,0); return; } a=sqlite3_value_int64(*argv)&0xFFFFFFFF; - if(a>=nobjects || !objects[a] || (objects[a]->dir&IOF_DEAD)) return; // result is null if object does not exist + if(a>=nobjects || !objects[a] || !objects[a]->generation) return; // result is null if object does not exist sqlite3_result_int64(cxt,a|((sqlite3_int64)objects[a]->generation<<32)); } static void fn_pfsize(sqlite3_context*cxt,int argc,sqlite3_value**argv) { sqlite3_result_int(cxt,*(Uint8*)sqlite3_user_data(cxt)); @@ -656,11 +656,11 @@ } } else { // This shouldn't happen return SQLITE_INTERNAL; } - if(!cur->eof && (objects[cur->rowid]->dir&IOF_DEAD)) goto again; + if(!cur->eof && !objects[cur->rowid]->generation) goto again; return SQLITE_OK; } static int vt1_objects_filter(sqlite3_vtab_cursor*pcur,int idxNum,const char*idxStr,int argc,sqlite3_value**argv) { Cursor*cur=(void*)pcur; Index: heromesh.h ================================================================== --- heromesh.h +++ heromesh.h @@ -166,26 +166,30 @@ // == exec == #define VOIDLINK ((Uint32)(-1)) -// The following "internal object flags" are part of the "dir" variable: -#define IOF_DEAD 0x10 // object doesn't exist, except to continue an animation -#define IOF_ANIM 0x20 // an animation is being displayed -// If the IOF_DEAD flag is set, then generation should also be set to zero, and OF_DESTROYED must be set, too. +typedef struct { + //TODO +} Animation; typedef struct { Sint32 height,weight,climb,density,volume,strength,arrivals,departures,temperature; Uint32 arrived,departed,arrived2,departed2,generation; Uint32 up,down,prev,next; // links to other objects Uint16 class,oflags,distance; Uint16 sharp[4]; Uint16 hard[4]; Uint8 x,y,shape,shovable,image,dir; + Animation*anim; Value misc1,misc2,misc3,misc4,misc5,misc6,misc7; Value uservars[0]; } Object; + +// Some objects may remain in memory for animation purposes even after they have been +// destroyed. In this case, their "generation" value is zero, and they will always +// have the OF_DESTROYED flag. extern Uint32 max_objects; extern Uint32 generation_number; extern Object**objects; extern Uint32 nobjects;