diff --git a/mods/extended-moveset.lua b/mods/extended-moveset.lua deleted file mode 100644 index 91d5ee2cd..000000000 --- a/mods/extended-moveset.lua +++ /dev/null @@ -1,1520 +0,0 @@ --- name: Extended Moveset --- incompatible: moveset --- description: Adds various new moves from games like Sunshine and Odyssey without replacing any existing ones.\n\nOriginal author: TheGag96 - -local enable_extended_moveset = true - ------------------------------- ------ Localize functions ----- ------------------------------- - -local allocate_mario_action, atan2s, sins, coss, mario_update_moving_sand, mario_update_windy_ground, mario_floor_is_slope, mario_set_forward_vel, set_mario_action, queue_rumble_data_mario, set_jumping_action, play_mario_sound, play_sound, set_mario_animation, common_slide_action, set_anim_to_frame, check_fall_damage_or_get_stuck, play_sound_and_spawn_particles, mario_bonk_reflection, play_mario_landing_sound_once, common_air_action_step, perform_air_step, should_get_stuck_in_ground, play_mario_heavy_landing_sound, check_fall_damage, set_camera_shake_from_hit, drop_and_set_mario_action, stationary_ground_step, check_common_action_exits, stopping_step, mario_drop_held_object, perform_water_step, perform_water_full_step, vec3f_copy, vec3s_set, approach_f32, is_anim_at_end, float_surface_gfx, set_swimming_at_surface_particles, apply_water_current, update_air_without_turn, play_mario_landing_sound, lava_boost_on_wall, check_kick_or_dive_in_air, update_sliding, mario_check_object_grab, mario_grab_used_object, analog_stick_held_back, approach_s32, apply_slope_accel, should_begin_sliding, begin_braking_action, set_jump_from_landing, check_ground_dive_or_punch, anim_and_audio_for_walk, perform_ground_step, push_or_sidle_wall, check_ledge_climb_down, tilt_body_walking, anim_and_audio_for_hold_walk, anim_and_audio_for_heavy_walk, align_with_floor, set_mario_anim_with_accel, play_step_sound = - allocate_mario_action, atan2s, sins, coss, mario_update_moving_sand, mario_update_windy_ground, mario_floor_is_slope, mario_set_forward_vel, set_mario_action, queue_rumble_data_mario, set_jumping_action, play_mario_sound, play_sound, set_mario_animation, common_slide_action, set_anim_to_frame, check_fall_damage_or_get_stuck, play_sound_and_spawn_particles, mario_bonk_reflection, play_mario_landing_sound_once, common_air_action_step, perform_air_step, should_get_stuck_in_ground, play_mario_heavy_landing_sound, check_fall_damage, set_camera_shake_from_hit, drop_and_set_mario_action, stationary_ground_step, check_common_action_exits, stopping_step, mario_drop_held_object, perform_water_step, perform_water_full_step, vec3f_copy, vec3s_set, approach_f32, is_anim_at_end, float_surface_gfx, set_swimming_at_surface_particles, apply_water_current, update_air_without_turn, play_mario_landing_sound, lava_boost_on_wall, check_kick_or_dive_in_air, update_sliding, mario_check_object_grab, mario_grab_used_object, analog_stick_held_back, approach_s32, apply_slope_accel, should_begin_sliding, begin_braking_action, set_jump_from_landing, check_ground_dive_or_punch, anim_and_audio_for_walk, perform_ground_step, push_or_sidle_wall, check_ledge_climb_down, tilt_body_walking, anim_and_audio_for_hold_walk, anim_and_audio_for_heavy_walk, align_with_floor, set_mario_anim_with_accel, play_step_sound -local math_sqrt, math_min, math_max, math_floor = math.sqrt, math.min, math.max, math.floor - ------------------------- --- initialize actions -- ------------------------- - -local ACT_SPIN_POUND_LAND = allocate_mario_action(ACT_GROUP_STATIONARY | ACT_FLAG_STATIONARY | ACT_FLAG_ATTACKING) -local ACT_ROLL = allocate_mario_action(ACT_GROUP_MOVING | ACT_FLAG_MOVING | ACT_FLAG_BUTT_OR_STOMACH_SLIDE) -local ACT_GROUND_POUND_JUMP = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) -local ACT_SPIN_JUMP = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) -local ACT_SPIN_POUND = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ATTACKING) -local ACT_LEDGE_PARKOUR = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR) -local ACT_ROLL_AIR = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) -local ACT_WALL_SLIDE = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_MOVING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) -local ACT_WATER_GROUND_POUND = allocate_mario_action(ACT_GROUP_SUBMERGED | ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT | ACT_FLAG_ATTACKING) -local ACT_WATER_GROUND_POUND_LAND = allocate_mario_action(ACT_GROUP_SUBMERGED | ACT_FLAG_STATIONARY | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT) -local ACT_WATER_GROUND_POUND_STROKE = allocate_mario_action(ACT_GROUP_SUBMERGED | ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT) -local ACT_WATER_GROUND_POUND_JUMP = allocate_mario_action(ACT_GROUP_SUBMERGED | ACT_FLAG_MOVING | ACT_FLAG_SWIMMING | ACT_FLAG_SWIMMING_OR_FLYING | ACT_FLAG_WATER_OR_TEXT) -local ACT_CUSTOM_DIVE_SLIDE = allocate_mario_action(ACT_GROUP_MOVING | ACT_FLAG_MOVING | ACT_FLAG_DIVING | ACT_FLAG_ATTACKING) -local ACT_CUSTOM_WALKING = allocate_mario_action(ACT_GROUP_MOVING | ACT_FLAG_MOVING | ACT_FLAG_ALLOW_FIRST_PERSON) -local ACT_CUSTOM_HOLD_WALKING = allocate_mario_action(ACT_GROUP_MOVING | ACT_FLAG_MOVING) -local ACT_CUSTOM_HOLD_HEAVY_WALKING = allocate_mario_action(ACT_GROUP_MOVING | ACT_FLAG_MOVING) -local ACT_CUSTOM_FINISH_TURNING_AROUND = allocate_mario_action(ACT_GROUP_MOVING | ACT_FLAG_MOVING) -local ACT_CUSTOM_CRAWLING = allocate_mario_action(ACT_GROUP_MOVING | ACT_FLAG_MOVING | ACT_FLAG_SHORT_HITBOX | ACT_FLAG_ALLOW_FIRST_PERSON) -local ACT_CUSTOM_AIR_HIT_WALL = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR) - ------------------------------ --- initialize extra fields -- ------------------------------ - -local ANGLE_QUEUE_SIZE = 9 -local SPIN_TIMER_SUCCESSFUL_INPUT = 4 - -local gMarioStateExtras = {} -for i=0,(MAX_PLAYERS-1) do - gMarioStateExtras[i] = {} - local m = gMarioStates[i] - local e = gMarioStateExtras[i] - e.angleDeltaQueue = {} - for j=0,(ANGLE_QUEUE_SIZE-1) do e.angleDeltaQueue[j] = 0 end - e.rotAngle = 0 - e.boostTimer = 0 - - e.stickLastAngle = 0 - e.spinDirection = 0 - e.spinBufferTimer = 0 - e.spinInput = 0 - e.lastIntendedMag = 0 - - e.lastPos = {} - e.lastPos.x = m.pos.x - e.lastPos.y = m.pos.y - e.lastPos.z = m.pos.z - - e.fakeSavedAction = 0 - e.fakeSavedPrevAction = 0 - e.fakeSavedActionTimer = 0 - e.fakeWroteAction = 0 - e.fakeSaved = false - - e.savedWallSlideHeight = 0 - e.savedWallSlide = false -end - -local function limit_angle(a) - return (a + 0x8000) % 0x10000 - 0x8000 -end - ----------- --- roll -- ----------- - -local function update_roll_sliding_angle(m, accel, lossFactor) - local floor = m.floor - local slopeAngle = atan2s(floor.normal.z, floor.normal.x) - local steepness = math_sqrt(floor.normal.x * floor.normal.x + floor.normal.z * floor.normal.z) - - m.slideVelX = m.slideVelX + accel * steepness * sins(slopeAngle) - m.slideVelZ = m.slideVelZ + accel * steepness * coss(slopeAngle) - - m.slideVelX = m.slideVelX * lossFactor - m.slideVelZ = m.slideVelZ * lossFactor - - m.slideYaw = atan2s(m.slideVelZ, m.slideVelX) - - local facingDYaw = limit_angle(m.faceAngle.y - m.slideYaw) - local newFacingDYaw = facingDYaw - - if newFacingDYaw > 0 and newFacingDYaw <= 0x8000 then - newFacingDYaw = newFacingDYaw - 0x800 - if newFacingDYaw < 0 then newFacingDYaw = 0 end - - elseif newFacingDYaw >= -0x8000 and newFacingDYaw < 0 then - newFacingDYaw = newFacingDYaw + 0x800 - if newFacingDYaw > 0 then newFacingDYaw = 0 end - end - - m.faceAngle.y = limit_angle(m.slideYaw + newFacingDYaw) - - m.vel.x = m.slideVelX - m.vel.y = 0.0 - m.vel.z = m.slideVelZ - - mario_update_moving_sand(m) - mario_update_windy_ground(m) - - --! Speed is capped a frame late (butt slide HSG) - m.forwardVel = math_sqrt(m.slideVelX * m.slideVelX + m.slideVelZ * m.slideVelZ) - if m.forwardVel > 100.0 then - m.slideVelX = m.slideVelX * 100.0 / m.forwardVel - m.slideVelZ = m.slideVelZ * 100.0 / m.forwardVel - end -end - -local function update_roll_sliding(m, stopSpeed) - local stopped = 0 - - local intendedDYaw = m.intendedYaw - m.slideYaw - local forward = coss(intendedDYaw) - local sideward = sins(intendedDYaw) - - --! 10k glitch - if forward < 0.0 and m.forwardVel >= 0.0 then - forward = forward * (0.5 + 0.5 * m.forwardVel / 100.0) - end - - local accel = 4.0 - local lossFactor = 0.994 - - local oldSpeed = math_sqrt(m.slideVelX * m.slideVelX + m.slideVelZ * m.slideVelZ) - - --! This is uses trig derivatives to rotate Mario's speed. - -- In vanilla, it was slightly off/asymmetric since it uses the new X speed, but the old - -- Z speed. I've gone and fixed it here. - local angleChange = (m.intendedMag / 32.0) * 0.6 - local modSlideVelX = m.slideVelZ * angleChange * sideward * 0.05 - local modSlideVelZ = m.slideVelX * angleChange * sideward * 0.05 - - m.slideVelX = m.slideVelX + modSlideVelX - m.slideVelZ = m.slideVelZ - modSlideVelZ - - local newSpeed = math_sqrt(m.slideVelX * m.slideVelX + m.slideVelZ * m.slideVelZ) - - if oldSpeed > 0.0 and newSpeed > 0.0 then - m.slideVelX = m.slideVelX * oldSpeed / newSpeed - m.slideVelZ = m.slideVelZ * oldSpeed / newSpeed - end - - update_roll_sliding_angle(m, accel, lossFactor) - - if m.playerIndex == 0 and mario_floor_is_slope(m) == 0 and m.forwardVel * m.forwardVel < stopSpeed * stopSpeed then - mario_set_forward_vel(m, 0.0) - stopped = 1 - end - - return stopped -end - -local function act_roll(m) - local e = gMarioStateExtras[m.playerIndex] - - local MAX_NORMAL_ROLL_SPEED = 50.0 - local ROLL_BOOST_GAIN = 10.0 - local ROLL_CANCEL_LOCKOUT_TIME = 10 - local BOOST_LOCKOUT_TIME = 20 - - -- e.rotAngle is used for Mario's rotation angle during the roll (persists when going into ACT_ROLL_AIR and back) - -- e.boostTimer is used for the boost lockout timer (persists when going into ACT_ROLL_AIR and back) - -- m.actionTimer is used to lockout walk canceling out of rollout (reset each action switch) - - if m.actionTimer == 0 then - if m.prevAction ~= ACT_ROLL_AIR then - e.rotAngle = 0 - e.boostTimer = 0 - end - elseif m.actionTimer >= ROLL_CANCEL_LOCKOUT_TIME or m.actionArg == 1 then - if (m.input & INPUT_Z_DOWN) == 0 then - return set_mario_action(m, ACT_WALKING, 0) - end - end - - if (m.input & INPUT_B_PRESSED) ~= 0 then - queue_rumble_data_mario(m, 5, 80) - return set_jumping_action(m, ACT_FORWARD_ROLLOUT, 0) - end - - if (m.input & INPUT_A_PRESSED) ~= 0 then - return set_jumping_action(m, ACT_LONG_JUMP, 0) - end - - if (m.controller.buttonPressed & X_BUTTON) ~= 0 and m.actionTimer > 0 then - m.vel.y = 19.0 - play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0) - - if e.boostTimer >= BOOST_LOCKOUT_TIME then - e.boostTimer = 0 - - if m.forwardVel < MAX_NORMAL_ROLL_SPEED then - mario_set_forward_vel(m, math_min(m.forwardVel + ROLL_BOOST_GAIN, MAX_NORMAL_ROLL_SPEED)) - end - - m.particleFlags = m.particleFlags | PARTICLE_HORIZONTAL_STAR - - -- ! playing this after the call to play_mario_sound seems to matter in making this sound play - play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) - end - - return set_mario_action(m, ACT_ROLL_AIR, m.actionArg) - end - - set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING) - - if update_roll_sliding(m, 10.0) ~= 0 then - return set_mario_action(m, ACT_CROUCH_SLIDE, 0) - end - - common_slide_action(m, ACT_CROUCH_SLIDE, ACT_ROLL_AIR, MARIO_ANIM_FORWARD_SPINNING) - - e.rotAngle = e.rotAngle + (0x80 * m.forwardVel) - if e.rotAngle > 0x10000 then - e.rotAngle = e.rotAngle - 0x10000 - end - set_anim_to_frame(m, 10 * e.rotAngle / 0x10000) - - e.boostTimer = e.boostTimer + 1 - - m.actionTimer = m.actionTimer + 1 - - return 0 -end - -local function act_roll_air(m) - local e = gMarioStateExtras[m.playerIndex] - local MAX_NORMAL_ROLL_SPEED = 50.0 - local ROLL_AIR_CANCEL_LOCKOUT_TIME = 15 - - if m.actionTimer == 0 then - if m.prevAction ~= ACT_ROLL then - e.rotAngle = 0 - e.boostTimer = 0 - end - end - - if (m.input & INPUT_Z_DOWN) == 0 and m.actionTimer >= ROLL_AIR_CANCEL_LOCKOUT_TIME then - return set_mario_action(m, ACT_FREEFALL, 0) - end - - set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING) - - local air_step = perform_air_step(m, 0) - if air_step == AIR_STEP_LANDED then - if check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB) == 0 then - play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_STEP, 0) - return set_mario_action(m, ACT_ROLL, m.actionArg) - end - elseif air_step == AIR_STEP_HIT_WALL then - queue_rumble_data_mario(m, 5, 40) - mario_bonk_reflection(m, false) - m.faceAngle.y = m.faceAngle.y + 0x8000 - - if m.vel.y > 0.0 then - m.vel.y = 0.0 - end - - m.particleFlags = m.particleFlags | PARTICLE_VERTICAL_STAR - return set_mario_action(m, ACT_BACKWARD_AIR_KB, 0) - end - - e.rotAngle = e.rotAngle + 0x80 * m.forwardVel - if e.rotAngle > 0x10000 then - e.rotAngle = e.rotAngle - 0x10000 - end - - set_anim_to_frame(m, 10 * e.rotAngle / 0x10000) - - e.boostTimer = e.boostTimer + 1 - m.actionTimer = m.actionTimer + 1 - - return false -end - -local function update_roll(m) - if m.action == ACT_DIVE_SLIDE then - if (m.input & INPUT_ABOVE_SLIDE) == 0 then - if (m.input & INPUT_Z_DOWN) ~= 0 and m.actionTimer < 2 then - return set_mario_action(m, ACT_ROLL, 1) - end - end - m.actionTimer = m.actionTimer + 1 - end - - if m.action == ACT_LONG_JUMP_LAND then - if (m.input & INPUT_Z_DOWN) ~= 0 and m.forwardVel > 15.0 and m.actionTimer < 1 then - play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING) - return set_mario_action(m, ACT_ROLL, 1) - end - end - - if m.action == ACT_CROUCHING then - if (m.controller.buttonPressed & X_BUTTON) ~= 0 then - m.vel.y = 19.0 - mario_set_forward_vel(m, 32.0) - play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0) - - play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) - - return set_mario_action(m, ACT_ROLL_AIR, 0) - end - end - - if m.action == ACT_CROUCH_SLIDE then - if (m.controller.buttonPressed & X_BUTTON) ~= 0 then - m.vel.y = 19.0 - mario_set_forward_vel(m, math_max(32, m.forwardVel)) - play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0) - - play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) - - return set_mario_action(m, ACT_ROLL_AIR, 0) - end - end - - if m.action == ACT_GROUND_POUND_LAND then - if (m.controller.buttonPressed & X_BUTTON) ~= 0 then - mario_set_forward_vel(m, 60) - - play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) - - return set_mario_action(m, ACT_ROLL, 0) - end - end -end - ----------- --- spin -- ----------- - -local function mario_update_spin_input(m) - local e = gMarioStateExtras[m.playerIndex] - local rawAngle = atan2s(-m.controller.stickY, m.controller.stickX) - e.spinInput = 0 - - -- prevent issues due to the frame going out of the dead zone registering the last angle as 0 - if e.lastIntendedMag > 0.5 and m.intendedMag > 0.5 then - local angleOverFrames = 0 - local thisFrameDelta = 0 - -- local i = 0 - - local newDirection = e.spinDirection - local signedOverflow = 0 - - if rawAngle < e.stickLastAngle then - if e.stickLastAngle - rawAngle > 0x8000 then - signedOverflow = 1 - end - if signedOverflow ~= 0 then - newDirection = 1 - else - newDirection = -1 - end - elseif rawAngle > e.stickLastAngle then - if rawAngle - e.stickLastAngle > 0x8000 then - signedOverflow = 1 - end - if signedOverflow ~= 0 then - newDirection = -1 - else - newDirection = 1 - end - end - - if e.spinDirection ~= newDirection then - for i=0,(ANGLE_QUEUE_SIZE-1) do - e.angleDeltaQueue[i] = 0 - end - e.spinDirection = newDirection - else - for i=(ANGLE_QUEUE_SIZE-1),1,-1 do - e.angleDeltaQueue[i] = e.angleDeltaQueue[i-1] - angleOverFrames = angleOverFrames + e.angleDeltaQueue[i] - end - end - - if e.spinDirection < 0 then - if signedOverflow ~= 0 then - thisFrameDelta = math_floor((1.0*e.stickLastAngle + 0x10000) - rawAngle) - else - thisFrameDelta = e.stickLastAngle - rawAngle - end - elseif e.spinDirection > 0 then - if signedOverflow ~= 0 then - thisFrameDelta = math_floor(1.0*rawAngle + 0x10000 - e.stickLastAngle) - else - thisFrameDelta = rawAngle - e.stickLastAngle - end - end - - e.angleDeltaQueue[0] = thisFrameDelta - angleOverFrames = angleOverFrames + thisFrameDelta - - if angleOverFrames >= 0xA000 then - e.spinBufferTimer = SPIN_TIMER_SUCCESSFUL_INPUT - end - - - -- allow a buffer after a successful input so that you can switch directions - if e.spinBufferTimer > 0 then - e.spinInput = 1 - e.spinBufferTimer = e.spinBufferTimer - 1 - end - else - e.spinDirection = 0 - e.spinBufferTimer = 0 - end - - e.stickLastAngle = rawAngle - e.lastIntendedMag = m.intendedMag -end - -local function act_spin_jump(m) - local e = gMarioStateExtras[m.playerIndex] - if m.actionTimer == 0 then - -- determine clockwise/counter-clockwise spin - if e.spinDirection < 0 then - m.actionState = 1 - end - elseif m.actionTimer == 1 or m.actionTimer == 4 then - play_sound(SOUND_ACTION_TWIRL, m.marioObj.header.gfx.cameraToObject) - end - - local spinDirFactor = 1 -- negative for clockwise, positive for counter-clockwise - if m.actionState == 1 then - spinDirFactor = -1 - end - - if (m.input & INPUT_B_PRESSED) ~= 0 then - return set_mario_action(m, ACT_DIVE, 0) - end - - if (m.input & INPUT_Z_PRESSED) ~= 0 then - play_sound(SOUND_ACTION_TWIRL, m.marioObj.header.gfx.cameraToObject) - - m.vel.y = -50.0 - mario_set_forward_vel(m, 0.0) - - -- choose which direction to be facing on land (practically random if no input) - if (m.input & INPUT_NONZERO_ANALOG) ~= 0 then - m.faceAngle.y = m.intendedYaw - else - m.faceAngle.y = limit_angle(e.rotAngle) - end - - return set_mario_action(m, ACT_SPIN_POUND, m.actionState) - end - - play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, CHAR_SOUND_YAHOO) - - common_air_action_step(m, ACT_DOUBLE_JUMP_LAND, MARIO_ANIM_TWIRL, - AIR_STEP_CHECK_HANG) - - e.rotAngle = e.rotAngle + 0x2867 - if (e.rotAngle > 0x10000) then e.rotAngle = e.rotAngle - 0x10000 end - if (e.rotAngle < -0x10000) then e.rotAngle = e.rotAngle + 0x10000 end - m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y + (e.rotAngle * spinDirFactor)) - - m.actionTimer = m.actionTimer + 1 - - return false -end - -local function act_spin_jump_gravity(m) - if (m.flags & MARIO_WING_CAP) ~= 0 and m.vel.y < 0.0 and (m.input & INPUT_A_DOWN) ~= 0 then - m.marioBodyState.wingFlutter = 1 - m.vel.y = m.vel.y - 0.7 - if m.vel.y < -37.5 then - m.vel.y = m.vel.y + 1.4 - if m.vel.y > -37.5 then - m.vel.y = -37.5 - end - end - else - if m.vel.y > 0 then - m.vel.y = m.vel.y - 4 - else - m.vel.y = m.vel.y - 1.4 - end - - if m.vel.y < -75.0 then - m.vel.y = -75.0 - end - end - - return 0 -end - -local function act_spin_pound(m) - local e = gMarioStateExtras[m.playerIndex] - if m.actionTimer == 0 then - m.actionState = m.actionArg - end - - local spinDirFactor = 1 -- negative for clockwise, positive for counter-clockwise - if m.actionState == 1 then spinDirFactor = -1 end - - set_mario_animation(m, MARIO_ANIM_TWIRL) - - if (m.input & INPUT_B_PRESSED) ~= 0 then - mario_set_forward_vel(m, 10.0) - m.vel.y = 35 - set_mario_action(m, ACT_DIVE, 0) - end - - local stepResult = perform_air_step(m, 0) - if stepResult == AIR_STEP_LANDED then - if should_get_stuck_in_ground(m) ~= 0 then - queue_rumble_data_mario(m, 5, 80) - play_sound(CHAR_SOUND_OOOF2, m.marioObj.header.gfx.cameraToObject) - m.particleFlags = m.particleFlags | PARTICLE_MIST_CIRCLE - set_mario_action(m, ACT_BUTT_STUCK_IN_GROUND, 0) - else - play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_HEAVY_LANDING) - if check_fall_damage(m, ACT_HARD_BACKWARD_GROUND_KB) == 0 then - m.particleFlags = m.particleFlags | PARTICLE_MIST_CIRCLE | PARTICLE_HORIZONTAL_STAR - set_mario_action(m, ACT_SPIN_POUND_LAND, 0) - end - end - set_camera_shake_from_hit(SHAKE_GROUND_POUND) - elseif stepResult == AIR_STEP_HIT_WALL then - mario_set_forward_vel(m, -16.0) - if m.vel.y > 0.0 then - m.vel.y = 0.0 - end - - m.particleFlags = m.particleFlags | PARTICLE_VERTICAL_STAR - set_mario_action(m, ACT_BACKWARD_AIR_KB, 0) - end - - -- set facing direction - -- not part of original Extended Moveset - local yawDiff = m.faceAngle.y - m.intendedYaw - e.rotAngle = limit_angle(e.rotAngle + yawDiff) - m.faceAngle.y = m.intendedYaw - - e.rotAngle = e.rotAngle + 0x3053 - if e.rotAngle > 0x10000 then e.rotAngle = e.rotAngle - 0x10000 end - if e.rotAngle < -0x10000 then e.rotAngle = e.rotAngle + 0x10000 end - m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y + e.rotAngle * spinDirFactor) - - m.actionTimer = m.actionTimer + 1 - - return 0 -end - -local function act_spin_pound_land(m) - m.actionState = 1 - - if m.actionTimer <= 8 then - if (m.input & INPUT_UNKNOWN_10) ~= 0 then - return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0) - end - - if (m.input & INPUT_OFF_FLOOR) ~= 0 then - return set_mario_action(m, ACT_FREEFALL, 0) - end - - if (m.input & INPUT_ABOVE_SLIDE) ~= 0 then - return set_mario_action(m, ACT_BUTT_SLIDE, 0) - end - - if (m.input & INPUT_A_PRESSED) ~= 0 then - return set_jumping_action(m, ACT_GROUND_POUND_JUMP, 0) - end - - if (m.controller.buttonPressed & X_BUTTON) ~= 0 then - mario_set_forward_vel(m, 60) - - play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) - return set_mario_action(m, ACT_ROLL, 0) - end - - stationary_ground_step(m) - set_mario_animation(m, MARIO_ANIM_LAND_FROM_DOUBLE_JUMP) - else - if (m.input & INPUT_UNKNOWN_10) ~= 0 then - return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0) - end - - if (m.input & (INPUT_NONZERO_ANALOG | INPUT_A_PRESSED | INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE)) ~= 0 then - return check_common_action_exits(m) - end - - stopping_step(m, MARIO_ANIM_LAND_FROM_DOUBLE_JUMP, ACT_IDLE) - end - - m.actionTimer = m.actionTimer + 1 - - return 0 -end - ----------------- --- wall slide -- ----------------- - -local function act_wall_slide(m) - local e = gMarioStateExtras[m.playerIndex] - e.savedWallSlideHeight = m.pos.y - e.savedWallSlide = true - - if (m.input & INPUT_A_PRESSED) ~= 0 then - m.vel.y = 52.0 - -- m.faceAngle.y = limit_angle(m.faceAngle.y + 0x8000) - return set_mario_action(m, ACT_WALL_KICK_AIR, 0) - end - - -- attempt to stick to the wall a bit. if it's 0, sometimes you'll get kicked off of slightly sloped walls - mario_set_forward_vel(m, -1.0) - - m.particleFlags = m.particleFlags | PARTICLE_DUST - - play_sound(SOUND_MOVING_TERRAIN_SLIDE + m.terrainSoundAddend, m.marioObj.header.gfx.cameraToObject) - set_mario_animation(m, MARIO_ANIM_START_WALLKICK) - - if perform_air_step(m, 0) == AIR_STEP_LANDED then - mario_set_forward_vel(m, 0.0) - if check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB) == 0 then - return set_mario_action(m, ACT_FREEFALL_LAND, 0) - end - end - - m.actionTimer = m.actionTimer + 1 - if not m.wall and m.actionTimer > 2 then - mario_set_forward_vel(m, 0.0) - return set_mario_action(m, ACT_FREEFALL, 0) - end - - return 0 -end - -local function act_wall_slide_gravity(m) - m.vel.y = m.vel.y - 2 - - if m.vel.y < -15 then - m.vel.y = -15 - end -end - -local function act_air_hit_wall(m) - if m.heldObj ~= 0 then - mario_drop_held_object(m) - end - - m.actionTimer = m.actionTimer + 1 - if m.actionTimer <= 1 and (m.input & INPUT_A_PRESSED) ~= 0 then - m.vel.y = 52.0 - m.faceAngle.y = limit_angle(m.faceAngle.y + 0x8000) - return set_mario_action(m, ACT_WALL_KICK_AIR, 0) - elseif m.forwardVel >= 38.0 then - m.wallKickTimer = 5 - if m.vel.y > 0.0 then - m.vel.y = 0.0 - end - - m.particleFlags = m.particleFlags | PARTICLE_VERTICAL_STAR - return set_mario_action(m, ACT_BACKWARD_AIR_KB, 0) - else - m.faceAngle.y = limit_angle(m.faceAngle.y + 0x8000) - return set_mario_action(m, ACT_WALL_SLIDE, 0) - end - - --! Missing return statement (in original C code). The returned value is the result of the call - -- to set_mario_animation. In practice, this value is nonzero. - -- This results in this action "cancelling" into itself. It is supposed to - -- execute three times, each on a separate frame, but instead it executes - -- three times on the same frame. - -- This results in firsties only being possible for a single frame, instead - -- of three. - return set_mario_animation(m, MARIO_ANIM_START_WALLKICK) -end - ------------------------- --- water ground pound -- ------------------------- - -local function act_water_ground_pound(m) - local GROUND_POUND_STROKE_SPEED = 27 - local GROUND_POUND_TIMER = 30 - - local stepResult = 0 - - if m.actionTimer == 0 then - -- coming into action from normal ground pound - if m.actionArg == 1 then - -- copied from water plunge code - play_sound(SOUND_ACTION_UNKNOWN430, m.marioObj.header.gfx.cameraToObject) - if m.peakHeight - m.pos.y > 1150.0 then - play_sound(CHAR_SOUND_HAHA_2, m.marioObj.header.gfx.cameraToObject) - end - - m.particleFlags = m.particleFlags | PARTICLE_WATER_SPLASH - - if (m.prevAction & ACT_FLAG_AIR) ~= 0 then - queue_rumble_data_mario(m, 5, 80) - end - end - - m.actionState = m.actionArg - elseif m.actionTimer == 1 then - play_sound(SOUND_ACTION_SWIM, m.marioObj.header.gfx.cameraToObject) - end - - if m.actionState == 0 then - if m.actionTimer == 0 then - m.vel.y = 0.0 - mario_set_forward_vel(m, 0.0) - end - - m.faceAngle.x = 0 - m.faceAngle.z = 0 - - set_mario_animation(m, MARIO_ANIM_START_GROUND_POUND) - if m.actionTimer == 0 then - play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) - end - - m.actionTimer = m.actionTimer + 1 - if (m.actionTimer >= m.marioObj.header.gfx.animInfo.curAnim.loopEnd + 4) then - -- play_sound(CHAR_SOUND_GROUND_POUND_WAH, m.marioObj.header.gfx.cameraToObject) - play_sound(SOUND_ACTION_SWIM_FAST, m.marioObj.header.gfx.cameraToObject) - m.vel.y = -45.0 - m.actionState = 1 - end - - if (m.input & INPUT_A_PRESSED) ~= 0 then - mario_set_forward_vel(m, GROUND_POUND_STROKE_SPEED) - m.vel.y = 0 - return set_mario_action(m, ACT_WATER_GROUND_POUND_STROKE, 0) - end - - -- make current apply - stepResult = perform_water_step(m) - else - set_mario_animation(m, MARIO_ANIM_GROUND_POUND) - - m.particleFlags = m.particleFlags | PARTICLE_PLUNGE_BUBBLE - - local nextPos = {} - nextPos.x = m.pos.x + m.vel.x - nextPos.y = m.pos.y + m.vel.y - nextPos.z = m.pos.z + m.vel.z - - -- call this one to make current NOT apply - stepResult = perform_water_full_step(m, nextPos) - - vec3f_copy(m.marioObj.header.gfx.pos, m.pos) - vec3s_set(m.marioObj.header.gfx.angle, -m.faceAngle.x, m.faceAngle.y, m.faceAngle.z) - - if stepResult == WATER_STEP_HIT_FLOOR then - play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_HEAVY_LANDING) - m.particleFlags = m.particleFlags | PARTICLE_MIST_CIRCLE | PARTICLE_HORIZONTAL_STAR - set_mario_action(m, ACT_WATER_GROUND_POUND_LAND, 0) - set_camera_shake_from_hit(SHAKE_GROUND_POUND) - else - if (m.input & INPUT_A_PRESSED) ~= 0 then - mario_set_forward_vel(m, GROUND_POUND_STROKE_SPEED) - m.vel.y = 0 - return set_mario_action(m, ACT_WATER_GROUND_POUND_STROKE, 0) - end - - m.vel.y = approach_f32(m.vel.y, 0, 2.0, 2.0) - - mario_set_forward_vel(m, 0.0) - - if m.actionTimer >= GROUND_POUND_TIMER or m.vel.y >= 0.0 then - set_mario_action(m, ACT_WATER_ACTION_END, 0) - end - end - - m.actionTimer = m.actionTimer + 1 - end - - return 0 -end - -local function act_water_ground_pound_land(m) - local GROUND_POUND_JUMP_VEL = 40.0 - - m.actionState = 1 - - if (m.input & INPUT_OFF_FLOOR) ~= 0 then - return set_mario_action(m, ACT_WATER_IDLE, 0) - end - - if (m.input & INPUT_A_PRESSED) ~= 0 then - m.vel.y = GROUND_POUND_JUMP_VEL - play_sound(SOUND_ACTION_SWIM_FAST, m.marioObj.header.gfx.cameraToObject) - return set_mario_action(m, ACT_WATER_GROUND_POUND_JUMP, 0) - end - - m.vel.y = 0.0 - m.pos.y = m.floorHeight - mario_set_forward_vel(m, 0.0) - - vec3f_copy(m.marioObj.header.gfx.pos, m.pos) - vec3s_set(m.marioObj.header.gfx.angle, 0, m.faceAngle.y, 0) - - set_mario_animation(m, MARIO_ANIM_GROUND_POUND_LANDING) - if is_anim_at_end(m) ~= 0 then - return set_mario_action(m, ACT_SWIMMING_END, 0) - end - - perform_water_step(m) - - return 0 -end - -local function act_water_ground_pound_stroke(m) - local GROUND_POUND_STROKE_TIMER = 20 - local GROUND_POUND_STROKE_DECAY = 0.3 - local stepResult = 0 - - set_mario_animation(m, MARIO_ANIM_SWIM_PART1) - - if m.actionTimer == 0 then - play_sound(SOUND_ACTION_SWIM_FAST, m.marioObj.header.gfx.cameraToObject) - end - - stepResult = perform_water_step(m) - if stepResult == WATER_STEP_HIT_WALL then - return set_mario_action(m, ACT_BACKWARD_WATER_KB, 0) - end - - if m.actionTimer >= GROUND_POUND_STROKE_TIMER then - if (m.input & INPUT_A_DOWN) ~= 0 then - return set_mario_action(m, ACT_FLUTTER_KICK, 0) - else - return set_mario_action(m, ACT_SWIMMING_END, 0) - end - end - m.actionTimer = m.actionTimer + 1 - - mario_set_forward_vel(m, approach_f32(m.forwardVel, 0.0, GROUND_POUND_STROKE_DECAY, GROUND_POUND_STROKE_DECAY)) - - float_surface_gfx(m) - set_swimming_at_surface_particles(m, PARTICLE_WAVE_TRAIL) - - return 0 -end - -local function act_water_ground_pound_jump(m) - local e = gMarioStateExtras[m.playerIndex] - local GROUND_POUND_JUMP_TIMER = 20 - local GROUND_POUND_JUMP_DECAY = 1.4 - - -- set_mario_animation(m, MARIO_ANIM_SWIM_PART1) - set_mario_animation(m, MARIO_ANIM_SINGLE_JUMP) - m.particleFlags = m.particleFlags | PARTICLE_PLUNGE_BUBBLE - - if m.actionTimer == 0 then - e.rotAngle = 0 - end - - local step = {} - vec3f_copy(step, m.vel) - apply_water_current(m, step) - - local nextPos = {} - nextPos.x = m.pos.x + step.x - nextPos.y = m.pos.y + step.y - nextPos.z = m.pos.z + step.z - - local stepResult = perform_water_full_step(m, nextPos) - - vec3f_copy(m.marioObj.header.gfx.pos, m.pos) - vec3s_set(m.marioObj.header.gfx.angle, -m.faceAngle.x, m.faceAngle.y, m.faceAngle.z) - - if m.pos.y > m.waterLevel - 80 then - return set_mario_action(m, ACT_WATER_JUMP, 0) - end - - if m.actionTimer >= GROUND_POUND_JUMP_TIMER then - mario_set_forward_vel(m, m.vel.y) -- normal swim routines will use forwardVel to calculate y speed - m.faceAngle.x = 0x3EFF - if (m.input & INPUT_A_DOWN) ~= 0 then - return set_mario_action(m, ACT_FLUTTER_KICK, 0) - else - return set_mario_action(m, ACT_SWIMMING_END, 0) - end - end - m.actionTimer = m.actionTimer + 1 - - mario_set_forward_vel(m, 0.0) - - m.vel.y = approach_f32(m.vel.y, 0.0, GROUND_POUND_JUMP_DECAY, GROUND_POUND_JUMP_DECAY) - -- m.faceAngle.x = 0x3EFF - - float_surface_gfx(m) - set_swimming_at_surface_particles(m, PARTICLE_WAVE_TRAIL) - - e.rotAngle = e.rotAngle + (0x10000*1.0 - e.rotAngle) / 5.0 - m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y - e.rotAngle) - - return 0 -end - -------------------- --- ledge parkour -- -------------------- - -local function act_ledge_parkour(m) - set_mario_animation(m, MARIO_ANIM_SLIDEFLIP) - - local animFrame = m.marioObj.header.gfx.animInfo.animFrame - - if m.actionTimer == 0 then - play_sound(CHAR_SOUND_HAHA_2, m.marioObj.header.gfx.cameraToObject) - elseif m.actionTimer == 1 then - play_sound(SOUND_ACTION_SIDE_FLIP_UNK, m.marioObj.header.gfx.cameraToObject) - end - - update_air_without_turn(m) - - local step = perform_air_step(m, AIR_STEP_CHECK_LEDGE_GRAB) - if step == AIR_STEP_NONE then - -- play the side flip animation at double speed for a portion of it - if animFrame < 15 then - animFrame = animFrame + 2 - elseif animFrame > 23 then - animFrame = 23 - else - animFrame = animFrame + 1 - end - - set_anim_to_frame(m, animFrame) - m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y + 0x8000 - - elseif step == AIR_STEP_LANDED then - m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y + 0x8000 - set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0) - play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING) - - elseif step == AIR_STEP_HIT_WALL then - m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y + 0x8000 - mario_set_forward_vel(m, 0.0) - - elseif step == AIR_STEP_HIT_LAVA_WALL then - m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y + 0x8000 - lava_boost_on_wall(m) - end - - m.actionTimer = m.actionTimer + 1 - - return 0 -end - -local function act_ground_pound_jump(m) - local e = gMarioStateExtras[m.playerIndex] - if check_kick_or_dive_in_air(m) ~= 0 then - m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y + e.rotAngle - return 1 - end - - if (m.input & INPUT_Z_PRESSED) ~= 0 then - m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y + e.rotAngle - return set_mario_action(m, ACT_GROUND_POUND, 0) - end - - if e.spinInput ~= 0 then - return set_mario_action(m, ACT_SPIN_JUMP, 1) - end - - if m.actionTimer == 0 then - e.rotAngle = 0 - elseif m.actionTimer == 1 then - play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) - end - - play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, CHAR_SOUND_YAHOO) - - common_air_action_step(m, ACT_JUMP_LAND, MARIO_ANIM_SINGLE_JUMP, - AIR_STEP_CHECK_LEDGE_GRAB | AIR_STEP_CHECK_HANG) - - e.rotAngle = e.rotAngle + (0x10000*1.0 - e.rotAngle) / 5.0 - m.marioObj.header.gfx.angle.y = m.marioObj.header.gfx.angle.y - e.rotAngle - - m.actionTimer = m.actionTimer + 1 - - return 0 -end - -------------------------------------- --- dive slide patched for dive hop -- -------------------------------------- - -local function act_dive_slide(m) - if (m.input & INPUT_ABOVE_SLIDE) == 0 and (m.input & INPUT_A_PRESSED) ~= 0 then - queue_rumble_data_mario(m, 5, 80) - if m.forwardVel > 0 then - return set_mario_action(m, ACT_FORWARD_ROLLOUT, 0) - else - return set_mario_action(m, ACT_BACKWARD_ROLLOUT, 0) - end - end - - if (m.input & INPUT_ABOVE_SLIDE) == 0 then - if (m.input & INPUT_B_PRESSED) ~= 0 then - -- dive hop - m.vel.y = 21.0 - return set_mario_action(m, ACT_DIVE, 1) - end - end - - play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND) - - --! If the dive slide ends on the same frame that we pick up on object, - -- Mario will not be in the dive slide action for the call to - -- mario_check_object_grab, and so will end up in the regular picking action, - -- rather than the picking up after dive action. - - if update_sliding(m, 8.0) ~= 0 and is_anim_at_end(m) ~= 0 then - mario_set_forward_vel(m, 0.0) - set_mario_action(m, ACT_STOMACH_SLIDE_STOP, 0) - end - - if mario_check_object_grab(m) ~= 0 then - mario_grab_used_object(m) - if m.heldObj ~= 0 then - m.marioBodyState.grabPos = GRAB_POS_LIGHT_OBJ - end - return true - end - - common_slide_action(m, ACT_STOMACH_SLIDE_STOP, ACT_FREEFALL, MARIO_ANIM_DIVE) - return false -end - -------------------------------------------------------- --- Patched actions using update_walking_speed action -- --- for Tight Controls and modfied speed caps -- -------------------------------------------------------- - -local function update_walking_speed_extended(m) - local maxTargetSpeed = 0 - local targetSpeed = 0 - local firmSpeedCap = 0 - local hardSpeedCap = 105.0 - - if m.prevAction == ACT_ROLL then - firmSpeedCap = 60.0 - else - firmSpeedCap = 48.0 - end - - if m.floor ~= 0 and m.floor.type == SURFACE_SLOW then - maxTargetSpeed = 24.0 - else - maxTargetSpeed = 32.0 - end - - if m.intendedMag < maxTargetSpeed then - targetSpeed = m.intendedMag - else - targetSpeed = maxTargetSpeed - end - - if m.quicksandDepth > 10.0 then - targetSpeed = targetSpeed * (6.25 / m.quicksandDepth) - end - - if m.forwardVel <= 8.0 then - m.forwardVel = math_min(m.intendedMag, 8.0) -- Same fix as Melee dashback (by Kaze) - end - - -- instead of a hard walk speed cap, going over this new firm speed cap makes you slow down to it twice as fast - local decayFactor = 0 - if m.forwardVel > firmSpeedCap then - decayFactor = 2.0 - else - decayFactor = 1.0 - end - - if m.forwardVel <= 0.0 then - m.forwardVel = m.forwardVel + 1.1 - elseif m.forwardVel <= targetSpeed then - m.forwardVel = m.forwardVel + (1.1 - m.forwardVel / 43.0) - elseif m.floor ~= 0 and m.floor.normal.y >= 0.95 then - m.forwardVel = m.forwardVel - decayFactor - else - -- reintroduce the old hardcap for the weird slopes where you kind of just maintain your speed - if (m.forwardVel > firmSpeedCap) then - m.forwardVel = firmSpeedCap; - end - end - - if m.forwardVel > hardSpeedCap then - m.forwardVel = hardSpeedCap - end - - if analog_stick_held_back(m) ~= 0 then - m.faceAngle.y = m.intendedYaw; - - if m.forwardVel < 0 then - mario_set_forward_vel(m, -m.forwardVel); - end - else - m.faceAngle.y = m.intendedYaw - approach_s32(limit_angle(m.intendedYaw - m.faceAngle.y), 0, 0xC00, 0xC00); - end - - apply_slope_accel(m) -end - -local function act_walking(m) - local startPos = m.pos - local startYaw = m.faceAngle.y - - mario_drop_held_object(m) - - if should_begin_sliding(m) ~= 0 then - return set_mario_action(m, ACT_BEGIN_SLIDING, 0) - end - - if (m.input & INPUT_FIRST_PERSON) ~= 0 then - return begin_braking_action(m) - end - - if (m.input & INPUT_A_PRESSED) ~= 0 then - return set_jump_from_landing(m) - end - - if check_ground_dive_or_punch(m) ~= 0 then - return true - end - - if (m.input & INPUT_ZERO_MOVEMENT) ~= 0 then - return begin_braking_action(m) - end - - if analog_stick_held_back(m) ~= 0 and m.forwardVel >= 12.0 then - return set_mario_action(m, ACT_TURNING_AROUND, 0) - end - - if (m.input & INPUT_Z_PRESSED) ~= 0 then - return set_mario_action(m, ACT_CROUCH_SLIDE, 0) - end - - m.actionState = 0 - - vec3f_copy(startPos, m.pos) - update_walking_speed_extended(m) - - local stepResult = perform_ground_step(m) - if stepResult == GROUND_STEP_LEFT_GROUND then - set_mario_action(m, ACT_FREEFALL, 0) - set_mario_animation(m, MARIO_ANIM_GENERAL_FALL) - elseif stepResult == GROUND_STEP_NONE then - anim_and_audio_for_walk(m) - if (m.intendedMag - m.forwardVel > 16.0) then - m.particleFlags = m.particleFlags | PARTICLE_DUST - end - elseif stepResult == GROUND_STEP_HIT_WALL then - push_or_sidle_wall(m, startPos) - m.actionTimer = 0 - end - - check_ledge_climb_down(m) - tilt_body_walking(m, startYaw) - return false -end - -local function act_hold_walking(m) - -- Unlikely to happen - if m.heldObj and obj_has_behavior_id(m.heldObj, id_bhvJumpingBox) == 1 then - return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0) - end - - if (m.marioObj.oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) ~= 0 then - return drop_and_set_mario_action(m, ACT_WALKING, 0) - end - - if should_begin_sliding(m) ~= 0 then - return set_mario_action(m, ACT_HOLD_BEGIN_SLIDING, 0) - end - - if (m.input & INPUT_B_PRESSED) ~= 0 then - return set_mario_action(m, ACT_THROWING, 0) - end - - if (m.input & INPUT_A_PRESSED) ~= 0 then - return set_jumping_action(m, ACT_HOLD_JUMP, 0) - end - - if (m.input & INPUT_ZERO_MOVEMENT) ~= 0 then - return set_mario_action(m, ACT_HOLD_DECELERATING, 0) - end - - if (m.input & INPUT_Z_PRESSED) ~= 0 then - return drop_and_set_mario_action(m, ACT_CROUCH_SLIDE, 0) - end - - m.intendedMag = m.intendedMag * 0.4 - - update_walking_speed_extended(m) - - local stepResult = perform_ground_step(m) - if stepResult == GROUND_STEP_LEFT_GROUND then - set_mario_action(m, ACT_HOLD_FREEFALL, 0) - elseif stepResult == GROUND_STEP_HIT_WALL then - if m.forwardVel > 16.0 then - mario_set_forward_vel(m, 16.0) - end - end - - anim_and_audio_for_hold_walk(m) - - if 0.4 * m.intendedMag - m.forwardVel > 10.0 then - m.particleFlags = m.particleFlags | PARTICLE_DUST - end - - return false -end - -local function act_hold_heavy_walking(m) - if (m.input & INPUT_B_PRESSED) ~= 0 then - return set_mario_action(m, ACT_HEAVY_THROW, 0) - end - - if should_begin_sliding(m) ~= 0 then - return drop_and_set_mario_action(m, ACT_BEGIN_SLIDING, 0) - end - - if (m.input & INPUT_ZERO_MOVEMENT) ~= 0 then - return set_mario_action(m, ACT_HOLD_HEAVY_IDLE, 0) - end - - m.intendedMag = m.intendedMag * 0.1 - - update_walking_speed_extended(m) - - local stepResult = perform_ground_step(m) - if stepResult == GROUND_STEP_LEFT_GROUND then - drop_and_set_mario_action(m, ACT_FREEFALL, 0) - elseif stepResult == GROUND_STEP_HIT_WALL then - if (m.forwardVel > 10.0) then - mario_set_forward_vel(m, 10.0) - end - end - - anim_and_audio_for_heavy_walk(m) - return false -end - -local function act_finish_turning_around(m) - if (m.input & INPUT_ABOVE_SLIDE) ~= 0 then - return set_mario_action(m, ACT_BEGIN_SLIDING, 0) - end - - if (m.input & INPUT_A_PRESSED) ~= 0 then - return set_jumping_action(m, ACT_SIDE_FLIP, 0) - end - - update_walking_speed_extended(m) - set_mario_animation(m, MARIO_ANIM_TURNING_PART2) - - if perform_ground_step(m) == GROUND_STEP_LEFT_GROUND then - set_mario_action(m, ACT_FREEFALL, 0) - end - - if is_anim_at_end(m) ~= 0 then - set_mario_action(m, ACT_WALKING, 0) - end - - m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y + 0x8000) - return false -end - -local function act_crawling(m) - if should_begin_sliding(m) ~= 0 then - return set_mario_action(m, ACT_BEGIN_SLIDING, 0) - end - - if (m.input & INPUT_FIRST_PERSON) ~= 0 then - return set_mario_action(m, ACT_STOP_CRAWLING, 0) - end - - if (m.input & INPUT_A_PRESSED) ~= 0 then - return set_jumping_action(m, ACT_JUMP, 0) - end - - if check_ground_dive_or_punch(m) ~= 0 then - return true - end - - if (m.input & INPUT_ZERO_MOVEMENT) ~= 0 then - return set_mario_action(m, ACT_STOP_CRAWLING, 0) - end - - if (m.input & INPUT_Z_DOWN) == 0 then - return set_mario_action(m, ACT_STOP_CRAWLING, 0) - end - - m.intendedMag = m.intendedMag * 0.1 - - update_walking_speed_extended(m) - - local stepResult = perform_ground_step(m) - if stepResult == GROUND_STEP_LEFT_GROUND then - set_mario_action(m, ACT_FREEFALL, 0) - elseif stepResult == GROUND_STEP_HIT_WALL then - if m.forwardVel > 10.0 then - mario_set_forward_vel(m, 10.0) - end - --! Possibly unintended missing break - align_with_floor(m) - elseif stepResult == GROUND_STEP_NONE then - align_with_floor(m) - end - - local val04 = (m.intendedMag * 2.0 * 0x10000) - set_mario_anim_with_accel(m, MARIO_ANIM_CRAWLING, val04) - play_step_sound(m, 26, 79) - return false -end - ---------------------------------------------------------- - -local function mario_on_set_action(m) - if not enable_extended_moveset then return end - local e = gMarioStateExtras[m.playerIndex] - - if (m.action & ACT_FLAG_MOVING) ~= 0 then - e.savedWallSlide = false - end - - if e.spinInput ~= 0 and (m.input & INPUT_ABOVE_SLIDE) == 0 then - if m.action == ACT_JUMP or - m.action == ACT_DOUBLE_JUMP or - m.action == ACT_TRIPLE_JUMP or - m.action == ACT_SPECIAL_TRIPLE_JUMP or - m.action == ACT_SIDE_FLIP or - m.action == ACT_BACKFLIP then - set_mario_action(m, ACT_SPIN_JUMP, 1) - m.vel.y = 65.0 - m.faceAngle.y = m.intendedYaw - end - end - - if m.action == ACT_GROUND_POUND_JUMP then - m.vel.y = 65.0 - elseif m.action == ACT_WATER_PLUNGE and m.prevAction == ACT_GROUND_POUND then - return set_mario_action(m, ACT_WATER_GROUND_POUND, 1) - elseif m.action == ACT_WALL_SLIDE then - m.vel.y = 0.0 - elseif m.action == ACT_GROUND_POUND and m.prevAction == ACT_SIDE_FLIP then - -- correct animation - m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y - 0x8000) - elseif m.action == ACT_LEDGE_GRAB then - e.rotAngle = m.forwardVel - end -end - -local function before_mario_update(m) - if not enable_extended_moveset then return end - local e = gMarioStateExtras[m.playerIndex] - -- revert fake saved action - if e.fakeSaved == true then - if m.action == e.fakeWroteAction and m.prevAction == e.fakeSavedPrevAction and m.actionTimer == e.fakeSavedActionTimer then - m.action = e.fakeSavedAction - end - e.fakeSaved = false - end -end - -local function after_mario_update(m) - local e = gMarioStateExtras[m.playerIndex] - -- pretend *_POUND_LAND is ACT_GROUND_POUND_LAND so switches work correctly - if m.action == ACT_SPIN_POUND_LAND or m.action == ACT_WATER_GROUND_POUND_LAND then - e.fakeSavedAction = m.action - e.fakeSavedPrevAction = m.prevAction - e.fakeSavedActionTimer = m.actionTimer - - m.action = ACT_GROUND_POUND_LAND - e.fakeWroteAction = m.action - e.fakeSaved = true - end -end - -local function mario_update(m) - if not enable_extended_moveset then return end - local e = gMarioStateExtras[m.playerIndex] - - mario_update_spin_input(m) - update_roll(m) - - -- dive out of ACT_GROUND_POUND - if m.action == ACT_GROUND_POUND and (m.input & INPUT_B_PRESSED) ~= 0 then - mario_set_forward_vel(m, 10.0) - m.vel.y = 35.0 - set_mario_action(m, ACT_DIVE, 0) - end - - -- spin - if (m.action == ACT_JUMP or - m.action == ACT_WALL_KICK_AIR or - m.action == ACT_DOUBLE_JUMP or - m.action == ACT_BACKFLIP or - m.action == ACT_SIDE_FLIP) and e.spinInput ~= 0 then - set_mario_action(m, ACT_SPIN_JUMP, 1) - e.spinInput = 0 - end - - -- twirl pound - if m.action == ACT_TWIRLING and (m.input & INPUT_Z_PRESSED) ~= 0 then - set_mario_action(m, ACT_SPIN_POUND, 0) - end - - -- ground pound jump - if m.action == ACT_GROUND_POUND_LAND and (m.input & INPUT_A_PRESSED) ~= 0 then - set_mario_action(m, ACT_GROUND_POUND_JUMP, 0) - end - - -- water ground pound - if (m.input & INPUT_Z_PRESSED) ~= 0 then - if m.action == ACT_WATER_IDLE or m.action == ACT_WATER_ACTION_END or m.action == ACT_BREASTSTROKE or m.action == ACT_SWIMMING_END or m.action == ACT_FLUTTER_KICK then - set_mario_action(m, ACT_WATER_GROUND_POUND, 0) - end - end - - -- maintain spinning from water ground pound jump anim - if m.action == ACT_WATER_JUMP and m.prevAction == ACT_WATER_GROUND_POUND_JUMP then - e.rotAngle = e.rotAngle + (0x10000*1.0 - e.rotAngle) / 5.0 - m.marioObj.header.gfx.angle.y = limit_angle(m.marioObj.header.gfx.angle.y - e.rotAngle) - end - - -- edge parkour - if m.action == ACT_LEDGE_GRAB and m.actionTimer < 4 and (m.input & INPUT_B_PRESSED) ~= 0 then - local hasSpaceForMario = (m.ceilHeight - m.floorHeight >= 160.0) - if hasSpaceForMario and (e.rotAngle >= 31.0 or m.forwardVel >= 31.0) then - mario_set_forward_vel(m, e.rotAngle + 5.0) - m.vel.y = 25.0 - queue_rumble_data_mario(m, 5, 80) - set_mario_action(m, ACT_LEDGE_PARKOUR, 0) - end - end - - -- save last pos - e.lastPos.x = m.pos.x - e.lastPos.y = m.pos.y - e.lastPos.z = m.pos.z - - after_mario_update(m) -end - -local convert_actions = { - [ACT_DIVE_SLIDE] = ACT_CUSTOM_DIVE_SLIDE, - [ACT_WALKING] = ACT_CUSTOM_WALKING, - [ACT_HOLD_WALKING] = ACT_CUSTOM_HOLD_WALKING, - [ACT_HOLD_HEAVY_WALKING] = ACT_CUSTOM_HOLD_HEAVY_WALKING, - [ACT_FINISH_TURNING_AROUND] = ACT_CUSTOM_FINISH_TURNING_AROUND, - [ACT_CRAWLING] = ACT_CUSTOM_CRAWLING, - [ACT_AIR_HIT_WALL] = ACT_CUSTOM_AIR_HIT_WALL -} - -local function before_set_mario_action(m, action) - if not enable_extended_moveset then return action end - - return convert_actions[action] ~= nil and convert_actions[action] or action -end - -local function on_chat_command(msg) - if msg:lower() == 'off' then - enable_extended_moveset = false - djui_chat_message_create("Extended moveset is now disabled") - elseif msg:lower() == 'on' then - enable_extended_moveset = true - djui_chat_message_create("Extended moveset is now enabled") - end - return true -end - ------------ --- hooks -- ------------ - -hook_event(HOOK_BEFORE_MARIO_UPDATE, before_mario_update) -hook_event(HOOK_MARIO_UPDATE, mario_update) -hook_event(HOOK_ON_SET_MARIO_ACTION, mario_on_set_action) -hook_event(HOOK_BEFORE_SET_MARIO_ACTION, before_set_mario_action) - -hook_mario_action(ACT_ROLL, { every_frame = act_roll }) -hook_mario_action(ACT_ROLL_AIR, { every_frame = act_roll_air }) -hook_mario_action(ACT_SPIN_JUMP, { every_frame = act_spin_jump, gravity = act_spin_jump_gravity }) -hook_mario_action(ACT_SPIN_POUND, { every_frame = act_spin_pound }) -hook_mario_action(ACT_SPIN_POUND_LAND, { every_frame = act_spin_pound_land }) -hook_mario_action(ACT_GROUND_POUND_JUMP, { every_frame = act_ground_pound_jump }) -hook_mario_action(ACT_WALL_SLIDE, { every_frame = act_wall_slide, gravity = act_wall_slide_gravity }) -hook_mario_action(ACT_WATER_GROUND_POUND, { every_frame = act_water_ground_pound }) -hook_mario_action(ACT_WATER_GROUND_POUND_LAND, { every_frame = act_water_ground_pound_land }) -hook_mario_action(ACT_WATER_GROUND_POUND_STROKE, { every_frame = act_water_ground_pound_stroke }) -hook_mario_action(ACT_WATER_GROUND_POUND_JUMP, { every_frame = act_water_ground_pound_jump }) -hook_mario_action(ACT_LEDGE_PARKOUR, { every_frame = act_ledge_parkour }) -hook_mario_action(ACT_CUSTOM_DIVE_SLIDE, { every_frame = act_dive_slide }) -hook_mario_action(ACT_CUSTOM_WALKING, { every_frame = act_walking }) -hook_mario_action(ACT_CUSTOM_HOLD_WALKING, { every_frame = act_hold_walking }) -hook_mario_action(ACT_CUSTOM_HOLD_HEAVY_WALKING, { every_frame = act_hold_heavy_walking }) -hook_mario_action(ACT_CUSTOM_FINISH_TURNING_AROUND, { every_frame = act_finish_turning_around }) -hook_mario_action(ACT_CUSTOM_CRAWLING, { every_frame = act_crawling }) -hook_mario_action(ACT_CUSTOM_AIR_HIT_WALL, { every_frame = act_air_hit_wall }) - -hook_chat_command('ext-moveset', "Turn extended moveset [on|off]", on_chat_command) \ No newline at end of file diff --git a/mods/hide-and-seek.lua b/mods/hide-and-seek.lua deleted file mode 100644 index 2bc16c909..000000000 --- a/mods/hide-and-seek.lua +++ /dev/null @@ -1,566 +0,0 @@ --- name: Hide and Seek --- incompatible: gamemode --- description: A simple hide-and-seek gamemode for\nCo-op.\n\nThe game is split into two teams:\n\nHiders and Seekers. The goal is for all\n\Hiders to be converted into a Seeker within a certain timeframe.\n\nAll Seekers appear as a metal character.\n\nEnjoy! :D\n\nConcept by: Super Keeberghrh - --- constants -local ROUND_STATE_WAIT = 0 -local ROUND_STATE_ACTIVE = 1 -local ROUND_STATE_SEEKERS_WIN = 2 -local ROUND_STATE_HIDERS_WIN = 3 -local ROUND_STATE_UNKNOWN_END = 4 - --- globals -gGlobalSyncTable.roundState = ROUND_STATE_WAIT -- current round state -gGlobalSyncTable.touchTag = false -gGlobalSyncTable.hiderCaps = false -gGlobalSyncTable.seekerCaps = false -gGlobalSyncTable.banKoopaShell = true -gGlobalSyncTable.disableBLJ = true -gGlobalSyncTable.displayTimer = 0 -- the displayed timer - --- variables -local sRoundTimer = 0 -- the server's round timer -local sRoundStartTimeout = 15 * 30 -- fifteen seconds -local sRoundEndTimeout = 3 * 60 * 30 -- three minutes -local pauseExitTimer = 0 -local canLeave = false -local sFlashingIndex = 0 -local puX = 0 -local puZ = 0 -local np = gNetworkPlayers[0] -local cannonTimer = 0 - --- server settings -gServerSettings.bubbleDeath = 0 - ---localize functions to improve performance -local -hook_chat_command, network_player_set_description, hook_on_sync_table_change, network_is_server, -hook_event, djui_popup_create, network_get_player_text_color_string, play_sound, -play_character_sound, djui_chat_message_create, djui_hud_set_resolution, djui_hud_set_font, -djui_hud_set_color, djui_hud_render_rect, djui_hud_print_text, djui_hud_get_screen_width, djui_hud_get_screen_height, -djui_hud_measure_text, tostring, warp_to_level, warp_to_start_level, stop_cap_music, dist_between_objects, -math_floor, math_ceil, table_insert, set_camera_mode -= -hook_chat_command, network_player_set_description, hook_on_sync_table_change, network_is_server, -hook_event, djui_popup_create, network_get_player_text_color_string, play_sound, -play_character_sound, djui_chat_message_create, djui_hud_set_resolution, djui_hud_set_font, -djui_hud_set_color, djui_hud_render_rect, djui_hud_print_text, djui_hud_get_screen_width, djui_hud_get_screen_height, -djui_hud_measure_text, tostring, warp_to_level, warp_to_start_level, stop_cap_music, dist_between_objects, -math.floor, math.ceil, table.insert, set_camera_mode - -local function on_or_off(value) - if value then return "enabled" end - return "disabled" -end - -local function server_update() - -- increment timer - sRoundTimer = sRoundTimer + 1 - gGlobalSyncTable.displayTimer = math_floor(sRoundTimer / 30) - - -- figure out state of the game - local hasSeeker = false - local hasHider = false - local activePlayers = {} - local connectedCount = 0 - for i = 0, (MAX_PLAYERS-1) do - if gNetworkPlayers[i].connected then - connectedCount = connectedCount + 1 - table_insert(activePlayers, gPlayerSyncTable[i]) - if gPlayerSyncTable[i].seeking then - hasSeeker = true - else - hasHider = true - end - end - end - - -- only change state if there are 2+ players - if connectedCount < 2 then - gGlobalSyncTable.roundState = ROUND_STATE_WAIT - return - elseif gGlobalSyncTable.roundState == ROUND_STATE_WAIT then - gGlobalSyncTable.roundState = ROUND_STATE_UNKNOWN_END - sRoundTimer = 0 - gGlobalSyncTable.displayTimer = 0 - end - - -- check to see if the round should end - if gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then - if not hasHider or not hasSeeker or sRoundTimer > sRoundEndTimeout then - if not hasHider then - gGlobalSyncTable.roundState = ROUND_STATE_SEEKERS_WIN - elseif sRoundTimer > sRoundEndTimeout then - gGlobalSyncTable.roundState = ROUND_STATE_HIDERS_WIN - else - gGlobalSyncTable.roundState = ROUND_STATE_UNKNOWN_END - end - sRoundTimer = 0 - gGlobalSyncTable.displayTimer = 0 - else - return - end - end - - -- start round - if sRoundTimer >= sRoundStartTimeout then - -- reset seekers - for i=0,(MAX_PLAYERS-1) do - gPlayerSyncTable[i].seeking = false - end - hasSeeker = false - - -- pick random seeker - if not hasSeeker then - local randNum = math.random(#activePlayers) - local s = activePlayers[randNum] - s.seeking = true - end - - -- set round state - gGlobalSyncTable.roundState = ROUND_STATE_ACTIVE - sRoundTimer = 0 - gGlobalSyncTable.displayTimer = 0 - - end -end - -local function update() - pauseExitTimer = pauseExitTimer + 1 - - if pauseExitTimer >= 900 and not canLeave then - canLeave = true - end - -- only allow the server to figure out the seeker - if network_is_server() then - server_update() - end -end - -local function screen_transition(trans) - -- if the local player died next to a seeker, make them a seeker - local s = gPlayerSyncTable[0] - if not s.seeking then - for i=1,(MAX_PLAYERS-1) do - if gNetworkPlayers[i].connected and gNetworkPlayers[i].currLevelNum == np.currLevelNum and - gNetworkPlayers[i].currActNum == np.currActNum and gNetworkPlayers[i].currAreaIndex == np.currAreaIndex - and gPlayerSyncTable[i].seeking then - - local m = gMarioStates[0] - local a = gMarioStates[i] - - if trans == WARP_TRANSITION_FADE_INTO_BOWSER or (m.floor.type == SURFACE_DEATH_PLANE and m.pos.y <= m.floorHeight + 2048) then - if dist_between_objects(m.marioObj, a.marioObj) <= 4000 and m.playerIndex == 0 then - s.seeking = true - end - end - end - end - end -end - ---- @param m MarioState -local function mario_update(m) - if (m.flags & MARIO_VANISH_CAP) ~= 0 then - m.flags = m.flags & ~MARIO_VANISH_CAP --Always Remove Vanish Cap - stop_cap_music() - end - - if gGlobalSyncTable.disableBLJ and m.forwardVel <= -55 then - m.forwardVel = -55 - end - - -- this code runs for all players - local s = gPlayerSyncTable[m.playerIndex] - - if m.playerIndex == 0 and m.action == ACT_IN_CANNON and m.actionState == 2 then - cannonTimer = cannonTimer + 1 - if cannonTimer >= 150 then -- 150 is 5 seconds - m.forwardVel = 100 * coss(m.faceAngle.x) - - m.vel.y = 100 * sins(m.faceAngle.x) - - m.pos.x = m.pos.x + 120 * coss(m.faceAngle.x) * sins(m.faceAngle.y) - m.pos.y = m.pos.y + 120 * sins(m.faceAngle.x) - m.pos.z = m.pos.z + 120 * coss(m.faceAngle.x) * coss(m.faceAngle.y) - - play_sound(SOUND_ACTION_FLYING_FAST, m.marioObj.header.gfx.cameraToObject) - play_sound(SOUND_OBJ_POUNDING_CANNON, m.marioObj.header.gfx.cameraToObject) - - m.marioObj.header.gfx.node.flags = m.marioObj.header.gfx.node.flags | GRAPH_RENDER_ACTIVE - set_camera_mode(m.area.camera, m.area.camera.defMode, 1) - - set_mario_action(m, ACT_SHOT_FROM_CANNON, 0) - queue_rumble_data_mario(m, 60, 70) - m.usedObj.oAction = 2 - cannonTimer = 0 - end - end - - -- remove caps - if m.playerIndex == 0 or gGlobalSyncTable.roundState ~= ROUND_STATE_ACTIVE then - if gGlobalSyncTable.seekerCaps and gPlayerSyncTable[m.playerIndex].seeking then - m.flags = m.flags & ~MARIO_WING_CAP -- remove wing cap if seeking - m.flags = m.flags & ~MARIO_METAL_CAP -- remove metal cap if seeking - stop_cap_music() - m.capTimer = 0 - elseif gGlobalSyncTable.hiderCaps and not gPlayerSyncTable[m.playerIndex].seeking then - m.flags = m.flags & ~MARIO_WING_CAP -- remove wing cap if hiding - m.flags = m.flags & ~MARIO_METAL_CAP -- remove metal cap if hiding - stop_cap_music() - m.capTimer = 0 - end - end - - -- warp to the beninging - if m.playerIndex == 0 then - if gPlayerSyncTable[m.playerIndex].seeking and gGlobalSyncTable.displayTimer == 0 and gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then - warp_to_start_level() - end - end - - -- display all seekers as metal - if s.seeking then - m.marioBodyState.modelState = m.marioBodyState.modelState | MODEL_STATE_METAL - end - - -- pu prevention - if m.pos.x >= 0 then - puX = math_floor((8192 + m.pos.x) / 65536) - else - puX = math_ceil((-8192 + m.pos.x) / 65536) - end - if m.pos.z >= 0 then - puZ = math_floor((8192 + m.pos.z) / 65536) - else - puZ = math_ceil((-8192 + m.pos.z) / 65536) - end - if puX ~= 0 or puZ ~= 0 then - s.seeking = true - warp_restart_level() - end -end - ----@param m MarioState ----@param action integer -local function before_set_mario_action(m, action) - if m.playerIndex == 0 then - if action == ACT_WAITING_FOR_DIALOG or action == ACT_READING_SIGN or action == ACT_READING_NPC_DIALOG or action == ACT_JUMBO_STAR_CUTSCENE then - return 1 - elseif action == ACT_READING_AUTOMATIC_DIALOG and get_id_from_behavior(m.interactObj.behavior) ~= id_bhvDoor and get_id_from_behavior(m.interactObj.behavior) ~= id_bhvStarDoor then - return 1 - elseif action == ACT_EXIT_LAND_SAVE_DIALOG then - set_camera_mode(m.area.camera, m.area.camera.defMode, 1) - return ACT_IDLE - end - end -end - ---- @param m MarioState -local function before_phys_step(m) - -- prevent physics from being altered when bubbled - local s = gPlayerSyncTable[m.playerIndex] - - if m.action == ACT_BUBBLED or s.seeking then return end - - -- only make seekers faster - - local hScale = 1.0 - local vScale = 1.0 - - -- make swimming seekers 5% faster - if (m.action & ACT_FLAG_SWIMMING) ~= 0 then - hScale = hScale * 1.05 - if m.action ~= ACT_WATER_PLUNGE then - vScale = vScale * 1.05 - end - end -end - -local function on_pvp_attack(attacker, victim) - -- this code runs when a player attacks another player - local sAttacker = gPlayerSyncTable[attacker.playerIndex] - local sVictim = gPlayerSyncTable[victim.playerIndex] - - -- only consider local player - if victim.playerIndex ~= 0 then - return - end - - -- make victim a seeker - if sAttacker.seeking and not sVictim.seeking then - sVictim.seeking = true - end -end - ---- @param m MarioState -local function on_player_connected(m) - -- start out as a seeker - local s = gPlayerSyncTable[m.playerIndex] - s.seeking = true - network_player_set_description(gNetworkPlayers[m.playerIndex], "seeker", 255, 64, 64, 255) -end - -local function hud_top_render() - local seconds = 0 - local text = "" - - if gGlobalSyncTable.roundState == ROUND_STATE_WAIT then - seconds = 60 - text = "waiting for players" - elseif gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then - seconds = math_floor(sRoundEndTimeout / 30 - gGlobalSyncTable.displayTimer) - if seconds < 0 then seconds = 0 end - text = "seekers have " .. seconds .. " seconds" - else - seconds = math_floor(sRoundStartTimeout / 30 - gGlobalSyncTable.displayTimer) - if seconds < 0 then seconds = 0 end - text = "next round in " .. seconds .. " seconds" - end - - local scale = 0.5 - - -- get width of screen and text - local screenWidth = djui_hud_get_screen_width() - local width = djui_hud_measure_text(text) * scale - - local x = (screenWidth - width) * 0.5 - local y = 0 - - local background = 0.0 - if seconds < 60 and gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then - background = (math.sin(sFlashingIndex * 0.1) * 0.5 + 0.5) * 1 - background = background * background - background = background * background - end - - -- render top - djui_hud_set_color(255 * background, 0, 0, 128) - djui_hud_render_rect(x - 6, y, width + 12, 16) - - djui_hud_set_color(255, 255, 255, 255) - djui_hud_print_text(text, x, y, scale) -end - -local function hud_center_render() - if gGlobalSyncTable.displayTimer > 3 then return end - - -- set text - local text = "" - if gGlobalSyncTable.roundState == ROUND_STATE_SEEKERS_WIN then - text = "Seekers Win!" - elseif gGlobalSyncTable.roundState == ROUND_STATE_HIDERS_WIN then - text = "Hiders Win!" - elseif gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then - text = "Go!" - else - return - end - - -- set scale - local scale = 1 - - -- get width of screen and text - local screenWidth = djui_hud_get_screen_width() - local screenHeight = djui_hud_get_screen_height() - local width = djui_hud_measure_text(text) * scale - local height = 32 * scale - - local x = (screenWidth - width) * 0.5 - local y = (screenHeight - height) * 0.5 - - -- render - djui_hud_set_color(0, 0, 0, 128) - djui_hud_render_rect(x - 6 * scale, y, width + 12 * scale, height) - - djui_hud_set_color(255, 255, 255, 255) - djui_hud_print_text(text, x, y, scale) -end - -local function on_hud_render() - -- render to N64 screen space, with the HUD font - djui_hud_set_resolution(RESOLUTION_N64) - djui_hud_set_font(FONT_NORMAL) - - hud_top_render() - hud_center_render() - - sFlashingIndex = sFlashingIndex + 1 -end - -local function on_touch_tag_command() - gGlobalSyncTable.touchTag = not gGlobalSyncTable.touchTag - djui_chat_message_create("Touch tag: " .. on_or_off(gGlobalSyncTable.touchTag)) - return true -end - -local function on_hider_cap_command() - gGlobalSyncTable.hiderCaps = not gGlobalSyncTable.hiderCaps - djui_chat_message_create("Hider Caps: " .. on_or_off(gGlobalSyncTable.hiderCaps)) - return true -end - -local function on_seeker_cap_command() - gGlobalSyncTable.seekerCaps = not gGlobalSyncTable.seekerCaps - djui_chat_message_create("Seeker Caps: " .. on_or_off(gGlobalSyncTable.seekerCaps)) - return true -end - -local function on_koopa_shell_command() - gGlobalSyncTable.banKoopaShell = not gGlobalSyncTable.banKoopaShell - djui_chat_message_create("Koopa Shells: " .. on_or_off(not gGlobalSyncTable.banKoopaShell)) - return true -end - -local function on_blj_command() - gGlobalSyncTable.disableBLJ = not gGlobalSyncTable.disableBLJ - djui_chat_message_create("BLJS: " .. on_or_off(not gGlobalSyncTable.disableBLJ)) - return true -end - - -local function level_init() - local s = gPlayerSyncTable[0] - - pauseExitTimer = 0 - canLeave = false - - if s.seeking then canLeave = true end -end - -local function on_pause_exit() - local s = gPlayerSyncTable[0] - - if not canLeave and not s.seeking then - djui_popup_create(tostring(math_floor(30 - pauseExitTimer / 30)).." Seconds until you can leave!", 2) - return false - end -end - ------------------------ --- network callbacks -- ------------------------ - -local function on_round_state_changed() - local rs = gGlobalSyncTable.roundState - - if rs == ROUND_STATE_ACTIVE then - play_character_sound(gMarioStates[0], CHAR_SOUND_HERE_WE_GO) - elseif rs == ROUND_STATE_SEEKERS_WIN then - play_sound(SOUND_MENU_CLICK_CHANGE_VIEW, gMarioStates[0].marioObj.header.gfx.cameraToObject) - elseif rs == ROUND_STATE_HIDERS_WIN then - play_sound(SOUND_MENU_CLICK_CHANGE_VIEW, gMarioStates[0].marioObj.header.gfx.cameraToObject) - end -end - -local function on_seeking_changed(tag, oldVal, newVal) - local m = gMarioStates[tag] - local npT = gNetworkPlayers[tag] - - -- play sound and create popup if became a seeker - if newVal and not oldVal then - play_sound(SOUND_OBJ_BOWSER_LAUGH, m.marioObj.header.gfx.cameraToObject) - playerColor = network_get_player_text_color_string(m.playerIndex) - djui_popup_create(playerColor .. npT.name .. "\\#ffa0a0\\ is now a seeker", 2) - sRoundTimer = 32 - end - - if newVal then - network_player_set_description(npT, "seeker", 255, 64, 64, 255) - else - network_player_set_description(npT, "hider", 128, 128, 128, 255) - end -end - -local function check_touch_tag_allowed(i) - if gMarioStates[i].action ~= ACT_TELEPORT_FADE_IN and gMarioStates[i].action ~= ACT_TELEPORT_FADE_OUT and gMarioStates[i].action ~= ACT_PULLING_DOOR and gMarioStates[i].action ~= ACT_PUSHING_DOOR and gMarioStates[i].action ~= ACT_WARP_DOOR_SPAWN and gMarioStates[i].action ~= ACT_ENTERING_STAR_DOOR and gMarioStates[i].action ~= ACT_STAR_DANCE_EXIT and gMarioStates[i].action ~= ACT_STAR_DANCE_NO_EXIT and gMarioStates[i].action ~= ACT_STAR_DANCE_WATER and gMarioStates[i].action ~= ACT_PANTING and gMarioStates[i].action ~= ACT_UNINITIALIZED and gMarioStates[i].action ~= ACT_WARP_DOOR_SPAWN then - return true - end - - return false -end - -local function on_interact(m, obj, intee) - if intee == INTERACT_PLAYER then - - if not gGlobalSyncTable.touchTag then - return - end - - if m ~= gMarioStates[0] then - for i=0,(MAX_PLAYERS-1) do - if gNetworkPlayers[i].connected and gNetworkPlayers[i].currAreaSyncValid then - if gPlayerSyncTable[m.playerIndex].seeking and not gPlayerSyncTable[i].seeking and obj == gMarioStates[i].marioObj and check_touch_tag_allowed(i) then - gPlayerSyncTable[i].seeking = true - - network_player_set_description(gNetworkPlayers[i], "seeker", 255, 64, 64, 255) - end - end - end - end - end -end - -local function allow_interact(_, _, intee) - if intee == INTERACT_KOOPA_SHELL and gGlobalSyncTable.banKoopaShell then - return false - end -end - -function allow_pvp_attack(m1, m2) - local s1 = gPlayerSyncTable[m1.playerIndex] - local s2 = gPlayerSyncTable[m2.playerIndex] - if s1.seeking == s2.seeking then - return false - end - return true -end - -gLevelValues.disableActs = true - ------------ --- hooks -- ------------ - -hook_event(HOOK_UPDATE, update) -hook_event(HOOK_ON_SCREEN_TRANSITION, screen_transition) -hook_event(HOOK_BEFORE_SET_MARIO_ACTION, before_set_mario_action) -hook_event(HOOK_MARIO_UPDATE, mario_update) -hook_event(HOOK_BEFORE_PHYS_STEP, before_phys_step) -hook_event(HOOK_ALLOW_PVP_ATTACK, allow_pvp_attack) -hook_event(HOOK_ON_PVP_ATTACK, on_pvp_attack) -hook_event(HOOK_ON_PLAYER_CONNECTED, on_player_connected) -hook_event(HOOK_ON_HUD_RENDER, on_hud_render) -hook_event(HOOK_ON_LEVEL_INIT, level_init) -hook_event(HOOK_ON_PAUSE_EXIT, on_pause_exit) -- timer -hook_event(HOOK_ON_INTERACT, on_interact) -hook_event(HOOK_ALLOW_INTERACT, allow_interact) -hook_event(HOOK_USE_ACT_SELECT, function () return false end) - -if network_is_server() then - hook_chat_command("touch-to-tag", "Turn touch tag on or off", on_touch_tag_command) - hook_chat_command("hiders-caps", "Turn caps for hiders on or off", on_hider_cap_command) - hook_chat_command("seekers-caps", "Turn caps for seekers on or off", on_seeker_cap_command) - hook_chat_command("koopa-shell", "Turn the koopa shell on or off", on_koopa_shell_command) - hook_chat_command("bljs", "Turn bljs on or off", on_blj_command) -end - --- call functions when certain sync table values change -hook_on_sync_table_change(gGlobalSyncTable, "roundState", 0, on_round_state_changed) - -for i = 0, (MAX_PLAYERS - 1) do - gPlayerSyncTable[i].seeking = true - hook_on_sync_table_change(gPlayerSyncTable[i], "seeking", i, on_seeking_changed) - network_player_set_description(gNetworkPlayers[i], "seeker", 255, 64, 64, 255) -end - -_G.HideAndSeek = { - is_player_seeker = function (playerIndex) - return gPlayerSyncTable[playerIndex].seeking - end, - - set_player_seeker = function (playerIndex, seeking) - gPlayerSyncTable[playerIndex].seeking = seeking - end, -} diff --git a/mods/personal-starcount-ex.lua b/mods/personal-starcount-ex.lua deleted file mode 100644 index 2a6076ccd..000000000 --- a/mods/personal-starcount-ex.lua +++ /dev/null @@ -1,339 +0,0 @@ --- name: Personal Star Counter --- description: See how many stars you've collected!\n\nCredits:\n\\#097419\\Mr.Needlemouse\\#FFFFFF\\ - Concept\nSunk\\#dcdcdc\\ - Creator\n\\#269A91\\Demnyx\\#dcdcdc\\ - Assistance\n\\#f296af\\PeachyPeach\\#dcdcdc\\ - Global functions --- incompatible: gamemode arena - ------------------------------- ------ Localize functions ----- ------------------------------- --- This looks strange but it makes the mod more performant -local tonumber, mod_storage_load, mod_storage_save, tostring, djui_hud_is_pause_menu_created, djui_hud_set_color, hud_get_value, djui_hud_print_text, djui_hud_render_texture, obj_get_first_with_behavior_id, djui_hud_set_resolution, djui_hud_set_font, djui_hud_get_screen_height, djui_hud_get_screen_width, djui_hud_set_render_behind_hud, hud_set_value, network_player_set_description, djui_popup_create = - tonumber, mod_storage_load, mod_storage_save, tostring, djui_hud_is_pause_menu_created, djui_hud_set_color, hud_get_value, djui_hud_print_text, djui_hud_render_texture, obj_get_first_with_behavior_id, djui_hud_set_resolution, djui_hud_set_font, djui_hud_get_screen_height, djui_hud_get_screen_width, djui_hud_set_render_behind_hud, hud_set_value, network_player_set_description, djui_popup_create ------------------------------- - --- Initialize a value for the psc for everyone -for i = 0, MAX_PLAYERS - 1 do - gPlayerSyncTable[i].psc = 0 -end - -local psc_toggle = true -local has_cheats_enabled = gServerSettings.enableCheats ~= 0 - --- If there is no value in storage, default to 0 -local TotalStarCounter = tonumber(mod_storage_load("StarCounter")) or 0 -local ThisGameStarCounter = 0 -local prevNumStars = 0 - -local introTimer = 0 - --- When in these cutscenes, do special things like hiding or moving the star counters -local is_in_cutscenes = { - [ACT_END_PEACH_CUTSCENE] = true, - [ACT_CREDITS_CUTSCENE] = true, - [ACT_END_WAVING_CUTSCENE] = true, -} - ---- Whenever a star is collected, increment the other star counters ----@param m MarioState The Mario that does the interaction ----@param obj Object The object the Mario interacted with (Unused here) ----@param intType integer The interaction type ----@param interacted boolean If the interaction was successful (Unused here) ----@return nil -local function star_counter_on_interact(m, obj, intType, interacted) - if not psc_toggle then return end - - if m.playerIndex == 0 and intType == INTERACT_STAR_OR_KEY then - -- Interactions happen before hud rendering, which is why this check can work - -- despite prevNumStars being updated every frame - if m.numStars ~= prevNumStars then - ThisGameStarCounter = ThisGameStarCounter + 1 -- Red star counter - -- Disable total star counter if cheats are enabled - if not has_cheats_enabled then - TotalStarCounter = TotalStarCounter + 1 -- Green star counter - mod_storage_save("StarCounter", tostring(TotalStarCounter)) -- Save to mod storage - end - end - end -end - ---- Hud alpha stuff from Agent X ---- Causes the hud to darken when the game is paused ----@param r number Red ----@param g number Green ----@param b number Blue ----@param a number Alpha (Transparency) ----@return nil -local function djui_hud_set_adjusted_color(r, g, b, a) - local multiplier = 1 - if djui_hud_is_pause_menu_created() then multiplier = 0.57 end -- Star Display compatibility - djui_hud_set_color(r * multiplier, g * multiplier, b * multiplier, a) -end - ---- Sets the star counters onto the hud ----@param m MarioState Mario ----@param height number Screen height (Unused) ----@param width number Screen width ----@return nil -local function set_hud_star_positions(m, height, width) - if introTimer >= 1195 or m.action ~= ACT_INTRO_CUTSCENE then - local star_texture = gTextures.star - -- Check if the timer is currently active - local timer_current_value = hud_get_value(HUD_DISPLAY_TIMER) - - -- Offset based on if the timer is active - local timer_offset_X = 0 - local timer_offset_Y = 0 - - -- Offset based on if each counter has less than 100 stars - local low_stars_offset_X = 0 - local low_stars_offset_Y = 0 - - -- Based off of star texture pos - local star_counter_offset_X = 0 - - -- Y position, based off of the top of the screen - local top_screen_offset_Y = 0 - - ------------------------------- - ----- Yellow star counter ----- - ------------------------------- - - -- Don't display while in a cutscene - if not is_in_cutscenes[m.action] then - star_counter_offset_X = 76 - top_screen_offset_Y = 15 - - low_stars_offset_X = 14 - - offsetX = 14 - if m.numStars < 100 then - djui_hud_set_adjusted_color(246, 246, 246, 255) - djui_hud_print_text("@", width - (star_counter_offset_X - 16), top_screen_offset_Y, 1) - offsetX = 0 - end - djui_hud_set_adjusted_color(255, 255, 255, 255) - djui_hud_print_text(tostring(m.numStars), width - (star_counter_offset_X - 30) - offsetX, top_screen_offset_Y, 1) - djui_hud_render_texture(star_texture, width - star_counter_offset_X, top_screen_offset_Y, 1, 1) - end - - ---------------------------- - ----- Red star counter ----- - ---------------------------- - - -- Move HUD graphics away from the TIMER HUD - if timer_current_value ~= 0 then - timer_offset_X = 60 - timer_offset_Y = -17 - end - - star_counter_offset_X = is_in_cutscenes[m.action] and 22 or 76 - top_screen_offset_Y = is_in_cutscenes[m.action] and 15 or 15 + 17 - - low_stars_offset_X = 14 - - local left_align = is_in_cutscenes[m.action] - -- Render X if this counter has less than 100 stars - if ThisGameStarCounter < 100 then - djui_hud_set_adjusted_color(246, 246, 246, 255) - djui_hud_print_text( - "@", -- Text - (left_align and (star_counter_offset_X + 16) or -- X pos in cutscenes - (width - (star_counter_offset_X - 16) - timer_offset_X)), -- X pos outside cutscenes - top_screen_offset_Y + timer_offset_Y, -- Y pos - 1) -- Scale - low_stars_offset_X = 0 - end - -- Render counter - djui_hud_set_adjusted_color(255, 255, 255, 255) - djui_hud_print_text( - tostring(ThisGameStarCounter), -- Text - (left_align and (star_counter_offset_X + 30 - low_stars_offset_X) or -- X pos in cutscenes - (width - (star_counter_offset_X - 30) - timer_offset_X - low_stars_offset_X)), -- X pos outside cutscenes - top_screen_offset_Y + timer_offset_Y, -- Y pos - 1) -- Scale - djui_hud_set_adjusted_color(232, 17, 35, 255) - djui_hud_render_texture( - star_texture, -- Texture - (left_align and star_counter_offset_X or -- X pos in cutscenes - (width - star_counter_offset_X - timer_offset_X)), -- X pos outside cutscenes - top_screen_offset_Y + timer_offset_Y, -- Y pos - 1, 1) -- Scale - - ------------------------------ - ----- Green star counter ----- - ------------------------------ - - -- Increment a seperate counter if the total star count is over 10000 - local perceived_total_counter = TotalStarCounter - local milestone_counter = 0 - while perceived_total_counter >= 10000 do - perceived_total_counter = perceived_total_counter - 10000 - milestone_counter = milestone_counter + 1 - end - - -- Move HUD graphics away from the TIMER HUD - if timer_current_value ~= 0 then - timer_offset_X = 0 - timer_offset_Y = 12 - end - - star_counter_offset_X = 76 - top_screen_offset_Y = is_in_cutscenes[m.action] and 15 or 15 + 17 * 2 - - low_stars_offset_X = 14 - -- Render X if this counter has less than 100 stars - if perceived_total_counter < 100 then - djui_hud_set_adjusted_color(246, 246, 246, 255) - djui_hud_print_text( - "@", -- Text - width - (star_counter_offset_X - 16) - timer_offset_X, -- X pos - top_screen_offset_Y + timer_offset_Y, -- Y pos - 1) -- Scale - low_stars_offset_X = 0 - end - -- Render counter - djui_hud_set_adjusted_color(255, 255, 255, 255) - djui_hud_print_text( - tostring(perceived_total_counter), -- Text - width - (star_counter_offset_X - 30) - timer_offset_X - low_stars_offset_X, -- X pos - top_screen_offset_Y + timer_offset_Y, -- Y pos - 1) -- Scale - djui_hud_set_adjusted_color(50, 176, 40, 255) - djui_hud_render_texture( - star_texture, -- Texture - width - star_counter_offset_X - timer_offset_X, -- X pos - top_screen_offset_Y + timer_offset_Y, -- Y pos - 1, 1) -- Scale - if milestone_counter ~= 0 then - djui_hud_set_adjusted_color(255, 255, 255, 255) - djui_hud_print_text( - "@" .. milestone_counter, -- Text - width - star_counter_offset_X - timer_offset_X, -- X pos - (top_screen_offset_Y + 16) + timer_offset_Y, -- Y pos - 0.5) -- Scale - end - end -end - ---- Renders star counters onto the screen ----@return nil -local function hud_render_psc() - if not psc_toggle then return end - -- If the act selector is active - if obj_get_first_with_behavior_id(id_bhvActSelector) then return end - - -- HOOK_ON_HUD_RENDER doesn't supply a MarioState, so one has to be gotten from this - ---@type MarioState - local m = gMarioStates[0] - - -- Make HUD appear when the real one does during the intro - if m.action == ACT_INTRO_CUTSCENE then - if introTimer < 1195 then - introTimer = introTimer + 1 - end - end - - djui_hud_set_resolution(RESOLUTION_N64) - djui_hud_set_font(FONT_HUD) - - local screen_height = djui_hud_get_screen_height() - local screen_width = djui_hud_get_screen_width() - - -- Set prevNumStars - prevNumStars = m.numStars - -- Draw over credits fades - djui_hud_set_render_behind_hud(not is_in_cutscenes[m.action]) - - -- Force the normal star counter to be hidden - hud_set_value(HUD_DISPLAY_FLAGS, hud_get_value(HUD_DISPLAY_FLAGS) & ~HUD_DISPLAY_FLAG_STAR_COUNT) - - set_hud_star_positions(m, screen_height, screen_width) -end - ---- Display each person's star counter in the player menu ----@return nil -local function psc_update() - gPlayerSyncTable[0].psc = ThisGameStarCounter - for i = 0, MAX_PLAYERS - 1 do - network_player_set_description(gNetworkPlayers[i], "\\#FF0000\\Stars: " .. tostring(gPlayerSyncTable[i].psc), 255, 255, 255, 255) - end -end - -local timer = 0 ---- Inform the player that they have joined a game with cheats enabled ---- and won't be able to get any green stars ----@param m MarioState ----@return nil -local function psc_mario_update_inform_cheats(m) - if m.playerIndex ~= 0 then return end - if has_cheats_enabled then - timer = timer + 1 - if timer == 30 then - djui_popup_create("This game has cheats enabled. You cannot gain any \\#00FF00\\green stars\\#DCDCDC\\ from this game.", 3) - end - end -end - ---- Toggle whether or not to display the star counter on the hud ----@param msg string ----@return boolean -local function toggle_psc(msg) - if msg:lower() == "on" then - psc_toggle = true - elseif msg:lower() == "off" then - psc_toggle = false - hud_set_value(HUD_DISPLAY_FLAGS, hud_get_value(HUD_DISPLAY_FLAGS) | HUD_DISPLAY_FLAG_STAR_COUNT) - end - return true -end - ------------------ ------ Hooks ----- ------------------ - -hook_event(HOOK_ON_INTERACT, star_counter_on_interact) -hook_event(HOOK_ON_HUD_RENDER, hud_render_psc) -hook_event(HOOK_UPDATE, psc_update) -hook_event(HOOK_MARIO_UPDATE, psc_mario_update_inform_cheats) -hook_chat_command('psc', "On|Off - Displays stars you've collected. Default is On.", toggle_psc) - --- Globalize functions for other mods to use --- Created by PeachyPeach -_G.PersonalStarCounter = { - --- Get the amount of red stars collected - ---@return integer - get_star_counter = function () - return ThisGameStarCounter - end, - - --- Get the amount of green stars collected - ---@return integer - get_total_star_counter = function () - return TotalStarCounter - end, - - --- Force show or hide the star counters - ---@param hide boolean - hide_star_counters = function (hide) - psc_toggle = hide - end, - - --- Modify the value of the star counters - ---@param red_change number How much to change the red (single game) star counter by - ---@param green_change number How much to change the green (total) star counter by - ---@param override_set boolean If true, force set the value of the star counters instead of change - ---@param save boolean If true, save the green star counter to mod storage - ---@return nil - change_star_counter_value = function (red_change, green_change, override_set, save) - ThisGameStarCounter = ThisGameStarCounter + red_change - if override_set then - ThisGameStarCounter = red_change - end - TotalStarCounter = TotalStarCounter + green_change - if override_set then - TotalStarCounter = green_change - end - if save then - mod_storage_save("StarCounter", tostring(TotalStarCounter)) - end - end -} \ No newline at end of file