Free Hero Mesh

Check-in [7f3f255b14]
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:Implement the connection movement.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7f3f255b14109d49d8deb2d9ed9ba8b0d90a36cd
User & Date: user on 2022-02-11 21:25:41
Other Links: manifest | tags
Context
2022-02-11
22:34
When checking for CollisionLayers during connection movement, ignore objects that are also moving at the same time. check-in: d05fed08fd user: user tags: trunk
21:25
Implement the connection movement. check-in: 7f3f255b14 user: user tags: trunk
2022-02-08
02:51
Implement a few new instructions dealing with links: exec ,exec link rtn check-in: 5ea66f6525 user: user tags: trunk
Changes

Modified TODO from [5f066df71d] to [faf6f0af8d].

1
2
3
4
5
6
7
8
9
10
11
12
* Sound effects
  * Compressed wave sounds (?)
  * Numeric sounds (?)
* Game engine features
  * Multiple connected objects moving as a unit
  * String data (partially implemented)
  * A ,PopUp command to use a popup with arguments starting from a mark
  * Returning a class from COLLIDE/COLLIDEBY to transform
  * Coordinate input (may be suitable for some kind of games)
  * Possibility to define auto-generation levels mode
* Editor
  * Mouse dragging




<







1
2
3
4

5
6
7
8
9
10
11
* Sound effects
  * Compressed wave sounds (?)
  * Numeric sounds (?)
* Game engine features

  * String data (partially implemented)
  * A ,PopUp command to use a popup with arguments starting from a mark
  * Returning a class from COLLIDE/COLLIDEBY to transform
  * Coordinate input (may be suitable for some kind of games)
  * Possibility to define auto-generation levels mode
* Editor
  * Mouse dragging
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
* Warning if file changed when uncommited data exists in the cache database
* Composite puzzle set format (implemented)
  * Optional hypertext help
  * Compressed class definitions (?)
* Option to auto display level titles
* Testing
  * Bizarro world
  * Deferred movement
  * Sweep, SweepEx, HitMe
  * Overriding order of execution
* Conversion from other games
  * DOS Hero Hearts
  * Berusky
  * PC Wanderer
  * Escape
  * Chroma
  * Xsok
  * PuzzleScript (limited; not everything is or will be capable)
  * Sokoban
  * Puzzle Boy
  * Pitman/Catrap







|













38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
* Warning if file changed when uncommited data exists in the cache database
* Composite puzzle set format (implemented)
  * Optional hypertext help
  * Compressed class definitions (?)
* Option to auto display level titles
* Testing
  * Bizarro world
  * Connection movement (it is partially tested, already)
  * Sweep, SweepEx, HitMe
  * Overriding order of execution
* Conversion from other games
  * DOS Hero Hearts
  * Berusky
  * PC Wanderer
  * Escape
  * Chroma
  * Xsok
  * PuzzleScript (limited; not everything is or will be capable)
  * Sokoban
  * Puzzle Boy
  * Pitman/Catrap

Modified class.c from [15832a8e0e] to [9f8ddd9795].

2091
2092
2093
2094
2095
2096
2097

2098
2099
2100
2101
2102
2103
2104
        case OP_VISUALONLY: cl->oflags|=OF_VISUALONLY; break;
        case OP_STEALTHY: cl->oflags|=OF_STEALTHY; break;
        case OP_USERSTATE: cl->oflags|=OF_USERSTATE; break;
        case OP_BIZARRO: cl->oflags|=OF_BIZARRO; break;
        case OP_SHOVABLE: cl->shovable=0x55; break;
        case OP_USERFLAG: class_user_flag(cl); break;
        case OP_ABSTRACT: cl->cflags|=CF_GROUP; break;

        case 0x4000 ... 0x7FFF: set_super_class(cl,ptr); ptr=2; break;
        default: ParseError("Invalid directly inside of a class definition\n");
      }
    } else if(Tokenf(TF_CLOSE)) {
      break;
    } else {
      ParseError("Invalid directly inside of a class definition\n");







>







2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
        case OP_VISUALONLY: cl->oflags|=OF_VISUALONLY; break;
        case OP_STEALTHY: cl->oflags|=OF_STEALTHY; break;
        case OP_USERSTATE: cl->oflags|=OF_USERSTATE; break;
        case OP_BIZARRO: cl->oflags|=OF_BIZARRO; break;
        case OP_SHOVABLE: cl->shovable=0x55; break;
        case OP_USERFLAG: class_user_flag(cl); break;
        case OP_ABSTRACT: cl->cflags|=CF_GROUP; break;
        case OP_CONNECTION: cl->oflags|=OF_CONNECTION; break;
        case 0x4000 ... 0x7FFF: set_super_class(cl,ptr); ptr=2; break;
        default: ParseError("Invalid directly inside of a class definition\n");
      }
    } else if(Tokenf(TF_CLOSE)) {
      break;
    } else {
      ParseError("Invalid directly inside of a class definition\n");
2603
2604
2605
2606
2607
2608
2609











2610
2611
2612
2613
2614
2615
2616
        case OP_CONTROL:
          if(control_class) ParseError("Extra (Control) block\n");
          strcpy(tokenstr,"(Control)");
          control_class=look_class_name();
          if(!(classes[control_class]->cflags&CF_NOCLASS1)) ParseError("Conflicting definition of (Control) class\n");
          class_definition(control_class,vst);
          break;











        case OP_LEVELTABLE:
          level_table_definition();
          break;
        default:
          ParseError("Invalid top level definition: %s\n",tokenstr);
      }
    } else {







>
>
>
>
>
>
>
>
>
>
>







2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
        case OP_CONTROL:
          if(control_class) ParseError("Extra (Control) block\n");
          strcpy(tokenstr,"(Control)");
          control_class=look_class_name();
          if(!(classes[control_class]->cflags&CF_NOCLASS1)) ParseError("Conflicting definition of (Control) class\n");
          class_definition(control_class,vst);
          break;
        case OP_CONNECTION:
          nxttok();
          if(!(tokent&TF_NAME) || tokenv!=OP_STRING) ParseError("String literal expected\n");
          for(i=0;tokenstr[i];i++) switch(tokenstr[i]) {
            case 't': conn_option|=0x02; break;
            case 'w': conn_option|=0x01; break;
            default: ParseError("Unrecognized (Connection) option\n");
          }
          nxttok();
          if(tokent!=TF_CLOSE) ParseError("Expected close parenthesis\n");
          break;
        case OP_LEVELTABLE:
          level_table_definition();
          break;
        default:
          ParseError("Invalid top level definition: %s\n",tokenstr);
      }
    } else {

Modified class.doc from [9e85956bac] to [72f1aea5b1].

267
268
269
270
271
272
273






274
275
276
277
278
279
280
  can optionally specify a second number, which is the background colour
  for the inventory; if not specified, uses the same colour for both.

(CodePage <number>)
  Define the code page, from 1 to 8388607. If not specified, then the
  default code page is used.







(Control <definitions...>)
  Define the control class. The format is the same like other class
  definitions, except that Image and Abstract are not allowed. An
  object of this class is automatically created when initializing the
  level, at X and Y coordinates both zero, and cannot otherwise be
  created, destroyed, or moved. It still receives broadcast messages
  normally, and can also be addressed specifically.







>
>
>
>
>
>







267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  can optionally specify a second number, which is the background colour
  for the inventory; if not specified, uses the same colour for both.

(CodePage <number>)
  Define the code page, from 1 to 8388607. If not specified, then the
  default code page is used.

(Connection <string>)
  Set options for connected movement. The string can include any
  combination of the below letters:
  "t" = Use two HIT/HITBY passes, skipping shove/sharp for first pass.
  "w" = Use the total weight of the group instead of each one separately.

(Control <definitions...>)
  Define the control class. The format is the same like other class
  definitions, except that Image and Abstract are not allowed. An
  object of this class is automatically created when initializing the
  level, at X and Y coordinates both zero, and cannot otherwise be
  created, destroyed, or moved. It still receives broadcast messages
  normally, and can also be addressed specifically.
397
398
399
400
401
402
403



404
405
406
407
408
409
410
  compatibility with Hero Mesh, and would not normally be used for new
  puzzle sets made with Free Hero Mesh.

,Compatible
  Sets the Compatible flag for this class, but removes the restriction of
  some variables limited to 16-bits.




(DefaultImage <list...>)
  Each entry is either a number of an image in this class, or two
  numbers in parentheses giving a range of images, or () to indicate
  that there are no default images. This specifies which images can
  be used in objects of this class which are initially present on
  the level (placed in the editor). If () is used, then this class
  is not available in the editor. If there is no (DefaultImage) block,







>
>
>







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
  compatibility with Hero Mesh, and would not normally be used for new
  puzzle sets made with Free Hero Mesh.

,Compatible
  Sets the Compatible flag for this class, but removes the restriction of
  some variables limited to 16-bits.

Connection
  Sets the Connection flag for this class.

(DefaultImage <list...>)
  Each entry is either a number of an image in this class, or two
  numbers in parentheses giving a range of images, or () to indicate
  that there are no default images. This specifies which images can
  be used in objects of this class which are initially present on
  the level (placed in the editor). If () is used, then this class
  is not available in the editor. If there is no (DefaultImage) block,
646
647
648
649
650
651
652

653
654
655
656
657
658
659
  ARRIVED
  BEGIN_TURN
  BLOCKED
  COLLIDE
  COLLIDEBY
  COLLIDING
  CONFLICT

  CREATE
  CREATED
  DEPARTED
  DESTROY
  DESTROYED
  END_TURN
  FLOATED







>







655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
  ARRIVED
  BEGIN_TURN
  BLOCKED
  COLLIDE
  COLLIDEBY
  COLLIDING
  CONFLICT
  CONNECT
  CREATE
  CREATED
  DEPARTED
  DESTROY
  DESTROYED
  END_TURN
  FLOATED
894
895
896
897
898
899
900







901
902
903
904
905
906
907
  Any set bit means no other object with that same bit set in this field
  may exist at the same location. (There is no effect in bizarro world.)

Compatible : bool [c] [ro]
  The compatibility flag. Class definitions imported from EKS Hero Mesh
  always set this flag; in new puzzle sets it is normally not set.








Density : int16/int32 [c]
  Determines the order that objects are stacked within each cell. When an
  object is moved or created, its Density is compared with the Density of
  the objects already present at that location, in order to insert it into
  the stack of objects there, at the top, bottom, or middle, where lesser
  numbers mean closer to the top, and greater numbers are deeper. If there
  are multiple objects of the same Density, the new one goes above others







>
>
>
>
>
>
>







904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
  Any set bit means no other object with that same bit set in this field
  may exist at the same location. (There is no effect in bizarro world.)

Compatible : bool [c] [ro]
  The compatibility flag. Class definitions imported from EKS Hero Mesh
  always set this flag; in new puzzle sets it is normally not set.

Connection : bool [c]
  If this flag is set, then moving this object by the use of the Move
  instruction will try to move an entire connected group of objects,
  instead of only one. This changes some of the behaviour and will
  cause additional messages to be sent, too. Deferred movement is not
  possible if this flag is set.

Density : int16/int32 [c]
  Determines the order that objects are stacked within each cell. When an
  object is moved or created, its Density is compared with the Density of
  the objects already present at that location, in order to insert it into
  the stack of objects there, at the top, bottom, or middle, where lesser
  numbers mean closer to the top, and greater numbers are deeper. If there
  are multiple objects of the same Density, the new one goes above others
1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
  to all objects which have moved; you can set or clear this flag by
  yourself if you want to cause it to trigger even though it didn't
  move or to not trigger even though it did move.

Moving : bool
  This flag indicates that a deferred movement is scheduled for this
  object. The direction of movement is specified by the Dir variable.


Player : bool [c] [ro]
  If this object is the player. This is used implicitly as the From of
  some messages sent by the game engine, and has a few other purposes.
  (Normally, a level should have exactly one object of such a class,
  although this is not mandatory; any number (including zero) is allowed.)








>







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
  to all objects which have moved; you can set or clear this flag by
  yourself if you want to cause it to trigger even though it didn't
  move or to not trigger even though it did move.

Moving : bool
  This flag indicates that a deferred movement is scheduled for this
  object. The direction of movement is specified by the Dir variable.
  This flag is also used for connected movement, for a different purpose.

Player : bool [c] [ro]
  If this object is the player. This is used implicitly as the From of
  some messages sent by the game engine, and has a few other purposes.
  (Normally, a level should have exactly one object of such a class,
  although this is not mandatory; any number (including zero) is allowed.)

1029
1030
1031
1032
1033
1034
1035
1036



1037
1038
1039
1040
1041
1042
1043
ShapeDir : int2 [c] [d]
  Allows accessing the individual 2-bit parts of Shape.

Sharp : int16 [c] [d]
  When one object tries to move into another object, the Hard and Sharp
  values for the sides that are touching will be compared. If the Sharp
  value for one is greater than the Hard of the other, then the object
  with insufficient Hardness is destroyed.




Shovable : int16 [c]
  Defines what directions the object may be shoved, where bit0 means east,
  bit2 means north, bit4 means west, and bit6 means south. Bit1, bit3,
  bit5, and bit7 can be used for diagonal shoving. Higher bits are
  reserved for future and should not be used.








|
>
>
>







1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
ShapeDir : int2 [c] [d]
  Allows accessing the individual 2-bit parts of Shape.

Sharp : int16 [c] [d]
  When one object tries to move into another object, the Hard and Sharp
  values for the sides that are touching will be compared. If the Sharp
  value for one is greater than the Hard of the other, then the object
  with insufficient Hardness is destroyed. If the object that is trying
  to move has the Connection flag, it cannot be destroyed due to running
  into something sharp, but may still destroy other things if it is sharp
  enough to do so (whether or not the other thing has a Connection flag).

Shovable : int16 [c]
  Defines what directions the object may be shoved, where bit0 means east,
  bit2 means north, bit4 means west, and bit6 means south. Bit1, bit3,
  bit5, and bit7 can be used for diagonal shoving. Higher bits are
  reserved for future and should not be used.

1328
1329
1330
1331
1332
1333
1334













1335
1336
1337
1338
1339
1340
1341
  false otherwise. Always false if the object is destroyed, or if one
  object is in the bizarro world and the other one isn't.

,Coloc  ( obj1 obj2 -- bool )
  True if the two specified objects are in the same place, or false
  otherwise. Always false if the object is destroyed, or if one object
  is in the bizarro world and the other one isn't.














Control  ( -- obj )
  Push the control object to the stack. (If no control class is defined,
  then there will be no control object and this will be zero.)

CopyArray  ( src dest -- ) **
  Copy one array to another. It is OK if the two references overlap.







>
>
>
>
>
>
>
>
>
>
>
>
>







1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
  false otherwise. Always false if the object is destroyed, or if one
  object is in the bizarro world and the other one isn't.

,Coloc  ( obj1 obj2 -- bool )
  True if the two specified objects are in the same place, or false
  otherwise. Always false if the object is destroyed, or if one object
  is in the bizarro world and the other one isn't.

Connect  ( -- ) **
  Adds this object to the connection list; has no effect if this object
  is already in the connection list or has the Moving, Destroyed, or
  Bizarro flags set, or does not have the Connection flag. This will
  also set the Moving and VisualOnly flag of this object; it will
  automatically clear the Moving flag after it is handled, and will
  restore the old value of VisualOnly. This should not be used outside
  of the CONNECT message.

,Connect  ( obj -- ) **
  Similar to Connect but for a specified object, instead of necessarily
  this object.

Control  ( -- obj )
  Push the control object to the stack. (If no control class is defined,
  then there will be no control object and this will be zero.)

CopyArray  ( src dest -- ) **
  Copy one array to another. It is OK if the two references overlap.
1400
1401
1402
1403
1404
1405
1406











1407
1408
1409
1410
1411
1412
1413
exec  ( link -- )
  Go to a link; does not continue executing from here afterward. If the
  link is zero then it will be the same as ret.

,exec  ( link -- )
  Go to a link and then continue executing from here afterward. If the
  link is zero then this instruction does nothing.












Finished  ( -- number )
  Returns the value of an internal flag which tells it that the beginning
  and ending phases should be skipped. This is a 8-bit number; zero means
  don't skip them, and any other number means it does. When the game engine
  sets this automatically, it normally sets it to 1, but "-1 FlushClass"
  during the input phase sets it to 255. When you set this value by







>
>
>
>
>
>
>
>
>
>
>







1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
exec  ( link -- )
  Go to a link; does not continue executing from here afterward. If the
  link is zero then it will be the same as ret.

,exec  ( link -- )
  Go to a link and then continue executing from here afterward. If the
  link is zero then this instruction does nothing.

FakeMove  ( dir -- result ) **
  Similar to IntMove but omits many capabilities, including the actual
  movement. This is the same as a function used internally to deal with
  HIT/HITBY for connection movement. If the HIT or HITBY message returns
  a mark, then it is added like using Connect (if the object's flags
  allow it) and then the return value will be 2.

,FakeMove  ( obj dir -- result ) **
  Works like FakeMove but you can specify a different object instead of
  the current one.

Finished  ( -- number )
  Returns the value of an internal flag which tells it that the beginning
  and ending phases should be skipped. This is a 8-bit number; zero means
  don't skip them, and any other number means it does. When the game engine
  sets this automatically, it normally sets it to 1, but "-1 FlushClass"
  during the input phase sets it to 255. When you set this value by
2143
2144
2145
2146
2147
2148
2149










2150
2151
2152
2153
2154
2155
2156

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.











CREATE
  Sent when the object is created by the Create instruction. This is done
  after the object is created, but before sending any other messages. The
  From is the object that created it. The return value will be used as the
  Arg3 of the SUNK and CREATED messages it might send if appropriate. From
  is the object which executed the Create instruction to create it.








>
>
>
>
>
>
>
>
>
>







2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211

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.

CONNECT
  Should use the ,Connect instruction to add additional objects to the
  connection group; it will then send this message to those objects too.
  If the return value is true, then the movement fails, and none of the
  objects in the group will move. The Inertia of this object is set
  automatically before calling this message; it can change the Inertia
  before returning if it wants a different value for Inertia. Arg1 is
  the number of objects in the group previously to this one, Arg2 is the
  direction of movement, and Arg3 is the total Weight so far.

CREATE
  Sent when the object is created by the Create instruction. This is done
  after the object is created, but before sending any other messages. The
  From is the object that created it. The return value will be used as the
  Arg3 of the SUNK and CREATED messages it might send if appropriate. From
  is the object which executed the Create instruction to create it.

2252
2253
2254
2255
2256
2257
2258
2259




2260
2261
2262
2263
2264
2265
2266
  description of END_TURN for details). The Moved variable will usually
  be set automatically; see the section about variables for details.

