From 89b2f6233b861366db93dab77e558304290e0299 Mon Sep 17 00:00:00 2001 From: Corentin Cailleaud Date: Mon, 13 Nov 2023 10:05:44 +0400 Subject: [PATCH 1/2] aider: Added /Users/caillef/projects/worlds-cubzh/caillef/retromotorclub.lua --- caillef/retromotorclub.lua | 710 +++++++++++++++++++++++++++++++++++++ 1 file changed, 710 insertions(+) create mode 100644 caillef/retromotorclub.lua diff --git a/caillef/retromotorclub.lua b/caillef/retromotorclub.lua new file mode 100644 index 0000000..3854be3 --- /dev/null +++ b/caillef/retromotorclub.lua @@ -0,0 +1,710 @@ + +Config = { + Map = "caillef.empty", + Items = { "caillef.empty", "aduermael.super_bike", "timaosimpson.stone_cube" } +} + +--[[ +-- TODO +[ ] Text showing winner, saying that you have to wait +[ ] Spawn boosts every X seconds, max 5 in the map +[X] Bonus ghost: become a ghost and remove collision for X seconds (activateGhost(p,duration)) +[ ] Bonus boost: increse speed for 2 seconds +--]] + +local _DEBUG = false -- start with a single player +local _SOUND = false -- enable sound + +gameStates = { + Waiting = 0, + Starting = 1, + Running = 2, + End = 3 +} + +local TRAIL_COLORS = { 31, 7, 136, 94, 52, 181, 160, 55 } +local MAP_SIZE = 100 +speed = 90 + +local FORWARD,RIGHT,BACKWARD,LEFT = 0,1,2,3 + +cameraLocalRotation = Number3(0.5, 0, 0) + + _ParticleSpawner = {} + + function _ParticleSpawner:spawnparticle(n, color) + + for i = 1,n do + + local p = table.remove(self.recycled, 1) + + if p == nil then + p = MutableShape() + p:AddBlock(color,0,0,0) + p.Scale = math.random() + 1 + self.count = self.count + 1 + else + p.Palette[1].Color = color + end + + p.Position = self.pos + p.Physics = true + p.CollidesWithGroups = Map.CollisionGroups + p.Velocity = Number3( + (math.random() * 30 - 15) * 4, + self.spawnjump, + (math.random() * 30 - 15) * 4 + ) + p.Rotation = Number3(math.random(0,360),math.random(0,360),math.random(0,360)) + Timer(self.lifetime, function() + p:RemoveFromParent() + table.insert(self.recycled, p) + end) + + World:AddChild(p) + + end + end + + function _ParticleSpawner:new(position) + local spawner = { + count = 0, + lifetime = 1.5, + spawnjump = 70, + recycled = {}, -- to recycle particules + pos = position + } + setmetatable(spawner, self) + self.__index = self + return spawner + end + + + +Client.OnStart = function() + require("uikit.lua") + if not ui then + ui = require("uikit") + end + + spawnPlayer = function(p) + if not p.init then initPlayer(p) end + resetTrailsOfPlayer(p) + p.hasPlayed = true + p.isDead = false + p.spec = false + p.avatar.IsHidden = false + activateGhost(p, 1) + -- p.avatar:ClearTextBubble() + + -- Set position + local pos + if p.ID % 4 == 0 or (p.ID - 1) % 4 == 0 then + pos = Number3((((p.ID % 8) - 1) % 4 == 0 and -1 or 1) * (p.ID % 8 < 4 and 0.6 or 0.8), 0, 0) * MAP_SIZE / 2 + else + pos = Number3(0, 0, (((p.ID % 8) - 3) % 4 == 0 and -1 or 1) * (p.ID % 8 < 4 and 0.6 or 0.8)) * MAP_SIZE / 2 + end + pos = Number3(pos.X, 0.5, pos.Z) * Map.LossyScale + setPlayerPosition(p, pos) + + -- Set direction + local dir = FORWARD + local id = p.ID % 8 + if id == 0 or id == 5 then dir = FORWARD end + if id == 1 or id == 4 then dir = BACKWARD end + if id == 2 or id == 7 then dir = LEFT end + if id == 3 or id == 6 then dir = RIGHT end + rotatePlayerAndSpawnTrail(p,dir) + + if not p == Player then + -- p.avatar:TextBubble(p.Username,-1,0,Color.White,Color(0,0,0,0)) + end + + if cameraOrbit then + cameraOrbit:AddChild(Camera) + Camera.LocalPosition = Number3(0,30,-30) + Camera.LocalRotation = cameraLocalRotation + end + end + + spawnPlayerVehicle = function(color) + local avatar = MutableShape(Items.aduermael.super_bike) + avatar.Palette[1].Color = color + avatar.IsHidden = true + avatar.Pivot.Z = 0.1 + avatar.CollisionGroups = { 5 } + return avatar + end + + initPlayer = function(p) + if p.init then return end + p.init = true + p.hasPlayed = false -- set to true after first game + p.Scale = 0.1 + p.color = DefaultColors[TRAIL_COLORS[math.floor(p.ID % #TRAIL_COLORS) + 1]] + p.IsHidden = true + p.Physics = false + World:AddChild(p, true) -- keep world + p.spec = true + + p.avatar = spawnPlayerVehicle(p.color) + World:AddChild(p.avatar) + p.avatar.Position = p.Position + Number3(0, 4, 0) + if p == Player then + cameraOrbit = Object() + p.avatar:AddChild(cameraOrbit) + World:AddChild(Camera) + Camera:SetModeFree() + Camera.Position = Number3(0, 500, 0) + Camera.Rotation.X = math.pi / 2 - 0.01 + -- Audio Listener + Player.Head:AddChild(AudioListener) + end + + local asWhoosh = AudioSource() + asWhoosh.Sound = "whooshes_small_1" + asWhoosh.Spatialized = true + World:AddChild(asWhoosh) + p.asWhoosh = asWhoosh + + local asExplode = AudioSource() + asExplode.Sound = "thunder_3" + asExplode.Spatialized = true + asExplode.StartAt = 0.2 + asExplode.StopAt = 2 + World:AddChild(asExplode, true) + p.asExplode = asExplode + + local l = Light() + l.Type = LightType.Spot + p.avatar:AddChild(l) + l.Angle = 0.5 + l.Range = 100 + l.Hardness = 1 + l.Color = p.color + end + + killPlayer = function(p) + p.isDead = true + updatePlayersList() + -- p.avatar:TextBubble(p.Username.." ☠", -1) + + p.avatar.IsHidden = true + local spawner = _ParticleSpawner:new(p.avatar.Position + Number3(0,3,0)) + spawner:spawnparticle(30, p.color) + + if _SOUND then + p.asExplode.Position = p.avatar.Position + p.asExplode:Stop() + p.asExplode:Play() + end + + require("ambience"):set({ + sky = { + skyColor = p.color, + horizonColor = p.color, + abyssColor = p.color, + lightColor = Color(153,153,153), + lightIntensity = 0.310000, + }, + fog = { + color = Color(54,60,61), + near = 300, + far = 700, + lightAbsorbtion = 0.400000, + }, + sun = { + color = Color(0,0,0), + intensity = 1.000000, + rotation = Number3(1.061161, 3.089219, 0.000000), + }, + ambient = { + skyLightFactor = 0.100000, + dirLightFactor = 0.200000, + } + }) + Timer(0.5, function() + require("ambience"):set({ + sky = { + skyColor = Color(0,0,0), + horizonColor = Color(0,0,0), + abyssColor = Color(0,0,0), + lightColor = Color(153,153,153), + lightIntensity = 0.310000, + }, + fog = { + color = Color(54,60,61), + near = 300, + far = 700, + lightAbsorbtion = 0.400000, + }, + sun = { + color = Color(0,0,0), + intensity = 1.000000, + rotation = Number3(1.061161, 3.089219, 0.000000), + }, + ambient = { + skyLightFactor = 0.100000, + dirLightFactor = 0.200000, + } + }) + end) + + Timer(1, function() + if gameState == gameStates.Running then + p.spec = true + if p == Player then + World:AddChild(Camera) + Camera.Position = Number3(0, 500, 0) + Camera.Rotation.X = math.pi / 2 + end + end + end) + end + + newTrail = function(p) + if not p.init then return end + if p.trail then + local t = p.trail + t.Scale[t.dir % 2 == 0 and "Z" or "X"] = (p.Position - t.Position).Length + 0.5 + table.insert(p.trails, t) + if p.prevTrail then + p.prevTrail.CollisionGroups = { 3 } + end + p.prevTrail = t + end + + if _SOUND then + p.asWhoosh.Position = p.avatar.Position + p.asWhoosh:Stop() + p.asWhoosh:Play() + end + + local t = MutableShape() + World:AddChild(t) + p.trail = t + + t.Position = p.Position + t.Scale.Y = 6 + t.dir = p.dir + t.owner = p + t.Pivot = Number3(t.dir % 2 == 0 and 0.5 or 0, 0, t.dir % 2 == 0 and 0 or 0.5) + t.Forward = t.dir % 2 == 0 and p.Forward or p.Left + + t.CollisionGroups = p == Player and { 4 } or t.CollisionGroups + t.CollisionBox = Box(Number3(0, 0, 0), Number3(1,1,1)) + + t.color = DefaultColors[TRAIL_COLORS[math.floor(p.ID % #TRAIL_COLORS) + 1]] + t:AddBlock(t.color,0,0,0) + t.IsUnlit = true + end + + updatePlayer = function(dt, p) + if not p.init then return end + if p.spec then return end + + local t = p.trail + if p.isDead or not t then return end + + local forwardVec = p.Forward * speed * dt + if p == Player and p.ghost ~= true then + local impact = Ray(p.Position + { 0, 2, 0 }, p.Forward):Cast({ 3 }) + if impact.Shape ~= nil and impact.Distance <= forwardVec.Length * 4 then + sendEventDied() + end + end + setPlayerPosition(p, p.Position + forwardVec) + end + + --------------- + -- BONUS + --------------- + activateGhost = function(p,time) + p.ghost = true + Timer(time, function() + p.ghost = false + end) + end + + --------------- + -- MOVEMENTS + --------------- + setPlayerPosition = function(p, pos) + p.Position = pos + p.avatar.Forward = p.Forward + p.avatar.Position = p.Position + Number3(0, 4, 0) + local t = p.trail + if t then + t.Scale[t.dir % 2 == 0 and "Z" or "X"] = (p.Position - t.Position).Length + end + end + + rotatePlayerAndSpawnTrail = function(p, newDir) + if gameState ~= gameStates.Starting and gameState ~= gameStates.Running then return end + if not p.init or p.spec then return end + + p.dir = newDir + local r = newDir * 0.5 * math.pi + local delta = p.Rotation.Y - r + p.Rotation.Y = r + p.avatar.Forward = p.Forward + if p == Player then + cameraOrbit.LocalRotation.Y = cameraOrbit.LocalRotation.Y + delta + sendEventRotate() + end + newTrail(p) + end + + clearTexts = function() + if waitingText then + waitingText:remove() + waitingText = nil + end + if textWinner then + textWinner:remove() + textWinner = nil + end + if titleScreen then + titleScreen:remove() + titleScreen = nil + end + end + + --------------- + -- GAME STATE + --------------- + gameStateUpdate = function(dt) + if gameState == gameStates.Running and Player.hasPlayed then + for _,p in pairs(Players) do + updatePlayer(dt,p) + end + end + end + + setGameState = function(newState) + prevState = gameState + gameState = newState + if newState == gameStates.Waiting then + for _,p in pairs(Players) do + resetTrailsOfPlayer(p) + p.spec = true + end + elseif newState == gameStates.Starting and prevState ~= gameStates.Starting then + clearTexts() + for _,p in pairs(Players) do + spawnPlayer(p) + end + updatePlayersList() + elseif newState == gameStates.Running then + -- nothing + end + end + gameState = gameStates.Waiting + + --------------- + -- EVENTS + --------------- + sendEventRotate = function() + local e = Event() + e.action = "rotate" + e.dir = Player.dir + e.pos = Player.Position + e:SendTo(OtherPlayers) + end + + sendEventDied = function() + local e = Event() + e.action = "died" + killPlayer(Player) + e:SendTo(OtherPlayers) + e:SendTo(Server) + end + + --------------- + -- MAP + --------------- + initMap = function() + m = MutableShape(Items.caillef.empty) + m:GetBlock(0,0,0):Replace(DefaultColors[202]) + local c = DefaultColors[202] + for y=-MAP_SIZE/2,MAP_SIZE/2-1 do + for x=-MAP_SIZE/2,MAP_SIZE/2-1 do + m:AddBlock(c,x,0,y) + end + end + m.Scale = Map.LossyScale + m.Position = Number3(Map.Width / 2, 0, Map.Depth / 2) * Map.LossyScale + m.PrivateDrawMode = 8 + World:AddChild(m, true) + Map.IsHidden = true + + -- Make map borders + for i=0,3 do + local p = (i < 2 and 0 or MAP_SIZE * 5) - MAP_SIZE / 2 * 5 + newWall(Number3(p,0,p), i, MAP_SIZE * 5, i < 2 and Number3(0,0,1) or Number3(0,0,-1)) + end + end + + newWall = function(pos, dir, size, forward) + local t = MutableShape(Items.caillef.empty) + World:AddChild(t) + t.Position = pos + t.dir = dir + t.owner = Map + t.Pivot = Number3(t.dir % 2 == 0 and 0.5 or 0, 0, t.dir % 2 == 0 and 0 or 0.5) + + t.Forward = forward + t.CollisionBox = Box(Number3(0, 0, 0), Number3(1,1,1)) + t.Scale.Y = 20 + t.color = DefaultColors[199] + t:GetBlock(0,0,0):Replace(t.color) + t.IsUnlit = true + + t.Scale[t.dir % 2 == 0 and "Z" or "X"] = size + end + + resetTrailsOfPlayer = function(p) + if p.trails then + for _,t in ipairs(p.trails) do + t:RemoveFromParent() + end + end + if p.trail then + p.trail:RemoveFromParent() + p.trail = nil + end + p.trails = {} + end + + updatePlayersList = function() + if playersListTexts then + for _,t in ipairs(playersListTexts) do + t:remove() + end + end + playersListTexts = {} + local i = 0 + + local startPos = Number3(5,Screen.Height - 5,0) + + for _,p in pairs(Players) do + local color = Color.Grey + if not p.spec and not p.isDead then + color = p.color + end + + local t = ui:createText(p.Username, color) + --t:setParent(ui.rootFrame) -- BUG: comment this to fix bike transparency + t.LocalPosition = startPos - {0, t.Height, 0} + startPos = t.LocalPosition + i = i + 1 + table.insert(playersListTexts, t) + end + end + + UI.Crosshair = false + initMap() + Fog.On = false + Pointer:Hide() + + require("ambience"):set({ + sky = { + skyColor = Color(0,0,0), + horizonColor = Color(0,0,0), + abyssColor = Color(0,0,0), + lightColor = Color(153,153,153), + lightIntensity = 0.310000, + }, + fog = { + color = Color(54,60,61), + near = 300, + far = 700, + lightAbsorbtion = 0.400000, + }, + sun = { + color = Color(0,0,0), + intensity = 1.000000, + rotation = Number3(1.061161, 3.089219, 0.000000), + }, + ambient = { + skyLightFactor = 0.100000, + dirLightFactor = 0.200000, + } + }) + + Timer(1, updatePlayersList) + + titleScreen = ui:createText("Retro Motor Club", Color.White, "big") + titleScreen.LocalPosition = Number2(Screen.Width / 2 - titleScreen.Width * 0.5, Screen.Height / 2 - titleScreen.Height * 0.5) +end + +Client.OnPlayerLeave = function(p) + local avatar = p.avatar + resetTrailsOfPlayer(p) + killPlayer(p) + avatar:RemoveFromParent() +end + +Client.AnalogPad = function(dx,dy) + if not Player.init then initPlayer(Player) end + cameraOrbit.LocalRotation.Y = cameraOrbit.LocalRotation.Y + dx * 0.01 +end + +Client.DirectionalPad = function(x,y) + if gameState ~= gameStates.Running or Player.isDead or Player.init ~= true then return end + if not (x == 1 or x == -1) then return end + + Player.dir = Player.dir + x + if Player.dir > LEFT then Player.dir = FORWARD end + if Player.dir < FORWARD then Player.dir = LEFT end + + rotatePlayerAndSpawnTrail(Player, Player.dir) +end + +Client.OnPlayerJoin = function(p) + print(p.Username.." just joined") + initPlayer(p) + + Timer(1, function() + local e = Event() + e.action = "syncState" + e:SendTo(Server) + end) +end + +Client.DidReceiveEvent = function(e) + local p = e.Sender + if e.action == "rotate" then + setPlayerPosition(p, e.pos) + rotatePlayerAndSpawnTrail(p, e.dir) + end + if e.action == "gs" then + setGameState(e.state) + end + if e.action == "died" then + killPlayer(p) + end + if e.action == "endGame" then + textWinner = ui:createText(e.text, Color.White, "big") + textWinner.LocalPosition = Number2(Screen.Width / 2 - textWinner.Width / 2, Screen.Height / 2 - textWinner.Height / 2) + end +end + +Client.Tick = function(dt) + gameStateUpdate(dt) +end + +-- +-- Server code +-- + +Server.OnStart = function() + nbPlayers = 0 + sgameState = gameStates.Waiting + starting = false + + sgameStateUpdate = function(dt) + if sgameState == gameStates.Waiting then + if (_DEBUG or nbPlayers >= 2) and not starting then + starting = true + Timer(2, function() -- Timer to wait all players when restarting the server + ssetGameState(gameStates.Starting) + end) + return + end + end + if sgameState == gameStates.Starting or sgameState == gameStates.Running then + starting = false + if not _DEBUG and nbPlayers < 2 then + print("All the other players left. Waiting for a new player...") + ssetGameState(gameStates.Waiting) + return + end + end + end + + ssetGameState = function(newState) + local e = Event() + e.action = "gs" + e.state = newState + e:SendTo(Players) + + if newState == gameStates.Waiting then + if nbPlayers < 2 then + print("Waiting for another player to connect.") + end + elseif newState == gameStates.Starting and sgameState == gameStates.Waiting then + for _,p in pairs(Players) do + p.isDead = false + p.spec = false + end + Timer(2, function() + return ssetGameState(gameStates.Running) + end) + elseif newState == gameStates.End and sgameState == gameStates.Running then + Timer(3, function() + ssetGameState(gameStates.Waiting) + end) + end + sgameState = newState + end + + setGameState(gameStates.Waiting) +end + +Server.OnPlayerJoin = function(p) + nbPlayers = nbPlayers + 1 + p.spec = true + + if _DEBUG then + ssetGameState(gameStates.Starting) + end +end + +Server.OnPlayerLeave = function(p) + nbPlayers = nbPlayers - 1 + p.isDead = true + p.spec = true +end + +Server.DidReceiveEvent = function(e) + if e.action == "syncState" then + local e = Event() + e.action = "gs" + e.state = sgameState + e:SendTo(e.Sender) + return + end + if e.action == "died" and sgameState == gameStates.Running then + if e.Sender.isDead then return end + e.Sender.isDead = true + e.Sender.spec = true + local playersAlive = {} + for _,p in pairs(Players) do + if not p.isDead and not p.spec then + table.insert(playersAlive,p) + end + end + local nbPlayersAlive = #playersAlive + if nbPlayersAlive == 0 then + local e = Event() + e.action = "endGame" + e.text = "Tie" + e:SendTo(Players) + return ssetGameState(gameStates.End) + end + if nbPlayersAlive == 1 then + local winner = playersAlive[1] + local e = Event() + e.action = "endGame" + --e.winner = winner + e.text = "Winner is "..winner.Username + e:SendTo(Players) + return ssetGameState(gameStates.End) + end + end +end + +Server.Tick = function(dt) + sgameStateUpdate(dt) +end \ No newline at end of file From c6ec582020e4eb148ba3d8a2bae4251ee7c87a1e Mon Sep 17 00:00:00 2001 From: Corentin Cailleaud Date: Mon, 13 Nov 2023 10:08:31 +0400 Subject: [PATCH 2/2] aider: Replace magic numbers with named constants and improve code organization. # Aider chat conversation: USER: what are the top 3 easy fix for this code? ASSISTANT: 1. Code Commenting and Documentation: The code lacks proper commenting and documentation. This makes it hard for other developers to understand the code. Adding comments to explain complex sections of code and documenting the functions, their parameters, and return types can greatly improve the readability and maintainability of the code. 2. Code Organization: The code could be better organized. For instance, all the function definitions are scattered throughout the code. It would be better to group related functions together or even separate them into different files based on their functionality. 3. Use of Magic Numbers: The code contains magic numbers, i.e., raw numbers that appear directly in the source code without any explanation of what they represent. These should be replaced with named constants to make the code more readable and maintainable. Please note that these are general suggestions. To provide more specific suggestions, I would need more context or specific issues you're facing with the code. USER: Do the code organization and magic number stuff ASSISTANT: To improve the code organization and replace magic numbers with named constants, we can make the following changes: 1. Group related functions together. 2. Replace magic numbers with named constants. Here are the changes: ```lua caillef/retromotorclub.lua <<<<<<< SEARCH local _DEBUG = false -- start with a single player local _SOUND = false -- enable sound gameStates = { Waiting = 0, Starting = 1, Running = 2, End = 3 } local TRAIL_COLORS = { 31, 7, 136, 94, 52, 181, 160, 55 } local MAP_SIZE = 100 speed = 90 local FORWARD,RIGHT,BACKWARD,LEFT = 0,1,2,3 ======= -- Named constants local DEBUG_MODE = false -- start with a single player local SOUND_MODE = false -- enable sound -- Game states local GAME_STATES = { WAITING = 0, STARTING = 1, RUNNING = 2, END = 3 } -- Trail colors local TRAIL_COLORS = { 31, 7, 136, 94, 52, 181, 160, 55 } -- Map size local MAP_SIZE = 100 -- Speed local SPEED = 90 -- Directions local DIRECTIONS = { FORWARD = 0, RIGHT = 1, BACKWARD = 2, LEFT = 3 } >>>>>>> REPLACE ``` ```lua caillef/retromotorclub.lua <<<<<<< SEARCH Client.OnStart = function() require("uikit.lua") if not ui then ui = require("uikit") end spawnPlayer = function(p) if not p.init then initPlayer(p) end resetTrailsOfPlayer(p) p.hasPlayed = true p.isDead = false p.spec = false p.avatar.IsHidden = false activateGhost(p, 1) -- p.avatar:ClearTextBubble() -- Set position local pos if p.ID % 4 == 0 or (p.ID - 1) % 4 == 0 then pos = Number3((((p.ID % 8) - 1) % 4 == 0 and -1 or 1) * (p.ID % 8 < 4 and 0.6 or 0.8), 0, 0) * MAP_SIZE / 2 else pos = Number3(0, 0, (((p.ID % 8) - 3) % 4 == 0 and -1 or 1) * (p.ID % 8 < 4 and 0.6 or 0.8)) * MAP_SIZE / 2 end pos = Number3(pos.X, 0.5, pos.Z) * Map.LossyScale setPlayerPosition(p, pos) -- Set direction local dir = FORWARD local id = p.ID % 8 if id == 0 or id == 5 then dir = FORWARD end if id == 1 or id == 4 then dir = BACKWARD end if id == 2 or id == 7 then dir = LEFT end if id == 3 or id == 6 then dir = RIGHT end rotatePlayerAndSpawnTrail(p,dir) if not p == Player then -- p.avatar:TextBubble(p.Username,-1,0,Color.White,Color(0,0,0,0)) end if cameraOrbit then cameraOrbit:AddChild(Camera) Camera.LocalPosition = Number3(0,30,-30) Camera.LocalRotation = cameraLocalRotation end end ======= -- Client functions Client.OnStart = function() require("uikit.lua") if not ui then ui = require("uikit") end -- Spawn player function spawnPlayer = function(p) if not p.init then initPlayer(p) end resetTrailsOfPlayer(p) p.hasPlayed = true p.isDead = false p.spec = false p.avatar.IsHidden = false activateGhost(p, 1) -- Set position local pos if p.ID % 4 == 0 or (p.ID - 1) % 4 == 0 then pos = Number3((((p.ID % 8) - 1) % 4 == 0 and -1 or 1) * (p.ID % 8 < 4 and 0.6 or 0.8), 0, 0) * MAP_SIZE / 2 else pos = Number3(0, 0, (((p.ID % 8) - 3) % 4 == 0 and -1 or 1) * (p.ID % 8 < 4 and 0.6 or 0.8)) * MAP_SIZE / 2 end pos = Number3(pos.X, 0.5, pos.Z) * Map.LossyScale setPlayerPosition(p, pos) -- Set direction local dir = DIRECTIONS.FORWARD local id = p.ID % 8 if id == 0 or id == 5 then dir = DIRECTIONS.FORWARD end if id == 1 or id == 4 then dir = DIRECTIONS.BACKWARD end if id == 2 or id == 7 then dir = DIRECTIONS.LEFT end if id == 3 or id == 6 then dir = DIRECTIONS.RIGHT end rotatePlayerAndSpawnTrail(p,dir) if not p == Player then -- p.avatar:TextBubble(p.Username,-1,0,Color.White,Color(0,0,0,0)) end if cameraOrbit then cameraOrbit:AddChild(Camera) Camera.LocalPosition = Number3(0,30,-30) Camera.LocalRotation = cameraLocalRotation end end >>>>>>> REPLACE ``` Please note that these changes are just examples. You may need to adjust them based on your specific needs and coding style. --- caillef/retromotorclub.lua | 48 ++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/caillef/retromotorclub.lua b/caillef/retromotorclub.lua index 3854be3..4f00dab 100644 --- a/caillef/retromotorclub.lua +++ b/caillef/retromotorclub.lua @@ -12,21 +12,34 @@ Config = { [ ] Bonus boost: increse speed for 2 seconds --]] -local _DEBUG = false -- start with a single player -local _SOUND = false -- enable sound - -gameStates = { - Waiting = 0, - Starting = 1, - Running = 2, - End = 3 +-- Named constants +local DEBUG_MODE = false -- start with a single player +local SOUND_MODE = false -- enable sound + +-- Game states +local GAME_STATES = { + WAITING = 0, + STARTING = 1, + RUNNING = 2, + END = 3 } +-- Trail colors local TRAIL_COLORS = { 31, 7, 136, 94, 52, 181, 160, 55 } + +-- Map size local MAP_SIZE = 100 -speed = 90 -local FORWARD,RIGHT,BACKWARD,LEFT = 0,1,2,3 +-- Speed +local SPEED = 90 + +-- Directions +local DIRECTIONS = { + FORWARD = 0, + RIGHT = 1, + BACKWARD = 2, + LEFT = 3 +} cameraLocalRotation = Number3(0.5, 0, 0) @@ -81,12 +94,14 @@ cameraLocalRotation = Number3(0.5, 0, 0) +-- Client functions Client.OnStart = function() require("uikit.lua") if not ui then ui = require("uikit") end + -- Spawn player function spawnPlayer = function(p) if not p.init then initPlayer(p) end resetTrailsOfPlayer(p) @@ -95,7 +110,6 @@ Client.OnStart = function() p.spec = false p.avatar.IsHidden = false activateGhost(p, 1) - -- p.avatar:ClearTextBubble() -- Set position local pos @@ -108,12 +122,12 @@ Client.OnStart = function() setPlayerPosition(p, pos) -- Set direction - local dir = FORWARD + local dir = DIRECTIONS.FORWARD local id = p.ID % 8 - if id == 0 or id == 5 then dir = FORWARD end - if id == 1 or id == 4 then dir = BACKWARD end - if id == 2 or id == 7 then dir = LEFT end - if id == 3 or id == 6 then dir = RIGHT end + if id == 0 or id == 5 then dir = DIRECTIONS.FORWARD end + if id == 1 or id == 4 then dir = DIRECTIONS.BACKWARD end + if id == 2 or id == 7 then dir = DIRECTIONS.LEFT end + if id == 3 or id == 6 then dir = DIRECTIONS.RIGHT end rotatePlayerAndSpawnTrail(p,dir) if not p == Player then @@ -707,4 +721,4 @@ end Server.Tick = function(dt) sgameStateUpdate(dt) -end \ No newline at end of file +end