From 7ae4eab5ae5050ffd02e45c1571fc435b60fb6b7 Mon Sep 17 00:00:00 2001
From: Max <clonet1019@gmail.com>
Date: Sat, 8 Jul 2023 18:42:28 -0500
Subject: [PATCH] Bug fixes and quality of life.

---
 client/Enums/FloorType.lua                    | 17 +---
 client/Enums/Steps/Ground.lua                 |  4 +-
 client/Enums/init.lua                         |  1 +
 .../{init.client.lua => init.server.lua}      |  0
 .../{init.client.lua => init.server.lua}      |  0
 .../{init.client.lua => init.server.lua}      |  0
 .../{init.client.lua => init.server.lua}      |  0
 client/Util/init.lua                          |  2 +-
 client/{init.client.lua => init.server.lua}   | 62 ++++++++++--
 server/LazyNetworking.server.lua              |  2 +-
 .../Appearance/METAL_MARIO.model.json         | 10 ++
 .../Appearance/init.server.lua                | 83 ++++++++++++----
 .../StarterCharacter/HumanoidRootPart.rbxmx   | 26 ++++-
 shared/Sounds.model.json                      | 96 ++++++++++++++-----
 shared/init.lua                               |  1 +
 15 files changed, 228 insertions(+), 76 deletions(-)
 rename client/Mario/Airborne/{init.client.lua => init.server.lua} (100%)
 rename client/Mario/Automatic/{init.client.lua => init.server.lua} (100%)
 rename client/Mario/Moving/{init.client.lua => init.server.lua} (100%)
 rename client/Mario/Stationary/{init.client.lua => init.server.lua} (100%)
 rename client/{init.client.lua => init.server.lua} (92%)
 create mode 100644 server/StarterCharacter/Appearance/METAL_MARIO.model.json

diff --git a/client/Enums/FloorType.lua b/client/Enums/FloorType.lua
index bf91f3a..c5613e0 100644
--- a/client/Enums/FloorType.lua
+++ b/client/Enums/FloorType.lua
@@ -1,20 +1,5 @@
 --!strict
 
 return {
-	NONZERO_ANALOG = 0x0001,
-	A_PRESSED = 0x0002,
-	OFF_FLOOR = 0x0004,
-	ABOVE_SLIDE = 0x0008,
-	FIRST_PERSON = 0x0010,
-	UNKNOWN_5 = 0x0020,
-	SQUISHED = 0x0040,
-	A_DOWN = 0x0080,
-	IN_POISON_GAS = 0x0100,
-	IN_WATER = 0x0200,
-	STOMPED = 0x0400,
-	INTERACT_OBJ_GRABBABLE = 0x0800,
-	UNKNOWN_12 = 0x1000,
-	B_PRESSED = 0x2000,
-	Z_DOWN = 0x4000,
-	Z_PRESSED = 0x8000,
+	-- TODO
 }
diff --git a/client/Enums/Steps/Ground.lua b/client/Enums/Steps/Ground.lua
index 26f9348..7fc9b29 100644
--- a/client/Enums/Steps/Ground.lua
+++ b/client/Enums/Steps/Ground.lua
@@ -4,6 +4,6 @@ return {
 	LEFT_GROUND = 0,
 	NONE = 1,
 	HIT_WALL = 2,
-	HIT_WALL_STOP_QSTEPS = 3,
-	HIT_WALL_CONTINUE_QSTEPS = 4,
+	HIT_WALL_STOP_QSTEPS = 2,
+	HIT_WALL_CONTINUE_QSTEPS = 3,
 }
