From Dark and Darker Wiki

action move penalty test
hit slow test
 
(One intermediate revision by the same user not shown)
Line 122: Line 122:
local function collect_multipliers(ability)
local function collect_multipliers(ability)
local move, prep_move = "",""
local move, prep_move = "",""
for i,attack_name in ipairs(ability.order) do
for _, attack_name in ipairs(ability.order) do
if ability[attack_name].movementmultiplier then
if ability[attack_name].movementmultiplier then
if i ~= 1 then
if move ~= "" then
move = move.."/"
move = move.."/"
prep_move = prep_move.."/"
prep_move = prep_move.."/"
Line 130: Line 130:
move = move..(ability[attack_name].movementmultiplier or "")
move = move..(ability[attack_name].movementmultiplier or "")
prep_move = prep_move..(ability[attack_name].preparemovementmultiplier or "")
prep_move = prep_move..(ability[attack_name].preparemovementmultiplier or "")
i = i + 1
end
end
end
end
Line 166: Line 165:
end
end
return "<td>"..wt.."</td>"
return "<td>"..wt.."</td>"
end
---Formats a table cell containing hitslow for each attack
local function slowdown_on_hit(utility,is_header)
if is_header then return [[<th style="width:8%">Slowdown On Hit</th>]] end
if not (utility.abilities.Primary or utility.abilities.Secondary or utility.abilities.Special) then return "<td></td>" end
local ability_type = "Primary"
-- if utility.slottype == "Off-Hand" then ability_type = "Secondary" end
local wt = format("<span style='color:#eee8'>%s Hitslow</span><br>", ability_type)
local duration = " for "
for i,attack in ipairs(utility.abilities[ability_type].order) do
if i~=1 then wt = wt.."/" end
wt = wt..(utility.abilities[ability_type][attack].effects.HitSlow.rarity.Global["Move Speed Add"]
or utility.abilities[ability_type][attack].effects.HitSlow.rarity.Global["Move Speed Bonus"] or "")
end
for i,attack in ipairs(utility.abilities[ability_type].order) do
if i~=1 then duration = duration.."/" end
duration = duration..(utility.abilities[ability_type][attack].effects.HitSlow.rarity.Global["Duration"] or "")
end
return "<td>"..wt..duration.."s</td>"
end
end


Line 181: Line 202:
["Consumable"] = {name, move_speed, effect, interaction_time, action_move_speed_penalty},
["Consumable"] = {name, move_speed, effect, interaction_time, action_move_speed_penalty},
["Installable"] = {name,class,move_speed,effect,interaction_time},
["Installable"] = {name,class,move_speed,effect,interaction_time},
["LightSource"] = {name, move_speed, damage_on_hit, effect, action_move_speed_penalty}, -- slowdown_on_hit
["LightSource"] = {name, move_speed, damage_on_hit, effect, action_move_speed_penalty, slowdown_on_hit},
["Throwable"] = {name, class, move_speed, damage_on_hit, effect, action_move_speed_penalty}, -- slowdown_on_hit
["Throwable"] = {name, class, move_speed, damage_on_hit, effect, action_move_speed_penalty, slowdown_on_hit},
["MusicalInstrument"] = {name, move_speed, damage_on_hit, effect, action_move_speed_penalty}, -- slowdown_on_hit
["MusicalInstrument"] = {name, move_speed, damage_on_hit, effect, action_move_speed_penalty, slowdown_on_hit},
["Mining"] = {name, move_speed, damage_on_hit, effect, action_move_speed_penalty}, --stats, slowdown_on_hit
["Mining"] = {name, move_speed, damage_on_hit, effect, action_move_speed_penalty, slowdown_on_hit}, --stats
["SoulHeart"] = {name, move_speed, effect},
["SoulHeart"] = {name, move_speed, effect},
["Food"] = {name, move_speed, effect},
["Food"] = {name, move_speed, effect},
["Tool"] = {name, move_speed, effect, action_move_speed_penalty}, --stats, slowdown_on_hit
["Tool"] = {name, move_speed, effect, action_move_speed_penalty, slowdown_on_hit}, --stats
["Default"] = {name, move_speed, damage_on_hit, effect, action_time, action_move_speed_penalty}
["Default"] = {name, move_speed, damage_on_hit, effect, action_time, action_move_speed_penalty}
}
}

