diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index cbe31fe9e..725e89243 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -72,7 +72,7 @@ override_allowed_functions = { "src/game/object_list_processor.h": [ "set_object_respawn_info_bits" ], "src/game/mario_misc.h": [ "bhv_toad.*", "bhv_unlock_door.*" ], "src/pc/utils/misc.h": [ "update_all_mario_stars" ], - "src/game/level_update.h": [ "level_trigger_warp" ], + "src/game/level_update.h": [ "level_trigger_warp", "get_painting_warp_node", "initiate_painting_warp" ], "src/game/area.h": [ "area_get_warp_node" ], "src/engine/level_script.h": [ "area_create_warp_node" ] } diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 9fbcbfdcf..3c0fb7c28 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -3745,7 +3745,7 @@ end --- @param pos Vec3f --- @param out Vec3f ---- @return nil +--- @return boolean function djui_hud_world_pos_to_screen_pos(pos, out) -- ... end @@ -4101,6 +4101,17 @@ function area_create_warp_node(id, destLevel, destArea, destNode, checkpoint, o) -- ... end +--- @return WarpNode +function get_painting_warp_node() + -- ... +end + +--- @param paintingIndex integer +--- @return nil +function initiate_painting_warp(paintingIndex) + -- ... +end + --- @param m MarioState --- @param warpOp integer --- @return integer diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index caaa6453d..d0c228c58 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -2426,7 +2426,7 @@ ## [djui_hud_world_pos_to_screen_pos](#djui_hud_world_pos_to_screen_pos) ### Lua Example -`djui_hud_world_pos_to_screen_pos(pos, out)` +`local booleanValue = djui_hud_world_pos_to_screen_pos(pos, out)` ### Parameters | Field | Type | @@ -2435,10 +2435,10 @@ | out | [Vec3f](structs.md#Vec3f) | ### Returns -- None +- `boolean` ### C Prototype -`void djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out);` +`bool djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out);` [:arrow_up_small:](#) @@ -3567,6 +3567,44 @@
+## [get_painting_warp_node](#get_painting_warp_node) + +### Lua Example +`local WarpNodeValue = get_painting_warp_node()` + +### Parameters +- None + +### Returns +[WarpNode](structs.md#WarpNode) + +### C Prototype +`struct WarpNode *get_painting_warp_node(void);` + +[:arrow_up_small:](#) + +
+ +## [initiate_painting_warp](#initiate_painting_warp) + +### Lua Example +`initiate_painting_warp(paintingIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| paintingIndex | `integer` | + +### Returns +- None + +### C Prototype +`void initiate_painting_warp(s16 paintingIndex);` + +[:arrow_up_small:](#) + +
+ ## [level_trigger_warp](#level_trigger_warp) ### Lua Example diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 2c79d0ca2..5262ae275 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -816,6 +816,8 @@
- level_update.h + - [get_painting_warp_node](functions-3.md#get_painting_warp_node) + - [initiate_painting_warp](functions-3.md#initiate_painting_warp) - [level_trigger_warp](functions-3.md#level_trigger_warp)
diff --git a/lang/English.ini b/lang/English.ini index c28677799..27efbd09a 100644 --- a/lang/English.ini +++ b/lang/English.ini @@ -323,6 +323,7 @@ RASPBERRY = "Raspberry" BUBBLEGUM = "Bubblegum" ICE_MARIO = "Ice Mario" ICE_LUIGI = "Ice Luigi" +TOAD = "Toad" CUSTOM = "Custom" [PLAYER_LIST] diff --git a/lang/French.ini b/lang/French.ini index 23d819f97..22b7ef90b 100644 --- a/lang/French.ini +++ b/lang/French.ini @@ -323,6 +323,7 @@ RASPBERRY = "Framboise" BUBBLEGUM = "Bubblegum" ICE_MARIO = "Mario de glace" ICE_LUIGI = "Luigi de glace" +TOAD = "Toad" CUSTOM = "Personnalisée" [PLAYER_LIST] diff --git a/lang/German.ini b/lang/German.ini index 8b238c1cd..f3c0efe61 100644 --- a/lang/German.ini +++ b/lang/German.ini @@ -323,6 +323,7 @@ RASPBERRY = "Himbeere" BUBBLEGUM = "Kaugummi" ICE_MARIO = "Eis Mario" ICE_LUIGI = "Eis Luigi" +TOAD = "Toad" CUSTOM = "Selbstgemacht" [PLAYER_LIST] diff --git a/lang/Italian.ini b/lang/Italian.ini index 002624cc9..e5443135c 100644 --- a/lang/Italian.ini +++ b/lang/Italian.ini @@ -320,6 +320,7 @@ RASPBERRY = "Mora" BUBBLEGUM = "Gomma da Masticare" ICE_MARIO = "Mario Ghiaccio" ICE_LUIGI = "Luigi Ghiaccio" +TOAD = "Toad" CUSTOM = "Personalizzato" [PLAYER_LIST] diff --git a/lang/Portuguese.ini b/lang/Portuguese.ini index 29564b637..09d12f520 100644 --- a/lang/Portuguese.ini +++ b/lang/Portuguese.ini @@ -323,6 +323,7 @@ RASPBERRY = "Framboesa" BUBBLEGUM = "Chiclete" ICE_MARIO = "Mario de Gelo" ICE_LUIGI = "Luigi de Gelo" +TOAD = "Toad" CUSTOM = "Customizado" [PLAYER_LIST] diff --git a/lang/Russian.ini b/lang/Russian.ini index f1db254b0..9c784775e 100644 --- a/lang/Russian.ini +++ b/lang/Russian.ini @@ -322,6 +322,7 @@ RASPBERRY = "Малина" BUBBLEGUM = "Жвачка" ICE_MARIO = "Ледяной Марио" ICE_LUIGI = "Ледяной Луиджи" +TOAD = "Тоад"s CUSTOM = "Свой" [PLAYER_LIST] diff --git a/lang/Spanish.ini b/lang/Spanish.ini index ca49c9735..1b92e4494 100644 --- a/lang/Spanish.ini +++ b/lang/Spanish.ini @@ -323,6 +323,7 @@ RASPBERRY = "Frambuesa" BUBBLEGUM = "Chicle" ICE_MARIO = "Mario de Hielo" ICE_LUIGI = "Luigi de Hielo" +TOAD = "Toad" CUSTOM = "Personalizada" [PLAYER_LIST] diff --git a/src/engine/level_script.c b/src/engine/level_script.c index b410dac07..2cace6b5e 100644 --- a/src/engine/level_script.c +++ b/src/engine/level_script.c @@ -626,9 +626,9 @@ static void level_cmd_create_painting_warp_node(void) { if (sCurrAreaIndex != -1) { if (gAreas[sCurrAreaIndex].paintingWarpNodes == NULL) { gAreas[sCurrAreaIndex].paintingWarpNodes = - alloc_only_pool_alloc(sLevelPool, 45 * sizeof(struct WarpNode)); + alloc_only_pool_alloc(sLevelPool, MAX_PAINTING_WARP_NODES * sizeof(struct WarpNode)); - for (i = 0; i < 45; i++) { + for (i = 0; i < MAX_PAINTING_WARP_NODES; i++) { gAreas[sCurrAreaIndex].paintingWarpNodes[i].id = 0; } } diff --git a/src/engine/level_script.h b/src/engine/level_script.h index ba4557da2..f62c4cebc 100644 --- a/src/engine/level_script.h +++ b/src/engine/level_script.h @@ -3,6 +3,8 @@ #include +#define MAX_PAINTING_WARP_NODES 45 + struct LevelCommand; extern s32 gLevelScriptModIndex; diff --git a/src/game/camera.c b/src/game/camera.c index fc54fc270..eccbc7911 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -115,7 +115,7 @@ s16 sCreditsPlayer2Yaw; */ u8 sFramesPaused; -extern struct CameraFOVStatus sFOVState; +extern struct CameraFOVStatus gFOVState; extern struct TransitionInfo sModeTransition; extern struct PlayerGeometry sMarioGeometry; extern s16 unusedFreeRoamWallYaw; @@ -182,7 +182,7 @@ extern struct Camera *gCamera; * @see LakituState */ struct LakituState gLakituState = { 0 }; -struct CameraFOVStatus sFOVState = { 0 }; +struct CameraFOVStatus gFOVState = { 0 }; struct TransitionInfo sModeTransition = { 0 }; struct PlayerGeometry sMarioGeometry = { 0 }; struct Camera *gCamera; @@ -3359,11 +3359,11 @@ void reset_camera(struct Camera *c) { gLakituState.lastFrameAction = 0; set_fov_function(CAM_FOV_DEFAULT); - sFOVState.fov = 45.f; - sFOVState.fovOffset = 0.f; - sFOVState.unusedIsSleeping = 0; - sFOVState.shakeAmplitude = 0.f; - sFOVState.shakePhase = 0; + gFOVState.fov = 45.f; + gFOVState.fovOffset = 0.f; + gFOVState.unusedIsSleeping = 0; + gFOVState.shakeAmplitude = 0.f; + gFOVState.shakePhase = 0; sObjectCutscene = 0; gRecentCutscene = 0; @@ -7617,7 +7617,7 @@ BAD_RETURN(s32) cutscene_ending_look_at_sky(struct Camera *c) { * called, it will stay at about 37.26f */ BAD_RETURN(s32) cutscene_ending_zoom_fov(UNUSED struct Camera *c) { - sFOVState.fov = 37.f; + gFOVState.fov = 37.f; } /** @@ -8492,7 +8492,7 @@ BAD_RETURN(s32) cutscene_red_coin_star_start(struct Camera *c) { object_pos_to_vec3f(sCutsceneVars[1].point, gCutsceneFocus); store_info_star(c); // Store the default fov for after the cutscene - sCutsceneVars[2].point[2] = sFOVState.fov; + sCutsceneVars[2].point[2] = gFOVState.fov; } /** @@ -8544,7 +8544,7 @@ BAD_RETURN(s32) cutscene_red_coin_star_warp(struct Camera *c) { * Zoom out while looking at the star. */ BAD_RETURN(s32) cutscene_red_coin_star_set_fov(UNUSED struct Camera *c) { - sFOVState.fov = 60.f; + gFOVState.fov = 60.f; } BAD_RETURN(s32) cutscene_red_coin_star(struct Camera *c) { @@ -8570,7 +8570,7 @@ BAD_RETURN(s32) cutscene_red_coin_star_end(struct Camera *c) { gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; // Restore the default fov - sFOVState.fov = sCutsceneVars[2].point[2]; + gFOVState.fov = sCutsceneVars[2].point[2]; } /** @@ -8949,7 +8949,7 @@ BAD_RETURN(s32) cutscene_pyramid_top_explode_warp(struct Camera *c) { f32 dist; set_fov_function(CAM_FOV_DEFAULT); - sFOVState.fov = 45.f; + gFOVState.fov = 45.f; vec3f_copy(sCutsceneVars[4].point, c->pos); vec3f_copy(sCutsceneVars[5].point, c->focus); @@ -8973,7 +8973,7 @@ BAD_RETURN(s32) cutscene_pyramid_top_explode_closeup(struct Camera *c) { c->focus[1] += 4.f; c->pos[1] -= 5.f; - sFOVState.fov = 45.f; + gFOVState.fov = 45.f; set_handheld_shake(HAND_CAM_SHAKE_CUTSCENE); } @@ -9739,7 +9739,7 @@ BAD_RETURN(s32) cutscene_intro_peach_clear_cutscene_status(UNUSED struct Camera * Set fov to 8 degrees, then zoom out to 30. */ BAD_RETURN(s32) cutscene_intro_peach_zoom_fov(UNUSED struct Camera *c) { - sFOVState.fov = 8.f; + gFOVState.fov = 8.f; set_fov_function(CAM_FOV_ZOOM_30); } @@ -11494,10 +11494,10 @@ s32 cutscene_spawn_obj(u32 obj, s16 frame) { * calculated from coss(), so this parameter can be thought of as an angular velocity. */ void set_fov_shake(s16 amplitude, s16 decay, s16 shakeSpeed) { - if (amplitude > sFOVState.shakeAmplitude) { - sFOVState.shakeAmplitude = amplitude; - sFOVState.decay = decay; - sFOVState.shakeSpeed = shakeSpeed; + if (amplitude > gFOVState.shakeAmplitude) { + gFOVState.shakeAmplitude = amplitude; + gFOVState.decay = decay; + gFOVState.shakeSpeed = shakeSpeed; } } @@ -11508,10 +11508,10 @@ void set_fov_shake_from_point(s16 amplitude, s16 decay, s16 shakeSpeed, f32 maxD amplitude = reduce_by_dist_from_camera(amplitude, maxDist, posX, posY, posZ); if (amplitude != 0) { - if (amplitude > sFOVState.shakeAmplitude) { // literally use the function above you silly nintendo, smh - sFOVState.shakeAmplitude = amplitude; - sFOVState.decay = decay; - sFOVState.shakeSpeed = shakeSpeed; + if (amplitude > gFOVState.shakeAmplitude) { // literally use the function above you silly nintendo, smh + gFOVState.shakeAmplitude = amplitude; + gFOVState.decay = decay; + gFOVState.shakeSpeed = shakeSpeed; } } } @@ -11520,13 +11520,13 @@ void set_fov_shake_from_point(s16 amplitude, s16 decay, s16 shakeSpeed, f32 maxD * Add a cyclic offset to the camera's field of view based on a cosine wave */ void shake_camera_fov(struct GraphNodePerspective *perspective) { - if (sFOVState.shakeAmplitude != 0.f) { - sFOVState.fovOffset = coss(sFOVState.shakePhase) * sFOVState.shakeAmplitude / 0x100; - sFOVState.shakePhase += sFOVState.shakeSpeed; - camera_approach_f32_symmetric_bool(&sFOVState.shakeAmplitude, 0.f, sFOVState.decay); - perspective->fov += sFOVState.fovOffset; + if (gFOVState.shakeAmplitude != 0.f) { + gFOVState.fovOffset = coss(gFOVState.shakePhase) * gFOVState.shakeAmplitude / 0x100; + gFOVState.shakePhase += gFOVState.shakeSpeed; + camera_approach_f32_symmetric_bool(&gFOVState.shakeAmplitude, 0.f, gFOVState.decay); + perspective->fov += gFOVState.fovOffset; } else { - sFOVState.shakePhase = 0; + gFOVState.shakePhase = 0; } } @@ -11535,25 +11535,25 @@ static UNUSED void unused_deactivate_sleeping_camera(UNUSED struct MarioState *m } void set_fov_30(UNUSED struct MarioState *m) { - sFOVState.fov = 30.f; + gFOVState.fov = 30.f; } void approach_fov_20(UNUSED struct MarioState *m) { - camera_approach_f32_symmetric_bool(&sFOVState.fov, 20.f, 0.3f); + camera_approach_f32_symmetric_bool(&gFOVState.fov, 20.f, 0.3f); } void set_fov_45(UNUSED struct MarioState *m) { - sFOVState.fov = 45.f; + gFOVState.fov = 45.f; } void set_fov_29(UNUSED struct MarioState *m) { - sFOVState.fov = 29.f; + gFOVState.fov = 29.f; } void zoom_fov_30(UNUSED struct MarioState *m) { // Pretty sure approach_f32_asymptotic_bool would do a much nicer job here, but you do you, // Nintendo. - camera_approach_f32_symmetric_bool(&sFOVState.fov, 30.f, (30.f - sFOVState.fov) / 60.f); + camera_approach_f32_symmetric_bool(&gFOVState.fov, 30.f, (30.f - gFOVState.fov) / 60.f); } /** @@ -11564,32 +11564,32 @@ void fov_default(struct MarioState *m) { sStatusFlags &= ~CAM_FLAG_SLEEPING; if ((m->action == ACT_SLEEPING) || (m->action == ACT_START_SLEEPING)) { - camera_approach_f32_symmetric_bool(&sFOVState.fov, 30.f, (30.f - sFOVState.fov) / 30.f); + camera_approach_f32_symmetric_bool(&gFOVState.fov, 30.f, (30.f - gFOVState.fov) / 30.f); sStatusFlags |= CAM_FLAG_SLEEPING; } else { - camera_approach_f32_symmetric_bool(&sFOVState.fov, 45.f, (45.f - sFOVState.fov) / 30.f); - sFOVState.unusedIsSleeping = 0; + camera_approach_f32_symmetric_bool(&gFOVState.fov, 45.f, (45.f - gFOVState.fov) / 30.f); + gFOVState.unusedIsSleeping = 0; } if (m->area->camera->cutscene == CUTSCENE_0F_UNUSED) { - sFOVState.fov = 45.f; + gFOVState.fov = 45.f; } } //??! Literally the exact same as below static UNUSED void unused_approach_fov_30(UNUSED struct MarioState *m) { - camera_approach_f32_symmetric_bool(&sFOVState.fov, 30.f, 1.f); + camera_approach_f32_symmetric_bool(&gFOVState.fov, 30.f, 1.f); } void approach_fov_30(UNUSED struct MarioState *m) { - camera_approach_f32_symmetric_bool(&sFOVState.fov, 30.f, 1.f); + camera_approach_f32_symmetric_bool(&gFOVState.fov, 30.f, 1.f); } void approach_fov_60(UNUSED struct MarioState *m) { - camera_approach_f32_symmetric_bool(&sFOVState.fov, 60.f, 1.f); + camera_approach_f32_symmetric_bool(&gFOVState.fov, 60.f, 1.f); } void approach_fov_45(struct MarioState *m) { - f32 targetFoV = sFOVState.fov; + f32 targetFoV = gFOVState.fov; if (m->area->camera->mode == CAMERA_MODE_FIXED && m->area->camera->cutscene == 0) { targetFoV = 45.f; @@ -11597,11 +11597,11 @@ void approach_fov_45(struct MarioState *m) { targetFoV = 45.f; } - sFOVState.fov = approach_f32(sFOVState.fov, targetFoV, 2.f, 2.f); + gFOVState.fov = approach_f32(gFOVState.fov, targetFoV, 2.f, 2.f); } void approach_fov_80(UNUSED struct MarioState *m) { - camera_approach_f32_symmetric_bool(&sFOVState.fov, 80.f, 3.5f); + camera_approach_f32_symmetric_bool(&gFOVState.fov, 80.f, 3.5f); } /** @@ -11609,7 +11609,7 @@ void approach_fov_80(UNUSED struct MarioState *m) { * If there's a cutscene, sets fov to 45. Otherwise sets fov to 60. */ void set_fov_bbh(struct MarioState *m) { - f32 targetFoV = sFOVState.fov; + f32 targetFoV = gFOVState.fov; if (m->area->camera->mode == CAMERA_MODE_FIXED && m->area->camera->cutscene == 0) { targetFoV = 60.f; @@ -11617,7 +11617,7 @@ void set_fov_bbh(struct MarioState *m) { targetFoV = 45.f; } - sFOVState.fov = approach_f32(sFOVState.fov, targetFoV, 2.f, 2.f); + gFOVState.fov = approach_f32(gFOVState.fov, targetFoV, 2.f, 2.f); } /** @@ -11626,7 +11626,7 @@ void set_fov_bbh(struct MarioState *m) { Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context) { struct GraphNodePerspective *perspective = (struct GraphNodePerspective *) g; struct MarioState *marioState = &gMarioStates[0]; - u8 fovFunc = sFOVState.fovFunc; + u8 fovFunc = gFOVState.fovFunc; if (callContext == GEO_CONTEXT_RENDER) { switch (fovFunc) { @@ -11667,7 +11667,7 @@ Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context) } } - perspective->fov = sFOVState.fov; + perspective->fov = gFOVState.fov; shake_camera_fov(perspective); return NULL; } @@ -11678,7 +11678,7 @@ Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context) * @see geo_camera_fov */ void set_fov_function(u8 func) { - sFOVState.fovFunc = func; + gFOVState.fovFunc = func; } /** diff --git a/src/game/camera.h b/src/game/camera.h index c7a02ed23..4528ed5e5 100644 --- a/src/game/camera.h +++ b/src/game/camera.h @@ -678,6 +678,7 @@ extern s32 gObjCutsceneDone; extern struct Camera *gCamera; #endif +extern struct CameraFOVStatus gFOVState; extern u8 gCameraUseCourseSpecificSettings; extern struct Object *gCutsceneFocus; extern struct Object *gSecondCameraFocus; diff --git a/src/game/characters.c b/src/game/characters.c index b6a53cace..684375a1d 100644 --- a/src/game/characters.c +++ b/src/game/characters.c @@ -363,8 +363,8 @@ const struct PlayerPalette gPalettePresets[PALETTE_PRESET_MAX] = { /* ---- PANTS ----- ---- SHIRT ----- ---- GLOVES ---- ---- SHOES ----- ----- HAIR ----- ----- SKIN ----- ----- CAP ------ */ {{{ 0x00, 0x00, 0xff }, { 0xff, 0x00, 0x00 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0xff, 0x00, 0x00 }}}, // Mario {{{ 0x00, 0x00, 0xfe }, { 0x00, 0x98, 0x00 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x00, 0x98, 0x00 }}}, // Luigi -{{{ 0x2c, 0x26, 0x3f }, { 0x6d, 0x3c, 0x9a }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x6d, 0x3c, 0x9a }}}, // Waluigi -{{{ 0x7f, 0x20, 0x7a }, { 0xf9, 0xeb, 0x30 }, { 0xff, 0xff, 0xff }, { 0x0e, 0x72, 0x1c }, { 0x73, 0x53, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0xf9, 0xeb, 0x30 }}}, // Wario +{{{ 0x2c, 0x26, 0x3f }, { 0x61, 0x26, 0xb0 }, { 0xff, 0xff, 0xff }, { 0xfe, 0x76, 0x00 }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x61, 0x26, 0xb0 }}}, // Waluigi +{{{ 0x7f, 0x20, 0x7a }, { 0xe3, 0xa9, 0x01 }, { 0xff, 0xff, 0xff }, { 0x0e, 0x72, 0x1c }, { 0x73, 0x53, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0xe3, 0xa9, 0x01 }}}, // Wario {{{ 0xff, 0x00, 0x00 }, { 0x7b, 0x00, 0xde }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x7b, 0x00, 0xde }}}, // Chuckya {{{ 0xc6, 0xb1, 0x32 }, { 0x95, 0x43, 0x01 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x95, 0x43, 0x01 }}}, // Goomba {{{ 0x07, 0x09, 0x07 }, { 0x4c, 0x5f, 0x20 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x4c, 0x5f, 0x20 }}}, // Clover @@ -393,6 +393,7 @@ const struct PlayerPalette gPalettePresets[PALETTE_PRESET_MAX] = { {{{ 0xd6, 0x35, 0x4d }, { 0xff, 0x8e, 0xb2 }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0xff, 0x8e, 0xb2 }}}, // Bubblegum {{{ 0xb2, 0x28, 0x18 }, { 0x47, 0xc5, 0xff }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x47, 0xc5, 0xff }}}, // Ice Mario {{{ 0x00, 0x98, 0x00 }, { 0x47, 0xc5, 0xff }, { 0xff, 0xff, 0xff }, { 0x72, 0x1c, 0x0e }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xc1, 0x79 }, { 0x47, 0xc5, 0xff }}}, // Ice Luigi +{{{ 0x4c, 0x2c, 0xd3 }, { 0xff, 0xff, 0xff }, { 0xff, 0xff, 0xff }, { 0x68, 0x40, 0x1b }, { 0x73, 0x06, 0x00 }, { 0xfe, 0xd5, 0xa1 }, { 0xff, 0x00, 0x00 }}}, // Toad }; enum AnimType { diff --git a/src/game/characters.h b/src/game/characters.h index 8606ebe72..726fca4b3 100644 --- a/src/game/characters.h +++ b/src/game/characters.h @@ -5,7 +5,7 @@ #include "pc/configfile.h" // NOTE: do not include any additional headers -#define PALETTE_PRESET_MAX 32 +#define PALETTE_PRESET_MAX 33 enum PlayerParts { PANTS, SHIRT, GLOVES, SHOES, HAIR, SKIN, CAP, PLAYER_PART_MAX, METAL = CAP diff --git a/src/game/level_update.c b/src/game/level_update.c index b11c26929..f8b0f4472 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -45,6 +45,8 @@ #include "game/screen_transition.h" +#include "engine/level_script.h" + #define WARP_NODE_F0 0xF0 #define WARP_NODE_DEATH 0xF1 #define WARP_NODE_F2 0xF2 @@ -748,6 +750,8 @@ void initiate_warp(s16 destLevel, s16 destArea, s16 destWarpNode, s32 arg3) { * corresponding warp node. */ struct WarpNode *get_painting_warp_node(void) { + if (!gMarioState || !gMarioState->floor || !gCurrentArea || !gCurrentArea->paintingWarpNodes) { return NULL; } + struct WarpNode *warpNode = NULL; s32 paintingIndex = gMarioState->floor->type - SURFACE_PAINTING_WARP_D3; @@ -783,9 +787,9 @@ static void initiate_painting_warp_node(struct WarpNode *pWarpNode) { /** * Check is Mario has entered a painting, and if so, initiate a warp. */ -void initiate_painting_warp(void) { - if (gCurrentArea != NULL && gCurrentArea->paintingWarpNodes != NULL && gMarioState->floor != NULL) { - struct WarpNode *pWarpNode = get_painting_warp_node(); +void initiate_painting_warp(s16 paintingIndex) { + if (gCurrentArea && gCurrentArea->paintingWarpNodes && gMarioState && gMarioState->floor && paintingIndex >= 0 && paintingIndex < MAX_PAINTING_WARP_NODES) { + struct WarpNode *pWarpNode = paintingIndex == -1 ? get_painting_warp_node() : &gCurrentArea->paintingWarpNodes[paintingIndex]; if (pWarpNode != NULL) { if (gMarioState->action & ACT_FLAG_INTANGIBLE) { @@ -1229,7 +1233,7 @@ s32 play_mode_normal(void) { update_camera(gCurrentArea->camera); } - initiate_painting_warp(); + initiate_painting_warp(-1); initiate_delayed_warp(); // If either initiate_painting_warp or initiate_delayed_warp initiated a diff --git a/src/game/level_update.h b/src/game/level_update.h index 904d7de4b..dbc729579 100644 --- a/src/game/level_update.h +++ b/src/game/level_update.h @@ -151,6 +151,8 @@ u8 level_control_timer_running(void); u16 level_control_timer(s32 timerOp); void fade_into_special_warp(u32 arg, u32 color); void load_level_init_text(u32 arg); +struct WarpNode *get_painting_warp_node(void); +void initiate_painting_warp(s16 paintingIndex); s16 level_trigger_warp(struct MarioState *m, s32 warpOp); void level_set_transition(s16 length, void (*updateFunction)(s16 *)); diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index 7d0015bf8..aff4bcf64 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -279,7 +279,7 @@ void bhv_mario_update(void) { // sanity check torsoPos, it isn't updated off-screen otherwise extern u32 gGlobalTimer; - if (gMarioState->marioBodyState->updateTorsoTime != (gGlobalTimer - 1)) { + if (gMarioState->marioBodyState && gMarioState->marioBodyState->updateTorsoTime != (gGlobalTimer - 1)) { vec3f_copy(gMarioState->marioBodyState->torsoPos, gMarioState->pos); } diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index 88001b453..5c1436661 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -177,7 +177,7 @@ u32 djui_hud_get_screen_width(void) { } return (sResolution == RESOLUTION_N64) - ? ((use_forced_4by3() ? (4.0f / 3.0f) : GFX_DIMENSIONS_ASPECT_RATIO) * SCREEN_HEIGHT) + ? (use_forced_4by3() ? (4.0f / 3.0f) : (GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_HEIGHT)) : (windowWidth / djui_gfx_get_scale()); } @@ -524,21 +524,28 @@ static void hud_rotate_and_translate_vec3f(Vec3f vec, Mat4* mtx, Vec3f out) { out[2] += (*mtx)[3][2]; } -void djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out) { +bool djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out) { hud_rotate_and_translate_vec3f(pos, &gCamera->mtx, out); - if (out[2] > -256.0f) { - return; + if (out[2] >= 0.0f) { + return false; } - out[0] *= 256.0 / -out[2]; - out[1] *= 256.0 / out[2]; - - // TODO: this is a hack to correct for the FOV. It only sort of works for the default fov - out[0] *= 1.135; - out[1] *= 1.135; + out[0] *= 256.0f / -out[2]; + out[1] *= 256.0f / out[2]; + + // fov of 45.0 is the default fov + f32 fovDefault = tanf(45.0f * ((f32)M_PI / 360.0f)); + f32 fovCurrent = tanf((gFOVState.fov + gFOVState.fovOffset) * ((f32)M_PI / 360.0f)); + + f32 fovDifference = (fovDefault / fovCurrent) * 1.13f; + + out[0] *= fovDifference; + out[1] *= fovDifference; out[0] += djui_hud_get_screen_width() / 2.0f; out[1] += djui_hud_get_screen_height() / 2.0f; + + return true; } void djui_hud_set_render_behind_hud(bool enable) { diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h index 09822b9e6..d069153f6 100644 --- a/src/pc/djui/djui_hud_utils.h +++ b/src/pc/djui/djui_hud_utils.h @@ -63,7 +63,7 @@ void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32 void djui_hud_render_rect(f32 x, f32 y, f32 width, f32 height); void djui_hud_render_rect_interpolated(f32 prevX, f32 prevY, f32 prevWidth, f32 prevHeight, f32 x, f32 y, f32 width, f32 height); -void djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out); +bool djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out); void djui_hud_set_render_behind_hud(bool enable); diff --git a/src/pc/djui/djui_panel_player.c b/src/pc/djui/djui_panel_player.c index a05d87b06..22e0e2d54 100644 --- a/src/pc/djui/djui_panel_player.c +++ b/src/pc/djui/djui_panel_player.c @@ -298,6 +298,7 @@ void djui_panel_player_create(struct DjuiBase* caller) { DLANG(PALETTE, BUBBLEGUM), DLANG(PALETTE, ICE_MARIO), DLANG(PALETTE, ICE_LUIGI), + DLANG(PALETTE, TOAD), DLANG(PALETTE, CUSTOM), }; diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index b9c5a4935..1b166a46a 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -11861,7 +11861,7 @@ int smlua_func_djui_hud_world_pos_to_screen_pos(lua_State* L) { out[2] = smlua_get_number_field(2, "z"); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "djui_hud_world_pos_to_screen_pos"); return 0; } - djui_hud_world_pos_to_screen_pos(pos, out); + lua_pushboolean(L, djui_hud_world_pos_to_screen_pos(pos, out)); smlua_push_number_field(1, "x", pos[0]); smlua_push_number_field(1, "y", pos[1]); @@ -12901,6 +12901,38 @@ int smlua_func_area_create_warp_node(lua_State* L) { // level_update.h // //////////////////// +int smlua_func_get_painting_warp_node(UNUSED lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_painting_warp_node", 0, top); + return 0; + } + + + smlua_push_object(L, LOT_WARPNODE, get_painting_warp_node()); + + return 1; +} + +int smlua_func_initiate_painting_warp(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "initiate_painting_warp", 1, top); + return 0; + } + + s16 paintingIndex = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "initiate_painting_warp"); return 0; } + + initiate_painting_warp(paintingIndex); + + return 1; +} + int smlua_func_level_trigger_warp(lua_State* L) { if (L == NULL) { return 0; } @@ -30143,6 +30175,8 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "area_create_warp_node", smlua_func_area_create_warp_node); // level_update.h + smlua_bind_function(L, "get_painting_warp_node", smlua_func_get_painting_warp_node); + smlua_bind_function(L, "initiate_painting_warp", smlua_func_initiate_painting_warp); smlua_bind_function(L, "level_trigger_warp", smlua_func_level_trigger_warp); // mario.h