diff --git a/client/Enums/init.lua b/client/Enums/init.lua
index 78c3487..3ef4252 100644
--- a/client/Enums/init.lua
+++ b/client/Enums/init.lua
@@ -16,6 +16,7 @@ local Enums = {
 	WaterStep = require(script.Steps.Water),
 	GroundStep = require(script.Steps.Ground),
 
+	FloorType = require(script.FloorType),
 	InputFlags = require(script.InputFlags),
 	ModelFlags = require(script.ModelFlags),
 	SurfaceClass = require(script.SurfaceClass),
diff --git a/client/Mario/Airborne/init.client.lua b/client/Mario/Airborne/init.server.lua
similarity index 100%
rename from client/Mario/Airborne/init.client.lua
rename to client/Mario/Airborne/init.server.lua
diff --git a/client/Mario/Automatic/init.client.lua b/client/Mario/Automatic/init.server.lua
similarity index 100%
rename from client/Mario/Automatic/init.client.lua
rename to client/Mario/Automatic/init.server.lua
diff --git a/client/Mario/Moving/init.client.lua b/client/Mario/Moving/init.server.lua
similarity index 100%
rename from client/Mario/Moving/init.client.lua
rename to client/Mario/Moving/init.server.lua
diff --git a/client/Mario/Stationary/init.client.lua b/client/Mario/Stationary/init.server.lua
similarity index 100%
rename from client/Mario/Stationary/init.client.lua
rename to client/Mario/Stationary/init.server.lua
diff --git a/client/Util/init.lua b/client/Util/init.lua
index 9b1ea6b..ef233da 100644
--- a/client/Util/init.lua
+++ b/client/Util/init.lua
@@ -3,7 +3,7 @@ local Core = script.Parent.Parent
 
 local Util = {
 	GlobalTimer = 0,
-	Scale = 1 / 16,
+	Scale = 1 / 20,
 }
 
 local rayParams = RaycastParams.new()
diff --git a/client/init.client.lua b/client/init.server.lua
similarity index 92%
rename from client/init.client.lua
rename to client/init.server.lua
index f224cac..32904f7 100644
--- a/client/init.client.lua
+++ b/client/init.server.lua
@@ -238,10 +238,27 @@ bindInput(
 -------------------------------------------------------------------------------------------------------------------------------------------------------------
 
 local Commands = {}
+local soundDecay = {}
 
 local lazyNetwork = ReplicatedStorage:WaitForChild("LazyNetwork")
 assert(lazyNetwork:IsA("RemoteEvent"), "bad lazyNetwork!")
 
+local function stepDecay(sound: Sound)
+	local decay = soundDecay[sound]
+
+	if decay then
+		task.cancel(decay)
+	end
+
+	soundDecay[sound] = task.delay(0.1, function()
+		sound:Stop()
+		sound:Destroy()
+		soundDecay[sound] = nil
+	end)
+
+	sound.Playing = true
+end
+
 function Commands.PlaySound(player: Player, name: string)
 	local sound: Sound? = Sounds[name]
 	local character = player.Character
@@ -249,17 +266,44 @@ function Commands.PlaySound(player: Player, name: string)
 
 	if rootPart and sound then
 		local oldSound: Instance? = rootPart:FindFirstChild(name)
+		local canPlay = true
 
-		if oldSound and oldSound:IsA("Sound") and name:find("MARIO") then
-			oldSound.TimePosition = 0
-		else
+		if oldSound and oldSound:IsA("Sound") then
+			canPlay = false
+
+			if name:sub(1, 5) == "MARIO" then
+				-- Restart mario sound if a 30hz interval passed.
+				local now = os.clock()
+				local lastPlay = oldSound:GetAttribute("LastPlay") or 0
+
+				if now - lastPlay >= 2 / STEP_RATE then
+					oldSound.TimePosition = 0
+					oldSound:SetAttribute("LastPlay", now)
+				end
+			elseif name:sub(1, 6) == "MOVING" then
+				-- Keep decaying audio alive.
+				stepDecay(oldSound)
+			else
+				-- Allow stacking.
+				canPlay = true
+			end
+		end
+
+		if canPlay then
 			local newSound: Sound = sound:Clone()
 			newSound.Parent = rootPart
 			newSound:Play()
 
+			if name:find("MOVING") then
+				-- Audio will decay if PlaySound isn't continuously called.
+				stepDecay(newSound)
+			end
+
 			newSound.Ended:Connect(function()
 				newSound:Destroy()
 			end)
+
+			newSound:SetAttribute("LastPlay", os.clock())
 		end
 	end
 end
@@ -270,7 +314,7 @@ function Commands.SetParticle(player: Player, name: string, set: boolean)
 
 	if rootPart then
 		local particles = rootPart:FindFirstChild("Particles")
-		local inst = particles and particles:FindFirstChild(name)
+		local inst = particles and particles:FindFirstChild(name, true)
 
 		if inst and PARTICLE_CLASSES[inst.ClassName] then
 			local particle = inst :: ParticleEmitter
@@ -422,7 +466,7 @@ local function update()
 	
 	-- stylua: ignore
 	local scale = character:GetScale()
-	Util.Scale = scale / 16 -- HACK! Should this be instanced?
+	Util.Scale = scale / 24 -- HACK! Should this be instanced?
 
 	local pos = character:GetPivot().Position
 	local dist = (Util.ToRoblox(mario.Position) - pos).Magnitude
@@ -438,12 +482,16 @@ local function update()
 
 	if character:GetAttribute("WingCap") or Core:GetAttribute("WingCap") then
 		mario.Flags:Add(MarioFlags.WING_CAP)
-		mario.Flags:Remove(MarioFlags.NORMAL_CAP)
 	else
-		mario.Flags:Add(MarioFlags.NORMAL_CAP)
 		mario.Flags:Remove(MarioFlags.WING_CAP)
 	end
 
+	if character:GetAttribute("Metal") then
+		mario.Flags:Add(MarioFlags.METAL_CAP)
+	else
+		mario.Flags:Remove(MarioFlags.METAL_CAP)
+	end
+
 	subframe = math.min(subframe, 4) -- Prevent execution runoff
 
 	while subframe >= 1 do
diff --git a/server/LazyNetworking.server.lua b/server/LazyNetworking.server.lua
index 2ead0c0..2d2dbc6 100644
--- a/server/LazyNetworking.server.lua
+++ b/server/LazyNetworking.server.lua
@@ -33,7 +33,7 @@ function Validators.SetParticle(player: Player, name: string, set: boolean?)
 
 	if rootPart then
 		local particles = rootPart:FindFirstChild("Particles")
-		local particle = particles and particles:FindFirstChild(name)
+		local particle = particles and particles:FindFirstChild(name, true)
 
 		if particle then
 			return true
diff --git a/server/StarterCharacter/Appearance/METAL_MARIO.model.json b/server/StarterCharacter/Appearance/METAL_MARIO.model.json
new file mode 100644
index 0000000..0398ec9
--- /dev/null
+++ b/server/StarterCharacter/Appearance/METAL_MARIO.model.json
@@ -0,0 +1,10 @@
+{
+    "className": "SurfaceAppearance",
+
+    "properties": {
+        "ColorMap": "rbxassetid://9316550550",
+        "MetalnessMap": "rbxassetid://4809886112",
+        "RoughnessMap": "rbxassetid://8271342298",
+        "NormalMap": "rbxassetid://11238076258"
+    }
+}
\ No newline at end of file
diff --git a/server/StarterCharacter/Appearance/init.server.lua b/server/StarterCharacter/Appearance/init.server.lua
index 3a25e20..196d253 100644
--- a/server/StarterCharacter/Appearance/init.server.lua
+++ b/server/StarterCharacter/Appearance/init.server.lua
@@ -1,41 +1,84 @@
 --!strict
 local Players = game:GetService("Players")
 
-local character: any = script.Parent
-local player = Players:GetPlayerFromCharacter(character)
+local character: Instance = assert(script.Parent)
+assert(character:IsA("Model"), "Not a character")
 
-if not player then
-	return
-end
+local player = Players:GetPlayerFromCharacter(character)
+assert(player, "No player!")
 
 local userId = player.UserId
 local hDesc: HumanoidDescription?
 
-local function patchCollision(desc: Instance)
-	if desc:IsA("BasePart") and desc.CollisionGroup ~= "Player" then
-		local canCollide = desc:GetPropertyChangedSignal("CanCollide")
-		desc.CollisionGroup = "Player"
-		desc.CanQuery = false
-		desc.CanTouch = false
-		desc.Massless = true
+local metalPointers = {} :: {
+	[MeshPart]: {
+		Metal: SurfaceAppearance?,
+	},
+}
+
+local function updateMetal(part: MeshPart)
+	local isMetal = character:GetAttribute("Metal")
+	local ptr = metalPointers[part]
+
+	if ptr == nil then
+		ptr = {}
+		metalPointers[part] = ptr
+	end
+
+	if isMetal and not ptr.Metal then
+		local surface = script.METAL_MARIO:Clone()
+		surface.Parent = part
+		ptr.Metal = surface
+	elseif ptr.Metal and not isMetal then
+		ptr.Metal:Destroy()
+		ptr.Metal = nil
+	end
+end
+
+local function onMetalChanged()
+	for meshPart in metalPointers do
+		updateMetal(meshPart)
+	end
+end
+
+local function onDescendantAdded(desc: Instance)
+	if desc:IsA("BasePart") then
+		if desc.CollisionGroup ~= "Player" then
+			local canCollide = desc:GetPropertyChangedSignal("CanCollide")
+			desc.CollisionGroup = "Player"
+			desc.CanQuery = false
+			desc.CanTouch = false
+			desc.Massless = true
+
+			canCollide:Connect(function()
+				desc.CanCollide = false
+			end)
 
-		canCollide:Connect(function()
 			desc.CanCollide = false
-		end)
+		end
 
-		desc.CanCollide = false
+		if desc:IsA("MeshPart") then
+			updateMetal(desc)
+		end
 	end
 end
 
-local function patchAllCollision()
-	for i, desc in character:GetDescendants() do
-		task.spawn(patchCollision, desc)
+local function onDescendantRemoving(desc: Instance)
+	if desc:IsA("MeshPart") then
+		metalPointers[desc] = nil
 	end
 end
 
-task.spawn(patchAllCollision)
-character.DescendantAdded:Connect(patchCollision)
+local metalListener = character:GetAttributeChangedSignal("Metal")
+metalListener:Connect(onMetalChanged)
+
+for i, desc in character:GetDescendants() do
+	task.spawn(onDescendantAdded, desc)
+end
+
 character:SetAttribute("TimeScale", 1)
+character.DescendantAdded:Connect(onDescendantAdded)
+character.DescendantRemoving:Connect(onDescendantRemoving)
 
 local function reload()
 	character:ScaleTo(1)
diff --git a/server/StarterCharacter/HumanoidRootPart.rbxmx b/server/StarterCharacter/HumanoidRootPart.rbxmx
index c2c61b2..8e7bcc6 100644
--- a/server/StarterCharacter/HumanoidRootPart.rbxmx
+++ b/server/StarterCharacter/HumanoidRootPart.rbxmx
@@ -49,7 +49,7 @@
 				</Vector3>
 			</Properties>
 		</Item>
-		<Item class="Attachment" referent="RBX4">
+		<Item class="Bone" referent="RBX4">
 			<Properties>
 				<CoordinateFrame name="CFrame">
 					<X>0</X>
@@ -74,10 +74,10 @@
 					<NumberRange name="Lifetime">1 1 </NumberRange>
 					<float name="LightInfluence">1</float>
 					<string name="Name">DUST</string>
-					<float name="Rate">16</float>
+					<float name="Rate">64</float>
 					<NumberRange name="RotSpeed">-360 360 </NumberRange>
 					<NumberRange name="Rotation">0 360 </NumberRange>
-					<NumberSequence name="Size">0 2 0 1 2 0 </NumberSequence>
+					<NumberSequence name="Size">0 3 0 1 3 0 </NumberSequence>
 					<NumberRange name="Speed">3 3 </NumberRange>
 					<Vector2 name="SpreadAngle">
 						<X>360</X>
@@ -191,6 +191,26 @@
 					</Vector3>
 				</Properties>
 			</Item>
+			<Item class="ParticleEmitter" referent="RBX13">
+				<Properties>
+					<ColorSequence name="Color">0 0.807843 0.807843 0.807843 0 1 0.807843 0.807843 0.807843 0 </ColorSequence>
+					<bool name="Enabled">false</bool>
+					<NumberRange name="Lifetime">1 1 </NumberRange>
+					<float name="LightInfluence">1</float>
+					<string name="Name">DIRT</string>
+					<float name="Rate">128</float>
+					<NumberRange name="RotSpeed">-360 360 </NumberRange>
+					<NumberRange name="Rotation">0 360 </NumberRange>
+					<NumberSequence name="Size">0 3 0 1 3 0 </NumberSequence>
+					<NumberRange name="Speed">3 3 </NumberRange>
+					<Vector2 name="SpreadAngle">
+						<X>360</X>
+						<Y>360</Y>
+					</Vector2>
+					<Content name="Texture"><url>rbxassetid://1349050856</url></Content>
+					<NumberSequence name="Transparency">0 0.5 0 0.8 0.5 0 1 1 0 </NumberSequence>
+				</Properties>
+			</Item>
 		</Item>
 		<Item class="Attachment" referent="RBX11">
 			<Properties>
diff --git a/shared/Sounds.model.json b/shared/Sounds.model.json
index fcd37f3..4bd8cd4 100644
--- a/shared/Sounds.model.json
+++ b/shared/Sounds.model.json
@@ -20,7 +20,8 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": ""
+				"SoundId": "rbxassetid://224339308",
+				"Volume": 2
 			}
 		},
         