MOVING
  Called when the object is about to be moved (whether due to Move,
  MoveTo, JumpTo, or any other reason). From is the object that caused
  the move, and Arg1 and Arg2 are the target X and Y coordinates. If the
  return value is true, then the move is aborted.





PLAYERMOVING
  If an object with the Player flag is about to move, then after the
  MOVING message is sent, PLAYERMOVING is sent to all objects. From is
  the object which is moving, Arg1 and Arg2 are where it will be moved to,
  and Arg3 is the From of the MOVING message. If the return value is true,
  then the move is aborted.







|
>
>
>
>







2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
  description of END_TURN for details). The Moved variable will usually
  be set automatically; see the section about variables for details.

MOVING
  Called when the object is about to be moved (whether due to Move,
  MoveTo, JumpTo, or any other reason). From is the object that caused
  the move, and Arg1 and Arg2 are the target X and Y coordinates. If the
  return value is true, then the move is aborted. From will be zero if
  it is the first pass of checking if it can be moved due to Connection;
  in that case, if all first passes are successful then it will try again
  the second pass with From set to the first object of the group, and
  this second time they will actually be moved.

PLAYERMOVING
  If an object with the Player flag is about to move, then after the
  MOVING message is sent, PLAYERMOVING is sent to all objects. From is
  the object which is moving, Arg1 and Arg2 are where it will be moved to,
  and Arg3 is the From of the MOVING message. If the return value is true,
  then the move is aborted.
2288
2289
2290
2291
2292
2293
2294




2295
2296


2297
2298
2299
2300
2301
2302
2303
2304
2305
2306

2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318


2319
2320
2321

2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340


2341
2342
2343
2344
2345
2346


2347
2348
2349
2350
2351
2352
2353
messages; these values are also used as the Arg3 of those messages.

Some descriptions below are marked with an asterisk. If the Compatible
flag is set for the object that returned this value, then all bits with
the asterisk in the below descriptions are masked out (bit15 is only
masked out for Compatible objects for diagonal movement).





bit0
  Do not send the HITBY message to the target object.



bit1
  Do not destroy either object due to hardness/sharpness.

bit2
  Do not attempt to shove the target object.

bit3
  Abort the move attempt immediately. Do not send any more HIT or HITBY
  messages, do not check hardness/sharpness, and do nothing else either.


bit4
  Do not send the HITBY message to the target object or to any further
  objects at the target location.

bit5
  Do not destroy either object due to hardness/sharpness, nor should any
  further objects at the target location be destroyed due to sharpness.

bit6
  Do not attempt to shove the target object, nor attempt to shove any
  other objects at the target location.



bit7 *
  Do not attempt sliding.


bit8
  Abort after sending the HITBY message.

bit9
  Abort after hardness/sharpness checking.

bit10
  Abort after attempting shoving.

bit11
  Set by the game engine if the move attempt has been restarted due to
  bit15 being set during the previous attempt.

bit12 *
  If the move attempt fails, pretend it was successful, even though the
  object hasn't actually moved. This means that the result of Move will
  be 1 and that the MOVED message will trigger; it does not trigger any
  ARRIVED, DEPARTED, FLOATED, or SUNK, nor does it set Distance.



bit13 *
  Abort before actually moving the object and before trying sliding.

bit14 *
  Do not set the Moved flag even if successful.



bit15 (*)
  Try again after trying shoving (whether or not the shoving is
  successful). If it tries to shove an object and it is successful, then
  it will automatically set this bit and automatically try again.

bit16







>
>
>
>

|
>
>










>











|
>
>


|
>


















|
>
>





|
>
>







2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
messages; these values are also used as the Arg3 of those messages.

Some descriptions below are marked with an asterisk. If the Compatible
flag is set for the object that returned this value, then all bits with
the asterisk in the below descriptions are masked out (bit15 is only
masked out for Compatible objects for diagonal movement).

(If the Connection flag is set for the object that is moving, then the
Compatible flag is ignored for the purpose of HIT/HITBY bits, but is not
ignored for other purposes.)

bit0
  Do not send the HITBY message to the target object. If the moving object
  has the Connection flag, then this bit is set in Arg3, but this does not
  prevent sending the HITBY message unless the return value also has bit0.

bit1
  Do not destroy either object due to hardness/sharpness.

bit2
  Do not attempt to shove the target object.

bit3
  Abort the move attempt immediately. Do not send any more HIT or HITBY
  messages, do not check hardness/sharpness, and do nothing else either.
  This bit is also set in Arg3 if the object can't move due to Volume.

bit4
  Do not send the HITBY message to the target object or to any further
  objects at the target location.

bit5
  Do not destroy either object due to hardness/sharpness, nor should any
  further objects at the target location be destroyed due to sharpness.

bit6
  Do not attempt to shove the target object, nor attempt to shove any
  other objects at the target location. (If you are using the two pass
  HIT/HITBY for connection movement, then this bit will automatically
  be set during the first pass.)

bit7 *
  Do not attempt sliding. (This bit is always set in Arg3 if it is due
  to Connection, and always prevents sliding in this case.)

bit8
  Abort after sending the HITBY message.

bit9
  Abort after hardness/sharpness checking.

bit10
  Abort after attempting shoving.

bit11
  Set by the game engine if the move attempt has been restarted due to
  bit15 being set during the previous attempt.

