Free Hero Mesh

Check-in [b8f6f2d21d]
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.
Overview
Comment:Correct some mistakes in the implementation and documentation of deferred movement.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b8f6f2d21d497f23ef91f8539783486613b6341c
User & Date: user on 2022-02-04 07:33:05
Other Links: manifest | tags
Context
2022-02-05
22:54
Fix a compiler warning relating to return without a value even though the function should have a return value. check-in: e7826dace2 user: user tags: trunk
2022-02-04
07:33
Correct some mistakes in the implementation and documentation of deferred movement. check-in: b8f6f2d21d user: user tags: trunk
06:56
Correct parsing instruction names beginning with a plus and minus sign. check-in: 547bf4ed86 user: user tags: trunk
Changes

Modified class.doc from [28dfcc240c] to [e1990b5929].

2112
2113
2114
2115
2116
2117
2118
2119



2120
2121
2122
2123
2124
2125
2126
  that it is colliding with, Arg1 and Arg2 are its location, and Arg3
  is the type of collision (0 if this object is trying to move into a
  stationary object, 1 if another object is trying to move into this
  stationary object, 2 if two objects are trying to move into the same
  space, or 3 if two or more objects forming a loop are trying to move
  into each other). There is no guarantee that this will only be called
  once; sometimes it will be called multiple times for a single collision
  or for multiple collisions with the same objects. (TODO)




CONFLICT
  Called during scheduling of a deferred move if it is already currently
  scheduled to move but in a different direction. Arg1 is the direction
  that it is trying to schedule the move in. If the return value is false
  then the schedule fails; if true, then it succeeds.








|
>
>
>







2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
  that it is colliding with, Arg1 and Arg2 are its location, and Arg3
  is the type of collision (0 if this object is trying to move into a
  stationary object, 1 if another object is trying to move into this
  stationary object, 2 if two objects are trying to move into the same
  space, or 3 if two or more objects forming a loop are trying to move
  into each other). There is no guarantee that this will only be called
  once; sometimes it will be called multiple times for a single collision
  or for multiple collisions with the same objects. The return value has
  bit0 to allow the move, bit1 to handle sharpness, and bit2 to retry if
  the move fails. The bit16 and higher bits will have the similar effect
  for the other object instead.

CONFLICT
  Called during scheduling of a deferred move if it is already currently
  scheduled to move but in a different direction. Arg1 is the direction
  that it is trying to schedule the move in. If the return value is false
  then the schedule fails; if true, then it succeeds.

Modified exec.c from [a961423181] to [bd3e85a5da].

1199
1200
1201
1202
1203
1204
1205

1206
1207
1208
1209
1210
1211


1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
  return 1;
}

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));
      if(!v_bool(v)) return 0;
    }
    o->oflags|=OF_MOVING;
    o->dir=dir;
  } else {
    if(!(o->oflags&OF_MOVING)) return 0;
    if(o->dir!=dir) return 0;
    o->oflags&=~OF_MOVING;
  }
  n=playfield[o->x+o->y*64-65];
  while(n!=VOIDLINK) {
    q=objects[n];
    if(!(q->oflags&(OF_DESTROYED|OF_VISUALONLY)) && ((q->height>0 && q->height>=o->climb) || (classes[q->class]->collisionLayers&classes[o->class]->collisionLayers))) {
      v=send_message(obj,n,MSG_BLOCKED,NVALUE(o->x),NVALUE(o->y),NVALUE(plus));
      if(v.t) Throw("Type mismatch");
      if(v.u&1) o->oflags&=~OF_MOVING;
      if(v.u&2) break;
    }
    n=q->up;
  }







>






>
>













|


|







1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
  return 1;
}

static int defer_move(Uint32 obj,Uint32 dir,Uint8 plus) {
  Object*o;
  Object*q;
  Uint32 n;
  Uint8 x,y;
  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);
  x=o->x+x_delta[dir]; y=o->y+y_delta[dir];
  if(x<1 || x>pfwidth || y<1 || y>pfheight) return 0;
  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));
      if(!v_bool(v)) return 0;
    }
    o->oflags|=OF_MOVING;
    o->dir=dir;
  } else {
    if(!(o->oflags&OF_MOVING)) return 0;
    if(o->dir!=dir) return 0;
    o->oflags&=~OF_MOVING;
  }
  n=playfield[x+y*64-65];
  while(n!=VOIDLINK) {
    q=objects[n];
    if(!(q->oflags&(OF_DESTROYED|OF_VISUALONLY|OF_MOVING)) && ((q->height>0 && q->height>=o->climb) || (classes[q->class]->collisionLayers&classes[o->class]->collisionLayers))) {
      v=send_message(obj,n,MSG_BLOCKED,NVALUE(o->x),NVALUE(o->y),NVALUE(plus));
      if(v.t) Throw("Type mismatch");
      if(v.u&1) o->oflags&=~OF_MOVING;
      if(v.u&2) break;
    }
    n=q->up;
  }
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
        if(o->height>oE->climb || oE->height>o->climb || (classes[o->class]->collisionLayers&classes[oE->class]->collisionLayers)) {
          h&=handle_colliding(obj,objE,2,2);
        }
      }
      objE=oE->up;
    }
  }
  return ~h;
}

static void do_deferred_moves(void) {
  Object*o;
  Object*p;
  Uint32 h,n;
  int i,x,y;







|







3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
        if(o->height>oE->climb || oE->height>o->climb || (classes[o->class]->collisionLayers&classes[oE->class]->collisionLayers)) {
          h&=handle_colliding(obj,objE,2,2);
        }
      }
      objE=oE->up;
    }
  }
  return h;
}

static void do_deferred_moves(void) {
  Object*o;
  Object*p;
  Uint32 h,n;
  int i,x,y;
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
        if((h&1) && (o->oflags&OF_MOVING) && move_to(VOIDLINK,n,x,y)) {
          re=1;
          o->oflags=(o->oflags|OF_MOVED)&~OF_MOVING;
          i-=65;
          if(i<0) i=0;
          goto retry;
        }
        stop:
        if((h&5)!=4) o->oflags&=~OF_MOVING;
      }
      skip:
      n=o->up;
    }
  }
  if(re) goto restart;
}







<
|







3080
3081
3082
3083
3084
3085
3086

3087
3088
3089
3090
3091
3092
3093
3094
        if((h&1) && (o->oflags&OF_MOVING) && move_to(VOIDLINK,n,x,y)) {
          re=1;
          o->oflags=(o->oflags|OF_MOVED)&~OF_MOVING;
          i-=65;
          if(i<0) i=0;
          goto retry;
        }

        if((h&5)!=4) stop: o->oflags&=~OF_MOVING;
      }
      skip:
      n=o->up;
    }
  }
  if(re) goto restart;
}