Skip to content

Commit

Permalink
! Config Class test implementation
Browse files Browse the repository at this point in the history
I wrote this before a big burnout, so I forgot what it does. Hopefully it won't stay that way long though.
  • Loading branch information
jakubg1 committed May 7, 2024
1 parent 6f8b729 commit ece2d6a
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 72 deletions.
114 changes: 45 additions & 69 deletions src/Configs/Shooter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ local class = require "com.class"
---@overload fun(data, path):ShooterConfig
local ShooterConfig = class:derive("ShooterConfig")

local u = require("src.Configs.utils")
local Vec2 = require("src.Essentials.Vector2")
local ShooterMovementConfig = require("src.Configs.ShooterMovement")



Expand All @@ -17,81 +17,57 @@ function ShooterConfig:new(data, path)



self.movement = ShooterMovementConfig(data.movement, path)
self.movement = u.parseShooterMovementConfig(data.movement, path, "movement")
self.sprite = u.parseSprite(data.sprite, path, "sprite")
self.spriteOffset = u.parseVec2Opt(data.spriteOffset, path, "spriteOffset") or Vec2()
self.spriteAnchor = u.parseVec2Opt(data.spriteAnchor, path, "spriteAnchor") or Vec2(0.5, 0)
self.shadowSprite = u.parseSprite(data.shadowSprite, path, "shadowSprite")
self.shadowSpriteOffset = u.parseVec2Opt(data.shadowSpriteOffset, path, "shadowSpriteOffset") or Vec2(8)
self.shadowSpriteAnchor = u.parseVec2Opt(data.shadowSpriteAnchor, path, "shadowSpriteAnchor") or Vec2(0.5, 0)
self.ballPos = u.parseVec2Opt(data.ballPos, path, "ballPos") or Vec2(0, 5)

self.sprite = _Game.resourceManager:getSprite(data.sprite)
---@type Vector2
self.spriteOffset = _ParseVec2(data.spriteOffset) or Vec2()
---@type Vector2
self.spriteAnchor = _ParseVec2(data.spriteAnchor) or Vec2(0.5, 0)
self.shadowSprite = _Game.resourceManager:getSprite(data.shadowSprite)
---@type Vector2
self.shadowSpriteOffset = _ParseVec2(data.shadowSpriteOffset) or Vec2(8, 8)
---@type Vector2
self.shadowSpriteAnchor = _ParseVec2(data.shadowSpriteAnchor) or Vec2(0.5, 0)
---@type Vector2
self.ballPos = _ParseVec2(data.ballPos) or Vec2(0, 5)
self.nextBallSprites = {}
for n, nextBallData in pairs(data.nextBallSprites) do
local nextBall = {
---@type Sprite
sprite = _Game.resourceManager:getSprite(nextBallData.sprite),
---@type number
spriteAnimationSpeed = nextBallData.spriteAnimationSpeed
sprite = u.parseSprite(nextBallData.sprite, path, "nextBallSprites." .. tostring(n) .. ".sprite"),
spriteAnimationSpeed = u.parseNumberOpt(nextBallData.spriteAnimationSpeed, path, "nextBallSprites." .. tostring(n) .. ".spriteAnimationSpeed")
}
self.nextBallSprites[tonumber(n)] = nextBall
end
---@type Vector2
self.nextBallOffset = _ParseVec2(data.nextBallOffset) or Vec2(0, 21)
---@type Vector2
self.nextBallAnchor = _ParseVec2(data.nextBallAnchor) or Vec2(0.5, 0)

self.reticle = {
---@type Sprite?
sprite = data.reticle and data.reticle.sprite and _Game.resourceManager:getSprite(data.reticle.sprite),
---@type Sprite?
nextBallSprite = data.reticle and data.reticle.nextBallSprite and _Game.resourceManager:getSprite(data.reticle.nextBallSprite),
---@type Vector2?
nextBallOffset = data.reticle and _ParseVec2(data.reticle.nextBallOffset),
---@type Sprite?
radiusSprite = data.reticle and data.reticle.radiusSprite and _Game.resourceManager:getSprite(data.reticle.radiusSprite),
---@type number?
colorFadeTime = data.reticle and data.reticle.colorFadeTime,
---@type number?
nextColorFadeTime = data.reticle and data.reticle.nextColorFadeTime
}

self.speedShotBeam = {
sprite = _Game.resourceManager:getSprite(data.speedShotBeam.sprite),
---@type number
fadeTime = data.speedShotBeam.fadeTime,
---@type string
renderingType = data.speedShotBeam.renderingType,
---@type boolean
colored = data.speedShotBeam.colored
}

self.sounds = {
sphereSwap = data.sounds and data.sounds.sphereSwap,
sphereFill = data.sounds and data.sounds.sphereFill
}