bit12 *
  If the move attempt fails, pretend it was successful, even though the
  object hasn't actually moved. This means that the result of Move will
  be 1 and that the MOVED message will trigger; it does not trigger any
  ARRIVED, DEPARTED, FLOATED, or SUNK, nor does it set Distance. (If the
  moving object has the Connection flag, then this does not stop it from
  moving; it will move anyways if this flag is set.)

bit13 *
  Abort before actually moving the object and before trying sliding.

bit14 *
  Do not set the Moved flag even if successful. (If you are using two pass
  HIT/HITBY for connection movement, then this bit will automatically be
  set in most cases during the first pass.)

bit15 (*)
  Try again after trying shoving (whether or not the shoving is
  successful). If it tries to shove an object and it is successful, then
  it will automatically set this bit and automatically try again.

bit16
2414
2415
2416
2417
2418
2419
2420
2421







2422
2423
2424
2425
2426
2427
2428

bit31
  Available for your own use.

The return value of HITBY can also be an object instead of a number. In
this case, a warp occurs. The movement is restarted, using the specified
object as the origin of the movement, and that object's direction as the
direction of movement.









=== Pattern matching ===

Where an instruction is expected, you can have pattern matching. This can
be (<operator> <pattern...>) where the operator can be one of:








|
>
>
>
>
>
>
>







2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508

bit31
  Available for your own use.

The return value of HITBY can also be an object instead of a number. In
this case, a warp occurs. The movement is restarted, using the specified
object as the origin of the movement, and that object's direction as the
direction of movement. (This is not allowed if bit0 of Arg3 is set; in
that case, it is an error.)

If the moving object has the Connection flag (and bit0 is set in Arg3),
then the return value of HIT or HITBY may be a mark. In this case, it
makes the object "sticky", adding it to the list of objects to be moved
as a part of the same connection group. (Returning a mark if bit0 of
Arg3 is not set is an error.)


=== Pattern matching ===

Where an instruction is expected, you can have pattern matching. This can
be (<operator> <pattern...>) where the operator can be one of:

Modified exec.c from [8214ecec6e] to [05cf8f416c].

38
39
40
41
42
43
44

45
46
47
48
49
50






51
52
53
54
55
56
57
58
59
60
61
62



63
64
65
66
67
68
69
unsigned char**levelstrings;
Uint16 nlevelstrings;
Value*array_data;
Uint16 ndeadanim;
DeadAnimation*deadanim;
Uint8 no_dead_anim;
Uint32 max_trigger;


typedef struct {
  Uint16 msg;
  Uint32 from;
  Value arg1,arg2,arg3;
} MessageVars;







static jmp_buf my_env;
static const char*my_error;
static MessageVars msgvars;
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







>






>
>
>
>
>
>












>
>
>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
unsigned char**levelstrings;
Uint16 nlevelstrings;
Value*array_data;
Uint16 ndeadanim;
DeadAnimation*deadanim;
Uint8 no_dead_anim;
Uint32 max_trigger;
Uint8 conn_option;

typedef struct {
  Uint16 msg;
  Uint32 from;
  Value arg1,arg2,arg3;
} MessageVars;

typedef struct {
  Uint32 obj;
  Uint16 id;
  Uint8 visual;
} Connection;

static jmp_buf my_env;
static const char*my_error;
static MessageVars msgvars;
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;
static Connection conn[VSTACKSIZE];
static int nconn,pconn;
static Uint8 conn_dir;

#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
947
948
949
950
951
952
953






































































































































































































































































954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969

970
971
972
973
974
975
976
  // Checks if sliding is possible, except the height of the target location.
  Uint8 m=(o->shape&(1<<d1))|(oF->shape&(1<<(4^d1)));
  if(!(m&(m-1))) return 0;
  if(!(o->shovable&(1<<d2))) return 0;
  if(height_at(o->x+x_delta[d2],o->y+y_delta[d2])<=o->climb) return 1;
  return vol+volume_at(o->x+x_delta[d2],o->y+y_delta[d2])<=max_volume;
}







































































































































































































































































static int move_dir(Uint32 from,Uint32 obj,Uint32 dir) {
  // This function is complicated, and there may be mistakes.
  Object*o;
  Object*oE;
  Object*oF;
  Object*oW;
  Uint32 objE,objF,objLF,objRF,objW;
  Uint32 hit=0;
  Uint32 vol;
  Value v;
  if(StackProtection()) Throw("Call stack overflow during movement");
  if(obj==VOIDLINK) return 0;
  oW=o=objects[objW=obj];
  o->dir=dir=resolve_dir(obj,dir);
  if(o->weight>o->inertia) goto fail;

  o->inertia-=o->weight;
  restart:
  if(hit&0x100000) dir=o->dir;
  objF=obj_dir(objW,dir);
  if(objF==VOIDLINK) goto fail;
  if(hit) hit=0x800|(hit&0x10000000);
  oF=objects[objF];







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















>







957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
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
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
  // Checks if sliding is possible, except the height of the target location.
  Uint8 m=(o->shape&(1<<d1))|(oF->shape&(1<<(4^d1)));
  if(!(m&(m-1))) return 0;
  if(!(o->shovable&(1<<d2))) return 0;
  if(height_at(o->x+x_delta[d2],o->y+y_delta[d2])<=o->climb) return 1;
  return vol+volume_at(o->x+x_delta[d2],o->y+y_delta[d2])<=max_volume;
}

static int move_dir(Uint32 from,Uint32 obj,Uint32 dir);

static void add_connection(Uint32 obj) {
  Object*o=objects[obj];
  if(nconn==VSTACKSIZE) Throw("Connection limit overflow");
  if((o->oflags^OF_CONNECTION)&(OF_MOVING|OF_DESTROYED|OF_CONNECTION|OF_BIZARRO)) return;
  conn[nconn].obj=obj;
  conn[nconn].id=nconn; // used for stable sorting
  conn[nconn].visual=(o->oflags&OF_VISUALONLY)?1:0;
  o->oflags|=OF_MOVING|OF_VISUALONLY;
  nconn++;
}

static int fake_move_dir(Uint32 obj,Uint32 dir,Uint8 no) {
  // This is similar to move_dir, but specialized for the HIT/HITBY processing in connected_move.
  // Note that this may result in calling the real move_dir due to shoving.
  Object*o;
  Object*oE;
  Object*oF;
  Uint32 objE,objF,objLF,objRF;
  Uint32 hit=0;
  Uint32 vol;
  Value v;
  if(StackProtection()) Throw("Call stack overflow during movement");
  if(obj==VOIDLINK) return 0;
  o=objects[obj];
  restart:
  if(hit&0x100000) dir=o->dir;
  objF=obj_dir(obj,dir);
  if(objF==VOIDLINK) goto fail;
  if(hit) hit=0x800|(hit&0x10000000);
  oF=objects[objF];
  objLF=obj_dir(obj,(dir+1)&7);
  objRF=obj_dir(obj,(dir-1)&7);
  if(height_at(oF->x,oF->y)<=o->climb) hit|=0x200000;
  if(no) {
    if((vol=classes[oF->class]->collisionLayers) && obj_layer_at(vol,oF->x,oF->y)!=VOIDLINK) goto fail;
    hit|=0x4066;
  }
  if(dir&1) {
    // Diagonal movement
    hit|=0x80000;
    vol=o->volume;
    if(objLF!=VOIDLINK) vol+=volume_at(objects[objLF]->x,objects[objLF]->y);
    if(objRF!=VOIDLINK) vol+=volume_at(objects[objRF]->x,objects[objRF]->y);
    if(vol<=max_volume) {
      objE=objF;
      while(objE!=VOIDLINK) {
        if(o->oflags&OF_DESTROYED) break;
        oE=objects[objE];
        if(oE->height>0) {
          hit&=0xFC287040;
          v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(hit|0x81));
          if(v.t==TY_MARK) goto sticky;
          if(v.t) Throw("Type mismatch in HIT/HITBY");
          hit|=v.u;
          if(hit&8) goto fail;
          if(!(hit&0x11)) {
            v=send_message(obj,objE,MSG_HITBY,NVALUE(o->x),NVALUE(o->y),NVALUE(hit|0x81));
            if(v.t==TY_MARK) goto sticky;
            if(v.t) Throw("Type mismatch in HIT/HITBY");
            hit|=v.u;
            if(hit&8) goto fail;
          }
        }
        // Shoving
        if(!(hit&0x44) && (oE->shovable&(1<<dir)) && o->inertia>=oE->weight && !(oE->oflags&OF_VISUALONLY)) {
          oE->inertia=o->inertia;
          if(move_dir(obj,objE,dir)) {
            if(!(oE->oflags&OF_DESTROYED)) o->inertia=oE->inertia;
            hit|=0x8000;
            if(hit&0x800000) goto restart;
          }
        }
        objE=obj_below(objE);
      }
      if((hit&0x48000)==0x8000) goto restart;
      if((hit&0x200000) && !(hit&0x402008)) {
        if((hit&0x20000) || oF) goto success; else goto fail;
      }
    } else {
      // Volume is too much; hit the objects it won't go between
      if(o->oflags&OF_DESTROYED) goto fail;
      objE=objLF;
      while(objE!=VOIDLINK) {
        oE=objects[objE];
        if(oE->height>0) {
          v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(0x80089));
          if(v.t==TY_MARK) goto sticky;
          if(v.t) Throw("Type mismatch in HIT/HITBY");
          if(!(v.u&1)) v=send_message(obj,objE,MSG_HITBY,NVALUE(o->x),NVALUE(o->y),NVALUE(v.u|0x80089));
          if(v.t==TY_MARK) goto sticky;
          if(v.t==TY_SOUND || v.t==TY_USOUND) Throw("Type mismatch in HIT/HITBY");
        }
        objE=obj_below(objE);
      }
      if(o->oflags&OF_DESTROYED) goto fail;
      objE=objRF;
      while(objE!=VOIDLINK) {
        oE=objects[objE];
        if(oE->height>0) {
          v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(0x80089));
          if(v.t==TY_MARK) goto sticky;
          if(v.t) Throw("Type mismatch in HIT/HITBY");
          if(!(v.u&1)) v=send_message(obj,objE,MSG_HITBY,NVALUE(o->x),NVALUE(o->y),NVALUE(v.u|0x80089));
          if(v.t==TY_MARK) goto sticky;
          if(v.t==TY_SOUND || v.t==TY_USOUND) Throw("Type mismatch in HIT/HITBY");
        }
        objE=obj_below(objE);
      }
    }
  } else {
    // Orthogonal movement
    if(!oF) goto fail;
    objE=objF;
    while(objE!=VOIDLINK) {
      if(o->oflags&OF_DESTROYED) break;
      oE=objects[objE];
      if(oE->height>0) {
        hit&=~7;
        // HIT/HITBY messages
        v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(hit|0x81));
        if(v.t==TY_MARK) goto sticky;
        if(v.t) Throw("Type mismatch in HIT/HITBY");
        hit|=v.u;
        if(hit&8) goto fail;
        if(!(hit&0x11)) {
          v=send_message(obj,objE,MSG_HITBY,NVALUE(o->x),NVALUE(o->y),NVALUE(hit|0x81));
          if(v.t==TY_MARK) goto sticky;
          if(v.t) Throw("Type mismatch in HIT/HITBY");
          hit|=v.u;
        }
        if(hit&0x108) goto fail;
        // Hardness/sharpness
        if(!(hit&0x22)) {
          if(o->sharp[dir>>1]>oE->hard[(dir^4)>>1] && !v_bool(destroy(obj,objE,2))) hit|=0x8004;
        }
        if(hit&0x200) goto fail;
      }
      // Shoving
      if(!(hit&0x44) && (oE->shovable&(1<<dir)) && o->inertia>=oE->weight && !(oE->oflags&OF_VISUALONLY)) {
        oE->inertia=o->inertia;
        if(move_dir(obj,objE,dir)) {
          if(!(oE->oflags&OF_DESTROYED)) o->inertia=oE->inertia;
          hit|=0x8000;
          if(hit&0x800000) goto restart;
        }
      }
      if(hit&0x400) goto fail;
      objE=obj_below(objE);
    }
    if(hit&0x2008) goto fail;
    if((hit&0x48000)==0x8000) goto restart;
    if((hit&0x200000) && !(hit&0x400000)) goto success;
  }
  fail: if(hit&0x1000) goto success; o->inertia=0; return 0;
  success: return 1;
  sticky: add_connection(objE); return 2;
}

