diff --git a/src/game/interaction.c b/src/game/interaction.c index 7b9a40dc2..397e7a960 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -2271,7 +2271,7 @@ void check_death_barrier(struct MarioState *m) { void check_lava_boost(struct MarioState *m) { bool allow = true; smlua_call_event_hooks_mario_param_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, &allow); - if (m->action == ACT_BUBBLED || (Cheats.enabled && Cheats.godMode) || (!allow)) { return; } + if (m->action == ACT_BUBBLED || (gServerSettings.enableCheats && gCheats.godMode) || (!allow)) { return; } if (!(m->action & ACT_FLAG_RIDING_SHELL) && m->pos[1] < m->floorHeight + 10.0f) { if (!(m->flags & MARIO_METAL_CAP)) { m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 12 : 18; diff --git a/src/game/mario.c b/src/game/mario.c index 1528c5a7f..cf1d1b81b 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1548,9 +1548,21 @@ void update_mario_inputs(struct MarioState *m) { debug_print_speed_action_normal(m); - if (Cheats.enabled && Cheats.moonJump && m->controller->buttonDown & L_TRIG) { + if (gServerSettings.enableCheats && gCheats.moonJump && m->playerIndex == 0 && m->controller->buttonDown & L_TRIG) { + if (m->action == ACT_FORWARD_GROUND_KB || + m->action == ACT_BACKWARD_GROUND_KB || + m->action == ACT_SOFT_FORWARD_GROUND_KB || + m->action == ACT_HARD_BACKWARD_GROUND_KB || + m->action == ACT_FORWARD_AIR_KB || + m->action == ACT_BACKWARD_AIR_KB || + m->action == ACT_HARD_FORWARD_AIR_KB || + m->action == ACT_HARD_BACKWARD_AIR_KB || + m->action == ACT_AIR_HIT_WALL) { + set_mario_action(m, ACT_FREEFALL, 0); + } + m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800); - m->vel[1] = 30; + m->vel[1] = 40; } /* Developer stuff */ @@ -1994,14 +2006,18 @@ s32 execute_mario_action(UNUSED struct Object *o) { np->fadeOpacity += 2; gMarioState->fadeWarpOpacity = np->fadeOpacity << 3; } - } - if (Cheats.enabled) { - if (Cheats.godMode) { gMarioState->health = 0x880; } + if (gServerSettings.enableCheats) { + if (gCheats.godMode) { + gMarioState->health = 0x880; + gMarioState->healCounter = 0; + gMarioState->hurtCounter = 0; + } - if (Cheats.infiniteLives && gMarioState->numLives < 100) { gMarioState->numLives = 100; } - - if (Cheats.superSpeed && gMarioState->controller->stickMag > 0.5f) { gMarioState->forwardVel += 100; } + if (gCheats.infiniteLives && gMarioState->numLives < 100) { + gMarioState->numLives = 100; + } + } } if (gMarioState->action) { @@ -2116,6 +2132,10 @@ s32 execute_mario_action(UNUSED struct Object *o) { #endif } + if (gServerSettings.enableCheats && gCheats.bljAnywhere && gMarioState->playerIndex == 0 && gMarioState->action == ACT_LONG_JUMP && gMarioState->forwardVel < -15 && gMarioState->input & INPUT_Z_DOWN && gMarioState->pos[1] - gMarioState->floorHeight < 90) { + gMarioState->vel[1] = -30; + } + play_infinite_stairs_music(); gMarioState->marioObj->oInteractStatus = 0; queue_particle_rumble(); diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index d1b4c057c..5e20fb084 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -55,7 +55,7 @@ void play_knockback_sound(struct MarioState *m) { s32 lava_boost_on_wall(struct MarioState *m) { bool allow = true; smlua_call_event_hooks_mario_param_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, &allow); - if ((Cheats.enabled && Cheats.godMode) || (!allow)) { return FALSE; } + if ((gServerSettings.enableCheats && gCheats.godMode) || (!allow)) { return FALSE; } m->faceAngle[1] = atan2s(m->wallNormal[2], m->wallNormal[0]); if (m->forwardVel < 24.0f) { @@ -72,7 +72,7 @@ s32 lava_boost_on_wall(struct MarioState *m) { } s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) { - if (Cheats.enabled && Cheats.godMode) { return FALSE; } + if (gServerSettings.enableCheats && gCheats.godMode && m->playerIndex == 0) { return FALSE; } f32 fallHeight; f32 damageHeight; diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 5eaca685b..5751cb3bb 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -24,6 +24,7 @@ #include "pc/configfile.h" #include "pc/network/network.h" #include "pc/lua/smlua.h" +#include "pc/cheats.h" #define POLE_NONE 0 #define POLE_TOUCHED_FLOOR 1 @@ -331,6 +332,11 @@ s32 perform_hanging_step(struct MarioState *m, Vec3f nextPos) { smlua_call_event_hooks_mario_param(HOOK_BEFORE_PHYS_STEP, m); + if (gServerSettings.enableCheats && gCheats.superSpeed && m->playerIndex == 0) { + m->vel[0] *= SUPER_SPEED_MULTIPLIER; + m->vel[2] *= SUPER_SPEED_MULTIPLIER; + } + struct WallCollisionData wcd = { 0 }; resolve_and_return_wall_collisions_data(nextPos, 50.0f, 50.0f, &wcd); m->wall = (wcd.numWalls > 0) diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 4a9831f7a..79cc8971d 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -152,7 +152,7 @@ void slide_bonk(struct MarioState *m, u32 fastAction, u32 slowAction) { s32 set_triple_jump_action(struct MarioState *m, UNUSED u32 action, UNUSED u32 actionArg) { if (m->flags & MARIO_WING_CAP) { return set_mario_action(m, ACT_FLYING_TRIPLE_JUMP, 0); - } else if (m->forwardVel > 20.0f) { + } else if (m->forwardVel > 20.0f || (gServerSettings.enableCheats && gCheats.alwaysTripleJump && m->playerIndex == 0)) { return set_mario_action(m, ACT_TRIPLE_JUMP, 0); } else { return set_mario_action(m, ACT_JUMP, 0); @@ -468,7 +468,7 @@ void update_walking_speed(struct MarioState *m) { } // handles the "Super responsive controls" cheat. The content of the "else" is Mario's original code for turning around. - if (Cheats.enabled && Cheats.responsive) { + if (gServerSettings.enableCheats && gCheats.responsiveControls && m->playerIndex == 0) { m->faceAngle[1] = m->intendedYaw; } else { m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800); diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index a6d3d340e..f87ff851b 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -21,6 +21,7 @@ #include "pc/network/network.h" #include "pc/lua/smlua.h" #include "pc/lua/smlua_hooks.h" +#include "pc/cheats.h" #define MIN_SWIM_STRENGTH 160 #define MIN_SWIM_SPEED 16.0f @@ -186,6 +187,11 @@ u32 perform_water_step(struct MarioState *m) { smlua_call_event_hooks_mario_param(HOOK_BEFORE_PHYS_STEP, m); + if (gServerSettings.enableCheats && gCheats.superSpeed && m->playerIndex == 0) { + m->vel[0] *= SUPER_SPEED_MULTIPLIER; + m->vel[2] *= SUPER_SPEED_MULTIPLIER; + } + vec3f_copy(step, m->vel); if (m->action & ACT_FLAG_SWIMMING) { diff --git a/src/game/mario_step.c b/src/game/mario_step.c index d188f9de9..34cbc7cef 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -111,7 +111,7 @@ void mario_bonk_reflection(struct MarioState *m, u32 negateSpeed) { u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) { bool allow = true; smlua_call_event_hooks_mario_param_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, &allow); - if (m->action & ACT_FLAG_RIDING_SHELL || (Cheats.enabled && Cheats.godMode) || (!allow)) { + if (m->action & ACT_FLAG_RIDING_SHELL || (gServerSettings.enableCheats && gCheats.godMode && m->playerIndex == 0) || (!allow)) { m->quicksandDepth = 0.0f; } else { if (m->quicksandDepth < 1.1f) { @@ -338,6 +338,11 @@ s32 perform_ground_step(struct MarioState *m) { smlua_call_event_hooks_mario_param(HOOK_BEFORE_PHYS_STEP, m); + if (gServerSettings.enableCheats && gCheats.superSpeed && m->playerIndex == 0) { + m->vel[0] *= SUPER_SPEED_MULTIPLIER; + m->vel[2] *= SUPER_SPEED_MULTIPLIER; + } + for (i = 0; i < 4; i++) { Vec3f step = { m->floor->normal.y * (m->vel[0] / 4.0f), @@ -684,6 +689,11 @@ s32 perform_air_step(struct MarioState *m, u32 stepArg) { smlua_call_event_hooks_mario_param(HOOK_BEFORE_PHYS_STEP, m); + if (gServerSettings.enableCheats && gCheats.superSpeed && m->playerIndex == 0) { + m->vel[0] *= SUPER_SPEED_MULTIPLIER; + m->vel[2] *= SUPER_SPEED_MULTIPLIER; + } + m->wall = NULL; for (i = 0; i < 4; i++) { diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index 0984d75b4..af4219f97 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -23,6 +23,7 @@ #include "engine/math_util.h" #include "pc/network/network.h" #include "pc/lua/smlua.h" +#include "pc/cheats.h" /** * Flags controlling what debug info is displayed. @@ -296,6 +297,10 @@ void bhv_mario_update(void) { particleFlags |= gMarioState->particleFlags; gCurrentObject->oMarioParticleFlags = particleFlags; + if (gServerSettings.enableCheats && gCheats.rapidFireA && gMarioState->playerIndex == 0) { + gMarioState->controller->buttonDown &= ~A_BUTTON; + } + // This code is meant to preserve old Lua mods' ability to set overridePaletteIndex and paletteIndex and still work // as they expected. USE_REAL_PALETTE_VAR is meant to help support cases where mods will do: // np.overridePaletteIndex = np.paletteIndex diff --git a/src/pc/cheats.c b/src/pc/cheats.c index adcc4efe0..c4528f39b 100644 --- a/src/pc/cheats.c +++ b/src/pc/cheats.c @@ -1,3 +1,3 @@ #include "cheats.h" -struct CheatList Cheats; +struct Cheats gCheats; diff --git a/src/pc/cheats.h b/src/pc/cheats.h index 0bf1ab429..c28247be0 100644 --- a/src/pc/cheats.h +++ b/src/pc/cheats.h @@ -2,16 +2,21 @@ #define _CHEATS_H #include +#include "network/network.h" -struct CheatList { - bool enabled; +#define SUPER_SPEED_MULTIPLIER 4 + +struct Cheats { bool moonJump; bool godMode; bool infiniteLives; bool superSpeed; - bool responsive; + bool responsiveControls; + bool rapidFireA; + bool alwaysTripleJump; + bool bljAnywhere; }; -extern struct CheatList Cheats; +extern struct Cheats gCheats; #endif // _CHEATS_H diff --git a/src/pc/cliopts.c b/src/pc/cliopts.c index 720d7a8e7..77cf84092 100644 --- a/src/pc/cliopts.c +++ b/src/pc/cliopts.c @@ -71,7 +71,7 @@ void parse_cli_opts(int argc, char* argv[]) { } } else if (strcmp(argv[i], "--cheats") == 0) // Enable cheats menu - Cheats.enabled = true; + gServerSettings.enableCheats = true; else if (strcmp(argv[i], "--poolsize") == 0) // Main pool size arg_uint("--poolsize", argv[++i], &gCLIOpts.PoolSize); diff --git a/src/pc/djui/djui_panel_cheats.c b/src/pc/djui/djui_panel_cheats.c index 3d3d0c8d7..01136dbe9 100644 --- a/src/pc/djui/djui_panel_cheats.c +++ b/src/pc/djui/djui_panel_cheats.c @@ -2,7 +2,7 @@ #include "pc/cheats.h" void djui_panel_cheats_create(struct DjuiBase* caller) { - f32 bodyHeight = 32 * 5 + 64 * 1 + 16 * 6; + f32 bodyHeight = 32 * 8 + 64 * 1 + 16 * 9; struct DjuiBase* defaultBase = NULL; struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\C\\#1be700\\H\\#00b3ff\\E\\#ffef00\\A\\#ff0800\\T\\#1be700\\S"); @@ -10,28 +10,43 @@ void djui_panel_cheats_create(struct DjuiBase* caller) { { { - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Moon jump", &Cheats.moonJump); + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Moon Jump", &gCheats.moonJump); djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); defaultBase = &checkbox->base; } { - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "God mode", &Cheats.godMode); + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "God Mode", &gCheats.godMode); djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); } { - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Infinite lives", &Cheats.infiniteLives); + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Infinite Lives", &gCheats.infiniteLives); djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); } { - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Super speed", &Cheats.superSpeed); + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Super Speed", &gCheats.superSpeed); djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); } { - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Responsive controls", &Cheats.responsive); + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Responsive Controls", &gCheats.responsiveControls); + djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox->base, 1.0f, 32); + } + { + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Rapid Fire (A)", &gCheats.rapidFireA); + djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox->base, 1.0f, 32); + } + { + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "BLJ Anywhere", &gCheats.bljAnywhere); + djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&checkbox->base, 1.0f, 32); + } + { + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Always Triple Jump", &gCheats.alwaysTripleJump); djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); } diff --git a/src/pc/djui/djui_panel_pause.c b/src/pc/djui/djui_panel_pause.c index 52473c166..526b31ab5 100644 --- a/src/pc/djui/djui_panel_pause.c +++ b/src/pc/djui/djui_panel_pause.c @@ -36,7 +36,7 @@ void djui_panel_pause_create(struct DjuiBase* caller) { if (gDjuiChatBoxFocus) { djui_chat_box_toggle(); } f32 bodyHeight = 64 * 5 + 16 * 4; - if (Cheats.enabled) { bodyHeight += 64 + 16; } + if (gServerSettings.enableCheats) { bodyHeight += 64 + 16; } struct DjuiBase* defaultBase = NULL; struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\P\\#1be700\\A\\#00b3ff\\U\\#ffef00\\S\\#ff0800\\E"); @@ -65,7 +65,7 @@ void djui_panel_pause_create(struct DjuiBase* caller) { djui_interactable_hook_click(&button3->base, djui_panel_options_create); defaultBase = &button3->base; - if (Cheats.enabled) { + if (gServerSettings.enableCheats) { struct DjuiButton* button4 = djui_button_create(&body->base, "Cheats"); djui_base_set_size_type(&button4->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button4->base, 1.0f, 64); diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 2f30815f0..06ad8df15 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -111,7 +111,6 @@ bool network_init(enum NetworkType inNetworkType) { #else gServerSettings.headlessServer = 0; #endif - Cheats.enabled = gServerSettings.enableCheats; // initialize the network system gNetworkSentJoin = false; diff --git a/src/pc/network/packets/packet_join.c b/src/pc/network/packets/packet_join.c index 4541191ae..5fb5e2d31 100644 --- a/src/pc/network/packets/packet_join.c +++ b/src/pc/network/packets/packet_join.c @@ -181,8 +181,6 @@ void network_receive_join(struct Packet* p) { packet_read(p, eeprom, sizeof(u8) * 512); packet_read(p, &modCount, sizeof(u8)); - Cheats.enabled = gServerSettings.enableCheats; - struct StringLinkedList head = { 0 }; for (s32 i = 0; i < modCount; i++) { char* modName = (char*) &p->buffer[p->cursor];