@@ -31,7 +32,14 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/action_jump_land.mp3"
+				"SoundId": "rbxassetid://9114589043",
+				"Volume": 1,
+
+				"PlaybackRegion": {
+					"NumberRange": [0.6, 1.25]
+				},
+
+				"PlaybackRegionsEnabled": true
 			}
 		},
         
@@ -53,7 +61,8 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": ""
+				"SoundId": "rbxassetid://9125670740",
+				"Volume": 2
 			}
 		},
         
@@ -64,7 +73,13 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": ""
+				"SoundId": "rbxassetid://9116887596",
+
+				"PlaybackRegion": {
+					"NumberRange": [0.25, 60000]
+				},
+
+				"PlaybackRegionsEnabled": true
 			}
 		},
         
@@ -75,7 +90,18 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": ""
+				"SoundId": "rbxassetid://9116519870"
+			}
+		},
+
+		{
+			"name": "ACTION_METAL_JUMP",
+			"className": "Sound",
+            
+			"properties": {
+				"RollOffMinDistance": 8,
+				"RollOffMaxDistance": 128,
+				"SoundId": "rbxassetid://9116519870"
 			}
 		},
         
@@ -86,7 +112,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": ""
+				"SoundId": "rbxassetid://5946029627"
 			}
 		},
         