Latest revision as of 06:50, 29 October 2026

Overview

Functions for making Utility tables. Data comes from Data:Utility.json.

Functions

draw_table

Creates a table of utilities

Parameters

  • 1 - <Type>


draw_table examples

Drink


{{#invoke:Utility|draw_table|Drink}}


NameMovement SpeedEffectAction TimeAction Movement Penalty
-10While active, gain 4 | 5 | 6 | 7 | 8 | 9 | 10 Strength and become drunk for 15 seconds.3s
100% Scaling
Other Actions
Always: x75%
-10Drink this to gain 5 to All Attributes for 10 seconds. In return, you also gain an unhealing debuff.3s
100% Scaling
Other Actions
Always: x75%
-10Recover 20 Magical Base Healing (50% Scaling) over 15 seconds.3s
100% Scaling
Other Actions
Always: x75%
-10Instantly restores 3 health and applies a festive effect.3s
100% Scaling
Other Actions
Always: x75%
-10Gain between 50 | 100 | 200 to 150 | 200 | 300 Luck.3s
100% Scaling
Other Actions
Always: x75%
-10Gain a shield that blocks 10 | 15 | 20 | 25 | 30 | 35 | 40 magical Damage for 24 seconds.3s
100% Scaling
Other Actions
Always: x75%
-10Gain 2 spell recovery every second for 20 | 40 | 60 | 80 | 100 | 120 | 140 seconds.3s
100% Scaling
Other Actions
Always: x75%
-10Recover 20 Magical Base Healing (50% Scaling) over 20 | 17.5 | 15 | 12.5 | 10 | 7.5 | 5 seconds.3s
100% Scaling
Other Actions
Always: x75%
-10Gain invisibility for 11 | 14 | 17 | 20 | 23 | 26 | 29 seconds. When you move, perform an action or take damage, the effect is removed.3s
100% Scaling
Other Actions
Always: x75%
-10Gain between 20 to 80 Luck.3s
100% Scaling
Other Actions
Always: x75%
-10Gain a shield that blocks 10 | 15 | 20 | 25 | 30 | 35 | 40 physical damage for 24 seconds.3s
100% Scaling
Other Actions
Always: x75%
-10Recover 20 | 30 | 40 | 50 | 60 | 70 | 80 Oxygen.3s
100% Scaling
Other Actions
Always: x75%
-10Recover 100 Magical Base Healing (50% Scaling) over 100 seconds.3s
100% Scaling
Other Actions
Always: x75%

Code


local p = {}
local UD = mw.loadJsonData("Data:Utility.json")
local concat = table.concat
local format = string.format

---Get the item's size in pixels
local function size(item)
	return tostring(item.invwidth*45).."x"..tostring(item.invheight*45).."px"
end

local function count(t)
	local c = 0
	for _ in pairs(t) do c = c + 1 end
	return c
end

---Marks up a list of values with color based on rarity
local function color_values(utility, values)
	if values == nil then return "" end
	if type(values)=="string" or type(values)=="number" then
		if count(utility.rarities) == 1 then return "<span class='cr"..utility.rarities[1].."'>"..values.."</span>" end
		return tostring(values)
	end

	local wt = ""
	local newline = ""
	for i, key in ipairs(utility.rarities) do
		wt = wt..newline.."<span class='cr"..key.."'>"..tostring(values[tonumber(key)] or "").."</span>"
		if i == 1 then newline = "<br>" end
	end
	return wt
end

---Returns a predetermined utility list
local function get_list(frame)
	if not (frame.args and frame.args[1]) then return {} end
	if not (UD[frame.args[1]] and UD[frame.args[1]]) then return {} end

	return UD[frame.args[1]]
end

---Formats a table cell for the iconbox
local function name(item, is_header)
	if is_header then return [[<th style="width:5%">Name</th>]] end

	local color = "2"
	local bold_link = "|<b>"..item.name
	if count(item.rarities) == 1 then
		color = item.rarities[1]
		bold_link = "|<b class=cr"..color..">"..item.name
	end

	local icon_amount = ""
	if item.maxammocount > 0 then
		icon_amount = "<span class='iconamount' style='pointer-events:none;color:#EEEA;font-size:16px'>"..item.maxammocount.."</span>"
	end

	return "<td><div class='iconbox' style='width:max-content;align-items:center'><div class='rarity"..color.." rounded relative'>[[File:"..item.name..".png|"..size(item).."|link="..item.name.."]]"
				..icon_amount
			.."</div><br>[["..item.name..bold_link.."</b>]]</div></td>"
end

---Formats a table cell of classes
local function class(utility,is_header)
	if is_header then return [[<th style="width:5%">Class</th>]] end
	
	local wt = {}
	wt[#wt+1] = "<td>"
	for _, class in ipairs(utility.classes) do
		wt[#wt+1] = class.."<br>"
	end
	wt[#wt+1] = "</td>"
	return concat(wt)
end

---Formats a table cell of move speeds
local function move_speed(utility,is_header)
	if is_header then return [[<th style="width:5%">Movement Speed</th>]] end

	return "<td>"..color_values(utility,utility.stats["move speed"]).."</td>"
end

---Formats a table cell of damages on hit
local function damage_on_hit(utility,is_header)
	if is_header then return [[<th style="width:5%">Damage on Hit</th>]] end

	return "<td>"..color_values(utility,utility.stats["physical base weapon damage"]).."</td>"
end

---Formats a table cell of effects
local function effect(utility,is_header)
	if is_header then return [[<th style="width:20%">Effect</th>]] end
	
	local effect = ""
	if utility.utilitydesc then effect = utility.utilitydesc end
	return "<td>"..effect.."</td>"
end

---Formats a table cell of action times
local function action_time(utility,is_header)
	if is_header then return [[<th style="width:10%">Action Time</th>]] end
	
	local actiontime = utility.actiontime
	local actiontimescaling = utility.actiontimescaling
	local finalstring = "<td></td>"
	if actiontime and actiontimescaling then finalstring = format("<td>%ss<br>%s Scaling</td>", actiontime, actiontimescaling) end
	return finalstring
end

---Formats a table cell of interaction times (This is the little loading circle with the percent when interacting vs stuff like drinking a potion)
local function interaction_time(utility,is_header)
	if is_header then return [[<th style="width:10%">Interaction Time</th>]] end
	
	local interactiontimescaling = utility.interactiontimescaling
	local interactiontimeformatted = utility.interactiontimeformatted
	local finalstring = "<td></td>"
	if interactiontimeformatted and interactiontimescaling then finalstring = format("<td>%s<br>%s Scaling</td>", interactiontimeformatted, interactiontimescaling) end
	return finalstring
end

---Helper function: Collects move mult and prepare move mult for display
local function collect_multipliers(ability)
	local move, prep_move = "",""
	for _, attack_name in ipairs(ability.order) do
		if ability[attack_name].movementmultiplier then
			if move ~= "" then
				move = move.."/"
				prep_move = prep_move.."/"
			end
			move = move..(ability[attack_name].movementmultiplier or "")
			prep_move = prep_move..(ability[attack_name].preparemovementmultiplier or "")
		end
	end

	return move,prep_move
end

---Formats a table cell containing speed penalties for each action
local function action_move_speed_penalty(utility,is_header)
	if is_header then return [=[<th style="width:10%">[[Weapons#Movement_Multiplier_Explanation|Action Movement Penalty]]</th>]=] end

	-- The below was brought from the Weapons Module, it appears "Other" abilities were ignored
	-- This seems to skip needed ones in utilities, maybe weapons also has some? this is a potential oversight
	
	-- local order = {} --reconstruct order to exclude the other ability group
	-- for _,ability in ipairs(utility.abilities.order) do
	-- 	if ability ~= "Other" then order[#order+1] = ability end
	-- end

	local wt = ""
	for i,ability_name in ipairs(utility.abilities.order) do
		if i~=1 then wt = wt.."<br><br>" end

		wt = wt.."<span style='color:#eee8; font-size:110%; font-weight:bold'>"
		if ability_name=="Other" or ability_name=="Block" then wt = wt..ability_name.." Actions" else wt = wt..ability_name.." Attacks" end
		wt = wt.."</span><br>"

		local movement_multiplier,prepare_movement_multiplier = collect_multipliers(utility.abilities[ability_name])
		if #prepare_movement_multiplier > 3 then
			wt = wt.."<span style='color:#eee8'>Mid Attack:&nbsp;</span>x"..movement_multiplier
			.."<br><span style='color:#eee8'>Otherwise:&nbsp;</span>x"..prepare_movement_multiplier
		else
			wt = wt.."<span style='color:#eee8'>Always:&nbsp;</span>x"..movement_multiplier
		end
	end
	return "<td>"..wt.."</td>"
end

---Formats a table cell containing hitslow for each attack
local function slowdown_on_hit(utility,is_header)
	if is_header then return [[<th style="width:8%">Slowdown On Hit</th>]] end
	if not (utility.abilities.Primary or utility.abilities.Secondary or utility.abilities.Special) then return "<td></td>" end

	local ability_type = "Primary"
	-- if utility.slottype == "Off-Hand" then ability_type = "Secondary" end

	local wt = format("<span style='color:#eee8'>%s Hitslow</span><br>", ability_type)
	local duration = " for "
	for i,attack in ipairs(utility.abilities[ability_type].order) do
		if i~=1 then wt = wt.."/" end
		wt = wt..(utility.abilities[ability_type][attack].effects.HitSlow.rarity.Global["Move Speed Add"]
				or utility.abilities[ability_type][attack].effects.HitSlow.rarity.Global["Move Speed Bonus"] or "")
	end
	for i,attack in ipairs(utility.abilities[ability_type].order) do
		if i~=1 then duration = duration.."/" end
		duration = duration..(utility.abilities[ability_type][attack].effects.HitSlow.rarity.Global["Duration"] or "")
	end
	return "<td>"..wt..duration.."s</td>"
end

local function determine_table_type(utility)
	if utility.args then
		return utility.args[1]
	elseif utility.utilitytype then
		return utility.utilitytype
	end
end

---Determines which table data goes into the table row
local row_type = {
	["Drink"] = {name, move_speed, effect, action_time, action_move_speed_penalty},
	["Consumable"] = {name, move_speed, effect, interaction_time, action_move_speed_penalty},
	["Installable"] = {name,class,move_speed,effect,interaction_time},
	["LightSource"] = {name, move_speed, damage_on_hit, effect, action_move_speed_penalty, slowdown_on_hit},
	["Throwable"] = {name, class, move_speed, damage_on_hit, effect, action_move_speed_penalty, slowdown_on_hit},
	["MusicalInstrument"] = {name, move_speed, damage_on_hit, effect, action_move_speed_penalty, slowdown_on_hit},
	["Mining"] = {name, move_speed, damage_on_hit, effect, action_move_speed_penalty, slowdown_on_hit}, --stats
	["SoulHeart"] = {name, move_speed, effect},
	["Food"] = {name, move_speed, effect},
	["Tool"] = {name, move_speed, effect, action_move_speed_penalty, slowdown_on_hit}, --stats
	["Default"] = {name, move_speed, damage_on_hit, effect, action_time, action_move_speed_penalty}
}

---Return a table row of data cells containing utility information,
local function row(utility, is_header)
	is_header = is_header or false
	local wt = {}
	wt[#wt+1] = "<tr>"
	for _,content in ipairs(row_type[determine_table_type(utility)]) do
		wt[#wt+1] = content(utility,is_header)
	end
	wt[#wt+1] = "</tr>"

	return concat(wt)
end

function p.draw_table(frame)
	local wt = {}
	local item_list = get_list(frame)
	if count(item_list) == 0 then return "<span style='font-size:24pt'>There are currently no items of this type.</span>" end

	wt[#wt+1] = "<table cellspacing='0' class='wikitable sortable jquery-tablesorter' style='text-align:center; vertical-align:middle;'>"
	wt[#wt+1] = row(frame, true)
	for _,item_name in ipairs(item_list) do
		wt[#wt+1] = row(UD.Utility[item_name])
	end
	wt[#wt+1] = "</table>"

	return concat(wt)
end

return p

-- Tests
-- mw.log(p.draw_table({args={"Drink"}}))
-- mw.log(p.draw_table({args={"Consumable"}}))
-- mw.log(p.draw_table({args={"Installable"}}))
-- mw.log(p.draw_table({args={"LightSource"}}))
-- mw.log(p.draw_table({args={"Throwable"}}))
-- mw.log(p.draw_table({args={"MusicalInstrument"}}))
-- mw.log(p.draw_table({args={"Mining"}}))
-- mw.log(p.draw_table({args={"SoulHeart"}}))
-- mw.log(p.draw_table({args={"Food"}}))
-- mw.log(p.draw_table({args={"Tool"}}))