Skip to content

Commit

Permalink
hub updates
Browse files Browse the repository at this point in the history
  • Loading branch information
aduermael committed Apr 5, 2024
1 parent 40db977 commit 40138ab
Show file tree
Hide file tree
Showing 8 changed files with 548 additions and 67 deletions.
25 changes: 21 additions & 4 deletions lua/modules/camera_modes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ cameraModes.setFree = function(self, config)
if self ~= cameraModes then
error("camera_modes:setFree(config) should be called with `:`", 2)
end
if type(config) ~= "table" then
if config ~= nil and type(config) ~= "table" then
error("camera_modes:setFree(config) - config should be a table", 2)
end

Expand Down Expand Up @@ -288,15 +288,18 @@ cameraModes.setThirdPerson = function(self, config)
target = nil, -- must be set
offset = nil, -- offset from target
rotationOffset = nil,
rotation = nil,
rigidity = 0.5,
collidesWithGroups = Map.CollisionGroups,
rotatesWithTarget = true,
}

config = conf:merge(defaultConfig, config, {
acceptTypes = {
target = { "Object", "Shape", "MutableShape", "Number3", "Player" },
offset = { "Number3" },
rotationOffset = { "Rotation" },
rotationOffset = { "Rotation", "Number3", "table" },
rotation = { "Rotation", "Number3", "table" },
collidesWithGroups = { "CollisionGroups", "table" },
},
})
Expand All @@ -322,8 +325,16 @@ cameraModes.setThirdPerson = function(self, config)
local rotationOffset = config.rotationOffset or Rotation(0, 0, 0)
local targetIsPlayer = type(target) == "Player"
local targetHasRotation = type(target) == "Object" or type(target) == "Shape" or type(target) == "MutableShape"
local rotatesWithTarget = config.rotatesWithTarget

camera:SetParent(World)
if config.rotation then
if not pcall(function()
worldObject.Rotation:Set(config.rotation)
end) then
error("can't set camera rotation", 2)
end
end

if showPointer then
Pointer:Show()
Expand Down Expand Up @@ -353,9 +364,15 @@ cameraModes.setThirdPerson = function(self, config)

if targetIsPlayer then
worldObject.Position.Y = worldObject.Position.Y + target.CollisionBox.Max.Y * target.Scale.Y
worldObject.Rotation:Set(target.Head.Rotation * rotationOffset)
if rotatesWithTarget then
worldObject.Rotation:Set(target.Head.Rotation * rotationOffset)
end
elseif targetHasRotation then
worldObject.Rotation:Set(target.Rotation * rotationOffset)
if rotatesWithTarget then
worldObject.Rotation:Set(target.Rotation * rotationOffset)
else
worldObject.Rotation:Set(rotationOffset)
end
else
worldObject.Rotation:Set(rotationOffset)
end
Expand Down
221 changes: 221 additions & 0 deletions lua/modules/ccc.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
mod = {}

controls = require("controls")

defaultConfig = {
firstPerson = false, -- third person by default
rotatePlayerWithCamera = false,
faceMotionDirection = true,
rotationSpeed = math.rad(180), -- 180° per second
showPointer = true, -- shows pointer on PC
target = nil, -- targets Player by default
targetSpeed = 50,
targetAlignYawWithCameraWhenMotionIsSet = true,
offset = nil, -- offset from target, added to target to define real target position
-- moving away from target position if possible, considering collisions
-- applied before moving backward to get final camera position
dynamicOffset = nil,
camera = Camera,
cameraRigidity = 0.5,
cameraRotation = nil,
cameraMinDistance = 20,
cameraMaxDistance = 75,
cameraDistance = 40,
cameraColliders = CollisionGroups(1),
cameraSoftColliders = nil,
cameraOnSoftCollisionBegin = nil,
cameraOnSoftCollisionEnd = nil,
cameraRotationSensitivity = 1.0,
}

cameraWorldObject = Object() -- object in World used to compute camera position and orientation
cameraWorldObject:SetParent(World)

local currentConfig = nil

dragListener = nil
tickListener = nil
dirpadListener = nil
pointerWheelListener = nil

function removeListeners()
if dragListener ~= nil then
dragListener:Remove()
dragListener = nil
end
if tickListener ~= nil then
tickListener:Remove()
tickListener = nil
end
if dirpadListener ~= nil then
dirpadListener:Remove()
dirpadListener = nil
end
if pointerWheelListener ~= nil then
pointerWheelListener:Remove()
pointerWheelListener = nil
end
end