static int compare_connection(const void*v1,const void*v2) {
  // Ensure that the sorting is stable.
  const Connection*c1=v1;
  const Connection*c2=v2;
  Object*o1=objects[c1->obj];
  Object*o2=objects[c2->obj];
  switch(conn_dir) {
    case 0: case 1: return (o2->x-o1->x)?:(o1->y-o2->y)?:c2->id-c1->id; // E, NE
    case 2: case 3: return (o1->y-o2->y)?:(o1->x-o2->x)?:c2->id-c1->id; // N, NW
    case 4: case 5: return (o1->x-o2->x)?:(o2->y-o1->y)?:c2->id-c1->id; // W, SW
    case 6: case 7: return (o2->y-o1->y)?:(o2->x-o1->x)?:c2->id-c1->id; // S, SE
  }
}

static int connected_move(Uint32 obj,Uint8 dir) {
  Object*o;
  Uint32 n;
  Sint32 inertia=objects[obj]->inertia;
  Sint32 weight=0;
  int first=nconn;
  int last;
  int i,j;
  if(nconn!=pconn) Throw("Improper nested connected move");
  // Find and add all connections
  add_connection(obj);
  for(i=first;i<nconn;i++) {
    loop1:
    objects[n=conn[i].obj]->inertia=inertia;
    if(v_bool(send_message(obj,n,MSG_CONNECT,NVALUE(i-first),NVALUE(dir),NVALUE(weight)))) goto fail;
    weight+=objects[n]->weight;
  }
  if(conn_option&0x01) {
    for(i=first;i<nconn;i++) {
      o=objects[conn[i].obj];
      if(o->inertia<weight) goto fail;
      inertia-=o->weight;
    }
  } else {
    weight=objects[conn[first].obj]->weight;
  }
  last=pconn=nconn;
  // Check HIT/HITBY; may shove other objects
  if(conn_option&0x02) {
    for(i=first;i<last;i++) {
      o=objects[n=conn[i].obj];
      j=fake_move_dir(n,o->dir=dir,1);
      if(!j) goto fail;
      if(j==2) {
        if(nconn==pconn) Throw("This object cannot be sticky");
        i=pconn;
        goto loop1;
      }
    }
  }
  for(i=first;i<last;i++) {
    o=objects[n=conn[i].obj];
    if(conn_option&0x01) o->inertia=inertia;
    j=fake_move_dir(n,o->dir=dir,0);
    if(!j) goto fail;
    if((conn_option&0x01) && !(o->oflags&OF_DESTROYED)) inertia=o->inertia;
    if(j==2) {
      if(nconn==pconn) Throw("This object cannot be sticky");
      i=pconn;
      goto loop1;
    }
  }
  // Check if each object in the group is movable
  for(i=first;i<last;i++) {
    o=objects[n=conn[i].obj];
    if(v_bool(send_message(VOIDLINK,n,MSG_MOVING,NVALUE(o->x+x_delta[dir]),NVALUE(o->y+y_delta[dir]),NVALUE(0)))) goto fail;
    if(classes[o->class]->cflags&CF_PLAYER) {
      n=lastobj;
      while(n!=VOIDLINK) {
        if(v_bool(send_message(conn[i].obj,n,MSG_PLAYERMOVING,NVALUE(o->x+x_delta[dir]),NVALUE(o->y+y_delta[dir]),NVALUE(0)))) goto fail;
        n=objects[n]->prev;
      }
    }
    if(j=classes[o->class]->collisionLayers) {
      if(obj_layer_at(j,o->x+x_delta[dir],o->y+y_delta[dir])!=VOIDLINK) goto fail;
    }
  }
  // Move everything in the group
  conn_dir=dir;
  qsort(conn+first,last-first,sizeof(Connection),compare_connection);
  for(i=first;i<last;i++) {
    o=objects[n=conn[i].obj];
    if(!conn[i].visual) o->oflags&=~OF_VISUALONLY;
    if(move_to(obj,n,o->x+x_delta[dir],o->y+y_delta[dir])) o->oflags|=OF_MOVED;
  }
  // Done
  j=1; goto done;
  fail: j=0;
  done:
  for(i=first;i<nconn;i++) {
    o=objects[conn[i].obj];
    o->oflags&=~OF_MOVING;
    if(conn[i].visual) o->oflags|=OF_VISUALONLY; else o->oflags&=~OF_VISUALONLY;
  }
  pconn=nconn=first;
  return j;
}

static int move_dir(Uint32 from,Uint32 obj,Uint32 dir) {
  // This function is complicated, and there may be mistakes.
  Object*o;
  Object*oE;
  Object*oF;
  Object*oW;
  Uint32 objE,objF,objLF,objRF,objW;
  Uint32 hit=0;
  Uint32 vol;
  Value v;
  if(StackProtection()) Throw("Call stack overflow during movement");
  if(obj==VOIDLINK) return 0;
  oW=o=objects[objW=obj];
  o->dir=dir=resolve_dir(obj,dir);
  if(o->weight>o->inertia) goto fail;
  if(o->oflags&OF_CONNECTION) return connected_move(obj,dir);
  o->inertia-=o->weight;
  restart:
  if(hit&0x100000) dir=o->dir;
  objF=obj_dir(objW,dir);
  if(objF==VOIDLINK) goto fail;
  if(hit) hit=0x800|(hit&0x10000000);
  oF=objects[objF];
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
    if(objRF!=VOIDLINK) vol+=volume_at(objects[objRF]->x,objects[objRF]->y);
    if(vol<=max_volume) {
      objE=objF;
      while(objE!=VOIDLINK) {
        if(o->oflags&(OF_DESTROYED|OF_VISUALONLY)) break;
        oE=objects[objE];
        if(oE->height>0) {
          hit&=0xFC287000;
          v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(hit));
          if(v.t) Throw("Type mismatch in HIT/HITBY");
          hit|=v.u&(classes[o->class]->cflags&CF_COMPATIBLE?0xC0090F7F:-1L);
          if(hit&8) goto fail;
          if(!(hit&0x11)) {
            v=send_message(obj,objE,MSG_HITBY,NVALUE(oW->x),NVALUE(oW->y),NVALUE(hit));
            if(v.t>TY_MAXTYPE) goto warp;







|







1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
    if(objRF!=VOIDLINK) vol+=volume_at(objects[objRF]->x,objects[objRF]->y);
    if(vol<=max_volume) {
      objE=objF;
      while(objE!=VOIDLINK) {
        if(o->oflags&(OF_DESTROYED|OF_VISUALONLY)) break;
        oE=objects[objE];
        if(oE->height>0) {
          hit&=0xFC287040;
          v=send_message(objE,obj,MSG_HIT,NVALUE(oE->x),NVALUE(oE->y),NVALUE(hit));
          if(v.t) Throw("Type mismatch in HIT/HITBY");
          hit|=v.u&(classes[o->class]->cflags&CF_COMPATIBLE?0xC0090F7F:-1L);
          if(hit&8) goto fail;
          if(!(hit&0x11)) {
            v=send_message(obj,objE,MSG_HITBY,NVALUE(oW->x),NVALUE(oW->y),NVALUE(hit));
            if(v.t>TY_MAXTYPE) goto warp;
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
  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));







|







1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
  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|OF_CONNECTION)) 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));
2496
2497
2498
2499
2500
2501
2502






2503
2504
2505
2506
2507
2508
2509
    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;







>
>
>
>
>
>







2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
    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_CONNECT: NoIgnore(); add_connection(obj); break;
    case OP_CONNECT_C: NoIgnore(); StackReq(1,0); i=v_object(Pop()); if(i!=VOIDLINK) add_connection(i); break;
    case OP_CONNECTION: StackReq(0,1); if(o->oflags&OF_CONNECTION) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_CONNECTION_C: StackReq(1,1); GetFlagOf(OF_CONNECTION); break;
    case OP_CONNECTION_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_CONNECTION; else o->oflags&=~OF_CONNECTION; break;
    case OP_CONNECTION_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_CONNECTION); 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;
2547
2548
2549
2550
2551
2552
2553


2554
2555
2556
2557
2558
2559
2560
    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;
    case OP_EQ2: StackReq(4,1); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t3)?(v_equal(t2,t4)?1:0):0)); break;
    case OP_EXEC: StackReq(1,0); t1=Pop(); i=convert_link(t1,obj,code); if(i==0xFFFF) return; code=classes[i>>16]->codes; ptr=i&0xFFFF; break;
    case OP_EXEC_C: StackReq(1,0); t1=Pop(); i=convert_link(t1,obj,code); if(i!=0xFFFF) execute_program(classes[i>>16]->codes,i&0xFFFF,obj); break;


    case OP_FINISHED: StackReq(0,1); Push(NVALUE(all_flushed)); break;
    case OP_FINISHED_E: StackReq(1,0); t1=Pop(); Numeric(t1); all_flushed=t1.u; break;
    case OP_FLIP: v_flip(); break;
    case OP_FLUSHCLASS: NoIgnore(); StackReq(1,0); t1=Pop(); if(t1.t==TY_CLASS) flush_class(t1.u); else if(t1.t==TY_NUMBER && t1.s==-1) flush_all(); else if(t1.t) Throw("Type mismatch"); break;
    case OP_FLUSHOBJ: NoIgnore(); flush_object(obj); break;
    case OP_FLUSHOBJ_C: NoIgnore(); StackReq(1,0); i=v_object(Pop()); if(i!=VOIDLINK) flush_object(i); break;
    case OP_FOR: NoIgnore(); StackReq(3,1); t3=Pop(); t2=Pop(); t1=Pop(); ptr=v_for(code,ptr,t1,t2,t3); break;







>
>







2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
    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;
    case OP_EQ2: StackReq(4,1); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t3)?(v_equal(t2,t4)?1:0):0)); break;
    case OP_EXEC: StackReq(1,0); t1=Pop(); i=convert_link(t1,obj,code); if(i==0xFFFF) return; code=classes[i>>16]->codes; ptr=i&0xFFFF; break;
    case OP_EXEC_C: StackReq(1,0); t1=Pop(); i=convert_link(t1,obj,code); if(i!=0xFFFF) execute_program(classes[i>>16]->codes,i&0xFFFF,obj); break;
    case OP_FAKEMOVE: NoIgnore(); StackReq(1,1); t1=Pop(); Numeric(t1); Push(NVALUE(fake_move_dir(obj,resolve_dir(obj,t1.u),0))); break;
    case OP_FAKEMOVE_C: NoIgnore(); StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else Push(NVALUE(fake_move_dir(i,resolve_dir(i,t1.u),0))); break;
    case OP_FINISHED: StackReq(0,1); Push(NVALUE(all_flushed)); break;
    case OP_FINISHED_E: StackReq(1,0); t1=Pop(); Numeric(t1); all_flushed=t1.u; break;
    case OP_FLIP: v_flip(); break;
    case OP_FLUSHCLASS: NoIgnore(); StackReq(1,0); t1=Pop(); if(t1.t==TY_CLASS) flush_class(t1.u); else if(t1.t==TY_NUMBER && t1.s==-1) flush_all(); else if(t1.t) Throw("Type mismatch"); break;
    case OP_FLUSHOBJ: NoIgnore(); flush_object(obj); break;
    case OP_FLUSHOBJ_C: NoIgnore(); StackReq(1,0); i=v_object(Pop()); if(i!=VOIDLINK) flush_object(i); break;
    case OP_FOR: NoIgnore(); StackReq(3,1); t3=Pop(); t2=Pop(); t1=Pop(); ptr=v_for(code,ptr,t1,t2,t3); break;
2946
2947
2948
2949
2950
2951
2952

2953
2954
2955
2956
2957
2958
2959
  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;







>







3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
  clear_inventory();
  for(i=0;i<nlevelstrings;i++) free(levelstrings[i]);
  nlevelstrings=0;
  free(deadanim);
  deadanim=0;
  ndeadanim=0;
  control_obj=VOIDLINK;
  nconn=pconn=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;

