From c0fd90474903e688d750eac1475d04451780c301 Mon Sep 17 00:00:00 2001 From: RealFD Date: Sun, 5 Jun 2022 18:52:33 +0200 Subject: [PATCH] rf --- scripts/gameplay.lua | 24 +++- scripts/gameplay/hitfx.lua | 245 ++++++++++++++++++++++++++++++------- 2 files changed, 218 insertions(+), 51 deletions(-) diff --git a/scripts/gameplay.lua b/scripts/gameplay.lua index ab78608..5673702 100644 --- a/scripts/gameplay.lua +++ b/scripts/gameplay.lua @@ -18,6 +18,7 @@ local Chain = require('gameplay.chain') local LaserAlert = require('gameplay.laser_alert') local HitFX = require 'gameplay.hitfx' +local EarlyLate = require 'gameplay.earlylate' local TrackEnd = require('gameplay.track_end') @@ -59,15 +60,26 @@ function render(deltaTime) Chain.render(deltaTime, gameplay.comboState, chain, gameplay.critLine.x, gameplay.critLine.y); LaserAlert.render(deltaTime); + + EarlyLate.render(deltaTime) end function render_crit_base(deltaTime) - CritLine.renderBase(deltaTime, gameplay.critLine.x, gameplay.critLine.y, -gameplay.critLine.rotation, gameplay.critLine.cursors); - HitFX.render(deltaTime, gameplay.critLine.x, gameplay.critLine.y, -gameplay.critLine.rotation, gameplay.critLine.cursors); - Console.render(deltaTime, gameplay.critLine.x, gameplay.critLine.y, -gameplay.critLine.rotation); + local cl = gameplay.critLine + + CritLine.renderBase(deltaTime, cl.x, cl.y, -cl.rotation); + Console.render(deltaTime, cl.x, cl.y, -cl.rotation); end function render_crit_overlay(deltaTime) + local cl = gameplay.critLine + local centerX = cl.x + local centerY = cl.y + local rot = -cl.rotation + + HitFX.renderButtons(deltaTime, centerX, centerY, rot); + HitFX.renderLasers(deltaTime, centerX, centerY, rot, cl.cursors); + CritLine.renderOverlay(deltaTime, centerX, centerY, rot, cl.cursors, gameplay.laserActive) end function render_intro(deltaTime) @@ -109,10 +121,14 @@ function button_hit(button, rating, delta) if (showHitAnims) then if (rating == 1) then HitFX.TriggerAnimation("Near", button + 1) - else + elseif (rating == 2) then HitFX.TriggerAnimation("Crit", button + 1) end end + + if 0 < rating and rating < 3 then + EarlyLate.TriggerAnimation(rating, delta) + end end function laser_slam_hit(slamLength, startPos, endPost, index) diff --git a/scripts/gameplay/hitfx.lua b/scripts/gameplay/hitfx.lua index ec9cd1e..71acc74 100644 --- a/scripts/gameplay/hitfx.lua +++ b/scripts/gameplay/hitfx.lua @@ -13,41 +13,166 @@ local Animations = { Near = Animation.new('gameplay/hit_animation_frames/near_taps', { centered = true, }), + + HoldCrit = Animation.new('gameplay/hit_animation_frames/hold_critical', { + centered = true, + loop = true, + }), + + HoldDome = Animation.new('gameplay/hit_animation_frames/hold_dome', { + centered = true, + loop = true, + loopPoint = 10 + }), + + HoldEnd = Animation.new('gameplay/hit_animation_frames/hold_end', { + centered = true, + }), + + HoldInner = Animation.new('gameplay/hit_animation_frames/hold_inner', { + centered = true, + loop = true, + }), + + LaserCrit = Animation.new('gameplay/hit_animation_frames/laser_critical', { + loop = true, + }), + + LaserDome = Animation.new('gameplay/hit_animation_frames/laser_dome', { + loop = true, + }), + + LaserEndOuter = Animation.new('gameplay/hit_animation_frames/laser_end_outer', {}), + + LaserEndLeft = Animation.new('gameplay/hit_animation_frames/laser_end_l_inner', {}), + + LaserEndRight = Animation.new('gameplay/hit_animation_frames/laser_end_r_inner', {}), }; -local animationStates = { - ---@type AnimationState[] - Hold = { }, - ---@type AnimationState[] - Tap = { } -}; +---@class LaserStateTable +---@field Crit AnimationState +---@field Dome AnimationState +---@field EndInner AnimationState +---@field EndOuter AnimationState + +---@type LaserStateTable[] +local laserStateTables = { + { + Crit = Animations.LaserCrit:createState(), + Dome = Animations.LaserDome:createState(), + EndInner = Animations.LaserEndLeft:createState(), + EndOuter = Animations.LaserEndOuter:createState() + }, + { + Crit = Animations.LaserCrit:createState(), + Dome = Animations.LaserDome:createState(), + EndInner = Animations.LaserEndRight:createState(), + EndOuter = Animations.LaserEndOuter:createState() + } +} + +---@class HoldStateTable +---@field Crit AnimationState +---@field Dome AnimationState +---@field End AnimationState +---@field Inner AnimationState + +---@type HoldStateTable[] +local holdStateTables = {} + +for i = 1, 6 do + holdStateTables[i] = { + Crit = Animations.HoldCrit:createState(), + Dome = Animations.HoldDome:createState(), + End = Animations.HoldEnd:createState(), + Inner = Animations.HoldInner:createState() + } +end + +---@type AnimationState[] +local tapStates = {} local HitFX = { }; -local LanePositions = { - 1.5 / 6, - 2.5 / 6, - 3.5 / 6, - 4.5 / 6, - 1 / 3, - 2 / 3 -}; +local function setUpTransform(critCenterX, critCenterY, critRotation, xScalar) + local critLine = gameplay.critLine + local x = critCenterX + (critLine.line.x2 - critLine.line.x1) * xScalar + local y = critCenterY + (critLine.line.y2 - critLine.line.y1) * xScalar -local function setupLaneTransform(lanePosition, critCenterX, critCenterY) - local critLine = gameplay.critLine; - local x = critCenterX + (critLine.line.x2 - critLine.line.x1) * lanePosition; - local y = critCenterY + (critLine.line.y2 - critLine.line.y1) * lanePosition; - Dimensions.setUpTransforms(x, y, -critLine.rotation); + Dimensions.setUpTransforms(x, y, critRotation) end -function HitFX.render(deltaTime, critCenterX, critCenterY, critRotation, cursors) - local baseHitSize = 325; +function HitFX.renderLasers(deltaTime, critCenterX, critCenterY, critRotation, cursors) + local hitSize = 406 + -- Lasers + for laser = 1, 2 do + -- Update + local isActive = gameplay.laserActive[laser] + local laserState = laserStateTables[laser] + local isAnimationPlaying = laserState.Dome.running + + if isActive and not isAnimationPlaying then + laserState.Crit:restart() + laserState.Dome:restart() + end + + if not isActive and isAnimationPlaying then + laserState.Crit:stop() + laserState.Dome:stop() + + laserState.EndInner:restart() + laserState.EndOuter:restart() + end + + -- Render + local laserColor = {game.GetLaserColor(laser - 1)} + local x = cursors[laser - 1].pos + + Dimensions.setUpTransforms(critCenterX, critCenterY, critRotation) + + laserState.Dome:render(deltaTime, { + centered = true, + width = hitSize, + height = hitSize, + color = laserColor, + x = x, + }) + + laserState.Crit:render(deltaTime, { + centered = true, + width = hitSize, + height = hitSize, + x = x, + }) + laserState.EndInner:render(deltaTime, { + centered = true, + width = hitSize, + height = hitSize, + x = x, + }) + laserState.EndOuter:render(deltaTime, { + centered = true, + width = hitSize, + height = hitSize, + color = laserColor, + x = x, + }) + end +end + +function HitFX.renderButtons(deltaTime, critCenterX, critCenterY, critRotation) + --local baseHitSize = 325; + local hitSize = 406 + + -- BT + FX for i = 1, 6 do + --[[ local hitSize = baseHitSize; if (i > 4) then hitSize = hitSize * 1.5; end + ]] local laneWidth = (track.GetCurrentLaneXPos(2) - track.GetCurrentLaneXPos(1)) * (i <= 4 and 1 or 2); local lanePosition = track.GetCurrentLaneXPos(i) + laneWidth / 2 @@ -55,40 +180,66 @@ function HitFX.render(deltaTime, critCenterX, critCenterY, critRotation, cursors lanePosition = -track.GetCurrentLaneXPos(6) - laneWidth / 2 end - local holdState = animationStates.Hold[i]; - local tapState = animationStates.Tap[i]; + -- Update Holds + local isHeld = gameplay.noteHeld[i] + local holdStates = holdStateTables[i] + local isAnimationPlaying = holdStates.Dome.running - local isHeld = gameplay.noteHeld[i]; - if (isHeld) then - if (holdState) then - if (not holdState.running) then - holdState:restart(); - end + if isHeld and not isAnimationPlaying then + holdStates.Crit:restart() + holdStates.Dome:restart() + holdStates.Inner:restart() + end - setupLaneTransform(lanePosition, critCenterX, critCenterY); - holdState:render(deltaTime); - gfx.ResetTransform(); - end - else - if (holdState and holdState.running) then - holdState:restart(); - end + if not isHeld and isAnimationPlaying then + holdStates.Crit:stop() + holdStates.Dome:stop() + holdStates.Inner:stop() - if (tapState and tapState.running) then - setupLaneTransform(lanePosition, critCenterX, critCenterY); - tapState:render(deltaTime, { - centered = true, - width = hitSize, - height = hitSize, - }); - gfx.ResetTransform(); - end + holdStates.End:restart() + end + + -- Render holds + setUpTransform(critCenterX, critCenterY, critRotation, lanePosition) + + holdStates.Inner:render(deltaTime, { + centered = true, + width = hitSize, + height = hitSize + }) + holdStates.Dome:render(deltaTime, { + centered = true, + width = hitSize, + height = hitSize + }) + holdStates.Crit:render(deltaTime, { + centered = true, + width = hitSize, + height = hitSize + }) + holdStates.End:render(deltaTime, { + centered = true, + width = hitSize, + height = hitSize + }) + + -- Render Taps + local tapState = tapStates[i] + + if tapState then + tapState:render(deltaTime, { + centered = true, + width = hitSize, + height = hitSize, + }); end end + + gfx.ResetTransform() end function HitFX.TriggerAnimation(name, lane) - animationStates.Tap[lane] = Animations[name]:start(); + tapStates[lane] = Animations[name]:start(); end return HitFX;