Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion export.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/bash
git archive --format zip --prefix=mod/ --output ../DiscoScience.zip master
git archive --format zip --output ../DiscoScience_2.0.2.zip master ./src/
2 changes: 2 additions & 0 deletions spec/mocks/prototypes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ prototypes.get_technology_filtered = function()
return game.mockTechPrototypes
end

--FIXME: Need to mock the mod_data

return prototypes
4 changes: 4 additions & 0 deletions changelog.txt → src/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Version: 2.0.2
Date: 08. 12. 2024
Changes:
- Changed prototype name to fix incompatibility with Developer Assistant mod
- Support for custom lab animation graphics
Bugfixes:
- Actually use the HR graphics
- Validate and normalize given colors
---------------------------------------------------------------------------------------------------
Version: 2.0.1
Date: 12. 10. 2024
Expand Down
17 changes: 10 additions & 7 deletions src/control.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ local labColoring = require("core.labColoring")
-- constants

local colorSwitchFrequency = 60
storage = {}

-- Track whether state is linked, in order to be able to avoid remote callbacks
-- before proper initialization (when a dependent mod is initialised later in a game)
Expand All @@ -26,8 +27,14 @@ local linkState = function ()
end

local removeOldData = function ()
---@deprecated Old
---@type nil
storage.scalarState = nil
---@deprecated Old
---@type nil
storage.labsByForce = nil
---@deprecated Old
---@type nil
storage.labAnimations = nil
end

Expand Down Expand Up @@ -89,18 +96,14 @@ script.on_configuration_changed(
)

script.on_event(
{
defines.events.on_script_trigger_effect
},
defines.events.on_script_trigger_effect,
function (event)
labRenderers.addLab(event.target_entity)
end
)

