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 @@
- -
+
-
0
@@ -74,10 +74,10 @@
1 1
1
DUST
- 16
+ 64
-360 360
0 360
- 0 2 0 1 2 0
+ 0 3 0 1 3 0
3 3
360
@@ -191,6 +191,26 @@
+ -
+
+ 0 0.807843 0.807843 0.807843 0 1 0.807843 0.807843 0.807843 0
+ false
+ 1 1
+ 1
+ DIRT
+ 128
+ -360 360
+ 0 360
+ 0 3 0 1 3 0
+ 3 3
+
+ 360
+ 360
+
+ rbxassetid://1349050856
+ 0 0.5 0 0.8 0.5 0 1 1 0
+
+
-
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,