@@ -130,7 +156,8 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxassetid://268933841"
+				"SoundId": "rbxasset://sounds/action_jump_land.mp3",
+				"Volume": 1
 			}
 		},
         
@@ -151,7 +178,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://5761648082"
 			}
 		},
         
@@ -162,7 +189,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://7340372339"
 			}
 		},
         
@@ -173,7 +200,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://9114861568"
 			}
 		},
         
@@ -184,7 +211,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://5946029627"
 			}
 		},
         
@@ -195,7 +222,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://8453417974"
 			}
 		},
         
@@ -206,7 +233,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://9119313820"
 			}
 		},
         
@@ -217,7 +244,8 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://6703174876",
+				"Volume": 0.25
 			}
 		},
         
@@ -228,7 +256,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://5761648082"
 			}
 		},
         
@@ -239,7 +267,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://9120584645"
 			}
 		},
         
@@ -277,7 +305,14 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://9114861568",
+				
+				"PlaybackRegion": {
+					"NumberRange": [0, 0.25]
+				},
+				
+				"PlaybackRegionsEnabled": true,
+				"Volume": 0.25
 			}
 		},
         
@@ -288,7 +323,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://5946029627"
 			}
 		},
         
@@ -299,7 +334,8 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxassetid://8453417974"
+				"SoundId": "rbxassetid://8453417974",
+				"Volume": 1
 			}
 		},
         