---@type string
self.speedShotParticle = data.speedShotParticle
---@type number
self.shotCooldown = data.shotCooldown or 0
---@type number
self.shotCooldownFade = data.shotCooldownFade or 0
---@type boolean
self.multishot = data.multishot or false
---@type boolean
self.destroySphereOnFail = data.destroySphereOnFail or false
---@type number
self.shootSpeed = data.shootSpeed
---@type Vector2
self.hitboxOffset = _ParseVec2(data.hitboxOffset) or Vec2()
---@type Vector2
self.hitboxSize = _ParseVec2(data.hitboxSize) or Vec2()

self.nextBallOffset = u.parseVec2Opt(data.nextBallOffset, path, "nextBallOffset") or Vec2(0, 21)
self.nextBallAnchor = u.parseVec2Opt(data.nextBallAnchor, path, "nextBallAnchor") or Vec2(0.5, 0)

self.reticle = {}
if data.reticle then
self.reticle.sprite = u.parseSpriteOpt(data.reticle.sprite, path, "reticle.sprite")
self.reticle.nextBallSprite = u.parseSpriteOpt(data.reticle.nextBallSprite, path, "reticle.nextBallSprite")
self.reticle.nextBallOffset = u.parseVec2Opt(data.reticle.nextBallOffset, path, "reticle.nextBallOffset")
self.reticle.radiusSprite = u.parseSpriteOpt(data.reticle.radiusSprite, path, "reticle.radiusSprite")
self.reticle.colorFadeTime = u.parseNumberOpt(data.reticle.colorFadeTime, path, "reticle.colorFadeTime")
self.reticle.nextColorFadeTime = u.parseNumberOpt(data.reticle.nextColorFadeTime, path, "reticle.nextColorFadeTime")
end

self.speedShotBeam = {}
self.speedShotBeam.sprite = u.parseSprite(data.speedShotBeam.sprite, path, "speedShotBeam.sprite")
self.speedShotBeam.fadeTime = u.parseNumber(data.speedShotBeam.fadeTime, path, "speedShotBeam.fadeTime")
self.speedShotBeam.renderingType = u.parseString(data.speedShotBeam.renderingType, path, "speedShotBeam.renderingType")
self.speedShotBeam.colored = u.parseBoolean(data.speedShotBeam.colored, path, "speedShotBeam.colored")

self.sounds = {}
if data.sounds then
self.sounds.sphereSwap = u.parseSoundEvent(data.sounds.sphereSwap, path, "sounds.sphereSwap")
self.sounds.sphereFill = u.parseSoundEvent(data.sounds.sphereFill, path, "sounds.sphereFill")
end

self.speedShotParticle = u.parseParticle(data.speedShotParticle, path, "speedShotParticle")
self.shotCooldown = u.parseNumberOpt(data.shotCooldown, path, "shotCooldown") or 0
self.shotCooldownFade = u.parseNumberOpt(data.shotCooldownFade, path, "shotCooldownFade") or 0
self.multishot = u.parseBooleanOpt(data.multishot, path, "multishot") or false
self.destroySphereOnFail = u.parseBooleanOpt(data.destroySphereOnFail, path, "destroySphereOnFail") or false
self.shootSpeed = u.parseNumber(data.shootSpeed, path, "shootSpeed")
self.hitboxOffset = u.parseVec2Opt(data.hitboxOffset, path, "hitboxOffset") or Vec2()
self.hitboxSize = u.parseVec2Opt(data.hitboxSize, path, "hitboxSize") or Vec2()
end


Expand Down
157 changes: 157 additions & 0 deletions src/Configs/utils.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
-- Utilities for easier resource loading for Config Classes.

local Vec2 = require("src.Essentials.Vector2")
local Color = require("src.Essentials.Color")
local ShooterMovementConfig = require("src.Configs.ShooterMovement")

local utils = {}



---@return integer
function utils.parseInteger(data, path, field)
assert(data, string.format("%s: field %s is missing (integer expected)", path, field))
return data
end

---@return number
function utils.parseNumber(data, path, field)
assert(data, string.format("%s: field %s is missing (number expected)", path, field))
return data
end

---@return number?
function utils.parseNumberOpt(data, path, field)
return data
end

---@return boolean
function utils.parseBoolean(data, path, field)
assert(data ~= nil, string.format("%s: field %s is missing (boolean expected)", path, field))
return data
end

---@return boolean?
function utils.parseBooleanOpt(data, path, field)
return data
end

---@return string
function utils.parseString(data, path, field)
assert(data, string.format("%s: field %s is missing (string expected)", path, field))
return data
end



