Skip to content
This repository has been archived by the owner on May 6, 2024. It is now read-only.

Commit

Permalink
! Functional Food Items
Browse files Browse the repository at this point in the history
So far, the only functional food item effects are:
- `curveClearsGiveOneSecond`
- `targetsGiveOneSecond`
- `multiplierCapAdditiveModifier`
- `shotSpeedModifier` (? - check Shooter.lua diff)

Thus, the list of functional Food items are:
- Cherry Time Tart
- Curvy Fries
- 10 Pound Turkey
- Potent Drinks (partial: 33% shot speed effect)

Again, you must edit runtime.lua in order to equip a food item. Most of them do nothing as they are not coded in.
  • Loading branch information
ShamblesSM committed Jan 20, 2023
1 parent 8d0c208 commit 91bef2e
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 13 deletions.
41 changes: 35 additions & 6 deletions src/ConfigManager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ local CollectibleGeneratorManager = require("src/CollectibleGenerator/Manager")

local ShooterConfig = require("src/Configs/Shooter")
local Power = require("src/Configs/Power")
local FoodItem = require("src/Configs/FoodItem")



Expand Down Expand Up @@ -82,13 +83,32 @@ end

---Loads config files which are implemented the new way so that they require to be loaded after the resources.
function ConfigManager:loadStuffAfterResources()
self.shooters = self:loadFolder("config/shooters", "shooter", false, ShooterConfig)
self.shooters = self:loadFolder("config/shooters", "shooter", false, ShooterConfig)
self.targetSprites = _LoadJson(_ParsePath("config/target_sprites.json"))

self.powers = self:loadFolder("config/powers", "power", false, Power)
for k, v in pairs(self.powers) do
v._name = k -- Only used for self-reference in Powers.lua
v:updateCurrentLevel()
for powerID, power in pairs(self.powers) do
power._name = powerID -- Only used for self-reference in Powers.lua
power:updateCurrentLevel()
end
self.foodItems = self:loadFolder("config/food_items", "food item", false, FoodItem)
for foodID, food in pairs(self.foodItems) do
food._name = foodID -- Only used for self-reference in FoodItem.lua
if food.variants then
for variant, data in pairs(food.variants) do
_Log:printt("ConfigManager", string.format("Loading food variant %s (base: %s). ID: %s", variant, food._name, food._name.."_"..variant))
local foodVariant = {
_name = food._name.."_"..variant,
displayName = data.displayName or food.displayName,
sprite = data.sprite or food.sprite,
price = data.price or food.price,
}
local instance = FoodItem(foodVariant, food._path)
instance.variantBase = food._name
table.insert(self.foodItems, instance)
end
end
end
self.targetSprites = _LoadJson(_ParsePath("config/target_sprites.json"))
end


Expand Down Expand Up @@ -130,7 +150,7 @@ end



---Returns a power config for a given shooter name.
---Returns a power config for a given power name.
---@param name string The name of the power.
---@return Power
function ConfigManager:getPower(name)
Expand All @@ -139,6 +159,15 @@ end



---Returns a food config for a given food item name.
---@param name string The name of the food.
---@return FoodItem
function ConfigManager:getFoodItem(name)
return self.foodItems[name]
end



---Returns the game name if specified, else the internal (folder) name.
---@return string
function ConfigManager:getGameName()
Expand Down
24 changes: 24 additions & 0 deletions src/Configs/FoodItem.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
local class = require "com/class"

---@class FoodItem
---@overload fun(data, path):FoodItem
local FoodItem = class:derive("FoodItem")

-- Place your imports here



function FoodItem:new(data, path)
self._path = path
self._name = nil -- Only used for self-reference; assigned in ConfigManager.lua
self.displayName = data.displayName
self.sprite = data.sprite
self.price = data.price or 10000
self.variants = data.variants
self.variantBase = nil
self.effects = data.effects
end



return FoodItem
8 changes: 7 additions & 1 deletion src/Game.lua
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ function Game:updateRichPresence()

local profile = _Game:getCurrentProfile()
local powerString = ""
local foodString = ""

if #profile.equippedPowers ~= 0 then
local powerNames = {}
Expand All @@ -176,6 +177,11 @@ function Game:updateRichPresence()
powerString = table.concat(powerNames, ", ")
else
powerString = "None"
end
if profile.equippedFood then
foodString = profile:getEquippedFoodItem(profile.equippedFood).displayName
else
foodString = "None"
end

line1 = string.format(
Expand All @@ -188,7 +194,7 @@ function Game:updateRichPresence()
line2 = string.format(
"Powers: %s | Food: %s",
powerString,
"None" -- add food later
foodString
)
--elseif p and p:getSession() then
--line2 = ""
Expand Down
9 changes: 7 additions & 2 deletions src/Level.lua
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,13 @@ function Level:updateLogic(dt)
for k, w in pairs(frequencies) do
if frequencies[powerup] > 0 and (math.random() < 1 / frequencies[powerup]) and frequencies[powerup] < self.stateCount - self.lastPowerupDeltas[powerup] then
local sphere = _Game.session:getRandomSphere()
if sphere then
if powerupToAdd == "multiplier" and self.multiplier < 10 then
if sphere then
local cap = 10
local raiseCap = _Game:getCurrentProfile():getEquippedFoodItemEffects() and _Game:getCurrentProfile():getEquippedFoodItemEffects().multiplierCapAdditiveModifier
if raiseCap then
cap = cap + raiseCap
end
if powerupToAdd == "multiplier" and self.multiplier < cap then
sphere:addPowerup("multiplier")
elseif powerupToAdd ~= "multiplier" then
sphere:addPowerup(powerupToAdd)
Expand Down
4 changes: 3 additions & 1 deletion src/Path.lua
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ function Path:update(dt)
"fonts/score0.json"
)
_Game:playSound("sound_events/curve_clear.json")
if not self.map.level.finish then