mod.set = function(self, config)
if self ~= mod then
error("ccc:set(config) should be called with `:`", 2)
end

local ok, err = pcall(function()
currentConfig = require("config"):merge(defaultConfig, config, {
acceptTypes = {
target = { "Object", "Shape", "MutableShape", "Number3", "Player" },
offset = { "Number3" },
dynamicOffset = { "Number3" },
cameraRotation = { "Rotation", "Number3", "table" },
cameraColliders = { "CollisionGroups", "table" },
cameraSoftColliders = { "CollisionGroups", "table" },
cameraOnSoftCollisionBegin = { "function" },
cameraOnSoftCollisionEnd = { "function" },
},
})
end)

if not ok then
error(err, 2)
end

removeListeners()

if currentConfig.cameraRotation then
if not pcall(function()
cameraWorldObject.Rotation:Set(config.cameraRotation)
end) then
error("can't set camera rotation", 2)
end
end

local offset = currentConfig.offset or Number3.Zero
local target = currentConfig.target

local targetIsPlayer = type(target) == "Player"
-- local targetHasRotation = type(target) == "Object" or type(target) == "Shape" or type(target) == "MutableShape"

if type(target) == "Number3" then
target = { Position = target }
end

local camera = currentConfig.camera
local thirdPerson = currentConfig.firstPerson == false

local colliders = currentConfig.cameraColliders

local boxHalfSize = Number3(1, 1, 1)
local box = Box()

local rigidityFactor = currentConfig.cameraRigidity * 60.0

local camDistance = currentConfig.cameraDistance

local impact
local distance
local dpad

camera:SetParent(World)

pointerWheelListener = LocalEvent:Listen(LocalEvent.Name.PointerWheel, function(delta)
camDistance = camDistance + delta * 0.1
camDistance = math.max(currentConfig.cameraMinDistance, camDistance)
camDistance = math.min(currentConfig.cameraMaxDistance, camDistance)
end)

dragListener = LocalEvent:Listen(LocalEvent.Name.PointerDrag, function(pe)
cameraWorldObject.Rotation.Y = cameraWorldObject.Rotation.Y + pe.DX * 0.01
cameraWorldObject.Rotation.X = cameraWorldObject.Rotation.X - pe.DY * 0.01

if target.Motion.SquaredLength > 0 then -- if target has motion
dpad = controls.DirectionalPadValues

-- target.Rotation:Set(0, cameraWorldObject.Rotation.Y, 0)
-- target.Motion = (target.Forward * dpad.Y + target.Right * dpad.X) * currentConfig.targetSpeed

local v = Number2(dpad.X, dpad.Y)
if v.SquaredLength > 0 then
local yDelta = math.atan(dpad.X, dpad.Y)
target.Rotation:Set(0, cameraWorldObject.Rotation.Y + yDelta, 0)
target.Motion:Set(target.Forward * v.Length * currentConfig.targetSpeed)
end
end
end)

dirpadListener = LocalEvent:Listen(LocalEvent.Name.DirPad, function(x, y)
pcall(function()
-- TODO: make this "strafe" mode
-- if Number2(x, y).SquaredLength > 0 then
-- if currentConfig.targetAlignYawWithCameraWhenMotionIsSet then
-- target.Rotation:Set(0, cameraWorldObject.Rotation.Y, 0)
-- end
-- end
-- target.Motion = (target.Forward * y + target.Right * x) * currentConfig.targetSpeed

local v = Number2(x, y)
if v.SquaredLength > 0 then
local yDelta = math.atan(x, y)
target.Rotation:Set(0, cameraWorldObject.Rotation.Y + yDelta, 0)
target.Motion:Set(target.Forward * v.Length * currentConfig.targetSpeed)
else
target.Motion:Set(Number3.Zero)
end
end)
end)

tickListener = LocalEvent:Listen(LocalEvent.Name.Tick, function(dt)
if thirdPerson then
cameraWorldObject.Position:Set(target.Position + offset)

if targetIsPlayer then
cameraWorldObject.Position.Y = cameraWorldObject.Position.Y + target.CollisionBox.Max.Y * target.Scale.Y
end

box.Min = cameraWorldObject.Position - boxHalfSize -- box.Min:Set doesn't work
box.Max = cameraWorldObject.Position + boxHalfSize -- box.Max:Set doesn't work

-- dynamic offset

impact = box:Cast(Number3.Up, 3, colliders)

distance = 3
if impact and impact.Distance < distance then
distance = impact.Distance
end

cameraWorldObject.Position = cameraWorldObject.Position + Number3.Up * distance

box.Min = cameraWorldObject.Position - boxHalfSize -- box.Min:Set doesn't work
box.Max = cameraWorldObject.Position + boxHalfSize -- box.Max:Set doesn't work

impact = box:Cast(camera.Backward, camDistance, colliders)

distance = camDistance
if impact and impact.Distance < distance then
distance = impact.Distance * 0.95
end

lerpFactor = math.min(rigidityFactor * dt, 1.0)
camera.Position:Lerp(
camera.Position,
cameraWorldObject.Position + cameraWorldObject.Backward * distance,
lerpFactor
)
camera.Rotation:Slerp(camera.Rotation, cameraWorldObject.Rotation, lerpFactor)
end
end)
end

