Free Hero Mesh

Diff
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.

Differences From Artifact [484f44c508]:

To Artifact [d3751950c5]:


55
56
57
58
59
60
61

62
63
64
65
66
67
68
static Uint8 lastimage_processing,changed,all_flushed;
static Value vstack[VSTACKSIZE];
static int vstackptr;
static const char*traceprefix;
static Uint8 current_key;
static Value quiz_obj;
static Value traced_obj;


#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







>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
static Uint8 lastimage_processing,changed,all_flushed;
static Value vstack[VSTACKSIZE];
static int vstackptr;
static const char*traceprefix;
static Uint8 current_key;
static Value quiz_obj;
static Value traced_obj;
static Uint32 control_obj=VOIDLINK;

#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
531
532
533
534
535
536
537




538
539
540
541
542
543
544
  if(!((o->oflags|p->oflags)&(OF_VISUALONLY|OF_DESTROYED))) send_message(y,x,MSG_SUNK,NVALUE(0),NVALUE(0),v);
}

static void change_density(Uint32 n,Sint32 v) {
  Object*o=objects[n];
  Uint32 i;
  if(o->oflags&OF_BIZARRO) return;




  if(v<o->density) {
    o->density=v;
    for(;;) {
      i=o->up;
      if(i==VOIDLINK || objects[i]->density<=v) return;
      sink(i,n);
    }







>
>
>
>







532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
  if(!((o->oflags|p->oflags)&(OF_VISUALONLY|OF_DESTROYED))) send_message(y,x,MSG_SUNK,NVALUE(0),NVALUE(0),v);
}

static void change_density(Uint32 n,Sint32 v) {
  Object*o=objects[n];
  Uint32 i;
  if(o->oflags&OF_BIZARRO) return;
  if(n==control_obj) {
    o->density=v;
    return;
  }
  if(v<o->density) {
    o->density=v;
    for(;;) {
      i=o->up;
      if(i==VOIDLINK || objects[i]->density<=v) return;
      sink(i,n);
    }
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
static Uint32 create(Uint32 from,Uint16 c,Uint32 x,Uint32 y,Uint32 im,Uint32 d) {
  Uint32 m,n;
  int i,xx,yy;
  Object*o;
  Object*p;
  Value v;
  if(d>7) d=0;
  if(x<1 || y<1 || x>pfwidth || y>pfheight) return VOIDLINK;
  if(!(classes[c]->oflags&OF_BIZARRO) && (i=classes[c]->collisionLayers) && (xx=collisions_at(x,y)&i)) {
    if(collide_with(xx,VOIDLINK,x,y,c)&0x01) return VOIDLINK;
  }
  n=objalloc(c);
  if(n==VOIDLINK) Throw("Error creating object");
  o=objects[n];
  o->x=x;







|







798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
static Uint32 create(Uint32 from,Uint16 c,Uint32 x,Uint32 y,Uint32 im,Uint32 d) {
  Uint32 m,n;
  int i,xx,yy;
  Object*o;
  Object*p;
  Value v;
  if(d>7) d=0;
  if(x<1 || y<1 || x>pfwidth || y>pfheight || c==control_class) return VOIDLINK;
  if(!(classes[c]->oflags&OF_BIZARRO) && (i=classes[c]->collisionLayers) && (xx=collisions_at(x,y)&i)) {
    if(collide_with(xx,VOIDLINK,x,y,c)&0x01) return VOIDLINK;
  }
  n=objalloc(c);
  if(n==VOIDLINK) Throw("Error creating object");
  o=objects[n];
  o->x=x;
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
}

static Value destroy(Uint32 from,Uint32 to,Uint32 why) {
  Object*o;
  Value v;
  int i,x,y,xx,yy;
  Uint32 n;
  if(to==VOIDLINK) return NVALUE(0);
  o=objects[to];
  // EKS Hero Mesh doesn't check if it already destroyed.
  v=why==8?NVALUE(0):send_message(from,to,MSG_DESTROY,NVALUE(0),NVALUE(0),NVALUE(why));
  if(!v_bool(v)) {
    if(!(o->oflags&OF_DESTROYED)) {
      if(firstobj==to) firstobj=o->next;
      if(lastobj==to) lastobj=o->prev;







|







843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
}

static Value destroy(Uint32 from,Uint32 to,Uint32 why) {
  Object*o;
  Value v;
  int i,x,y,xx,yy;
  Uint32 n;
  if(to==VOIDLINK || to==control_obj) return NVALUE(0);
  o=objects[to];
  // EKS Hero Mesh doesn't check if it already destroyed.
  v=why==8?NVALUE(0):send_message(from,to,MSG_DESTROY,NVALUE(0),NVALUE(0),NVALUE(why));
  if(!v_bool(v)) {
    if(!(o->oflags&OF_DESTROYED)) {
      if(firstobj==to) firstobj=o->next;
      if(lastobj==to) lastobj=o->prev;
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889

static int move_to(Uint32 from,Uint32 n,Uint32 x,Uint32 y) {
  Uint32 m;
  int i,xx,yy;
  Object*o;
  Object*p;
  Value v;
  if(n==VOIDLINK || (objects[n]->oflags&OF_DESTROYED)) return 0;
  o=objects[n];
  if(lastimage_processing) Throw("Can't move during animation processing");
  if(x<1 || y<1 || x>pfwidth || y>pfheight) return 0;
  if(v_bool(send_message(from,n,MSG_MOVING,NVALUE(x),NVALUE(y),NVALUE(0)))) return 0;
  if(classes[o->class]->cflags&CF_PLAYER) {
    m=lastobj;
    while(m!=VOIDLINK) {







|







880
881
882
883
884
885
886
887
888
889
890
891
892
893
894

static int move_to(Uint32 from,Uint32 n,Uint32 x,Uint32 y) {
  Uint32 m;
  int i,xx,yy;
  Object*o;
  Object*p;
  Value v;
  if(n==VOIDLINK || (objects[n]->oflags&OF_DESTROYED) || n==control_obj) return 0;
  o=objects[n];
  if(lastimage_processing) Throw("Can't move during animation processing");
  if(x<1 || y<1 || x>pfwidth || y>pfheight) return 0;
  if(v_bool(send_message(from,n,MSG_MOVING,NVALUE(x),NVALUE(y),NVALUE(0)))) return 0;
  if(classes[o->class]->cflags&CF_PLAYER) {
    m=lastobj;
    while(m!=VOIDLINK) {
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210

static int defer_move(Uint32 obj,Uint32 dir,Uint8 plus) {
  Object*o;
  Object*q;
  Uint32 n;
  Value v;
  if(StackProtection()) Throw("Call stack overflow during movement");
  if(obj==VOIDLINK) return 0;
  o=objects[obj];
  if(o->oflags&(OF_DESTROYED|OF_BIZARRO)) return 0;
  dir=resolve_dir(obj,dir);
  if(plus) {
    if(o->oflags&OF_MOVING) {
      if(o->dir==dir) return 1;
      v=send_message(VOIDLINK,obj,MSG_CONFLICT,NVALUE(dir),NVALUE(0),NVALUE(0));







|







1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215

static int defer_move(Uint32 obj,Uint32 dir,Uint8 plus) {
  Object*o;
  Object*q;
  Uint32 n;
  Value v;
  if(StackProtection()) Throw("Call stack overflow during movement");
  if(obj==VOIDLINK || obj==control_obj) return 0;
  o=objects[obj];
  if(o->oflags&(OF_DESTROYED|OF_BIZARRO)) return 0;
  dir=resolve_dir(obj,dir);
  if(plus) {
    if(o->oflags&OF_MOVING) {
      if(o->dir==dir) return 1;
      v=send_message(VOIDLINK,obj,MSG_CONFLICT,NVALUE(dir),NVALUE(0),NVALUE(0));
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
  if(current_key) all_flushed=255;
  flush_class(0);
}

static void set_bizarro(Uint32 n,Uint32 v) {
  Object*o;
  Uint8 b;
  if(n==VOIDLINK) return;
  o=objects[n];
  if(o->oflags&OF_DESTROYED) return;
  if(v) {
    if(o->oflags&OF_BIZARRO) return;
    pfunlink(n);
    o->oflags|=OF_BIZARRO;
    pflink(n);







|







1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
  if(current_key) all_flushed=255;
  flush_class(0);
}

static void set_bizarro(Uint32 n,Uint32 v) {
  Object*o;
  Uint8 b;
  if(n==VOIDLINK || n==control_obj) return;
  o=objects[n];
  if(o->oflags&OF_DESTROYED) return;
  if(v) {
    if(o->oflags&OF_BIZARRO) return;
    pfunlink(n);
    o->oflags|=OF_BIZARRO;
    pflink(n);
1860
1861
1862
1863
1864
1865
1866

1867
1868
1869
1870
1871
1872
1873
  Uint8 d=objects[obj]->dir;
  Uint32 n=VOIDLINK;
  Uint32 m;
  Uint16 g;
  Value v;
  static ChoicePoint cp[MAXCHOICE];
  Uint8 cpi=0;

  cp->depth=vstackptr;
  again: switch(code[ptr++]) {
    case 0 ... 7:
      n=VOIDLINK;
      x+=x_delta[code[ptr-1]];
      y+=y_delta[code[ptr-1]];
      if(x<1 || x>pfwidth || y<1 || y>pfheight) goto fail;







>







1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
  Uint8 d=objects[obj]->dir;
  Uint32 n=VOIDLINK;
  Uint32 m;
  Uint16 g;
  Value v;
  static ChoicePoint cp[MAXCHOICE];
  Uint8 cpi=0;
  if(!x) return VOIDLINK;
  cp->depth=vstackptr;
  again: switch(code[ptr++]) {
    case 0 ... 7:
      n=VOIDLINK;
      x+=x_delta[code[ptr-1]];
      y+=y_delta[code[ptr-1]];
      if(x<1 || x>pfwidth || y<1 || y>pfheight) goto fail;
1909
1910
1911
1912
1913
1914
1915

1916
1917
1918
1919
1920
1921
1922
          if(v.u==1) goto fail;
          else if(v.u==2) break;
          else if(v.u) Throw("Invalid return value from message in pattern matching");
        } else if(v.t>TY_MAXTYPE) {
          n=v_object(v);
          x=objects[n]->x;
          y=objects[n]->y;

        } else {
          Throw("Type mismatch");
        }
        m=objects[m]->up;
      }
      break;
    case OP_ADD:







>







1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
          if(v.u==1) goto fail;
          else if(v.u==2) break;
          else if(v.u) Throw("Invalid return value from message in pattern matching");
        } else if(v.t>TY_MAXTYPE) {
          n=v_object(v);
          x=objects[n]->x;
          y=objects[n]->y;
          if(!x) return VOIDLINK;
        } else {
          Throw("Type mismatch");
        }
        m=objects[m]->up;
      }
      break;
    case OP_ADD:
1993
1994
1995
1996
1997
1998
1999

2000
2001
2002
2003
2004
2005
2006
        d=v.u&7;
      } else if(v.t==TY_MARK) {
        goto fail;
      } else if(v.t>TY_MAXTYPE) {
        n=v_object(v);
        x=objects[n]->x;
        y=objects[n]->y;

      } else {
        Throw("Type mismatch");
      }
      break;
    case OP_HEIGHT:
      if(playfield[x+y*64-65]==VOIDLINK || height_at(x,y)<=objects[obj]->climb) goto fail;
      break;







>







2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
        d=v.u&7;
      } else if(v.t==TY_MARK) {
        goto fail;
      } else if(v.t>TY_MAXTYPE) {
        n=v_object(v);
        x=objects[n]->x;
        y=objects[n]->y;
        if(!x) return VOIDLINK;
      } else {
        Throw("Type mismatch");
      }
      break;
    case OP_HEIGHT:
      if(playfield[x+y*64-65]==VOIDLINK || height_at(x,y)<=objects[obj]->climb) goto fail;
      break;
2468
2469
2470
2471
2472
2473
2474

2475
2476
2477
2478
2479
2480
2481
    case OP_CLIMB_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->climb=t1.u&0xFFFF; break;
    case OP_COLLISIONLAYERS: StackReq(0,1); Push(NVALUE(classes[o->class]->collisionLayers)); break;
    case OP_COLLISIONLAYERS_C: StackReq(1,1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else Push(NVALUE(classes[objects[i]->class]->collisionLayers)); break;
    case OP_COLOC: StackReq(1,1); t1=Pop(); i=colocation(obj,v_object(t1)); Push(NVALUE(i)); break;
    case OP_COLOC_C: StackReq(2,1); t1=Pop(); t2=Pop(); i=colocation(v_object(t1),v_object(t2)); Push(NVALUE(i)); break;
    case OP_COMPATIBLE: StackReq(0,1); if(classes[o->class]->cflags&CF_COMPATIBLE) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_COMPATIBLE_C: StackReq(1,1); GetClassFlagOf(CF_COMPATIBLE); break;

    case OP_COPYARRAY: NoIgnore(); StackReq(2,0); t2=Pop(); t1=Pop(); v_copy_array(t1,t2); break;
    case OP_COUNT: StackReq(1,2); i=v_count(); Push(NVALUE(i)); break;
    case OP_CREATE: NoIgnore(); StackReq(5,1); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_create(obj,t1,t2,t3,t4,t5)); break;
    case OP_CREATE_D: NoIgnore(); StackReq(5,0); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); v_create(obj,t1,t2,t3,t4,t5); break;
    case OP_DATA: StackReq(2,1); t2=Pop(); t1=Pop(); v_data(t1,t2); break;
    case OP_DELINVENTORY: StackReq(2,0); t2=Pop(); t1=Pop(); v_delete_inventory(t1,t2); break;
    case OP_DELTA: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u>t2.u?t1.u-t2.u:t2.u-t1.u)); break;







>







2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
    case OP_CLIMB_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->climb=t1.u&0xFFFF; break;
    case OP_COLLISIONLAYERS: StackReq(0,1); Push(NVALUE(classes[o->class]->collisionLayers)); break;
    case OP_COLLISIONLAYERS_C: StackReq(1,1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else Push(NVALUE(classes[objects[i]->class]->collisionLayers)); break;
    case OP_COLOC: StackReq(1,1); t1=Pop(); i=colocation(obj,v_object(t1)); Push(NVALUE(i)); break;
    case OP_COLOC_C: StackReq(2,1); t1=Pop(); t2=Pop(); i=colocation(v_object(t1),v_object(t2)); Push(NVALUE(i)); break;
    case OP_COMPATIBLE: StackReq(0,1); if(classes[o->class]->cflags&CF_COMPATIBLE) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_COMPATIBLE_C: StackReq(1,1); GetClassFlagOf(CF_COMPATIBLE); break;
    case OP_CONTROL: StackReq(0,1); Push(OVALUE(control_obj)); break;
    case OP_COPYARRAY: NoIgnore(); StackReq(2,0); t2=Pop(); t1=Pop(); v_copy_array(t1,t2); break;
    case OP_COUNT: StackReq(1,2); i=v_count(); Push(NVALUE(i)); break;
    case OP_CREATE: NoIgnore(); StackReq(5,1); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_create(obj,t1,t2,t3,t4,t5)); break;
    case OP_CREATE_D: NoIgnore(); StackReq(5,0); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); v_create(obj,t1,t2,t3,t4,t5); break;
    case OP_DATA: StackReq(2,1); t2=Pop(); t1=Pop(); v_data(t1,t2); break;
    case OP_DELINVENTORY: StackReq(2,0); t2=Pop(); t1=Pop(); v_delete_inventory(t1,t2); break;
    case OP_DELTA: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u>t2.u?t1.u-t2.u:t2.u-t1.u)); break;
2913
2914
2915
2916
2917
2918
2919

2920
2921
2922
2923
2924
2925
2926
  gameover=0;
  clear_inventory();
  for(i=0;i<nlevelstrings;i++) free(levelstrings[i]);
  nlevelstrings=0;
  free(deadanim);
  deadanim=0;
  ndeadanim=0;

}

static inline int try_sharp(Uint32 n1,Uint32 n2) {
  Object*o=objects[n1];
  Object*p=objects[n2];
  if((o->oflags|p->oflags)&OF_DESTROYED) return 0;
  if(o->dir&1) return 0;







>







2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
  gameover=0;
  clear_inventory();
  for(i=0;i<nlevelstrings;i++) free(levelstrings[i]);
  nlevelstrings=0;
  free(deadanim);
  deadanim=0;
  ndeadanim=0;
  control_obj=VOIDLINK;
}

static inline int try_sharp(Uint32 n1,Uint32 n2) {
  Object*o=objects[n1];
  Object*p=objects[n2];
  if((o->oflags|p->oflags)&OF_DESTROYED) return 0;
  if(o->dir&1) return 0;
3301
3302
3303
3304
3305
3306
3307




3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
  changed=0;
  key_ignored=0;
  all_flushed=0;
  lastimage_processing=0;
  vstackptr=0;
  move_number=0;
  current_key=0;




  n=lastobj;
  while(n!=VOIDLINK && !(objects[n]->oflags&OF_ORDERED)) {
    send_message(VOIDLINK,n,MSG_INIT,NVALUE(0),NVALUE(0),NVALUE(0));
    if(classes[objects[n]->class]->order && !(objects[n]->oflags&OF_DESTROYED)) set_order(n);
    n=objects[n]->prev;
  }
  broadcast(VOIDLINK,0,MSG_POSTINIT,NVALUE(0),NVALUE(0),NVALUE(0),0);
  if(gameover) return 0;
  return execute_turn(0);
}







>
>
>
>










3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
  changed=0;
  key_ignored=0;
  all_flushed=0;
  lastimage_processing=0;
  vstackptr=0;
  move_number=0;
  current_key=0;
  if(control_class) {
    control_obj=objalloc(control_class);
    if(control_obj==VOIDLINK) Throw("Error creating object");
  }
  n=lastobj;
  while(n!=VOIDLINK && !(objects[n]->oflags&OF_ORDERED)) {
    send_message(VOIDLINK,n,MSG_INIT,NVALUE(0),NVALUE(0),NVALUE(0));
    if(classes[objects[n]->class]->order && !(objects[n]->oflags&OF_DESTROYED)) set_order(n);
    n=objects[n]->prev;
  }
  broadcast(VOIDLINK,0,MSG_POSTINIT,NVALUE(0),NVALUE(0),NVALUE(0),0);
  if(gameover) return 0;
  return execute_turn(0);
}