Modified game.c from [73bec037e1] to [145146cd02].

377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395



396
397
398
399
400
401
402
  }
}

static inline void exam_flags(int y,Uint16 v) {
  y=(y-exam_scroll)*8;
  if(y<0 || y>screen->h-8) return;
  draw_text(0,y,"Flags:",0xF0,0xF7);
  draw_text(200,y,"--- --- --- --- --- --- --- --- --- --- ---",0xF0,0xF8);
  if(v&OF_INVISIBLE) draw_text(200,y,"Inv",0xF0,0xFF);
  if(v&OF_VISUALONLY) draw_text(232,y,"Vis",0xF0,0xFF);
  if(v&OF_STEALTHY) draw_text(264,y,"Stl",0xF0,0xFF);
  if(v&OF_BUSY) draw_text(296,y,"Bus",0xF0,0xFF);
  if(v&OF_USERSTATE) draw_text(328,y,"Ust",0xF0,0xFF);
  if(v&OF_USERSIGNAL) draw_text(360,y,"Usg",0xF0,0xFF);
  if(v&OF_MOVED) draw_text(392,y,"Mov",0xF0,0xFF);
  if(v&OF_DONE) draw_text(424,y,"Don",0xF0,0xFF);
  if(v&OF_KEYCLEARED) draw_text(456,y,"Key",0xF0,0xFF);
  if(v&OF_DESTROYED) draw_text(488,y,"Des",0xF0,0xFF);
  if(v&OF_BIZARRO) draw_text(520,y,"Biz",0xF0,0xFF);



}

static inline void exam_hardsharp(const char*t,int y,Uint16*v) {
  int i;
  char buf[16];
  y=(y-exam_scroll)*8;
  if(y<0 || y>screen->h-8) return;







|











>
>
>







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
  }
}

static inline void exam_flags(int y,Uint16 v) {
  y=(y-exam_scroll)*8;
  if(y<0 || y>screen->h-8) return;
  draw_text(0,y,"Flags:",0xF0,0xF7);
  draw_text(200,y,"--- --- --- --- --- --- --- --- --- --- --- --- --- ---",0xF0,0xF8);
  if(v&OF_INVISIBLE) draw_text(200,y,"Inv",0xF0,0xFF);
  if(v&OF_VISUALONLY) draw_text(232,y,"Vis",0xF0,0xFF);
  if(v&OF_STEALTHY) draw_text(264,y,"Stl",0xF0,0xFF);
  if(v&OF_BUSY) draw_text(296,y,"Bus",0xF0,0xFF);
  if(v&OF_USERSTATE) draw_text(328,y,"Ust",0xF0,0xFF);
  if(v&OF_USERSIGNAL) draw_text(360,y,"Usg",0xF0,0xFF);
  if(v&OF_MOVED) draw_text(392,y,"Mov",0xF0,0xFF);
  if(v&OF_DONE) draw_text(424,y,"Don",0xF0,0xFF);
  if(v&OF_KEYCLEARED) draw_text(456,y,"Key",0xF0,0xFF);
  if(v&OF_DESTROYED) draw_text(488,y,"Des",0xF0,0xFF);
  if(v&OF_BIZARRO) draw_text(520,y,"Biz",0xF0,0xFF);
  if(v&OF_CONNECTION) draw_text(552,y,"Con",0xF0,0xFF);
  if(v&OF_MOVING) draw_text(584,y,"Mvi",0xF0,0xFF);
  if(v&OF_ORDERED) draw_text(616,y,"Ord",0xF0,0xFF);
}