mod.unset = function(self)
if self ~= mod then
error("ccc:unset() should be called with `:`", 2)
end

removeListeners()
end

mod.aim = function(self) end

return mod
5 changes: 4 additions & 1 deletion lua/modules/chat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ local logTypes = {
-- same order as logLevels to be able to do logLevelColors[logLevels.Info]
local logTypeColors = {
Color(30, 215, 96), -- Info
Color.White, -- Warning
Color.Yellow, -- Warning
Color.White, -- Error
Color.White, -- ChatMessage
Color(17, 169, 255), -- PrivateChatMessage (whispering)
Expand Down Expand Up @@ -453,6 +453,9 @@ local createChat = function(_, config)
message.status = status
if message.text ~= nil then
message.text.Color = chatMessageStatusColors[status] or chatMessageStatusColors["error"]
if status == "reported" then
LocalEvent:Send(LocalEvent.Name.WarningMessage, "sent message moderated")
end
end
end
end)
Expand Down
2 changes: 1 addition & 1 deletion lua/modules/coins.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ coins.createModalContent = function(_, config)

local content = modal:createContent()
content.closeButton = true
content.title = "Coinzh"
content.title = "Bank Account"
content.icon = "💰"

local node = ui:createFrame()
Expand Down
21 changes: 16 additions & 5 deletions lua/modules/controls.lua
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,9 @@ local _activateDirPad = function(x, y, pointerEventIndex, eventType)
end
if eventType == "up" then
_state.inputPointers.dirpad = nil
if Client.DirectionalPad ~= nil then

local captured = LocalEvent:Send(LocalEvent.Name.DirPad, 0, 0)
if not captured and Client.DirectionalPad ~= nil then
Client.DirectionalPad(0, 0)
end

Expand Down Expand Up @@ -663,7 +665,11 @@ local _activateDirPad = function(x, y, pointerEventIndex, eventType)
dirpadInput:Normalize()
rot:Normalize()

Client.DirectionalPad(dirpadInput.X, dirpadInput.Y)
local captured = LocalEvent:Send(LocalEvent.Name.DirPad, dirpadInput.X, dirpadInput.Y)
if not captured and Client.DirectionalPad ~= nil then
Client.DirectionalPad(dirpadInput.X, dirpadInput.Y)
end

ease:cancel(_state.anim)
ease:outBack(_state.anim, 0.22, {
onUpdate = function(o)
Expand Down Expand Up @@ -1124,7 +1130,7 @@ _state.dragListener = LocalEvent:Listen(LocalEvent.Name.PointerDrag, function(po
end
end
end
end, { system = System })
end, { system = System }) -- top priority?

_state.sensitivityListener = LocalEvent:Listen(LocalEvent.Name.SensitivityUpdated, function()
_state.sensitivity = Pointer.Sensitivity
Expand Down Expand Up @@ -1302,9 +1308,13 @@ function applyKey(keyCode, down)
end
end

if updateDirPad and Client.DirectionalPad ~= nil then
if updateDirPad then
dirpadInput:Normalize()
Client.DirectionalPad(dirpadInput.X, dirpadInput.Y)

local captured = LocalEvent:Send(LocalEvent.Name.DirPad, dirpadInput.X, dirpadInput.Y)
if not captured and Client.DirectionalPad ~= nil then
Client.DirectionalPad(dirpadInput.X, dirpadInput.Y)
end
end
end

Expand Down Expand Up @@ -1371,6 +1381,7 @@ index.refresh = function()
_state.action2:hide()
_state.action3:hide()
if _state.on and _state.virtualKeyboardShown == false and _isMobile and _state.chatInput == nil then
-- TODO: condition should be "there's at least one DirPad listener"
if Client.DirectionalPad ~= nil then
_state.dirpad:show()
end
Expand Down
Loading

0 comments on commit 40138ab

Please sign in to comment.