diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py
index 0352b44f2..e39219fbf 100644
--- a/autogen/convert_structs.py
+++ b/autogen/convert_structs.py
@@ -91,6 +91,7 @@ override_field_mutable = {
override_field_invisible = {
"Mod": [ "files", "showedScriptWarning" ],
+ "Camera": [ "paletteEditorCapState" ],
"MarioState": [ "visibleToEnemies" ],
"NetworkPlayer": [ "gag", "moderator", "discordId" ],
"GraphNode": [ "_guard1", "_guard2", "padding" ],
diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua
index 4f814b1d4..4333f0881 100644
--- a/autogen/lua_definitions/constants.lua
+++ b/autogen/lua_definitions/constants.lua
@@ -7367,6 +7367,9 @@ ACT_COUGHING = 0x0C40020A
--- @type integer
ACT_SHIVERING = 0x0C40020B
+--- @type integer
+ACT_PALETTE_EDITOR_CAP = 0x0000020C
+
--- @type integer
ACT_IN_QUICKSAND = 0x0002020D
@@ -7949,9 +7952,6 @@ ACT_FEET_STUCK_IN_GROUND = 0x0002033C
--- @type integer
ACT_PUTTING_ON_CAP = 0x0000133D
---- @type integer
-ACT_TAKING_OFF_CAP = 0x0000133E
-
--- @type integer
ACT_HOLDING_POLE = 0x08100340
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index cca3e4ab6..51a732094 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -6247,6 +6247,13 @@ function check_common_landing_cancels(m, action)
-- ...
end
+--- @param m MarioState
+--- @param c Camera
+--- @return integer
+function mario_exit_palette_editor(m, c)
+ -- ...
+end
+
--- @param m MarioState
--- @return integer
--- Checks for and handles common conditions that would cancel Mario's current stationary action.
diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua
index 7012bfe3a..d9a4c330b 100644
--- a/autogen/lua_definitions/structs.lua
+++ b/autogen/lua_definitions/structs.lua
@@ -225,7 +225,6 @@
--- @field public mode integer
--- @field public mtx Mat4
--- @field public nextYaw integer
---- @field public paletteEditorCap boolean
--- @field public pos Vec3f
--- @field public unusedVec1 Vec3f
--- @field public yaw integer
diff --git a/docs/lua/constants.md b/docs/lua/constants.md
index f91d7a48b..fdeb3bc26 100644
--- a/docs/lua/constants.md
+++ b/docs/lua/constants.md
@@ -3221,6 +3221,7 @@
- ACT_STANDING_AGAINST_WALL
- ACT_COUGHING
- ACT_SHIVERING
+- ACT_PALETTE_EDITOR_CAP
- ACT_IN_QUICKSAND
- ACT_UNKNOWN_0002020E
- ACT_CROUCHING
@@ -3415,7 +3416,6 @@
- ACT_BUTT_STUCK_IN_GROUND
- ACT_FEET_STUCK_IN_GROUND
- ACT_PUTTING_ON_CAP
-- ACT_TAKING_OFF_CAP
- ACT_HOLDING_POLE
- ACT_GRAB_POLE_SLOW
- ACT_GRAB_POLE_FAST
diff --git a/docs/lua/functions-2.md b/docs/lua/functions-2.md
index 73ab4f69f..6bd635827 100644
--- a/docs/lua/functions-2.md
+++ b/docs/lua/functions-2.md
@@ -2,7 +2,7 @@
---
-[< prev](functions.md) | [1](functions.md) | 2 | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [next >](functions-3.md)]
+[< prev](functions.md) | [1](functions.md) | 2 | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-3.md)]
---
@@ -12081,5 +12081,5 @@ Spawns a Star that won't make Mario exit the level with an ID corresponding to t
---
-[< prev](functions.md) | [1](functions.md) | 2 | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [next >](functions-3.md)]
+[< prev](functions.md) | [1](functions.md) | 2 | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-3.md)]
diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md
index 271479817..96c844c73 100644
--- a/docs/lua/functions-3.md
+++ b/docs/lua/functions-3.md
@@ -2,7 +2,7 @@
---
-[< prev](functions-2.md) | [1](functions.md) | [2](functions-2.md) | 3 | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [next >](functions-4.md)]
+[< prev](functions-2.md) | [1](functions.md) | [2](functions-2.md) | 3 | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-4.md)]
---
@@ -7183,5 +7183,5 @@ Sets whether a lighting engine point light will use a surface's normals to deter
---
-[< prev](functions-2.md) | [1](functions.md) | [2](functions-2.md) | 3 | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [next >](functions-4.md)]
+[< prev](functions-2.md) | [1](functions.md) | [2](functions-2.md) | 3 | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-4.md)]
diff --git a/docs/lua/functions-4.md b/docs/lua/functions-4.md
index 636e195d5..358633568 100644
--- a/docs/lua/functions-4.md
+++ b/docs/lua/functions-4.md
@@ -2,7 +2,7 @@
---
-[< prev](functions-3.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | 4 | [5](functions-5.md) | [6](functions-6.md) | [next >](functions-5.md)]
+[< prev](functions-3.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | 4 | [5](functions-5.md) | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-5.md)]
---
@@ -3526,6 +3526,27 @@ Checks for and handles common conditions that would cancel Mario's current landi
+## [mario_exit_palette_editor](#mario_exit_palette_editor)
+
+### Lua Example
+`local integerValue = mario_exit_palette_editor(m, c)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+| c | [Camera](structs.md#Camera) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 mario_exit_palette_editor(struct MarioState *m, struct Camera *c);`
+
+[:arrow_up_small:](#)
+
+
+
## [check_common_stationary_cancels](#check_common_stationary_cancels)
### Description
@@ -6738,5 +6759,5 @@ Converts a 3D short integer vector `a` into a 3D integer vector and stores the r
---
-[< prev](functions-3.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | 4 | [5](functions-5.md) | [6](functions-6.md) | [next >](functions-5.md)]
+[< prev](functions-3.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | 4 | [5](functions-5.md) | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-5.md)]
diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md
index e29068ee5..53f109eba 100644
--- a/docs/lua/functions-5.md
+++ b/docs/lua/functions-5.md
@@ -2,7 +2,7 @@
---
-[< prev](functions-4.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | 5 | [6](functions-6.md) | [next >](functions-6.md)]
+[< prev](functions-4.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | 5 | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-6.md)]
---
@@ -8206,5 +8206,5 @@ Gets a trajectory's length
---
-[< prev](functions-4.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | 5 | [6](functions-6.md) | [next >](functions-6.md)]
+[< prev](functions-4.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | 5 | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-6.md)]
diff --git a/docs/lua/functions-6.md b/docs/lua/functions-6.md
index 5ad76c5cb..a9fd4062c 100644
--- a/docs/lua/functions-6.md
+++ b/docs/lua/functions-6.md
@@ -2,7 +2,7 @@
---
-[< prev](functions-5.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | 6]
+[< prev](functions-5.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | 6 | [7](functions-7.md) | [next >](functions-7.md)]
---
@@ -8517,83 +8517,7 @@ Checks if a surface has force
[:arrow_up_small:](#)
-
----
-# functions from sync_object.h
-
-
-
-
-## [sync_object_get_object](#sync_object_get_object)
-
-### Description
-Retrieves an object from a sync ID
-
-### Lua Example
-`local ObjectValue = sync_object_get_object(syncId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| syncId | `integer` |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object* sync_object_get_object(u32 syncId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [sync_object_is_initialized](#sync_object_is_initialized)
-
-### Description
-Checks if a sync object is initialized using a `syncId`
-
-### Lua Example
-`local booleanValue = sync_object_is_initialized(syncId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| syncId | `integer` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool sync_object_is_initialized(u32 syncId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [sync_object_is_owned_locally](#sync_object_is_owned_locally)
-
-### Description
-Checks if a sync object is owned locally using a `syncId`
-
-### Lua Example
-`local booleanValue = sync_object_is_owned_locally(syncId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| syncId | `integer` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool sync_object_is_owned_locally(u32 syncId);`
-
-[:arrow_up_small:](#)
-
-
-
---
-[< prev](functions-5.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | 6]
+[< prev](functions-5.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | 6 | [7](functions-7.md) | [next >](functions-7.md)]
diff --git a/docs/lua/functions-7.md b/docs/lua/functions-7.md
new file mode 100644
index 000000000..bc3786df4
--- /dev/null
+++ b/docs/lua/functions-7.md
@@ -0,0 +1,86 @@
+## [:rewind: Lua Functions](functions.md)
+
+---
+
+[< prev](functions-6.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | 7]
+
+
+---
+# functions from sync_object.h
+
+
+
+
+## [sync_object_get_object](#sync_object_get_object)
+
+### Description
+Retrieves an object from a sync ID
+
+### Lua Example
+`local ObjectValue = sync_object_get_object(syncId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| syncId | `integer` |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object* sync_object_get_object(u32 syncId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [sync_object_is_initialized](#sync_object_is_initialized)
+
+### Description
+Checks if a sync object is initialized using a `syncId`
+
+### Lua Example
+`local booleanValue = sync_object_is_initialized(syncId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| syncId | `integer` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool sync_object_is_initialized(u32 syncId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [sync_object_is_owned_locally](#sync_object_is_owned_locally)
+
+### Description
+Checks if a sync object is owned locally using a `syncId`
+
+### Lua Example
+`local booleanValue = sync_object_is_owned_locally(syncId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| syncId | `integer` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool sync_object_is_owned_locally(u32 syncId);`
+
+[:arrow_up_small:](#)
+
+
+
+---
+
+[< prev](functions-6.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | 7]
+
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index f1e0ae3a1..76fc6a55b 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -2,7 +2,7 @@
---
-1 | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [next >](functions-2.md)]
+1 | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-2.md)]
---
@@ -1159,6 +1159,7 @@
- [stopping_step](functions-4.md#stopping_step)
- [landing_step](functions-4.md#landing_step)
- [check_common_landing_cancels](functions-4.md#check_common_landing_cancels)
+ - [mario_exit_palette_editor](functions-4.md#mario_exit_palette_editor)
- [check_common_stationary_cancels](functions-4.md#check_common_stationary_cancels)
- [mario_execute_stationary_action](functions-4.md#mario_execute_stationary_action)
@@ -2186,9 +2187,9 @@
- sync_object.h
- - [sync_object_get_object](functions-6.md#sync_object_get_object)
- - [sync_object_is_initialized](functions-6.md#sync_object_is_initialized)
- - [sync_object_is_owned_locally](functions-6.md#sync_object_is_owned_locally)
+ - [sync_object_get_object](functions-7.md#sync_object_get_object)
+ - [sync_object_is_initialized](functions-7.md#sync_object_is_initialized)
+ - [sync_object_is_owned_locally](functions-7.md#sync_object_is_owned_locally)
@@ -2834,5 +2835,5 @@ Plays a screen transition after a `delay` in frames
---
-1 | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [next >](functions-2.md)]
+1 | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-2.md)]
diff --git a/docs/lua/structs.md b/docs/lua/structs.md
index 0c510030f..31e0a2fc1 100644
--- a/docs/lua/structs.md
+++ b/docs/lua/structs.md
@@ -413,7 +413,6 @@
| mode | `integer` | |
| mtx | [Mat4](structs.md#Mat4) | read-only |
| nextYaw | `integer` | |
-| paletteEditorCap | `boolean` | |
| pos | [Vec3f](structs.md#Vec3f) | read-only |
| unusedVec1 | [Vec3f](structs.md#Vec3f) | read-only |
| yaw | `integer` | |
diff --git a/include/sm64.h b/include/sm64.h
index b3a2c68ad..7805d3576 100644
--- a/include/sm64.h
+++ b/include/sm64.h
@@ -194,6 +194,7 @@
#define ACT_STANDING_AGAINST_WALL 0x0C400209 // (0x009 | ACT_FLAG_STATIONARY | ACT_FLAG_IDLE | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT)
#define ACT_COUGHING 0x0C40020A // (0x00A | ACT_FLAG_STATIONARY | ACT_FLAG_IDLE | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT)
#define ACT_SHIVERING 0x0C40020B // (0x00B | ACT_FLAG_STATIONARY | ACT_FLAG_IDLE | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT)
+#define ACT_PALETTE_EDITOR_CAP 0x0000020C // (0x00C | ACT_FLAG_STATIONARY) // ! COOP ACTION
#define ACT_IN_QUICKSAND 0x0002020D // (0x00D | ACT_FLAG_STATIONARY | ACT_FLAG_INVULNERABLE)
#define ACT_UNKNOWN_0002020E 0x0002020E // (0x00E | ACT_FLAG_STATIONARY | ACT_FLAG_INVULNERABLE)
#define ACT_CROUCHING 0x0C008220 // (0x020 | ACT_FLAG_STATIONARY | ACT_FLAG_SHORT_HITBOX | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT)
@@ -396,7 +397,6 @@
#define ACT_BUTT_STUCK_IN_GROUND 0x0002033B // (0x13B | ACT_FLAG_STATIONARY | ACT_FLAG_INVULNERABLE)
#define ACT_FEET_STUCK_IN_GROUND 0x0002033C // (0x13C | ACT_FLAG_STATIONARY | ACT_FLAG_INVULNERABLE)
#define ACT_PUTTING_ON_CAP 0x0000133D // (0x13D | ACT_FLAG_STATIONARY | ACT_FLAG_INTANGIBLE)
-#define ACT_TAKING_OFF_CAP 0x0000133E // (0x13E | ACT_FLAG_STATIONARY | ACT_FLAG_INTANGIBLE) // ! COOP ACTION
// group 0x140: "automatic" actions
#define ACT_HOLDING_POLE 0x08100340 // (0x140 | ACT_FLAG_STATIONARY | ACT_FLAG_ON_POLE | ACT_FLAG_PAUSE_EXIT)
diff --git a/src/game/camera.c b/src/game/camera.c
index f18325c50..ae77be9a0 100644
--- a/src/game/camera.c
+++ b/src/game/camera.c
@@ -17,6 +17,7 @@
#include "engine/behavior_script.h"
#include "level_update.h"
#include "ingame_menu.h"
+#include "mario_actions_stationary.h"
#include "mario_actions_cutscene.h"
#include "save_file.h"
#include "object_helpers.h"
@@ -500,8 +501,6 @@ s32 update_slide_or_0f_camera(struct Camera *c, Vec3f, Vec3f);
s32 update_spiral_stairs_camera(struct Camera *c, Vec3f, Vec3f);
s32 update_rom_hack_camera(struct Camera *c, Vec3f, Vec3f);
void mode_rom_hack_camera(struct Camera *c);
-void cutscene_take_cap_off(struct MarioState *m);
-void cutscene_put_cap_on(struct MarioState *m);
typedef s32 (*CameraTransition)(struct Camera *c, Vec3f, Vec3f);
CameraTransition sModeTransitions[] = {
@@ -3396,13 +3395,8 @@ void update_camera(struct Camera *c) {
// Make sure the palette editor cutscene is properly reset
struct MarioState *m = gMarioState;
- if (c->paletteEditorCap) {
- if (m->flags & MARIO_CAP_ON_HEAD) {
- c->paletteEditorCap = false;
- } else if (c->cutscene != CUTSCENE_PALETTE_EDITOR && m->action != ACT_PUTTING_ON_CAP) {
- cutscene_put_cap_on(m);
- c->paletteEditorCap = false;
- }
+ if (c->cutscene != CUTSCENE_PALETTE_EDITOR && c->paletteEditorCapState) {
+ mario_exit_palette_editor(m, c);
}
}
@@ -10930,19 +10924,14 @@ void cutscene_palette_editor(struct Camera *c) {
if (!c) { return; }
struct MarioState* m = gMarioState;
+ // Init cap state
+ // Ensures that Mario regains his correct cap state when exiting the palette editor
+ if (!c->paletteEditorCapState) {
+ c->paletteEditorCapState = (m->flags & MARIO_CAP_ON_HEAD) ? 1 : 2;
+ }
+
if (!gDjuiInPlayerMenu) {
- if (c->paletteEditorCap) {
- if (m->flags & MARIO_CAP_ON_HEAD) {
- gCamera->paletteEditorCap = false;
- } else {
- if (m->action == ACT_IDLE) {
- set_mario_action(m, ACT_PUTTING_ON_CAP, 0);
- } else {
- cutscene_put_cap_on(m);
- gCamera->paletteEditorCap = false;
- }
- }
- }
+ mario_exit_palette_editor(m, c);
gCutsceneTimer = CUTSCENE_STOP;
c->cutscene = 0;
skip_camera_interpolation();
@@ -10953,11 +10942,7 @@ void cutscene_palette_editor(struct Camera *c) {
static bool pressed = false;
if (gInteractablePad.button & PAD_BUTTON_Z) {
if (!pressed && m->action == ACT_IDLE) {
- if (m->flags & MARIO_CAP_ON_HEAD) {
- set_mario_action(m, ACT_TAKING_OFF_CAP, 1); // Add palette editor action arg
- } else {
- set_mario_action(m, ACT_PUTTING_ON_CAP, 0);
- }
+ set_mario_action(m, ACT_PALETTE_EDITOR_CAP, (m->flags & MARIO_CAP_ON_HEAD) != 0);
}
pressed = true;
} else {
@@ -10969,8 +10954,7 @@ void cutscene_palette_editor(struct Camera *c) {
djui_base_set_visible(
&gDjuiPaletteToggle->base,
m->action == ACT_IDLE ||
- m->action == ACT_TAKING_OFF_CAP ||
- m->action == ACT_PUTTING_ON_CAP
+ m->action == ACT_PALETTE_EDITOR_CAP
);
}
diff --git a/src/game/camera.h b/src/game/camera.h
index c4992e5e1..2d69e5dc4 100644
--- a/src/game/camera.h
+++ b/src/game/camera.h
@@ -596,7 +596,7 @@ struct Camera
/// when paused. See zoom_out_if_paused_and_outside
/*0x68*/ f32 areaCenY;
/*????*/ Mat4 mtx;
- /*????*/ bool paletteEditorCap;
+ /*????*/ u8 paletteEditorCapState;
};
/**
diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c
index bd660a2ce..a06f5705f 100644
--- a/src/game/mario_actions_cutscene.c
+++ b/src/game/mario_actions_cutscene.c
@@ -1897,13 +1897,12 @@ s32 act_squished(struct MarioState *m) {
s32 act_putting_on_cap(struct MarioState *m) {
s32 animFrame = set_character_animation(m, CHAR_ANIM_PUT_CAP_ON);
- if (animFrame == 0 && !gCamera->paletteEditorCap) {
+ if (animFrame == 0) {
enable_time_stop_if_alone();
}
if (animFrame == 28) {
cutscene_put_cap_on(m);
- gCamera->paletteEditorCap = false;
}
if (is_anim_at_end(m)) {
@@ -1915,30 +1914,6 @@ s32 act_putting_on_cap(struct MarioState *m) {
return FALSE;
}
-// coop custom action
-// actionArg == 1: the action was inited from CUTSCENE_PALETTE_EDITOR
-s32 act_taking_off_cap(struct MarioState *m) {
- s16 animFrame = set_character_animation(m, CHAR_ANIM_TAKE_CAP_OFF_THEN_ON);
- switch (animFrame) {
- case 0:
- if (m->actionArg != 1) {
- enable_time_stop_if_alone();
- }
- break;
- case 12:
- cutscene_take_cap_off(m);
- if (m->actionArg == 1) { gCamera->paletteEditorCap = true; }
- break;
- }
- if (animFrame >= 30 || gCamera->cutscene != CUTSCENE_PALETTE_EDITOR) {
- set_mario_action(m, ACT_IDLE, 0);
- disable_time_stop();
- }
-
- stationary_ground_step(m);
- return FALSE;
-}
-
/* |description|
Handles the cutscene and animation sequence for when Mario is stuck in the ground (head, butt, or feet). Plays a designated `animation`, checks specific frames (`unstuckFrame`, `target2`, `target3`) for sound effects or transitions, and frees Mario to the `endAction` once the animation completes
|descriptionEnd| */
@@ -3215,7 +3190,6 @@ s32 mario_execute_cutscene_action(struct MarioState *m) {
case ACT_BUTT_STUCK_IN_GROUND: cancel = act_butt_stuck_in_ground(m); break;
case ACT_FEET_STUCK_IN_GROUND: cancel = act_feet_stuck_in_ground(m); break;
case ACT_PUTTING_ON_CAP: cancel = act_putting_on_cap(m); break;
- case ACT_TAKING_OFF_CAP: cancel = act_taking_off_cap(m); break;
default:
LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action);
set_mario_action(m, ACT_IDLE, 0);
diff --git a/src/game/mario_actions_cutscene.h b/src/game/mario_actions_cutscene.h
index 73143d01e..44bf906f4 100644
--- a/src/game/mario_actions_cutscene.h
+++ b/src/game/mario_actions_cutscene.h
@@ -14,5 +14,7 @@ s32 mario_ready_to_speak(struct MarioState* m);
u8 should_start_or_continue_dialog(struct MarioState* m, struct Object* object);
s32 set_mario_npc_dialog(struct MarioState* m, s32 actionArg, u8(*inContinueDialogFunction)(void));
s32 mario_execute_cutscene_action(struct MarioState *m);
+void cutscene_take_cap_off(struct MarioState *m);
+void cutscene_put_cap_on(struct MarioState *m);
#endif // MARIO_ACTIONS_CUTSCENE_H
diff --git a/src/game/mario_actions_stationary.c b/src/game/mario_actions_stationary.c
index a5228c3cb..05334b243 100644
--- a/src/game/mario_actions_stationary.c
+++ b/src/game/mario_actions_stationary.c
@@ -10,6 +10,7 @@
#include "level_update.h"
#include "mario.h"
#include "mario_actions_stationary.h"
+#include "mario_actions_cutscene.h"
#include "mario_step.h"
#include "memory.h"
#include "save_file.h"
@@ -1160,6 +1161,47 @@ s32 act_first_person(struct MarioState *m) {
return FALSE;
}
+s32 mario_exit_palette_editor(struct MarioState *m, struct Camera *c) {
+ switch (c->paletteEditorCapState) {
+ case 0: return FALSE;
+ case 1: cutscene_put_cap_on(m); break;
+ case 2: cutscene_take_cap_off(m); break;
+ }
+ c->paletteEditorCapState = 0;
+ return set_mario_action(m, ACT_IDLE, 0);
+}
+
+s32 act_palette_editor_cap(struct MarioState *m) {
+ if (gCamera->cutscene != CUTSCENE_PALETTE_EDITOR) {
+ return mario_exit_palette_editor(m, gCamera);
+ }
+
+ // Put cap on
+ if (m->actionArg == 0) {
+ s16 animFrame = set_character_animation(m, CHAR_ANIM_PUT_CAP_ON);
+ if (animFrame == 28) {
+ cutscene_put_cap_on(m);
+ }
+ if (is_anim_at_end(m)) {
+ set_mario_action(m, ACT_IDLE, 0);
+ }
+ }
+
+ // Take cap off
+ else {
+ s16 animFrame = set_character_animation(m, CHAR_ANIM_TAKE_CAP_OFF_THEN_ON);
+ if (animFrame == 12) {
+ cutscene_take_cap_off(m);
+ }
+ if (animFrame >= 30) {
+ set_mario_action(m, ACT_IDLE, 0);
+ }
+ }
+
+ stationary_ground_step(m);
+ return FALSE;
+}
+
/* |description|
Checks for and handles common conditions that would cancel Mario's current stationary action.
|descriptionEnd| */
@@ -1249,6 +1291,7 @@ s32 mario_execute_stationary_action(struct MarioState *m) {
case ACT_BRAKING_STOP: cancel = act_braking_stop(m); break;
case ACT_BUTT_SLIDE_STOP: cancel = act_butt_slide_stop(m); break;
case ACT_HOLD_BUTT_SLIDE_STOP: cancel = act_hold_butt_slide_stop(m); break;
+ case ACT_PALETTE_EDITOR_CAP: cancel = act_palette_editor_cap(m); break;
default:
LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action);
set_mario_action(m, ACT_IDLE, 0);
diff --git a/src/game/mario_actions_stationary.h b/src/game/mario_actions_stationary.h
index beb884b5e..182147e53 100644
--- a/src/game/mario_actions_stationary.h
+++ b/src/game/mario_actions_stationary.h
@@ -5,6 +5,8 @@
#include "types.h"
+struct Camera;
+
s32 check_common_idle_cancels(struct MarioState *m);
s32 check_common_hold_idle_cancels(struct MarioState *m);
s32 act_idle(struct MarioState *m);
@@ -44,6 +46,8 @@ s32 act_air_throw_land(struct MarioState *m);
s32 act_twirl_land(struct MarioState *m);
s32 act_ground_pound_land(struct MarioState *m);
s32 act_first_person(struct MarioState *m);
+s32 mario_exit_palette_editor(struct MarioState *m, struct Camera *c);
+s32 act_palette_editor_cap(struct MarioState *m);
s32 check_common_stationary_cancels(struct MarioState *m);
s32 mario_execute_stationary_action(struct MarioState *m);
diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c
index da4895392..31abf4de9 100644
--- a/src/pc/lua/smlua_cobject_autogen.c
+++ b/src/pc/lua/smlua_cobject_autogen.c
@@ -393,24 +393,23 @@ static struct LuaObjectField sBullyCollisionDataFields[LUA_BULLY_COLLISION_DATA_
{ "velZ", LVT_F32, offsetof(struct BullyCollisionData, velZ), false, LOT_NONE, 1, sizeof(f32) },
};
-#define LUA_CAMERA_FIELD_COUNT 16
+#define LUA_CAMERA_FIELD_COUNT 15
static struct LuaObjectField sCameraFields[LUA_CAMERA_FIELD_COUNT] = {
- { "areaCenX", LVT_F32, offsetof(struct Camera, areaCenX), false, LOT_NONE, 1, sizeof(f32) },
- { "areaCenY", LVT_F32, offsetof(struct Camera, areaCenY), false, LOT_NONE, 1, sizeof(f32) },
- { "areaCenZ", LVT_F32, offsetof(struct Camera, areaCenZ), false, LOT_NONE, 1, sizeof(f32) },
- { "cutscene", LVT_U8, offsetof(struct Camera, cutscene), false, LOT_NONE, 1, sizeof(u8) },
- { "defMode", LVT_U8, offsetof(struct Camera, defMode), false, LOT_NONE, 1, sizeof(u8) },
- { "doorStatus", LVT_U8, offsetof(struct Camera, doorStatus), false, LOT_NONE, 1, sizeof(u8) },
- { "filler31", LVT_U8, offsetof(struct Camera, filler31), false, LOT_NONE, 8, sizeof(u8) },
- { "filler3C", LVT_U8, offsetof(struct Camera, filler3C), false, LOT_NONE, 40, sizeof(u8) },
- { "focus", LVT_COBJECT, offsetof(struct Camera, focus), true, LOT_VEC3F, 1, sizeof(Vec3f) },
- { "mode", LVT_U8, offsetof(struct Camera, mode), false, LOT_NONE, 1, sizeof(u8) },
- { "mtx", LVT_COBJECT, offsetof(struct Camera, mtx), true, LOT_MAT4, 1, sizeof(Mat4) },
- { "nextYaw", LVT_S16, offsetof(struct Camera, nextYaw), false, LOT_NONE, 1, sizeof(s16) },
- { "paletteEditorCap", LVT_BOOL, offsetof(struct Camera, paletteEditorCap), false, LOT_NONE, 1, sizeof(bool) },
- { "pos", LVT_COBJECT, offsetof(struct Camera, pos), true, LOT_VEC3F, 1, sizeof(Vec3f) },
- { "unusedVec1", LVT_COBJECT, offsetof(struct Camera, unusedVec1), true, LOT_VEC3F, 1, sizeof(Vec3f) },
- { "yaw", LVT_S16, offsetof(struct Camera, yaw), false, LOT_NONE, 1, sizeof(s16) },
+ { "areaCenX", LVT_F32, offsetof(struct Camera, areaCenX), false, LOT_NONE, 1, sizeof(f32) },
+ { "areaCenY", LVT_F32, offsetof(struct Camera, areaCenY), false, LOT_NONE, 1, sizeof(f32) },
+ { "areaCenZ", LVT_F32, offsetof(struct Camera, areaCenZ), false, LOT_NONE, 1, sizeof(f32) },
+ { "cutscene", LVT_U8, offsetof(struct Camera, cutscene), false, LOT_NONE, 1, sizeof(u8) },
+ { "defMode", LVT_U8, offsetof(struct Camera, defMode), false, LOT_NONE, 1, sizeof(u8) },
+ { "doorStatus", LVT_U8, offsetof(struct Camera, doorStatus), false, LOT_NONE, 1, sizeof(u8) },
+ { "filler31", LVT_U8, offsetof(struct Camera, filler31), false, LOT_NONE, 8, sizeof(u8) },
+ { "filler3C", LVT_U8, offsetof(struct Camera, filler3C), false, LOT_NONE, 40, sizeof(u8) },
+ { "focus", LVT_COBJECT, offsetof(struct Camera, focus), true, LOT_VEC3F, 1, sizeof(Vec3f) },
+ { "mode", LVT_U8, offsetof(struct Camera, mode), false, LOT_NONE, 1, sizeof(u8) },
+ { "mtx", LVT_COBJECT, offsetof(struct Camera, mtx), true, LOT_MAT4, 1, sizeof(Mat4) },
+ { "nextYaw", LVT_S16, offsetof(struct Camera, nextYaw), false, LOT_NONE, 1, sizeof(s16) },
+ { "pos", LVT_COBJECT, offsetof(struct Camera, pos), true, LOT_VEC3F, 1, sizeof(Vec3f) },
+ { "unusedVec1", LVT_COBJECT, offsetof(struct Camera, unusedVec1), true, LOT_VEC3F, 1, sizeof(Vec3f) },
+ { "yaw", LVT_S16, offsetof(struct Camera, yaw), false, LOT_NONE, 1, sizeof(s16) },
};
#define LUA_CAMERA_FOVSTATUS_FIELD_COUNT 8
diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c
index 35995263c..bc0dfdae1 100644
--- a/src/pc/lua/smlua_constants_autogen.c
+++ b/src/pc/lua/smlua_constants_autogen.c
@@ -3195,6 +3195,7 @@ char gSmluaConstants[] = ""
"ACT_STANDING_AGAINST_WALL=0x0C400209\n"
"ACT_COUGHING=0x0C40020A\n"
"ACT_SHIVERING=0x0C40020B\n"
+"ACT_PALETTE_EDITOR_CAP=0x0000020C\n"
"ACT_IN_QUICKSAND=0x0002020D\n"
"ACT_UNKNOWN_0002020E=0x0002020E\n"
"ACT_CROUCHING=0x0C008220\n"
@@ -3389,7 +3390,6 @@ char gSmluaConstants[] = ""
"ACT_BUTT_STUCK_IN_GROUND=0x0002033B\n"
"ACT_FEET_STUCK_IN_GROUND=0x0002033C\n"
"ACT_PUTTING_ON_CAP=0x0000133D\n"
-"ACT_TAKING_OFF_CAP=0x0000133E\n"
"ACT_HOLDING_POLE=0x08100340\n"
"ACT_GRAB_POLE_SLOW=0x00100341\n"
"ACT_GRAB_POLE_FAST=0x00100342\n"
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 396739a18..14226a5f7 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -18875,6 +18875,26 @@ int smlua_func_check_common_landing_cancels(lua_State* L) {
return 1;
}
+int smlua_func_mario_exit_palette_editor(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 2) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mario_exit_palette_editor", 2, top);
+ return 0;
+ }
+
+ struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mario_exit_palette_editor"); return 0; }
+ struct Camera* c = (struct Camera*)smlua_to_cobject(L, 2, LOT_CAMERA);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "mario_exit_palette_editor"); return 0; }
+
+ extern s32 mario_exit_palette_editor(struct MarioState *m, struct Camera *c);
+ lua_pushinteger(L, mario_exit_palette_editor(m, c));
+
+ return 1;
+}
+
int smlua_func_check_common_stationary_cancels(lua_State* L) {
if (L == NULL) { return 0; }
@@ -37505,6 +37525,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "stopping_step", smlua_func_stopping_step);
smlua_bind_function(L, "landing_step", smlua_func_landing_step);
smlua_bind_function(L, "check_common_landing_cancels", smlua_func_check_common_landing_cancels);
+ smlua_bind_function(L, "mario_exit_palette_editor", smlua_func_mario_exit_palette_editor);
smlua_bind_function(L, "check_common_stationary_cancels", smlua_func_check_common_stationary_cancels);
smlua_bind_function(L, "mario_execute_stationary_action", smlua_func_mario_execute_stationary_action);