static inline void exam_hardsharp(const char*t,int y,Uint16*v) {
  int i;
  char buf[16];
  y=(y-exam_scroll)*8;
  if(y<0 || y>screen->h-8) return;

Modified heromesh.h from [db1c986fad] to [3ad0961a68].

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#define CVALUE(x) UVALUE(x,TY_CLASS)
#define MVALUE(x) UVALUE(x,TY_MESSAGE)
#define ZVALUE(x) UVALUE(x,TY_STRING)
#define OVALUE(x) ((x)==VOIDLINK?NVALUE(0):UVALUE(x,objects[x]->generation))
#define ValueTo64(v) (((sqlite3_int64)((v).u))|(((sqlite3_int64)((v).t))<<32))
#define ValueEq(x,y) ((x).t==(y).t && (x).u==(y).u)

#define N_MESSAGES 25
extern const char*const standard_message_names[];
extern const char*const standard_sound_names[];
extern const char*const heromesh_key_names[256];

extern sqlite3*userdb;
extern xrm_db*resourcedb;
extern const char*basefilename;







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#define CVALUE(x) UVALUE(x,TY_CLASS)
#define MVALUE(x) UVALUE(x,TY_MESSAGE)
#define ZVALUE(x) UVALUE(x,TY_STRING)
#define OVALUE(x) ((x)==VOIDLINK?NVALUE(0):UVALUE(x,objects[x]->generation))
#define ValueTo64(v) (((sqlite3_int64)((v).u))|(((sqlite3_int64)((v).t))<<32))
#define ValueEq(x,y) ((x).t==(y).t && (x).u==(y).u)

#define N_MESSAGES 26
extern const char*const standard_message_names[];
extern const char*const standard_sound_names[];
extern const char*const heromesh_key_names[256];

extern sqlite3*userdb;
extern xrm_db*resourcedb;
extern const char*basefilename;
145
146
147
148
149
150
151

152
153
154
155
156
157
158
#define OF_DONE 0x0080
#define OF_KEYCLEARED 0x0100
#define OF_DESTROYED 0x0200
#define OF_BIZARRO 0x0400
#define OF_MOVED2 0x0800
#define OF_MOVING 0x1000
#define OF_ORDERED 0x2000


typedef struct {
  const char*name;
  const char*edithelp; // not present if CF_GROUP
  const char*gamehelp; // not present if CF_GROUP
  Uint16*codes;
  Uint16*messages; // use 0xFFFF if no such message block







>







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#define OF_DONE 0x0080
#define OF_KEYCLEARED 0x0100
#define OF_DESTROYED 0x0200
#define OF_BIZARRO 0x0400
#define OF_MOVED2 0x0800
#define OF_MOVING 0x1000
#define OF_ORDERED 0x2000
#define OF_CONNECTION 0x4000

typedef struct {
  const char*name;
  const char*edithelp; // not present if CF_GROUP
  const char*gamehelp; // not present if CF_GROUP
  Uint16*codes;
  Uint16*messages; // use 0xFFFF if no such message block
299
300
301
302
303
304
305

306
307
308
309
310
311
312
extern unsigned char**levelstrings;
extern Uint16 nlevelstrings;
extern Value*array_data;
extern Uint16 ndeadanim;
extern DeadAnimation*deadanim;
extern Uint8 no_dead_anim;
extern Uint32 max_trigger;


const unsigned char*value_string_ptr(Value v);
void pfunlink(Uint32 n);
void pflink(Uint32 n);
Uint32 objalloc(Uint16 c);
void objtrash(Uint32 n);
void annihilate(void);







>







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
extern unsigned char**levelstrings;
extern Uint16 nlevelstrings;
extern Value*array_data;
extern Uint16 ndeadanim;
extern DeadAnimation*deadanim;
extern Uint8 no_dead_anim;
extern Uint32 max_trigger;
extern Uint8 conn_option;

const unsigned char*value_string_ptr(Value v);
void pfunlink(Uint32 n);
void pflink(Uint32 n);
Uint32 objalloc(Uint16 c);
void objtrash(Uint32 n);
void annihilate(void);

Modified instruc from [87ecbf7c86] to [9a205534d1].

181
182
183
184
185
186
187

188
189
190
191
192
193
194
,=UserSignal
,=UserState
,=VisualOnly
,=Stealthy
,=Moved
,=Moving
,=Done

,Destroyed
,Player
,Compatible
,CollisionLayers
Self
Msg
From







>







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
,=UserSignal
,=UserState
,=VisualOnly
,=Stealthy
,=Moved
,=Moving
,=Done
,=Connection
,Destroyed
,Player
,Compatible
,CollisionLayers
Self
Msg
From
229
230
231
232
233
234
235

236
237
238
239
240

241
242
243
244
245
246
247
BroadcastList ; Broadcast, pushing results to stack
BroadcastListEx
BroadcastSum ; Broadcast, but result is sum of return values
BroadcastSumEx
chain
,Chebyshev
,Coloc

.Create
Data
DelInventory
Delta
.,Destroy

FlushClass
,FlushObj
GetInventory
HeightAt
HitMe
IgnoreKey
.,IntMove ; move without initializing Inertia







>





>







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
BroadcastList ; Broadcast, pushing results to stack
BroadcastListEx
BroadcastSum ; Broadcast, but result is sum of return values
BroadcastSumEx
chain
,Chebyshev
,Coloc
,Connect
.Create
Data
DelInventory
Delta
.,Destroy
,FakeMove
FlushClass
,FlushObj
GetInventory
HeightAt
HitMe
IgnoreKey
.,IntMove ; move without initializing Inertia

Modified instruc.h from [7d4bbe3ce8] to [bdabcd4ee7].

263
264
265
266
267
268
269




270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327


328
329
330
331
332
333
334
335
336


337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535
536


537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
#define OP_MOVING_C 34934
#define OP_MOVING_E 36982
#define OP_MOVING_EC 39030
#define OP_DONE 32887
#define OP_DONE_C 34935
#define OP_DONE_E 36983
#define OP_DONE_EC 39031




#define OP_DESTROYED 32888
#define OP_DESTROYED_C 34936
#define OP_PLAYER 32889
#define OP_PLAYER_C 34937
#define OP_COMPATIBLE 32890
#define OP_COMPATIBLE_C 34938
#define OP_COLLISIONLAYERS 32891
#define OP_COLLISIONLAYERS_C 34939
#define OP_SELF 32892
#define OP_MSG 32893
#define OP_FROM 32894
#define OP_ARG1 32895
#define OP_ARG1_E 36991
#define OP_ARG2 32896
#define OP_ARG2_E 36992
#define OP_ARG3 32897
#define OP_ARG3_E 36993
#define OP_MOVENUMBER 32898
#define OP_MOVENUMBER_E 36994
#define OP_LEVEL 32899
#define OP_KEY 32900
#define OP_FINISHED 32901
#define OP_FINISHED_E 36997
#define OP_BACKGROUND 32902
#define OP_CODEPAGE 32903
#define OP_ORDER 32904
#define OP_CONTROL 32905
#define OP_LEVELTABLE 32906
#define OP_INPUT 32907
#define OP_QUIZ 32908
#define OP_INPLACE 32909
#define OP_DEFAULTIMAGE 32910
#define OP_HELP 32911
#define OP_EDITORHELP 32912
#define OP_OTHERS 32913
#define OP_SUBS 32914
#define OP_ANIMATE 32915
#define OP_ANIMATE_E 37011
#define OP_ANIMATEDEAD 32916
#define OP_ANIMATEDEAD_E 37012
#define OP_ASSASSINATE 32917
#define OP_ASSASSINATE_C 34965
#define OP_BROADCAST 32918
#define OP_BROADCAST_D 41110
#define OP_BROADCASTAND 32919
#define OP_BROADCASTANDEX 32920
#define OP_BROADCASTCLASS 32921
#define OP_BROADCASTEX 32922
#define OP_BROADCASTEX_D 41114
#define OP_BROADCASTLIST 32923
#define OP_BROADCASTLISTEX 32924
#define OP_BROADCASTSUM 32925
#define OP_BROADCASTSUMEX 32926
#define OP_CHAIN 32927
#define OP_CHEBYSHEV 32928
#define OP_CHEBYSHEV_C 34976
#define OP_COLOC 32929
#define OP_COLOC_C 34977


#define OP_CREATE 32930
#define OP_CREATE_D 41122
#define OP_DATA 32931
#define OP_DELINVENTORY 32932
#define OP_DELTA 32933
#define OP_DESTROY 32934
#define OP_DESTROY_C 34982
#define OP_DESTROY_D 41126
#define OP_DESTROY_CD 43174


#define OP_FLUSHCLASS 32935
#define OP_FLUSHOBJ 32936
#define OP_FLUSHOBJ_C 34984
#define OP_GETINVENTORY 32937
#define OP_HEIGHTAT 32938
#define OP_HITME 32939
#define OP_IGNOREKEY 32940
#define OP_INTMOVE 32941
#define OP_INTMOVE_C 34989
#define OP_INTMOVE_D 41133
#define OP_INTMOVE_CD 43181
#define OP_JUMPTO 32942
#define OP_JUMPTO_C 34990
#define OP_JUMPTO_D 41134
#define OP_JUMPTO_CD 43182
#define OP_LOC 32943
#define OP_LOC_C 34991
#define OP_LOCATEME 32944
#define OP_LOCATEME_C 34992
#define OP_LOSELEVEL 32945
#define OP_MANHATTAN 32946
#define OP_MANHATTAN_C 34994
#define OP_MAXINVENTORY 32947
#define OP_MOVE 32948
#define OP_MOVE_C 34996
#define OP_MOVE_D 41140
#define OP_MOVE_CD 43188
#define OP_MOVEPLUS 32949
#define OP_MOVEPLUS_C 34997
#define OP_MOVEPLUS_D 41141
#define OP_MOVEPLUS_CD 43189
#define OP_MOVETO 32950
#define OP_MOVETO_C 34998
#define OP_MOVETO_D 41142
#define OP_MOVETO_CD 43190
#define OP_PLUSMOVE 32951
#define OP_PLUSMOVE_C 34999
#define OP_PLUSMOVE_D 41143
#define OP_PLUSMOVE_CD 43191
#define OP_MINUSMOVE 32952
#define OP_MINUSMOVE_C 35000
#define OP_MINUSMOVE_D 41144
#define OP_MINUSMOVE_CD 43192
#define OP_NEWX 32953
#define OP_NEWXY 32954
#define OP_NEWY 32955
#define OP_OBJABOVE 32956
#define OP_OBJABOVE_C 35004
#define OP_OBJBELOW 32957
#define OP_OBJBELOW_C 35005
#define OP_OBJBOTTOMAT 32958
#define OP_OBJCLASSAT 32959
#define OP_OBJDIR 32960
#define OP_OBJDIR_C 35008
#define OP_OBJLAYERAT 32961
#define OP_OBJMOVINGTO 32962
#define OP_OBJTOPAT 32963
#define OP_POPUP 32964
#define OP_POPUPARGS 32965
#define OP_REL 32966
#define OP_REL_C 35014
#define OP_SEEK 32967
#define OP_SEEK_C 35015
#define OP_SEND 32968
#define OP_SEND_C 35016
#define OP_SEND_D 41160
#define OP_SEND_CD 43208
#define OP_SENDEX 32969
#define OP_SENDEX_C 35017
#define OP_SENDEX_D 41161
#define OP_SENDEX_CD 43209
#define OP_SETINVENTORY 32970
#define OP_SOUND 32971
#define OP_SWEEP 32972
#define OP_SWEEPEX 32973
#define OP_SYNCHRONIZE 32974
#define OP_TARGET 32975
#define OP_TARGET_C 35023
#define OP_TRACE 32976
#define OP_TRIGGER 32977
#define OP_TRIGGERAT 32978
#define OP_VOLUMEAT 32979
#define OP_WINLEVEL 32980
#define OP_XDIR 32981
#define OP_XDIR_C 35029
#define OP_XYDIR 32982
#define OP_YDIR 32983
#define OP_YDIR_C 35031
#define OP_MARK 32984
#define OP_TMARK 32985
#define OP_IN 32986
#define OP_NIN 32987
#define OP_MBEGIN 32988
#define OP_FLIP 32989
#define OP_COUNT 32990
#define OP_CLEAR 32991
#define OP_UNIQ 32992
#define OP_ARRAY 32993
#define OP_GETARRAY 32994
#define OP_INITARRAY 32995
#define OP_SETARRAY 32996
#define OP_ARRAYCELL 32997
#define OP_ARRAYSLICE 32998
#define OP_COPYARRAY 32999
#define OP_DOTPRODUCT 33000
#define OP_PATTERN 33001
#define OP_PATTERN_C 35049
#define OP_PATTERN_E 37097
#define OP_PATTERN_EC 39145
#define OP_PATTERNS 33002
#define OP_PATTERNS_C 35050
#define OP_PATTERNS_E 37098
#define OP_PATTERNS_EC 39146
#define OP_ROOK 33003
#define OP_BISHOP 33004
#define OP_QUEEN 33005
#define OP_CUT 33006
#define OP_BIZARRO 33007
#define OP_BIZARRO_C 35055
#define OP_BIZARRO_E 37103
#define OP_BIZARRO_EC 39151
#define OP_BIZARROSWAP 33008
#define OP_BIZARROSWAP_D 41200
#define OP_SWAPWORLD 33009
#define OP_ABSTRACT 33010
#define OP_SUPER 33011
#define OP_SUPER_C 35059
#define OP_FUNCTION 33012
#define OP_LOCAL 33013
#define OP_LABEL 33014
#define OP_STRING 33015
#define OP_INT16 33016
#define OP_INT32 33017
#define OP_DISPATCH 33018
#define OP_USERFLAG 33019
#ifdef HEROMESH_CLASS
static const Op_Names op_names[]={
{"*",8486943},
{"+",8421405},
{"+Move",10584247},
{"-",8421406},
{"-Move",10584248},
{"-rot",8421382},
{".",10518528},
{"/",8486944},
{"ANHH",8389394},
{"ARRIVED",8389124},
{"Abstract",8683762},
{"Animate",8552595},
{"AnimateDead",8552596},
{"Arg1",8552575},
{"Arg2",8552576},
{"Arg3",8552577},
{"Array",8683745},
{"ArrayCell",8421605},
{"ArraySlice",8421606},
{"Arrivals",8618092},
{"Arrived",8618090},
{"Assassinate",8487061},
{"B",9437196},
{"BANG",8389380},
{"BEDOINGNG",8389406},
{"BEEDEEP",8389404},
{"BEGIN_TURN",8389123},
{"BLOCKED",8389144},
{"BOOOM",8389410},
{"BOUNCE",8389415},
{"BRRREEET",8389396},
{"BRRRT",8389395},
{"BUZZER",8389420},
{"BWEEP",8389397},
{"Background",8683654},
{"Bishop",8683756},
{"Bizarro",8618223},
{"BizarroSwap",10518768},
{"Broadcast",10518678},
{"BroadcastAnd",8421527},
{"BroadcastAndEx",8421528},
{"BroadcastEx",10518682},
{"BroadcastList",8421531},
{"BroadcastListEx",8421532},
{"BroadcastSum",8421533},
{"BroadcastSumEx",8421534},
{"Busy",8618094},
{"CHEEP",8389393},
{"CHYEW",8389392},
{"CLICK",8389388},
{"COLLIDE",8389142},
{"COLLIDEBY",8389141},
{"COLLIDING",8389143},
{"CONFLICT",8389140},

{"CREATE",8389121},
{"CREATED",8389137},
{"Chebyshev",8487072},
{"Class",8486976},
{"Climb",9142356},
{"CodePage",8683655},
{"CollisionLayers",8487035},
{"Coloc",8487073},
{"Compatible",8487034},


{"Control",8421513},
{"CopyArray",8421607},
{"Create",10518690},
{"DEEP_POP",8389417},
{"DEPARTED",8389125},
{"DESTROY",8389122},
{"DESTROYED",8389136},
{"DINK",8389390},
{"DOOR",8389378},
{"DRLRLRINK",8389398},
{"DYUPE",8389413},
{"Data",8421539},
{"DefaultImage",8683662},
{"DelInventory",8421540},
{"Delta",8421541},
{"Density",9142348},
{"Departed",8618091},
{"Departures",8618093},
{"Destroy",10584230},
{"Destroyed",8487032},
{"Dir",8618054},
{"Distance",9142346},
{"Done",8618103},
{"DotProduct",8421608},
{"E",9437184},
{"END_TURN",8389139},
{"EditorHelp",8683664},
{"F",9437192},
{"FAROUT",8389421},
{"FFFFTT",8389399},
{"FLOATED",8389132},
{"FROG",8389383},

{"Finished",8552581},
{"FlushClass",8421543},
{"FlushObj",8487080},
{"From",8421502},
{"GLASS",8389379},
{"GLISSANT",8389419},
{"GetArray",8421602},
{"GetInventory",8421545},
{"HAWK",8389425},
{"HEARTBEAT",8389407},
{"HIT",8389134},
{"HITBY",8389135},
{"Hard",8618072},
{"Height",9142354},
{"HeightAt",8421546},
{"Help",8683663},
{"HitMe",8421547},
{"INIT",8389120},
{"IgnoreKey",8421548},
{"Image",8618055},
{"InPlace",8683661},
{"Inertia",9142344},
{"InitArray",8421603},
{"Input",8683659},
{"IntMove",10584237},
{"Invisible",8618095},
{"JAYAYAYNG",8389416},
{"JUMPED",8389128},
{"JumpTo",10584238},
{"KEWEL",8389422},
{"KEY",8389129},
{"KLECK",8389387},
{"KLINKK",8389385},
{"Key",8421508},
{"KeyCleared",8618096},
{"L",9437194},
{"LASTIMAGE",8389126},
{"LB",9437195},
{"LF",9437193},
{"LOCK",8389408},
{"LOOP",8388610},
{"Level",8421507},
{"LevelTable",8683658},
{"Loc",8487087},
{"LocateMe",8487088},
{"LoseLevel",8421553},
{"MOVED",8389127},
{"MOVING",8389130},
{"Manhattan",8487090},
{"MaxInventory",8421555},
{"Misc1",9142364},
{"Misc2",9142366},
{"Misc3",9142368},
{"Misc4",9142370},
{"Misc5",9142372},
{"Misc6",9142374},
{"Misc7",9142376},
{"Move",10584244},
{"Move+",10584245},
{"MoveNumber",8552578},
{"MoveTo",10584246},
{"Moved",8618101},
{"Moving",8618102},
{"Msg",8421501},
{"N",9437186},
{"NE",9437185},
{"NW",9437187},
{"NewX",8421561},
{"NewXY",8421562},
{"NewY",8421563},
{"OLDPHONE",8389402},
{"ONCE",8388609},
{"OSC",8388616},
{"OSCLOOP",8388618},
{"ObjAbove",8487100},
{"ObjBelow",8487101},
{"ObjBottomAt",8421566},
{"ObjClassAt",8421567},
{"ObjDir",8487104},
{"ObjLayerAt",8421569},
{"ObjMovingTo",8421570},
{"ObjTopAt",8421571},
{"Order",8683656},
{"Others",8683665},
{"P",8880361},
{"P*",8880362},
{"PLAYERMOVING",8389133},
{"POSTINIT",8389138},
{"POUR",8389377},
{"POWER",8389386},
{"Player",8487033},
{"PopUp",8421572},
{"Queen",8683757},
{"Quiz",8683660},
{"R",9437198},
{"RATCHET1",8389418},
{"RATCHET2",8389412},
{"RATTLE",8389403},
{"RB",9437197},
{"RF",9437199},
{"Rel",8487110},
{"Rook",8683755},
{"S",9437190},
{"SE",9437191},
{"SMALL_POP",8389389},
{"SPLASH",8389376},
{"STEAM",8389424},
{"STOP",8388608},
{"SUBS",8683666},
{"SUNK",8389131},
{"SW",9437189},
{"Seek",8487111},
{"Self",8421500},
{"Send",10584264},
{"SendEx",10584265},
{"SetArray",8421604},
{"SetInventory",8421578},
{"Shape",8618051},
{"ShapeDir",8618074},
{"Sharp",8618073},
{"Shovable",8618075},
{"Sound",8421579},
{"Stealthy",8618100},
{"Strength",9142358},
{"Super",8487155},
{"SwapWorld",8421617},
{"Sweep",8421580},
{"SweepEx",8421581},
{"Synchronize",8421582},
{"TAHTASHH",8389409},
{"THMP_thmp",8389405},
{"THWIT",8389384},
{"TICK",8389391},
{"Target",8487119},
{"Temperature",9142337},
{"Trace",8421584},
{"Trigger",8421585},
{"TriggerAt",8421586},
{"UH_OH",8389382},
{"UNCORK",8389414},
{"UNHH",8389381},
{"UserSignal",8618097},
{"UserState",8618098},
{"VACUUM",8389411},
{"VisualOnly",8618099},
{"Volume",9142350},
{"VolumeAt",8421587},
{"W",9437188},
{"WAHOO",8389400},
{"WHACK",8389423},
{"Weight",9142352},
{"WinLevel",8421588},
{"XDir",8487125},
{"XYDir",8421590},
{"Xloc",8486980},
{"YDir",8487127},
{"YEEHAW",8389401},
{"Yloc",8486981},
{"_",8421592},
{"a?",8421439},
{"again",8683533},
{"and",8683544},
{"band",8421415},
{"begin",8683532},
{"bit",8683563},
{"bit0",8388609},







>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|
|
|
|
|
|
|
|
|
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|

|





|
|
|
|
|
|
|
|
|


|












|
|
|
|
|
|
|
|
|
|
|
|








>


|


|
|
|
|
>
>
|
|
|








|
|
|
|



|
|



|


|





>
|
|
|
|


|
|






|
|
|

|

|

|
|
|



|




|







|
|
|
|
|


|
|







|
|
|
|


|



|
|
|




|
|
|
|
|
|
|
|
|
|
|
|




|
|
|
|






|
|






|


|
|
|
|
|
|




|


|
|
|
|
|




|

|
|
|








|




|
|
|

|


|







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
#define OP_MOVING_C 34934
#define OP_MOVING_E 36982
#define OP_MOVING_EC 39030
#define OP_DONE 32887
#define OP_DONE_C 34935
#define OP_DONE_E 36983
#define OP_DONE_EC 39031
#define OP_CONNECTION 32888
#define OP_CONNECTION_C 34936
#define OP_CONNECTION_E 36984
#define OP_CONNECTION_EC 39032
#define OP_DESTROYED 32889
#define OP_DESTROYED_C 34937
#define OP_PLAYER 32890
#define OP_PLAYER_C 34938
#define OP_COMPATIBLE 32891
#define OP_COMPATIBLE_C 34939
#define OP_COLLISIONLAYERS 32892
#define OP_COLLISIONLAYERS_C 34940
#define OP_SELF 32893
#define OP_MSG 32894
#define OP_FROM 32895
#define OP_ARG1 32896
#define OP_ARG1_E 36992
#define OP_ARG2 32897
#define OP_ARG2_E 36993
#define OP_ARG3 32898
#define OP_ARG3_E 36994
#define OP_MOVENUMBER 32899
#define OP_MOVENUMBER_E 36995
#define OP_LEVEL 32900
#define OP_KEY 32901
#define OP_FINISHED 32902
#define OP_FINISHED_E 36998
#define OP_BACKGROUND 32903
#define OP_CODEPAGE 32904
#define OP_ORDER 32905
#define OP_CONTROL 32906
#define OP_LEVELTABLE 32907
#define OP_INPUT 32908
#define OP_QUIZ 32909
#define OP_INPLACE 32910
#define OP_DEFAULTIMAGE 32911
#define OP_HELP 32912
#define OP_EDITORHELP 32913
#define OP_OTHERS 32914
#define OP_SUBS 32915
#define OP_ANIMATE 32916
#define OP_ANIMATE_E 37012
#define OP_ANIMATEDEAD 32917
#define OP_ANIMATEDEAD_E 37013
#define OP_ASSASSINATE 32918
#define OP_ASSASSINATE_C 34966
#define OP_BROADCAST 32919
#define OP_BROADCAST_D 41111
#define OP_BROADCASTAND 32920
#define OP_BROADCASTANDEX 32921
#define OP_BROADCASTCLASS 32922
#define OP_BROADCASTEX 32923
#define OP_BROADCASTEX_D 41115
#define OP_BROADCASTLIST 32924
#define OP_BROADCASTLISTEX 32925
#define OP_BROADCASTSUM 32926
#define OP_BROADCASTSUMEX 32927
#define OP_CHAIN 32928
#define OP_CHEBYSHEV 32929
#define OP_CHEBYSHEV_C 34977
#define OP_COLOC 32930
#define OP_COLOC_C 34978
#define OP_CONNECT 32931
#define OP_CONNECT_C 34979
#define OP_CREATE 32932
#define OP_CREATE_D 41124
#define OP_DATA 32933
#define OP_DELINVENTORY 32934
#define OP_DELTA 32935
#define OP_DESTROY 32936
#define OP_DESTROY_C 34984
#define OP_DESTROY_D 41128
#define OP_DESTROY_CD 43176
#define OP_FAKEMOVE 32937
#define OP_FAKEMOVE_C 34985
#define OP_FLUSHCLASS 32938
#define OP_FLUSHOBJ 32939
#define OP_FLUSHOBJ_C 34987
#define OP_GETINVENTORY 32940
#define OP_HEIGHTAT 32941
#define OP_HITME 32942
#define OP_IGNOREKEY 32943
#define OP_INTMOVE 32944
#define OP_INTMOVE_C 34992
#define OP_INTMOVE_D 41136
#define OP_INTMOVE_CD 43184
#define OP_JUMPTO 32945
#define OP_JUMPTO_C 34993
#define OP_JUMPTO_D 41137
#define OP_JUMPTO_CD 43185
#define OP_LOC 32946
#define OP_LOC_C 34994
#define OP_LOCATEME 32947
#define OP_LOCATEME_C 34995
#define OP_LOSELEVEL 32948
#define OP_MANHATTAN 32949
#define OP_MANHATTAN_C 34997
#define OP_MAXINVENTORY 32950
#define OP_MOVE 32951
#define OP_MOVE_C 34999
#define OP_MOVE_D 41143
#define OP_MOVE_CD 43191
#define OP_MOVEPLUS 32952
#define OP_MOVEPLUS_C 35000
#define OP_MOVEPLUS_D 41144
#define OP_MOVEPLUS_CD 43192
#define OP_MOVETO 32953
#define OP_MOVETO_C 35001
#define OP_MOVETO_D 41145
#define OP_MOVETO_CD 43193
#define OP_PLUSMOVE 32954
#define OP_PLUSMOVE_C 35002
#define OP_PLUSMOVE_D 41146
#define OP_PLUSMOVE_CD 43194
#define OP_MINUSMOVE 32955
#define OP_MINUSMOVE_C 35003
#define OP_MINUSMOVE_D 41147
#define OP_MINUSMOVE_CD 43195
#define OP_NEWX 32956
#define OP_NEWXY 32957
#define OP_NEWY 32958
#define OP_OBJABOVE 32959
#define OP_OBJABOVE_C 35007
#define OP_OBJBELOW 32960
#define OP_OBJBELOW_C 35008
#define OP_OBJBOTTOMAT 32961
#define OP_OBJCLASSAT 32962
#define OP_OBJDIR 32963
#define OP_OBJDIR_C 35011
#define OP_OBJLAYERAT 32964
#define OP_OBJMOVINGTO 32965
#define OP_OBJTOPAT 32966
#define OP_POPUP 32967
#define OP_POPUPARGS 32968
#define OP_REL 32969
#define OP_REL_C 35017
#define OP_SEEK 32970
#define OP_SEEK_C 35018
#define OP_SEND 32971
#define OP_SEND_C 35019
#define OP_SEND_D 41163
#define OP_SEND_CD 43211
#define OP_SENDEX 32972
#define OP_SENDEX_C 35020
#define OP_SENDEX_D 41164
#define OP_SENDEX_CD 43212
#define OP_SETINVENTORY 32973
#define OP_SOUND 32974
#define OP_SWEEP 32975
#define OP_SWEEPEX 32976
#define OP_SYNCHRONIZE 32977
#define OP_TARGET 32978
#define OP_TARGET_C 35026
#define OP_TRACE 32979
#define OP_TRIGGER 32980
#define OP_TRIGGERAT 32981
#define OP_VOLUMEAT 32982
#define OP_WINLEVEL 32983
#define OP_XDIR 32984
#define OP_XDIR_C 35032
#define OP_XYDIR 32985
#define OP_YDIR 32986
#define OP_YDIR_C 35034
#define OP_MARK 32987
#define OP_TMARK 32988
#define OP_IN 32989
#define OP_NIN 32990
#define OP_MBEGIN 32991
#define OP_FLIP 32992
#define OP_COUNT 32993
#define OP_CLEAR 32994
#define OP_UNIQ 32995
#define OP_ARRAY 32996
#define OP_GETARRAY 32997
#define OP_INITARRAY 32998
#define OP_SETARRAY 32999
#define OP_ARRAYCELL 33000
#define OP_ARRAYSLICE 33001
#define OP_COPYARRAY 33002
#define OP_DOTPRODUCT 33003
#define OP_PATTERN 33004
#define OP_PATTERN_C 35052
#define OP_PATTERN_E 37100
#define OP_PATTERN_EC 39148
#define OP_PATTERNS 33005
#define OP_PATTERNS_C 35053
#define OP_PATTERNS_E 37101
#define OP_PATTERNS_EC 39149
#define OP_ROOK 33006
#define OP_BISHOP 33007
#define OP_QUEEN 33008
#define OP_CUT 33009
#define OP_BIZARRO 33010
#define OP_BIZARRO_C 35058
#define OP_BIZARRO_E 37106
#define OP_BIZARRO_EC 39154
#define OP_BIZARROSWAP 33011
#define OP_BIZARROSWAP_D 41203
#define OP_SWAPWORLD 33012
#define OP_ABSTRACT 33013
#define OP_SUPER 33014
#define OP_SUPER_C 35062
#define OP_FUNCTION 33015
#define OP_LOCAL 33016
#define OP_LABEL 33017
#define OP_STRING 33018
#define OP_INT16 33019
#define OP_INT32 33020
#define OP_DISPATCH 33021
#define OP_USERFLAG 33022
#ifdef HEROMESH_CLASS
static const Op_Names op_names[]={
{"*",8486943},
{"+",8421405},
{"+Move",10584250},
{"-",8421406},
{"-Move",10584251},
{"-rot",8421382},
{".",10518528},
{"/",8486944},
{"ANHH",8389394},
{"ARRIVED",8389124},
{"Abstract",8683765},
{"Animate",8552596},
{"AnimateDead",8552597},
{"Arg1",8552576},
{"Arg2",8552577},
{"Arg3",8552578},
{"Array",8683748},
{"ArrayCell",8421608},
{"ArraySlice",8421609},
{"Arrivals",8618092},
{"Arrived",8618090},
{"Assassinate",8487062},
{"B",9437196},
{"BANG",8389380},
{"BEDOINGNG",8389406},
{"BEEDEEP",8389404},
{"BEGIN_TURN",8389123},
{"BLOCKED",8389144},
{"BOOOM",8389410},
{"BOUNCE",8389415},
{"BRRREEET",8389396},
{"BRRRT",8389395},
{"BUZZER",8389420},
{"BWEEP",8389397},
{"Background",8683655},
{"Bishop",8683759},
{"Bizarro",8618226},
{"BizarroSwap",10518771},
{"Broadcast",10518679},
{"BroadcastAnd",8421528},
{"BroadcastAndEx",8421529},
{"BroadcastEx",10518683},
{"BroadcastList",8421532},
{"BroadcastListEx",8421533},
{"BroadcastSum",8421534},
{"BroadcastSumEx",8421535},
{"Busy",8618094},
{"CHEEP",8389393},
{"CHYEW",8389392},
{"CLICK",8389388},
{"COLLIDE",8389142},
{"COLLIDEBY",8389141},
{"COLLIDING",8389143},
{"CONFLICT",8389140},
{"CONNECT",8389145},
{"CREATE",8389121},
{"CREATED",8389137},
{"Chebyshev",8487073},
{"Class",8486976},
{"Climb",9142356},
{"CodePage",8683656},
{"CollisionLayers",8487036},
{"Coloc",8487074},
{"Compatible",8487035},
{"Connect",8487075},
{"Connection",8618104},
{"Control",8421514},
{"CopyArray",8421610},
{"Create",10518692},
{"DEEP_POP",8389417},
{"DEPARTED",8389125},
{"DESTROY",8389122},
{"DESTROYED",8389136},
{"DINK",8389390},
{"DOOR",8389378},
{"DRLRLRINK",8389398},
{"DYUPE",8389413},
{"Data",8421541},
{"DefaultImage",8683663},
{"DelInventory",8421542},
{"Delta",8421543},
{"Density",9142348},
{"Departed",8618091},
{"Departures",8618093},
{"Destroy",10584232},
{"Destroyed",8487033},
{"Dir",8618054},
{"Distance",9142346},
{"Done",8618103},
{"DotProduct",8421611},
{"E",9437184},
{"END_TURN",8389139},
{"EditorHelp",8683665},
{"F",9437192},
{"FAROUT",8389421},
{"FFFFTT",8389399},
{"FLOATED",8389132},
{"FROG",8389383},
{"FakeMove",8487081},
{"Finished",8552582},
{"FlushClass",8421546},
{"FlushObj",8487083},
{"From",8421503},
{"GLASS",8389379},
{"GLISSANT",8389419},
{"GetArray",8421605},
{"GetInventory",8421548},
{"HAWK",8389425},
{"HEARTBEAT",8389407},
{"HIT",8389134},
{"HITBY",8389135},
{"Hard",8618072},
{"Height",9142354},
{"HeightAt",8421549},
{"Help",8683664},
{"HitMe",8421550},
{"INIT",8389120},
{"IgnoreKey",8421551},
{"Image",8618055},
{"InPlace",8683662},
{"Inertia",9142344},
{"InitArray",8421606},
{"Input",8683660},
{"IntMove",10584240},
{"Invisible",8618095},
{"JAYAYAYNG",8389416},
{"JUMPED",8389128},
{"JumpTo",10584241},
{"KEWEL",8389422},
{"KEY",8389129},
{"KLECK",8389387},
{"KLINKK",8389385},
{"Key",8421509},
{"KeyCleared",8618096},
{"L",9437194},
{"LASTIMAGE",8389126},
{"LB",9437195},
{"LF",9437193},
{"LOCK",8389408},
{"LOOP",8388610},
{"Level",8421508},
{"LevelTable",8683659},
{"Loc",8487090},
{"LocateMe",8487091},
{"LoseLevel",8421556},
{"MOVED",8389127},
{"MOVING",8389130},
{"Manhattan",8487093},
{"MaxInventory",8421558},
{"Misc1",9142364},
{"Misc2",9142366},
{"Misc3",9142368},
{"Misc4",9142370},
{"Misc5",9142372},
{"Misc6",9142374},
{"Misc7",9142376},
{"Move",10584247},
{"Move+",10584248},
{"MoveNumber",8552579},
{"MoveTo",10584249},
{"Moved",8618101},
{"Moving",8618102},
{"Msg",8421502},
{"N",9437186},
{"NE",9437185},
{"NW",9437187},
{"NewX",8421564},
{"NewXY",8421565},
{"NewY",8421566},
{"OLDPHONE",8389402},
{"ONCE",8388609},
{"OSC",8388616},
{"OSCLOOP",8388618},
{"ObjAbove",8487103},
{"ObjBelow",8487104},
{"ObjBottomAt",8421569},
{"ObjClassAt",8421570},
{"ObjDir",8487107},
{"ObjLayerAt",8421572},
{"ObjMovingTo",8421573},
{"ObjTopAt",8421574},
{"Order",8683657},
{"Others",8683666},
{"P",8880364},
{"P*",8880365},
{"PLAYERMOVING",8389133},
{"POSTINIT",8389138},
{"POUR",8389377},
{"POWER",8389386},
{"Player",8487034},
{"PopUp",8421575},
{"Queen",8683760},
{"Quiz",8683661},
{"R",9437198},
{"RATCHET1",8389418},
{"RATCHET2",8389412},
{"RATTLE",8389403},
{"RB",9437197},
{"RF",9437199},
{"Rel",8487113},
{"Rook",8683758},
{"S",9437190},
{"SE",9437191},
{"SMALL_POP",8389389},
{"SPLASH",8389376},
{"STEAM",8389424},
{"STOP",8388608},
{"SUBS",8683667},
{"SUNK",8389131},
{"SW",9437189},
{"Seek",8487114},
{"Self",8421501},
{"Send",10584267},
{"SendEx",10584268},
{"SetArray",8421607},
{"SetInventory",8421581},
{"Shape",8618051},
{"ShapeDir",8618074},
{"Sharp",8618073},
{"Shovable",8618075},
{"Sound",8421582},
{"Stealthy",8618100},
{"Strength",9142358},
{"Super",8487158},
{"SwapWorld",8421620},
{"Sweep",8421583},
{"SweepEx",8421584},
{"Synchronize",8421585},
{"TAHTASHH",8389409},
{"THMP_thmp",8389405},
{"THWIT",8389384},
{"TICK",8389391},
{"Target",8487122},
{"Temperature",9142337},
{"Trace",8421587},
{"Trigger",8421588},
{"TriggerAt",8421589},
{"UH_OH",8389382},
{"UNCORK",8389414},
{"UNHH",8389381},
{"UserSignal",8618097},
{"UserState",8618098},
{"VACUUM",8389411},
{"VisualOnly",8618099},
{"Volume",9142350},
{"VolumeAt",8421590},
{"W",9437188},
{"WAHOO",8389400},
{"WHACK",8389423},
{"Weight",9142352},
{"WinLevel",8421591},
{"XDir",8487128},
{"XYDir",8421593},
{"Xloc",8486980},
{"YDir",8487130},
{"YEEHAW",8389401},
{"Yloc",8486981},
{"_",8421595},
{"a?",8421439},
{"again",8683533},
{"and",8683544},
{"band",8421415},
{"begin",8683532},
{"bit",8683563},
{"bit0",8388609},
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
{"bit8",8423400},
{"bit9",8423401},
{"bnot",8421418},
{"bor",8421416},
{"bxor",8421417},
{"c?",8421433},
{"case",8683542},
{"chain",8421535},
{"clear",8421599},
{"count",8421598},
{"cut",8683758},
{"cz?",8421434},
{"dup",8421377},
{"else",8683530},
{"eq",8421424},
{"eq2",8421425},
{"exec",8486940},
{"flip",8421597},
{"for",8683537},
{"fork",8683545},
{"ge",8486965},
{"gt",8486963},
{"if",8683529},
{"in",8421594},
{"is",8421431},
{"land",8421420},
{"le",8486966},
{"link",8683547},
{"lnot",8421423},
{"lor",8421421},
{"lsh",8421413},
{"lt",8486964},
{"lxor",8421422},
{"m?",8421435},
{"max",8486948},
{"mbegin",8683740},
{"min",8486947},
{"mod",8486945},
{"n?",8421432},
{"ne",8421426},
{"neg",8421410},
{"next",8683538},
{"nin",8421595},
{"nip",8421379},
{"o?",8421437},
{"or",8683543},
{"over",8421384},
{"oz?",8421438},
{"pick",8421383},
{"repeat",8683536},
{"ret",8421397},
{"rot",8421381},
{"rsh",8486950},
{"rtn",8683546},
{"s?",8421436},
{"swap",8421378},
{"then",8683531},
{"tmark",8421593},
{"tuck",8421380},
{"uniq",8421600},
{"until",8683534},
{"while",8683535},
};
#define N_OP_NAMES 352
#endif







|
|
|
|






|





|











|






|














|

|



|

776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
{"bit8",8423400},
{"bit9",8423401},
{"bnot",8421418},
{"bor",8421416},
{"bxor",8421417},
{"c?",8421433},
{"case",8683542},
{"chain",8421536},
{"clear",8421602},
{"count",8421601},
{"cut",8683761},
{"cz?",8421434},
{"dup",8421377},
{"else",8683530},
{"eq",8421424},
{"eq2",8421425},
{"exec",8486940},
{"flip",8421600},
{"for",8683537},
{"fork",8683545},
{"ge",8486965},
{"gt",8486963},
{"if",8683529},
{"in",8421597},
{"is",8421431},
{"land",8421420},
{"le",8486966},
{"link",8683547},
{"lnot",8421423},
{"lor",8421421},
{"lsh",8421413},
{"lt",8486964},
{"lxor",8421422},
{"m?",8421435},
{"max",8486948},
{"mbegin",8683743},
{"min",8486947},
{"mod",8486945},
{"n?",8421432},
{"ne",8421426},
{"neg",8421410},
{"next",8683538},
{"nin",8421598},
{"nip",8421379},
{"o?",8421437},
{"or",8683543},
{"over",8421384},
{"oz?",8421438},
{"pick",8421383},
{"repeat",8683536},
{"ret",8421397},
{"rot",8421381},
{"rsh",8486950},
{"rtn",8683546},
{"s?",8421436},
{"swap",8421378},
{"then",8683531},
{"tmark",8421596},
{"tuck",8421380},
{"uniq",8421603},
{"until",8683534},
{"while",8683535},
};
#define N_OP_NAMES 356
#endif

Modified names.h from [76542780c7] to [c6fc8993e8].

20
21
22
23
24
25
26

27
28
29
30
31
32
33
#define MSG_POSTINIT 18
#define MSG_END_TURN 19
#define MSG_CONFLICT 20
#define MSG_COLLIDEBY 21
#define MSG_COLLIDE 22
#define MSG_COLLIDING 23
#define MSG_BLOCKED 24

#ifdef HEROMESH_MAIN
const char*const standard_message_names[]={
 "INIT",
 "CREATE",
 "DESTROY",
 "BEGIN_TURN",
 "ARRIVED",







>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#define MSG_POSTINIT 18
#define MSG_END_TURN 19
#define MSG_CONFLICT 20
#define MSG_COLLIDEBY 21
#define MSG_COLLIDE 22
#define MSG_COLLIDING 23
#define MSG_BLOCKED 24
#define MSG_CONNECT 25
#ifdef HEROMESH_MAIN
const char*const standard_message_names[]={
 "INIT",
 "CREATE",
 "DESTROY",
 "BEGIN_TURN",
 "ARRIVED",
47
48
49
50
51
52
53

54
55
56
57
58
59
60
 "POSTINIT",
 "END_TURN",
 "CONFLICT",
 "COLLIDEBY",
 "COLLIDE",
 "COLLIDING",
 "BLOCKED",

};
#endif
#define SND_SPLASH 0
#define SND_POUR 1
#define SND_DOOR 2
#define SND_GLASS 3
#define SND_BANG 4







>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 "POSTINIT",
 "END_TURN",
 "CONFLICT",
 "COLLIDEBY",
 "COLLIDE",
 "COLLIDING",
 "BLOCKED",
 "CONNECT",
};
#endif
#define SND_SPLASH 0
#define SND_POUR 1
#define SND_DOOR 2
#define SND_GLASS 3
#define SND_BANG 4

Modified names.js from [528389457e] to [d3641d4495].

25
26
27
28
29
30
31

32
33
34
35
36
37
38
 19 = END_TURN
 // New
 20 = CONFLICT
 21 = COLLIDEBY
 22 = COLLIDE
 23 = COLLIDING
 24 = BLOCKED

`.split("\n").map(x=>/^ *([0-9]+) = ([^ ]*) *$/.exec(x)).filter(x=>x);
const standard_sound_names=[];
`
 SPLASH
 POUR
 DOOR
 GLASS







>







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 19 = END_TURN
 // New
 20 = CONFLICT
 21 = COLLIDEBY
 22 = COLLIDE
 23 = COLLIDING
 24 = BLOCKED
 25 = CONNECT
`.split("\n").map(x=>/^ *([0-9]+) = ([^ ]*) *$/.exec(x)).filter(x=>x);
const standard_sound_names=[];
`
 SPLASH
 POUR
 DOOR
 GLASS