script.on_event(
{
defines.events.on_object_destroyed
},
defines.events.on_object_destroyed,
function (event)
if event.type ~= defines.target_type.entity then return end
labRenderers.removeLab(event.useful_id)
Expand All @@ -116,7 +119,7 @@ script.on_nth_tick(
)

script.on_event(
{defines.events.on_tick},
defines.events.on_tick,
function (event)
researchColor.validateIngredientColors()
labColoring.updateRenderers(event, labRenderers, researchColor)
Expand Down
12 changes: 11 additions & 1 deletion src/core/labColoring.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ labColoring.chooseNewDirection = function()
end
end

---@param lab LuaEntity
---@param colors Color.0
---@param hq boolean
---@param playerPosition MapPosition
---@param labRenderers LabRenderer
---@param fcolor Color.0
labColoring.updateRenderer = function (lab, colors, hq, playerPosition, labRenderers, fcolor)
local animation = labRenderers.getRenderObjects(lab)
if lab.status == working or lab.status == low_power then
Expand All @@ -79,12 +85,16 @@ labColoring.updateRenderer = function (lab, colors, hq, playerPosition, labRende
end
end

---@param event EventData
---@param labRenderers LabRenderer
---@param researchColor ResearchColor
labColoring.updateRenderers = function (event, labRenderers, researchColor)
local hq = settings.global["discoscience-high-quality"].value
local hq = settings.global["discoscience-high-quality"].value --[[@as boolean]]
labColoring.state.meanderingTick = max(0, labColoring.state.meanderingTick + labColoring.state.direction)
local stride = getStride(hq)
local offset = event.tick % stride
local fcolor = {r=0, g=0, b=0, a=0}
---@type table<uint, {[1]:Color.0[], [2]:MapPosition}>
local forceInfo = {}
for name, force in pairs(game.forces) do
local forceResearchColors = researchColor.getColorsForResearch(force.current_research)
Expand Down
108 changes: 83 additions & 25 deletions src/core/labRenderers.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---@class LabRenderer
local labRenderers = {}

local draw_animation = rendering.draw_animation
Expand All @@ -8,60 +9,115 @@ local random = math.random

labRenderers.state = nil

---@param state LabRendererState
labRenderers.linkState = function (state)
labRenderers.state = state
return state
end

-- Data Validation
local labData = prototypes.mod_data["discoscience-lab-data"].data --[[@as table<data.EntityID, LabData>]]

---@param lab data.EntityID
---@param data LabData
---@return LabData? validatedData return nil to get it removed from the data lookup
local function validateLabData(lab, data)
local labPrototype = prototypes.entity[lab]
-- These are logs so stale data in the mod-data isn't a crashable offense
if not labPrototype then
log("Given lab data for non-existent lab: "..lab.."\t"..serpent.line(data))
return nil
end
if labPrototype.type ~= "lab" then
log("Given lab data for a non-lab entity: "..lab)
return nil
end

--FIXME: This has to wait for 2.1: https://forums.factorio.com/132999
-- if type(data.animation) ~= "string"
-- or not helpers.is_valid_animation_path(data.animation) then
-- error("Given animation name is not a valid animation: "..lab.." -> "..serpent.line(data.animation))
-- end

if not data.scale then
data.scale = 1
elseif type(data.scale) ~= "number" then
error("Given animation scale is not a number: "..lab.." -> "..serpent.line(data.scale))
end

return data
end

for lab, data in pairs(labData) do
labData[lab] = validateLabData(lab, data)
end

labRenderers.createInitialState = function()
---@class LabRendererState
---@field labs table<uint, LuaEntity>
---@field labAnimations table<uint, LuaRenderObject>
---@field labData table<data.EntityID, LabData>
return {
labs = {},
labAnimations = {},
labScales = {
["lab"] = 1,
}
labData = labData
}
end

---@deprecated Trying to move to mod data
labRenderers.setLabScale = function (name, scale)
labRenderers.state.labScales[name] = scale
if not scale then
labRenderers.state.labData[name] = nil
return
end

local labData = labRenderers.state.labData[name]
if not labData then
labRenderers.state.labData[name] = {
animation = "discoscience-lab-storm",
scale = scale,
}
else
labData.scale = scale
end
end

---@param entity LuaEntity
labRenderers.createAnimation = function (entity)
local scale = labRenderers.state.labScales[entity.name]
labRenderers.state.labAnimations[entity.unit_number] = draw_animation({
animation = "discoscience-lab-storm",
local labData = labRenderers.state.labData[entity.name]
labRenderers.state.labAnimations[entity.unit_number--[[@as uint]]] = draw_animation({
animation = labData.animation,
surface = entity.surface,
target = entity,
x_scale = scale,
y_scale = scale,
x_scale = labData.scale,
y_scale = labData.scale,
render_layer = "higher-object-under",
animation_offset = floor(random()*300),
visible = false,
})
end

---@param entity LuaEntity
---@return boolean
labRenderers.isCompatibleLab = function (entity)
if not entity.type == "lab" then return false end
for name, _ in pairs(labRenderers.state.labScales) do
if entity.name == name then return true end
end
return false
return labRenderers.state.labData[entity.name] and true or false
end

---@param entity LuaEntity
labRenderers.addLab = function (entity)
if not entity or not entity.valid then
if not entity or not entity.valid
or not labRenderers.isCompatibleLab(entity) then
return
end
if labRenderers.isCompatibleLab(entity) then
local labUnitNumber = entity.unit_number
if labRenderers.state.labs[labUnitNumber] then
return
end
labRenderers.state.labs[labUnitNumber] = entity
if not labRenderers.state.labAnimations[labUnitNumber] then
labRenderers.createAnimation(entity)
end

local labUnitNumber = entity.unit_number--[[@as uint]]
if labRenderers.state.labs[labUnitNumber] then
return
end
labRenderers.state.labs[labUnitNumber] = entity
if not labRenderers.state.labAnimations[labUnitNumber] then
labRenderers.createAnimation(entity)
end
script.register_on_object_destroyed(entity)
end
Expand All @@ -70,14 +126,14 @@ labRenderers.reloadLabs = function ()
labRenderers.state.labs = {}
labRenderers.state.labAnimations = {}
rendering.clear("DiscoScience")
for surfaceIndex in pairs(game.surfaces) do
local surface = game.get_surface(surfaceIndex)
for _, surface in pairs(game.surfaces) do
for index, lab in ipairs(surface.find_entities_filtered({type = "lab"})) do
labRenderers.addLab(lab)
end
end
end

---@param labUnitNumber uint
labRenderers.removeLab = function (labUnitNumber)
labRenderers.state.labAnimations[labUnitNumber] = nil
labRenderers.state.labs[labUnitNumber] = nil
Expand All @@ -87,6 +143,8 @@ labRenderers.getLabs = function()
return labRenderers.state.labs
end

---@param entity LuaEntity
---@return LuaRenderObject
labRenderers.getRenderObjects = function(entity)
local labUnitNumber = entity.unit_number
if not labRenderers.state.labAnimations[labUnitNumber].valid then
Expand Down
Loading