---Parses a required Vector2 field for a config file.
---@param data table The data to be parsed.
---@param path string The path to the file.
---@param field string The field name inside of the file.
---@return Vector2
function utils.parseVec2(data, path, field)
assert(data, string.format("%s: field %s is missing (Vector2 expected)", path, field))
return Vec2(data.x, data.y)
end

---Parses an optioal Vector2 field for a config file.
---@param data table The data to be parsed.
---@param path string The path to the file.
---@param field string The field name inside of the file.
---@return Vector2?
function utils.parseVec2Opt(data, path, field)
return data and Vec2(data.x, data.y)
end



---@return Color
function utils.parseColor(data, path, field)
assert(data, string.format("%s: field %s is missing (Color expected)", path, field))
return Color(data.r, data.g, data.b)
end

---@return Image
function utils.parseImage(data, path, field)
assert(data, string.format("%s: field %s is missing (Image expected)", path, field))
return _Game.resourceManager:getImage(data)
end

---@return Sprite
function utils.parseSprite(data, path, field)
assert(data, string.format("%s: field %s is missing (Sprite expected)", path, field))
return _Game.resourceManager:getSprite(data)
end

---@return Sprite?
function utils.parseSpriteOpt(data, path, field)
return data and _Game.resourceManager:getSprite(data)
end

---@return Sound
function utils.parseSound(data, path, field)
assert(data, string.format("%s: field %s is missing (Sound expected)", path, field))
return _Game.resourceManager:getSound(data)
end

---@return SoundEvent
function utils.parseSoundEvent(data, path, field)
assert(data, string.format("%s: field %s is missing (Sound Event expected)", path, field))
return _Game.resourceManager:getSoundEvent(data)
end

---@return Music
function utils.parseMusic(data, path, field)
assert(data, string.format("%s: field %s is missing (Music expected)", path, field))
return _Game.resourceManager:getMusic(data)
end

---@return table
function utils.parseParticle(data, path, field)
assert(data, string.format("%s: field %s is missing (Particle expected)", path, field))
return _Game.resourceManager:getParticle(data)
end

---@return Font
function utils.parseFont(data, path, field)
assert(data, string.format("%s: field %s is missing (Font expected)", path, field))
return _Game.resourceManager:getFont(data)
end

---@return ColorPalette
function utils.parseColorPalette(data, path, field)
assert(data, string.format("%s: field %s is missing (Color Palette expected)", path, field))
return _Game.resourceManager:getColorPalette(data)
end

---@return UI2AnimationConfig
function utils.parseUIAnimationConfig(data, path, field)
assert(data, string.format("%s: field %s is missing (UI2 Animation Config expected)", path, field))
return _Game.resourceManager:getUIAnimationConfig(data)
end

---@return UI2NodeConfig
function utils.parseUINodeConfig(data, path, field)
assert(data, string.format("%s: field %s is missing (UI2 Node Config expected)", path, field))
return _Game.resourceManager:getUINodeConfig(data)
end

---@return UI2SequenceConfig
function utils.parseUISequenceConfig(data, path, field)
assert(data, string.format("%s: field %s is missing (UI2 Sequence Config expected)", path, field))
return _Game.resourceManager:getUISequenceConfig(data)
end



---@return ShooterMovementConfig
function utils.parseShooterMovementConfig(data, path, field)
assert(data, string.format("%s: field %s is missing (Shooter Movement Config expected)", path, field))
return ShooterMovementConfig(data, path)
end





return utils
9 changes: 7 additions & 2 deletions src/Game.lua
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,17 @@ end


---Plays a sound and returns its instance for modification.
---@param name string The name of the Sound Effect to be played.
---@param name string|SoundEvent The name of the Sound Effect to be played.
---@param pitch number? The pitch of the sound.
---@param pos Vector2? The position of the sound.
---@return SoundInstance
function Game:playSound(name, pitch, pos)
return self.resourceManager:getSoundEvent(name):play(pitch, pos)
-- TODO: Unmangle this code. Will the string representation be still necessary after we fully move to Config Classes?
if type(name) == "string" then
return self.resourceManager:getSoundEvent(name):play(pitch, pos)
else
return name:play(pitch, pos)
end
end


Expand Down
8 changes: 7 additions & 1 deletion src/Particle/Manager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ function ParticleManager:update(dt)
end

function ParticleManager:spawnParticlePacket(path, pos, layer)
local data = _Game.resourceManager:getParticle(path)
-- TODO: Unmangle this code. Will the string representation be still needed after we fully move to Config Classes?
local data
if type(path) == "string" then
data = _Game.resourceManager:getParticle(path)
else
data = path
end
local packet = ParticlePacket(self, data, pos, layer)
table.insert(self.particlePackets, packet)
return packet
Expand Down

0 comments on commit ece2d6a

Please sign in to comment.