FieldModelInstruction.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. /*
  2. * Copyright (C) 2022 V-Gears Team
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #pragma once
  18. #include "decompiler/instruction/KernelCallInstruction.h"
  19. #include "decompiler/field/FieldEngine.h"
  20. /**
  21. * A model instruction.
  22. */
  23. class FieldModelInstruction : public KernelCallInstruction{
  24. public:
  25. /**
  26. * Processes the instruction.
  27. *
  28. * @param[in] func Function to process.
  29. * @param[out] stack Function stack.
  30. * @param[in] engine Engine.
  31. * @param[in] code_gen Code generator.
  32. */
  33. virtual void ProcessInst(
  34. Function& func, ValueStack &stack, Engine* engine, CodeGenerator* code_gen
  35. ) override;
  36. private:
  37. /**
  38. * Processes a JOIN opcode.
  39. *
  40. * Opcode: 0x08
  41. * Short name: JOIN
  42. * Long name: Party Field Join
  43. * Memory layout (2 bytes)
  44. * |0x08|S|
  45. *
  46. * Arguments
  47. * - const UByte S: Speed that the characters join back together.
  48. *
  49. * Causes seperated party characters that have previously been SPLIT onto the field, to be
  50. * joined back together again; that is, only the party leader becomes visible on the field.
  51. * This should be called if a previous SPLIT has completed (the party members have finished
  52. * speaking, or performing their actions, for example). As with SPLIT, the speed of the
  53. * join is specified, from a scale of 1 (almost instant) to FF (very slow walk), and must
  54. * be non-zero. In contrast to most MOVE related op codes, the speed is this setting is
  55. * actually the total number of frames required. Depending on the distance from the player
  56. * character and the number of frames required, the entity plays a run or walk animation.
  57. * Also, all characters take the same time irrespective of distance. Calling JOIN without
  58. * having previously SPLIT the characters will cause the party members to appear at the
  59. * walkmesh origin and attempt to JOIN from there. This is not normally the required
  60. * behavior and should be avoided.
  61. *
  62. * @param[in,out] code_gen Code generator to append lines.
  63. */
  64. void ProcessJOIN(CodeGenerator* code_gen);
  65. /**
  66. * Processes a SPLIT opcode.
  67. *
  68. * Opcode: 0x09
  69. * Short name: SPLIT
  70. * Long name: Party Field Split
  71. *
  72. * Memory layout (15 bytes)
  73. * |0x20|B1/B2|B3/B4|B5/B6|XA|XA|YA|YA|DA|XB|XB|YB|YB|DB|S|
  74. *
  75. * Arguments
  76. * - const Bit[4] B1: Bank for XA, or zero if XA is specified as a literal value.
  77. * - const Bit[4] B2: Bank for YA, or zero if YA is specified as a literal value.
  78. * - const Bit[4] B3: Bank for DA, or zero if DA is specified as a literal value.
  79. * - const Bit[4] B4: Bank for XB, or zero if XB is specified as a literal value.
  80. * - const Bit[4] B5: Bank for YB, or zero if YB is specified as a literal value.
  81. * - const Bit[4] B6: Bank for DB, or zero if DB is specified as a literal value.
  82. * - const Short XA: X-coordinate of the second character in the party after the split, or
  83. * address for the value if B1 is non-zero.
  84. * - const Short YA: Y-coordinate of the second character in the party after the split, or
  85. * address for the value if B2 is non-zero.
  86. * - const UByte DA: Direction the second character faces after the split, or address for
  87. * the value if B3 is non-zero.
  88. * - const Short XB: X-coordinate of the third character in the party after the split, or
  89. * address for the value if B4 is non-zero.
  90. * - const Short YB: Y-coordinate of the third character in the party after the split, or
  91. * address for the value if B5 is non-zero.
  92. * - const UByte DB: Direction the third character faces after the split, or address for
  93. * the value if B6 is non-zero.
  94. * - const UByte S: Speed that the characters split.
  95. *
  96. * Causes the common 'split effect' whereby the second and third characters in the current
  97. * party 'come out' from the party leader. That is, they become visible in the field,
  98. * starting from the center of the party leader, and move out to the coordinates specified
  99. * in the argument list. This is commonly used when the other characters in the current
  100. * party have an action or dialog to perform and must be individually visible in the field.
  101. * As well as specifying final coordinates for the two other party characters, the
  102. * directions each character faces after the split are specified as a byte, using the
  103. * common direction values found throughout the game. Speed is also given and is used to
  104. * specify the rate at which the characters leave the party leader, using a scale from 1
  105. * (almost instant) to FF (extremely slow walk); this must be non-zero. In contrast to most
  106. * MOVE related op codes, the speed is this setting is actually the total number of frames
  107. * required. Depending on the distance from the player character and the number of frames
  108. * required, the entity plays a run or walk animation. Also, all characters take the same
  109. * time irrespective of distance.
  110. *
  111. * @param[in,out] code_gen Code generator to append lines.
  112. */
  113. void ProcessSPLIT(CodeGenerator* code_gen);
  114. /**
  115. * Processes a TLKON opcode.
  116. *
  117. * Opcode: 0x7E
  118. * Short name: TLKON
  119. * Long name: Talk Switch
  120. *
  121. * Memory layout (2 bytes)
  122. * |0x7E|S
  123. *
  124. * Arguments:
  125. *
  126. * - const UByte B: Switch on/off (0/1, respectively).
  127. *
  128. * Turns on or off, for an entity, the ability for the playable character to interact with
  129. * the entity by pressing the [X] button. More precisely, this enables or disables the On
  130. * Press script (script 2); if set to off, script 2 will not execute when the button is
  131. * pressed and the player is facing the entity's object. If set to on, the script will
  132. * execute, as normal.
  133. */
  134. void ProcessTLKON(CodeGenerator* code_gen, const std::string& entity);
  135. void ProcessPC(CodeGenerator* code_gen, const std::string& entity, int char_id);
  136. void ProcessCHAR(CodeGenerator* code_gen, const std::string& entity);
  137. void ProcessDFANM(CodeGenerator* code_gen, const std::string& entity, int char_id);
  138. void ProcessANIME1(CodeGenerator* code_gen, const std::string& entity, int char_id);
  139. void ProcessVISI(CodeGenerator* code_gen, const std::string& entity);
  140. void ProcessXYZI(CodeGenerator* code_gen, const std::string& entity);
  141. void ProcessMOVE(CodeGenerator* code_gen, const std::string& entity);
  142. /**
  143. * Processes a MOVA opcode.
  144. *
  145. * Opcode: 0xAA
  146. * Short name: MOVA
  147. * Long name: Move to Entity
  148. *
  149. * Memory layout (2 bytes)
  150. * |0xAA|E|
  151. *
  152. * Walks the model towards the entity with ID E, up to the point where the two touch, and
  153. * waits until it gets there.
  154. *
  155. * @param[in,out] code_gen Code generator to append lines.
  156. * @param[in] entity Name of the entity.
  157. * @param[in] engine Engine, to find the entity.
  158. */
  159. void ProcessMOVA(
  160. CodeGenerator* code_gen, const std::string& entity, const FieldEngine& engine
  161. );
  162. /**
  163. * Processes a TALKR or TLKR2 opcode.
  164. *
  165. * Opcodes: 0xC5 and 0xD6
  166. * Short names: TALKR and TLKR2
  167. * Long names: Talk Range and Talk Range (16-bit)
  168. *
  169. * Sets how far from the model the player can start a conversation with it. It's the same
  170. * for both opcodes, which only differ in the size of the value.
  171. *
  172. * @param[in,out] code_gen Code generator to append lines.
  173. * @param[in] entity Name of the entity.
  174. */
  175. void ProcessTALKR(CodeGenerator* code_gen, const std::string& entity);
  176. /**
  177. * Processes a DIRA opcode.
  178. *
  179. * Opcode: 0xB6
  180. * Short name: DIRA
  181. * Long name: Direction to Entity
  182. *
  183. * Memory layout (2 bytes)
  184. * |0xB6|E|
  185. *
  186. * Turns the model towards the entity with ID E at once.
  187. *
  188. * @param[in,out] code_gen Code generator to append lines.
  189. * @param[in] entity Name of the entity.
  190. * @param[in] engine Engine, to find the entity.
  191. */
  192. void ProcessDIRA(
  193. CodeGenerator* code_gen, const std::string& entity, const FieldEngine& engine
  194. );
  195. /**
  196. * Processes an ASPED opcode.
  197. *
  198. * Opcode: 0xBD
  199. * Short name: ASPED
  200. * Long name: Animation Speed
  201. *
  202. * Sets the speed of all the animations the model plays: 16 is normal speed, 32 is double
  203. * and 8 is half.
  204. *
  205. * @param[in,out] code_gen Code generator to append lines.
  206. * @param[in] entity Name of the entity.
  207. */
  208. void ProcessASPED(CodeGenerator* code_gen, const std::string& entity);
  209. /**
  210. * Processes an ANIME2 opcode.
  211. *
  212. * Plays an animation of the model and goes back to the previous state, without waiting
  213. * for it to end.
  214. *
  215. * @param[in,out] code_gen Code generator to append lines.
  216. * @param[in] entity Name of the entity.
  217. * @param[in] char_id ID of the model, to name the animation.
  218. */
  219. void ProcessANIME2(CodeGenerator* code_gen, const std::string& entity, int char_id);
  220. /**
  221. * Processes an ANIM!1 opcode.
  222. *
  223. * Plays an animation of the model and stops at its last frame, without waiting for it to
  224. * end. It's the non-waiting version of ANIM!2.
  225. *
  226. * @param[in,out] code_gen Code generator to append lines.
  227. * @param[in] entity Name of the entity.
  228. * @param[in] char_id ID of the model, to name the animation.
  229. */
  230. void ProcessANIM_1(CodeGenerator* code_gen, const std::string& entity, int char_id);
  231. /**
  232. * Processes a CANIM1 opcode.
  233. *
  234. * Plays part of an animation and goes back to the previous state, without waiting for it
  235. * to end. It's the non-waiting version of CANIM2.
  236. *
  237. * @param[in,out] code_gen Code generator to append lines.
  238. * @param[in] entity Name of the entity.
  239. * @param[in] char_id ID of the model, to name the animation.
  240. */
  241. void ProcessCANIM1(CodeGenerator* code_gen, const std::string& entity, int char_id);
  242. /**
  243. * Processes a CANM!1 opcode.
  244. *
  245. * Plays part of an animation and stops at its last frame, without waiting for it to end.
  246. * It's the non-waiting version of CANM!2.
  247. *
  248. * @param[in,out] code_gen Code generator to append lines.
  249. * @param[in] entity Name of the entity.
  250. * @param[in] char_id ID of the model, to name the animation.
  251. */
  252. void ProcessCANM_1(CodeGenerator* code_gen, const std::string& entity, int char_id);
  253. /**
  254. * Processes an ANIMW opcode.
  255. *
  256. * Waits for the animation that was played by one of the non-waiting animation opcodes.
  257. *
  258. * @param[in,out] code_gen Code generator to append lines.
  259. * @param[in] entity Name of the entity.
  260. */
  261. void ProcessANIMW(CodeGenerator* code_gen, const std::string& entity);
  262. /**
  263. * Processes an FMOVE opcode.
  264. *
  265. * Opcode: 0xAD
  266. * Short name: FMOVE
  267. *
  268. * Memory layout (6 bytes)
  269. * |0xAD|B1/B2|X|Y|
  270. *
  271. * Moves the entity's model to the position, and waits for it to arrive, like MOVE. The
  272. * animation is the one the script chose, instead of the walking one. The documentation
  273. * for this opcode in the repository is a copy of the one for CMOVE, so this is taken from
  274. * how the scripts use it: they set a running animation, call FMOVE, and then set an idle
  275. * animation.
  276. *
  277. * @param[in,out] code_gen Code generator to append lines.
  278. * @param[in] entity Name of the entity.
  279. */
  280. void ProcessFMOVE(CodeGenerator* code_gen, const std::string& entity);
  281. /**
  282. * Processes a TURA opcode.
  283. *
  284. * Opcode: 0xAB
  285. * Short name: TURA
  286. * Long name: Turn to entity
  287. *
  288. * Memory layout (4 bytes)
  289. * |0xB4|Entity id|Rotate side type|Steps in rotation
  290. *
  291. * Arguments
  292. *
  293. * - const Bit[4] Entity id: Entity id to which model we calculate direction during first
  294. * opcode call.
  295. * - const Short Rotate side type: Specify how model will be rotated. (0 - clockwise/ 1 -
  296. * anti-clockwise/ 2 - closest)
  297. * - const Short Steps in rotation: Set number of steps in rotation.
  298. *
  299. * Rotation calculated like in TUGNGEN, except end direction calculated during first opcode
  300. * call. Rotation always calculated smoothly. Like in TURNGEN(XX,XX,XX,XX,02); This opcode
  301. * will be called until turn is over and then continue script execution.
  302. *
  303. * @param[in,out] code_gen Code generator to append lines.
  304. * @param[in] entity The name of the entity.
  305. * @param[in] engine The field engine.
  306. */
  307. void ProcessTURA(
  308. CodeGenerator* code_gen, const std::string& entity, const FieldEngine& engine
  309. );
  310. void ProcessMSPED(CodeGenerator* code_gen, const std::string& entity);
  311. void ProcessDIR(CodeGenerator* code_gen, const std::string& entity);
  312. void ProcessTURNGEN(CodeGenerator* code_gen, const std::string& entity);
  313. void ProcessGETAI(CodeGenerator* code_gen, const FieldEngine& engine);
  314. void ProcessANIM_2(CodeGenerator* code_gen, const std::string& entity, int char_id);
  315. void ProcessCANIM2(CodeGenerator* code_gen, const std::string& entity, int char_id);
  316. void ProcessCANM_2(CodeGenerator* code_gen, const std::string& entity, int char_id);
  317. void ProcessCC(CodeGenerator* code_gen, const FieldEngine& engine);
  318. /**
  319. * Processes a JUMP opcode.
  320. *
  321. * Opcode: 0xC0
  322. * Short name: JUMP
  323. * Long name: Jump
  324. *
  325. * Memory layout (7 bytes)
  326. * |0xC2|B1/B2|B3/B4|X|Y|I|Steps|
  327. *
  328. * Arguments
  329. * - const Bit[4] B1: Bank to retrieve X-coordinate, or zero if specifying X as a literal.
  330. * - const Bit[4] B2: Bank to retrieve Y-coordinate, or zero if specifying Y as a literal.
  331. * - const Bit[4] B3: Bank to retrieve triangle ID, or zero if specifying Z as a literal.
  332. * - const Bit[4] B4: Bank to retrieve jump height, or zero if specifying H as a literal.
  333. * - const Short X: X-coordinate of the target to jump to, or lower byte specifying address
  334. * if B1 is non-zero.
  335. * - const Short Y: Y-coordinate of the target to jump to, or lower byte specifying address
  336. * if B2 is non-zero.
  337. * - const Short I: Triangle ID of the target to jump to, or lower byte specifying address
  338. * if B3 is non-zero.
  339. * - const UShort Steps: Steps in jump. Must be non-zero if a literal value. Alternatively,
  340. * lower byte specifies address if B4 is non-zero.
  341. *
  342. * Causes the character to jump to the specified point and triangle ID, with the jump curve
  343. * peaking at a height which is increased by using a larger value for the H argument. In
  344. * addition, the larger the number, the longer the jump will take to complete. A "normal"
  345. * value is around 0x15, 0x01 is fast and instantaneous; the argument must not be zero or
  346. * the game will crash. Whilst this is an unsigned two-byte number, a large value (beyond
  347. * around 0x60) will not only cause a vast jump height, but also cause the screen to scroll
  348. * erratically (the larger the number, the more erratic). Main update function go through
  349. * all entity with JUMP state and if stage is 0 it calculates final Z point according to
  350. * triangle id. It sets current coords as start coords. The main thing this function does
  351. * is set B coefficient for later calculation. It defines as follows:
  352. * B = (Z_final - Z_start) / steps - steps * 1.45;
  353. * Then it set current step to 0 and stage to 1. On next update other part of function
  354. * works. It's calculate real position. First it increment current step number. Then it
  355. * calculate X and Y. They change linear so nothing interesting here. The Z calculation is
  356. * as follows:
  357. * Z_current = - step^2 * 1.45 + step * B + Z_start;
  358. * If current substep equal number of steps then we set current triangle to final triangle
  359. * and set stage to 2. Which finalizes the routine on next opcode call. Neither animation
  360. * nor sound is specified in this opcode. An animation is played by using an animation
  361. * opcode such as DFANM, and a SOUND played, before the jump.
  362. *
  363. * @param[in,out] code_gen Code generator to append lines.
  364. * @param[in] entity The name of the entity.
  365. */
  366. void ProcessJUMP(CodeGenerator* code_gen, const std::string& entity);
  367. /**
  368. * Processes a AXYZI opcode
  369. *
  370. * Opcode: 0xC1
  371. * Short name: AXYZI
  372. * Long name: Entity Get Position
  373. *
  374. * Memory layout (8 bytes)
  375. * |0xC1|B1/B2|B3/B4|A|X|Y|Z|I|
  376. *
  377. * Arguments
  378. * - const Bit[4] B1: Bank to store X.
  379. * - const Bit[4] B2: Bank to store Y.
  380. * - const Bit[4] B3: Bank to store Z.
  381. * - const Bit[4] B4: Bank to store I.
  382. * - const UByte A: Entity ID whose field object will have its position retrieved from.
  383. * - const UByte X: Address to store the X-coordinate.
  384. * - const UByte Y: Address to store the Y-coordinate.
  385. * - const UByte Z: Address to store the Z-coordinate.
  386. * - const UByte I: Address to store the ID of the walkmesh triangle the object is standing
  387. * on.
  388. *
  389. * Retrieves the coordinates of the field object that the entity, whose ID specified in A,
  390. * is associated with. This opcode uses an entity ID, not a field object offset; as such,
  391. * if an entity ID is given that does not have a field object, this opcode will store zero
  392. * in each of the four address specified.
  393. *
  394. * @param[in,out] code_gen Code generator to append lines.
  395. */
  396. void ProcessAXYZI(CodeGenerator* code_gen);
  397. /**
  398. * Processes a LADER opcode.
  399. *
  400. * Opcode: 0xC2
  401. * Short name: LADER
  402. * Long name: Ladder
  403. *
  404. * Memory layout (15 bytes)
  405. * |0xC2|B1/B2|B3/B4|X|X|Y|Y|Z|Z|I|I|K|A|D|S|
  406. *
  407. * Arguments
  408. * - const Bit[4] B1: Bank to retrieve X-coordinate, or zero if X is specified as a literal
  409. * value.
  410. * - const Bit[4] B2: Bank to retrieve Y-coordinate, or zero if Y is specified as a literal
  411. * value.
  412. * - const Bit[4] B3: Bank to retrieve Z-coordinate, or zero if Z is specified as a literal
  413. * value.
  414. * - const Bit[4] B4: Bank to retrieve ID, or zero if I is specifiedas a literal value.
  415. * - const Short X: X-coordinate of the end of the ladder, or address to find X-coordinate
  416. * if B1 is non-zero.
  417. * - const Short Y: Y-coordinate of the end of the ladder, or address to find Y-coordinate
  418. * if B2 is non-zero.
  419. * - const Short Z: Z-coordinate of the end of the ladder, or address to find Z-coordinate
  420. * if B3 is non-zero.
  421. * - const UShort I: ID of the walkmesh triangle found at the end of the ladder, or address
  422. * to find ID if B4 is non-zero.
  423. * - const UByte K: The keys used to move the character on the ladder.
  424. * - const UByte A: Animation ID for the field object's movement animation.
  425. * - const UByte D: Direction the character faces when climbing the ladder.
  426. * - const UByte S: Speed of the animation whilst climbing the ladder.
  427. *
  428. * Causes the character to climb a ladder; that is, switching from standard walkmesh
  429. * movement, to climbing along a line connecting two points on the walkmesh. If B1, B2, B3
  430. * or B4 is non-zero, then the value for that particular component is taken from memory
  431. * using the corresponding bank and address specified, rather than as a literal value. Both
  432. * retrieved values and literals can be used for different components. If using X, Y, Z or
  433. * I as addresses, the lower byte should hold the address whilst the higher byte should be
  434. * zero. The coordinates specify the end-point of the ladder; the current position of the
  435. * character is used as the start point. The ID of the walkmesh triangle must be specified;
  436. * this is the triangle the character will step onto after reaching the end point of the
  437. * ladder. The K value specifies the keys used to move the character across the ladder;
  438. * keys outside the range found in the table will cause unpredictable behavior. The
  439. * animation ID specifies an offset into the field object's animation list; this animation
  440. * is played at the speed specified by S whilst the character climbs. Finally, the D
  441. * argument is a direction value in the game's standard direction format, which orients the
  442. * character on the ladder. This opcode is used as part of the character's entity, rather
  443. * than in a separate entity, as with a LINE. A LINE is used to set the start point of
  444. * the ladder on the walkmesh. When this LINE is crossed by the player, a script in the
  445. * LINE then uses a PREQ (or one of its variants), calling the script in the party leader
  446. * that defines the LADER, causing the character to switch to 'climbing mode'. To set up a
  447. * two-way ladder, two LINEs are used at either end, with different values for the LADER
  448. * arguments, such as differing end points. If this opcode is used as part of a
  449. * non-playable character entity, the NPC object will automatically climb from the start to
  450. * the end point without need for player interaction.
  451. *
  452. * @param[in,out] code_gen Code generator to append lines.
  453. * @param[in] entity The name of the entity.
  454. * @param[in] char_id ID of the character model, to name the climbing animation.
  455. */
  456. void ProcessLADER(CodeGenerator* code_gen, const std::string& entity, int char_id);
  457. /**
  458. * Processes an SLIDR opcode.
  459. *
  460. * Opcode: 0xC6
  461. * Short name: SLIDR
  462. * Long name: Solid Range
  463. *
  464. * Memory layout (3 bytes)
  465. * |0xC6|B|R|
  466. *
  467. * Arguments:
  468. *
  469. * - const UByte B: Bank to retrieve R, or zero if R is specified as a literal value.
  470. * - const UByte R: Range value.
  471. *
  472. * Adjusts the range of the collision circle for the entity's field object, changing the
  473. * distance threshold for collisions between the object, and both other objects and the
  474. * walkmesh boundaries. Lower values produce a lower circle for the object; higher values
  475. * increase the circle size.
  476. */
  477. void ProcessSLIDR(CodeGenerator* code_gen, const std::string& entity);
  478. /**
  479. * Processes a SOLID opcode.
  480. *
  481. * Opcode: 0xC7
  482. * Short name: SOLID
  483. * Long name: Solid object
  484. *
  485. * Memory layout (2 bytes)
  486. * |0xC7|S|
  487. *
  488. * Arguments:
  489. *
  490. * const UByte S: Switch on/off (0/1, respectively).
  491. *
  492. * Switches the solidity of the field object associated with this entity; that is, turns
  493. * collision detection on or off. When off, the playable character will be able to walk
  494. * through the entity's object, as if it were not there. This may be used for such objects
  495. * as save points, where the character must be able to walk through the object to be able
  496. * to access the save menu item.
  497. */
  498. void ProcessSOLID(CodeGenerator* code_gen, const std::string& entity);
  499. /**
  500. * Processes an OFST opcode.
  501. *
  502. * Opcode: 0xC3
  503. * Short name: OFST
  504. * Long name: Offset Object
  505. *
  506. * Memory layout (8 bytes)
  507. * |0xC3|B1/B2|B3/B4|T|X|Y|Z|S|
  508. *
  509. * Arguments:
  510. * - const Bit[4] B1: Bank to retrieve X offset, or zero if X is specified as a literal.
  511. * - const Bit[4] B2: Bank to retrieve Y offset, or zero if Y is specified as a literal.
  512. * - const Bit[4] B3: Bank to retrieve Z offset, or zero if Z is specified as a literal.
  513. * - const Bit[4] B4: Bank to retrieve speed, or zero if S is specified as a literal.
  514. * - const UByte T: Type of movement.
  515. * - const Short X: X offset amount, relative to current position, or address to find X
  516. * offset, if B1 is non-zero.
  517. * - const Short Y: Y offset amount, relative to current position, or address to find Y
  518. * offset, if B2 is non-zero.
  519. * - const Short Z: Z offset amount, relative to current position, or address to find Z
  520. * offset, if B3 is non-zero.
  521. * - const UShort S: Speed of the offset movement, if type is non-zero, or address to find
  522. * speed, if B4 is non-zero.
  523. *
  524. * Offsets the field object, belonging to the entity whose script this opcode resides in,
  525. * by a certain amount. After being offset, the character continues to be constrained in
  526. * movement as defined by the walkmesh's shape, but at a certain distance away from the
  527. * normal walkmesh position. Other field objects are unaffected, and their position or
  528. * movements are maintained on the walkmesh's original position. If B1, B2, B3 or B4 is
  529. * non-zero, then the value for that particular component is taken from memory using the
  530. * corresponding bank and address specified, rather than as a literal value. Both retrieved
  531. * values and literals can be used for different components. If using T, X, Y or S as
  532. * addresses, the lower byte should hold the address whilst the higher byte should be zero.
  533. * The amount to offset is specified relative to the current position. If Type is
  534. * specified, the object moves gradually from its current point to the offset position;
  535. * this can be used to simulate movements such as elevators. Any type outside the range in
  536. * the table will cause the offset not to occur. If the object is set to move gradually,
  537. * then the speed of offset can be set; the greater the number, the slower the object moves
  538. * to its target offset. Script execution may also be halted until the gradual offset has
  539. * been completed. For this, see OFSTW.
  540. *
  541. * @param[in,out] code_gen Code generator to append lines.
  542. * @param[in] entity The entity name.
  543. */
  544. void ProcessOFST(CodeGenerator* code_gen, const std::string& entity);
  545. };