@@ -310,7 +346,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/flashbulb.wav"
+				"SoundId": "rbxassetid://9119313820"
 			}
 		},
         
@@ -321,7 +357,8 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxassetid://6703174876"
+				"SoundId": "rbxassetid://6703174876",
+				"Volume": 0.25
 			}
 		},
         
@@ -343,7 +380,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxasset://sounds/switch.wav"
+				"SoundId": "rbxassetid://9120584645"
 			}
 		},
         
@@ -409,7 +446,8 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": ""
+				"SoundId": "rbxassetid://14000781869",
+				"Volume": 3
 			}
 		},
         
@@ -689,7 +727,13 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": "rbxassetid://11276297854"
+				"SoundId": "rbxassetid://11276297854",
+
+				"PlaybackRegion": {
+					"NumberRange": [0.1, 60000]
+				},
+
+				"PlaybackRegionsEnabled": true
 			}
 		},
         
@@ -744,7 +788,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": ""
+				"SoundId": "rbxassetid://9119462210"
 			}
 		},
         
@@ -766,7 +810,7 @@
 			"properties": {
 				"RollOffMinDistance": 8,
 				"RollOffMaxDistance": 128,
-				"SoundId": ""
+				"SoundId": "rbxassetid://9118770924"
 			}
 		}
 	]
diff --git a/shared/init.lua b/shared/init.lua
index 6097130..3524bc8 100644
--- a/shared/init.lua
+++ b/shared/init.lua
@@ -222,6 +222,7 @@ local SoundTable = {
 	ACTION_METAL_HEAVY_LANDING = Sounds.ACTION_METAL_HEAVY_LANDING,
 	ACTION_METAL_LANDING = Sounds.ACTION_METAL_LANDING,
 	ACTION_METAL_STEP = Sounds.ACTION_METAL_STEP,
+	ACTION_METAL_JUMP = Sounds.ACTION_METAL_JUMP,
 	ACTION_PAT_BACK = Sounds.ACTION_PAT_BACK,
 	ACTION_SIDE_FLIP = Sounds.ACTION_SIDE_FLIP,
 	ACTION_SPIN = Sounds.ACTION_SPIN,