local shouldGiveOneSecond = _Game:getCurrentProfile():getEquippedFoodItemEffects() and _Game:getCurrentProfile():getEquippedFoodItemEffects().curveClearsGiveOneSecond
if not self.map.level.finish and shouldGiveOneSecond then
self.map.level:applyEffect({type = "addTime", amount = 1})
end
-- 10% of this path's length to be able to reclaim path clear bonus
Expand Down
85 changes: 83 additions & 2 deletions src/Profile.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ function Profile:new(data, name)
self.checkpoints = {}
self.variables = {}
self.equippedPowers = {}
self.powerCatalog = {}
self.powerCatalog = {}
self.equippedFood = nil
self.foodInventory = {}

if data then
self:deserialize(data)
Expand Down Expand Up @@ -598,6 +599,84 @@ end



-- Food items



---Equips a Food Item.
---@param foodItem string
function Profile:equipFoodItem(foodItem)
if not _Game.configManager.foodItems[foodItem] then
_Log:printt("Profile", string.format("Food ID %s does not exist", foodItem))
return
end
if not self:isFoodItemEquipped(foodItem) then
self.equippedFood = foodItem
else
_Log:printt("Profile", string.format("Food ID %s is already equipped", foodItem))
end
end



---Unequips a Food Item.
---@param foodItem string
function Profile:unequipFoodItem(foodItem)
if not _Game.configManager.powers[foodItem] then
_Log:printt("Profile", string.format("Food ID %s does not exist", foodItem))
return
end
if self:isPowerEquipped(foodItem) then
self.equippedFood = nil
else
_Log:printt("Profile", string.format("Food ID %s is already unequipped", foodItem))
end
end



---Returns true if a Food Item is already equipped.
---@param foodItem string
---@return boolean
function Profile:isFoodItemEquipped(foodItem)
if self.equippedFood == foodItem then
return true
end
return false
end



---Returns the specified Food Item if it is equipped or `nil`.
---
---This should only be used for UI related functions.
---If you wish to get the gameplay effects, use `Profile:getEquippedFoodItemEffects()`.
---@return FoodItem|nil
function Profile:getEquippedFoodItem(foodItem)
if not _Game.configManager.foodItems[foodItem] then
_Log:printt("Profile", string.format("Food ID %s does not exist", foodItem))
return
end
if self.equippedFood == foodItem then
return _Game.configManager:getFoodItem(foodItem)
end
end



---Returns the specified Food Item's effects if it is equipped or `nil`.
---
---Use this instead of `Profile:isFoodItemEquipped` and `_Game.configManager:getFoodItem()`.
---@return table|nil
function Profile:getEquippedFoodItemEffects()
if not self.equippedFood then
return
end
return self:getEquippedFoodItem(self.equippedFood).effects or nil
end



-- Serialization

---Serializes the Profile's data for saving purposes.
Expand All @@ -610,7 +689,8 @@ function Profile:serialize()
variables = self.variables,
equippedPowers = self.equippedPowers,
equippedFood = self.equippedFood,
powerCatalog = self.powerCatalog,
powerCatalog = self.powerCatalog,
foodInventory = self.foodInventory,
ultimatelySatisfyingMode = self.ultimatelySatisfyingMode
}
return t
Expand All @@ -629,6 +709,7 @@ function Profile:deserialize(t)
end
self.equippedPowers = t.equippedPowers
self.powerCatalog = t.powerCatalog
self.foodInventory = t.foodInventory
self.equippedFood = t.equippedFood
self.ultimatelySatisfyingMode = t.ultimatelySatisfyingMode

Expand Down
6 changes: 5 additions & 1 deletion src/Shooter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,11 @@ function Shooter:getShootingSpeed()
end
local speedShot = _Game:getCurrentProfile():getEquippedPower("speed_shot")
local powerMultiplier = (speedShot and speedShot:getCurrentLevelData().additiveMultiplier) or 0
return self.config.shootSpeed + (self.config.shootSpeed * powerMultiplier)

local foodSpeedShot = _Game:getCurrentProfile():getEquippedFoodItemEffects() and _Game:getCurrentProfile():getEquippedFoodItemEffects().shotSpeedModifier
-- TODO: What's the order of speed shot multipliers?
-- Is it Speed Shot power > Food Item? And am I doing this one-liner right?
return self.config.shootSpeed + (self.config.shootSpeed * powerMultiplier + (self.config.shootSpeed * foodSpeedShot))
end


Expand Down
4 changes: 4 additions & 0 deletions src/Target.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ function Target:onShot()
self:destroy()
_Game:playSound("sound_events/target_hit.json")
_Game.session.level:grantScore(_Game.session.level.targetHitScore)
local shouldGiveOneSecond = _Game:getCurrentProfile():getEquippedFoodItemEffects() and _Game:getCurrentProfile():getEquippedFoodItemEffects().targetsGiveOneSecond
if shouldGiveOneSecond then
_Game.session.level:applyEffect({type = "addTime", amount = 1})
end
_Game.session.level:spawnFloatingText(
string.format("BONUS\n+%s", _NumStr(_Game.session.level.targetHitScore * _Game.session.level.multiplier)),
self.pos,
Expand Down

0 comments on commit 91bef2e

Please sign in to comment.