diff --git a/lang/Czech.ini b/lang/Czech.ini index 5f63540f..5fa3f13a 100644 --- a/lang/Czech.ini +++ b/lang/Czech.ini @@ -333,6 +333,7 @@ EDIT_PALETTE = "Upravit barvy" PRESET_NAME = "Název" DELETE_PRESET = "Smazat" SAVE_PRESET = "Uložit" +CAP_TOGGLE = "Stisknutím tlačítka Z přepnete čepici pro nošení." [PALETTE] MARIO = "Mario" diff --git a/lang/Dutch.ini b/lang/Dutch.ini index d6c916f7..36284c6c 100644 --- a/lang/Dutch.ini +++ b/lang/Dutch.ini @@ -333,6 +333,7 @@ EDIT_PALETTE = "Bewerk Palet" PRESET_NAME = "Naam" DELETE_PRESET = "Verwijderen" SAVE_PRESET = "Opslaan" +CAP_TOGGLE = "Druk op Z om te wisselen tussen de draagmuts." [PALETTE] MARIO = "Mario" diff --git a/lang/English.ini b/lang/English.ini index 5366cc4a..3cbcc9f3 100644 --- a/lang/English.ini +++ b/lang/English.ini @@ -333,6 +333,7 @@ EDIT_PALETTE = "Edit Palette" PRESET_NAME = "Preset Name" DELETE_PRESET = "Delete Preset" SAVE_PRESET = "Save Preset" +CAP_TOGGLE = "Press Z to toggle wearing cap." [PALETTE] MARIO = "Mario" diff --git a/lang/French.ini b/lang/French.ini index 1bc3c0ef..329be6f3 100644 --- a/lang/French.ini +++ b/lang/French.ini @@ -333,6 +333,7 @@ EDIT_PALETTE = "Modifier la palette" PRESET_NAME = "Nom" DELETE_PRESET = "Supprimer" SAVE_PRESET = "Enregistrer" +CAP_TOGGLE = "Appuyez sur Z pour mettre ou enlever la casquette." [PALETTE] MARIO = "Mario" diff --git a/lang/German.ini b/lang/German.ini index fbb22036..82eacc0c 100644 --- a/lang/German.ini +++ b/lang/German.ini @@ -333,6 +333,7 @@ EDIT_PALETTE = "Palette bearbeiten" PRESET_NAME = "Name" DELETE_PRESET = "Löschen" SAVE_PRESET = "Speichern" +CAP_TOGGLE = "Drücken Sie Z, um das Tragen der Kappe umzuschalten." [PALETTE] MARIO = "Mario" diff --git a/lang/Italian.ini b/lang/Italian.ini index 98df107a..026e650e 100644 --- a/lang/Italian.ini +++ b/lang/Italian.ini @@ -331,6 +331,7 @@ EDIT_PALETTE = "Modifica Palette" PRESET_NAME = "Nome" DELETE_PRESET = "Eliminare" SAVE_PRESET = "Salvare" +CAP_TOGGLE = "Premere Z per attivare il cappuccio di protezione." [PALETTE] MARIO = "Mario" diff --git a/lang/Polish.ini b/lang/Polish.ini index 95d81621..7f013522 100644 --- a/lang/Polish.ini +++ b/lang/Polish.ini @@ -333,6 +333,7 @@ EDIT_PALETTE = "Edytuj Palete" PRESET_NAME = "Nazwa presetu" DELETE_PRESET = "Usuń preset" SAVE_PRESET = "Zapisz preset" +CAP_TOGGLE = "Naciśnij Z, aby zdjąć lub założyć czapkę." [PALETTE] MARIO = "Mario" diff --git a/lang/Portuguese.ini b/lang/Portuguese.ini index 0d75288d..96018ae3 100644 --- a/lang/Portuguese.ini +++ b/lang/Portuguese.ini @@ -333,6 +333,7 @@ EDIT_PALETTE = "Editar paleta" PRESET_NAME = "Nome" DELETE_PRESET = "Excluir" SAVE_PRESET = "Salvar" +CAP_TOGGLE = "Prima Z para alternar a capa de proteção." [PALETTE] MARIO = "Mario" diff --git a/lang/Russian.ini b/lang/Russian.ini index 5f3589bc..199de455 100644 --- a/lang/Russian.ini +++ b/lang/Russian.ini @@ -332,6 +332,7 @@ EDIT_PALETTE = "Редактировать палитру" PRESET_NAME = "Имя" DELETE_PRESET = "Удалить" SAVE_PRESET = "Сохранить" +CAP_TOGGLE = "Нажмите Z, чтобы переключить режим ношения шапки." [PALETTE] MARIO = "Марио" diff --git a/lang/Spanish.ini b/lang/Spanish.ini index 17e67ed5..7d9b79e0 100644 --- a/lang/Spanish.ini +++ b/lang/Spanish.ini @@ -333,6 +333,7 @@ EDIT_PALETTE = "Editar Paleta" PRESET_NAME = "Nombre" DELETE_PRESET = "Eliminar" SAVE_PRESET = "Guardar" +CAP_TOGGLE = "Pulsa Z para poner o quitar la gorra." [PALETTE] MARIO = "Mario" @@ -410,4 +411,4 @@ SEARCH = "Buscar" NONE_FOUND = "No se han encontrado partidas." [CHANGELOG] -CHANGELOG_TITLE = "REGISTRO DE CAMBIOS" \ No newline at end of file +CHANGELOG_TITLE = "REGISTRO DE CAMBIOS" diff --git a/src/game/camera.c b/src/game/camera.c index 26f39326..b8727b77 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -3348,8 +3348,9 @@ void update_camera(struct Camera *c) { gLakituState.lastFrameAction = sMarioCamState->action; // Make sure the palette editor cutscene is properly reset - if (c->paletteEditorCap && c->cutscene != CUTSCENE_PALETTE_EDITOR && (gMarioState->flags & MARIO_CAP_ON_HEAD) == 0) { - cutscene_put_cap_on(gMarioState); + struct MarioState *m = gMarioState; + if (c->paletteEditorCap && c->cutscene != CUTSCENE_PALETTE_EDITOR && !(m->flags & MARIO_CAP_ON_HEAD) && m->action != ACT_PUTTING_ON_CAP) { + cutscene_put_cap_on(m); c->paletteEditorCap = false; } } @@ -10865,18 +10866,37 @@ void cutscene_palette_editor(struct Camera *c) { if (!gInPlayerMenu) { if (c->paletteEditorCap) { - if (!(m->flags & MARIO_CAP_ON_HEAD)) { + if (m->action == ACT_IDLE && !(m->flags & MARIO_CAP_ON_HEAD)) { set_mario_action(m, ACT_PUTTING_ON_CAP, 0); } - c->paletteEditorCap = false; } gCutsceneTimer = CUTSCENE_STOP; c->cutscene = 0; return; } - if (m->action == ACT_IDLE && m->flags & MARIO_CAP_ON_HEAD) { - set_mario_action(m, ACT_TAKING_OFF_CAP, 0); - c->paletteEditorCap = true; + + static bool pressed = false; + if (gInteractablePad.button & PAD_BUTTON_Z) { + if (!pressed && m->action != ACT_TAKING_OFF_CAP && m->action != ACT_PUTTING_ON_CAP) { + if (m->flags & MARIO_CAP_ON_HEAD) { + if (m->action == ACT_IDLE) { + set_mario_action(m, ACT_TAKING_OFF_CAP, 0); + } else { + cutscene_take_cap_off(m); + gCamera->paletteEditorCap = true; + } + } else { + if (m->action == ACT_IDLE) { + set_mario_action(m, ACT_PUTTING_ON_CAP, 0); + } else { + cutscene_put_cap_on(m); + gCamera->paletteEditorCap = false; + } + } + } + pressed = true; + } else { + pressed = false; } c->pos[0] = m->pos[0] + (0x200 * sins(m->faceAngle[1])); diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 898bf5ad..b234fd3d 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -1863,12 +1863,13 @@ 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 && !m->area->camera->paletteEditorCap) { + if (animFrame == 0 && !gCamera->paletteEditorCap) { enable_time_stop_if_alone(); } if (animFrame == 28) { cutscene_put_cap_on(m); + gCamera->paletteEditorCap = false; } if (is_anim_at_end(m)) { @@ -1885,16 +1886,19 @@ 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->area->camera->paletteEditorCap) { + if (!gCamera->paletteEditorCap) { enable_time_stop_if_alone(); } break; case 12: cutscene_take_cap_off(m); + if (gCamera->cutscene == CUTSCENE_PALETTE_EDITOR) { gCamera->paletteEditorCap = true; } break; - case 30: - set_mario_action(m, ACT_IDLE, 0); - disable_time_stop(); + default: + if (animFrame >= 30) { + set_mario_action(m, ACT_IDLE, 0); + disable_time_stop(); + } break; } diff --git a/src/pc/djui/djui_interactable.h b/src/pc/djui/djui_interactable.h index 0ab84478..9496e45a 100644 --- a/src/pc/djui/djui_interactable.h +++ b/src/pc/djui/djui_interactable.h @@ -4,6 +4,7 @@ #define PAD_BUTTON_A ((u16)(1 << 15)) #define PAD_BUTTON_B ((u16)(1 << 14)) +#define PAD_BUTTON_Z ((u16)(1 << 13)) #define PAD_BUTTON_START ((u16)(1 << 12)) #define MOUSE_BUTTON_1 ((u16)(1 << 0)) diff --git a/src/pc/djui/djui_panel_player.c b/src/pc/djui/djui_panel_player.c index 0a7d40d1..ddaafa24 100644 --- a/src/pc/djui/djui_panel_player.c +++ b/src/pc/djui/djui_panel_player.c @@ -338,8 +338,8 @@ static void djui_panel_player_prevent_demo(struct DjuiBase* caller) { } static void djui_panel_player_update_camera_cutscene(void) { - if (gMarioState->area && gMarioState->area->camera && gMarioState->area->camera->cutscene == 0) { - gMarioState->area->camera->cutscene = CUTSCENE_PALETTE_EDITOR; + if (gCamera && gCamera->cutscene == 0) { + gCamera->cutscene = CUTSCENE_PALETTE_EDITOR; } } @@ -412,7 +412,7 @@ void djui_panel_player_create(struct DjuiBase* caller) { if (sPalettePresetIndex >= gPresetPaletteCount) { sPalettePresetIndex = 0; } - + for (int i = 0; i < gPresetPaletteCount; i++) { palettePresets[i + 1] = gPresetPalettes[i].name; @@ -425,6 +425,13 @@ void djui_panel_player_create(struct DjuiBase* caller) { djui_button_create(body, DLANG(PLAYER, EDIT_PALETTE), DJUI_BUTTON_STYLE_NORMAL, djui_panel_player_edit_palette_create); djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back); + + { + struct DjuiText *text = djui_text_create(body, DLANG(PLAYER, CAP_TOGGLE)); + djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP); + djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&text->base, 1.0f, 64); + } } struct DjuiPanel* p = djui_panel_add(caller, panel, NULL); diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c index 9cc36f28..53aaa930 100644 --- a/src/pc/lua/smlua_cobject.c +++ b/src/pc/lua/smlua_cobject.c @@ -574,60 +574,17 @@ static int smlua__set_field(lua_State* L) { void smlua_cobject_init_globals(void) { lua_State* L = gLuaState; - { - lua_newtable(L); - int t = lua_gettop(gLuaState); - for (s32 i = 0; i < MAX_PLAYERS; i++) { - lua_pushinteger(L, i); - smlua_push_object(L, LOT_MARIOSTATE, &gMarioStates[i]); - lua_settable(L, t); - } - lua_setglobal(L, "gMarioStates"); - } - - { - lua_newtable(L); - int t = lua_gettop(gLuaState); - for (s32 i = 0; i < MAX_PLAYERS; i++) { - lua_pushinteger(L, i); - smlua_push_object(L, LOT_NETWORKPLAYER, &gNetworkPlayers[i]); - lua_settable(L, t); - } - lua_setglobal(L, "gNetworkPlayers"); - } - - { - lua_newtable(L); - int t = lua_gettop(gLuaState); - for (s32 i = 0; i < gActiveMods.entryCount; i++) { - lua_pushinteger(L, i); - smlua_push_object(L, LOT_MOD, gActiveMods.entries[i]); - lua_settable(L, t); - } - lua_setglobal(L, "gActiveMods"); - } - - { - lua_newtable(L); - int t = lua_gettop(gLuaState); - for (s32 i = 0; i < CT_MAX; i++) { - lua_pushinteger(L, i); - smlua_push_object(L, LOT_CHARACTER, &gCharacters[i]); - lua_settable(L, t); - } - lua_setglobal(L, "gCharacters"); - } - - { - lua_newtable(L); - int t = lua_gettop(gLuaState); - for (s32 i = 0; i < MAX_PLAYERS; i++) { - lua_pushinteger(L, i); - smlua_push_object(L, LOT_CONTROLLER, &gControllers[i]); - lua_settable(L, t); - } - lua_setglobal(L, "gControllers"); - } +#define EXPOSE_GLOBAL_ARRAY(lot, ptr, iterator) \ + { \ + lua_newtable(L); \ + int t = lua_gettop(gLuaState); \ + for (s32 i = 0; i < iterator; i++) { \ + lua_pushinteger(L, i); \ + smlua_push_object(L, lot, &ptr[i]); \ + lua_settable(L, t); \ + } \ + lua_setglobal(L, #ptr); \ + } \ #define EXPOSE_GLOBAL(lot, ptr) \ { \ @@ -641,13 +598,36 @@ void smlua_cobject_init_globals(void) { lua_setglobal(L, name); \ } \ + // Array structs + + EXPOSE_GLOBAL_ARRAY(LOT_MARIOSTATE, gMarioStates, MAX_PLAYERS); + + EXPOSE_GLOBAL_ARRAY(LOT_NETWORKPLAYER, gNetworkPlayers, MAX_PLAYERS); + + { + lua_newtable(L); + int t = lua_gettop(gLuaState); + for (s32 i = 0; i < gActiveMods.entryCount; i++) { + lua_pushinteger(L, i); + smlua_push_object(L, LOT_MOD, gActiveMods.entries[i]); + lua_settable(L, t); + } + lua_setglobal(L, "gActiveMods"); + } + + EXPOSE_GLOBAL_ARRAY(LOT_CHARACTER, gCharacters, CT_MAX); + + EXPOSE_GLOBAL_ARRAY(LOT_CONTROLLER, gControllers, MAX_PLAYERS); + + // Structs + EXPOSE_GLOBAL_WITH_NAME(LOT_GLOBALTEXTURES, gGlobalTextures, "gTextures"); EXPOSE_GLOBAL_WITH_NAME(LOT_GLOBALOBJECTANIMATIONS, gGlobalObjectAnimations, "gObjectAnimations"); EXPOSE_GLOBAL(LOT_PAINTINGVALUES, gPaintingValues); - EXPOSE_GLOBAL(LOT_GLOBALOBJECTCOLLISIONDATA, gGlobalObjectCollisionData); // I wish we named this gObjectCollisionData + EXPOSE_GLOBAL(LOT_GLOBALOBJECTCOLLISIONDATA, gGlobalObjectCollisionData); EXPOSE_GLOBAL(LOT_LEVELVALUES, gLevelValues);