Toggle menu
1.3K
1.7K
694
23.9K
Veloren Wiki
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Loot

From Veloren Wiki
Revision as of 04:07, 10 October 2023 by Horblegorble (talk | contribs)

--helpers
local module_frame = mw.getCurrentFrame()

tier_text = {module_frame:expandTemplate{title="Low"},
	         module_frame:expandTemplate{title="Common"},
	         module_frame:expandTemplate{title="Moderate"},
	         module_frame:expandTemplate{title="High"},
	         module_frame:expandTemplate{title="Epic"},
	         module_frame:expandTemplate{title="Legendary"},
	         module_frame:expandTemplate{title="Artifact"},
	         }
metal_text = {"Bronze", "Iron", "Steel", "Cobalt", "Bloodsteel", "Orichalcum"}
wood_text = {"Wooden", "Bamboo", "Hardwood", "Ironwood", "Frostwood", "Eldwood"}

upper_first = function(str)
	return str:sub(1, 1):upper() .. str:sub(2)
end


str_split_iter = function(str, sep, escape)
	if escape then
		sep = "%"..sep
	end
	return string.gmatch(str, "[^"..sep.."]+")
end


-- worker function
process = function(frame, txt, entries, depth, p_prev, reuse_p)
	
	local p_order = {}
	local hidep
	if not reuse_p then
		--sort indices by drop chance
		for idx, entry in ipairs(entries) do
			p_order[idx] = {idx, entry[1]}
		end
		table.sort(p_order, function(a, b) return a[2] > b[2] end)
		hidep = 0
	else
		-- use entries directly (re-using same probability)
		p_order = entries
		hidep = 1
	end
	
	-- process entries
	for _, val in ipairs(p_order) do
		-- unpack data
		local entry
		if not reuse_p then
			entry = entries[val[1]]
		else
			entry = val	
		end
    	local p_flt, box, p_str
    	if not reuse_p then
    		p_flt = entry[1] * p_prev
    		box = entry[2]
    	else
    		p_flt = p_prev
    		box = entry
    	end
    	local box_type = box.t
    	local box_content = box.c
    	
    	-- format probability string
    	local p_perc = p_flt * 100
    	p_str = tostring(p_perc)
    	if p_str ~= tostring(math.floor(p_perc)) then
    		p_str = string.format("%.2f", p_perc)
    	end
    	
    	-- handle box type
    	if box_type == "Item" then
    		-- single item row
    		local item = box_content[2]
    		txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=depth, item=item, n=1, p=p_str, hidep=hidep} }
		
		elseif box_type == "Nothing" then
    		-- single row
    		txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=depth, item="Nothing", p=p_str, hidep=hidep, noimg=1} }
		
    	elseif box_type == "MultiDrop" then
    		-- multidrop
			local nested_box = box_content[1]
			local nested_type = nested_box.t
			local low = box_content[2]
			local high = box_content[3]
			local n_str
			if low == high then
				n_str = tostring(low)
			else
				n_str = string.format("%s - %s", low, high)
			end
			if nested_type == "Item" then
				-- multiple of one item
				local item = nested_box.c[2]
				txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
	    			                              args={depth=depth, item=item, n=n_str, p=p_str, hidep=hidep} }
			elseif nested_type == "SubTable" then
				-- multidrop from nested table
				local sub_box = nested_box.c[1]
				local sub_depth = depth + 1
				local name = "Misc"
				txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable',
    			                                  args={depth=sub_depth, collapsed=0, title=name, n=n_str, p=p_str, hidep=hidep} }
				txt = process(frame, txt, sub_box, sub_depth, p_flt, false)
				txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootEndNested'}
			
			else
				-- other case (unhandled for now)
				
			end
    	
    	elseif box_type == "SubTable" then
    		local sub_depth = depth + 1
    		local sub_box = box_content[1]
			local sub_path = box_content[2]
			local override = false
    		
    		-- sub table header
			local path_sections = {}
			for section in str_split_iter(sub_path, '.', true) do
			-- for section in string.gmatch(sub_path, "[^%.]+") do
				path_sections[#path_sections+1] = section
			end
			local last_section = path_sections[#path_sections]
			local second_last_section = path_sections[#path_sections-1]
			local item_category = path_sections[3]
			local is_modular = "tier" == string.sub(last_section, 1, 4)
			local idx_tier
			if is_modular then
				idx_tier = 1 + tonumber(string.sub(last_section, -1, -1))
			end
			if item_category == "weapons" then
				if not is_modular then
					-- non-modular weapon
					local name = upper_first(last_section).."  Weapon"
					txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable',
    			                                      args={depth=sub_depth, title=name, p=p_str, hidep=hidep} }
				else
					if second_last_section == "components" then
						-- primary component
						local name = tier_text[idx_tier].."  Primary Component"
						txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable',
	    			                                      args={depth=sub_depth, title=name, n=1, p=p_str, hidep=hidep} }
						local metal = metal_text[idx_tier]
						local wood = wood_text[idx_tier]
						local p_wep = string.format("%.2f", 100 * p_flt / 6)
	    				txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=metal.." Sword Blade", p=p_wep, noimg=1} }
						txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=metal.." Axe Head", p=p_wep, noimg=1} }
    			        txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=metal.." Hammer Head", p=p_wep, noimg=1} }
    			        txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=wood.." Bow Limbs", p=p_wep, noimg=1} }
    			        txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=wood.." Sceptre Shaft", p=p_wep, noimg=1} }
    			        txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=wood.." Staff Shaft", p=p_wep, noimg=1} }
						-- **TODO**
						-- MediaWiki template for primary components of parameterised tier (sans outer header and end)
						override = true
						
					elseif second_last_section == "secondary" then
						-- secondary component
						-- **TODO**
						-- MediaWiki template for secondary components (sans outer header and end)
						override = true
						
					else
						-- modular weapon
						local name = tier_text[idx_tier].."  Weapon"
						txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable',
	    			                                      args={depth=sub_depth, title=name, n=1, p=p_str, hidep=hidep} }
						local metal = metal_text[idx_tier]
						local wood = wood_text[idx_tier]
						local p_wep = string.format("%.2f", 100 * p_flt / 6)
	    				txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=metal.." Sword", p=p_wep, noimg=1} }
						txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=metal.." Axe", p=p_wep, noimg=1} }
    			        txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=metal.." Hammer", p=p_wep, noimg=1} }
    			        txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=wood.." Bow", p=p_wep, noimg=1} }
    			        txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=wood.." Sceptre", p=p_wep, noimg=1} }
    			        txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=sub_depth, item=wood.." Staff", p=p_wep, noimg=1} }
    			        
						-- **TODO**
						-- MediaWiki template for complete modular weapon of parameterised tier (sans outer header and end)
						override = true
						
						
					end
				end
			elseif item_category == "armor" then
				if not is_modular then
					-- specific armor
					local name = upper_first(last_section)
					local image = name.." Armor Set.png"
					name = name.." Armor"
					txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable',
    			                            	      args={depth=sub_depth, title=name, image=image, p=p_str, hidep=hidep} }
				else
					-- modular armor tier
					local name = tier_text[idx_tier].."  Armor"
					txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable',
    			                                      args={depth=sub_depth, title=name, n=1, p=p_str, hidep=hidep} }
				end
			elseif item_category == "food" then
				--food sub tables (hard-code matching for now)
				local name
				if last_section == "wild_ingredients" then
					name = "Wild Ingredients"
				elseif last_section == "prepared" then
					name = "Prepared Food"
				elseif last_section == "farm_ingredients" then
					name = "Farm Ingredients"
				else
					name = "Food"
				end
				txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable',
    			                                  args={depth=sub_depth, collapsed=1, title=name, p=p_str, hidep=hidep} }
			elseif item_category == "materials" then
				local name
				if last_section == "gems" then
					name = "Gems"
				elseif last_section == "underground" then
					name = "Underground Materials"
				else
					name = "Materials"
				end
				txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable',
    			                                  args={depth=sub_depth, collapsed=1, title=name, p=p_str, hidep=hidep} }
			else
				-- non weeapon/armor sub table
				-- local name = last_section..second_last_section
				local name = "Misc"
				txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable',
    			                                  args={depth=sub_depth, collapsed=0, title=name, p=p_str, hidep=hidep} }
			end
			
			-- sub table rows (unless direct template was used)
			if not override then
				txt = process(frame, txt, sub_box, sub_depth, p_flt, false)
			end
			
			-- sub table end 
			txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootEndNested'}
			
    	elseif box_type == "All" then
    		local sub_depth = depth + 1
    		txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable',
    			                              args={depth=sub_depth, title="All", collapsed=0, p=p_str, hidep=hidep} }
			txt = process(frame, txt, box_content, sub_depth, p_flt, true)   			                               
			txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootEndNested'}
    		
    		-- spacer row approach
    		-- txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowSpacer'}
    		-- txt = process(frame, txt, box_content, sub_depth, p_flt/100, true)
    		-- txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowSpacer'}
			
		else
			-- fallback (shouldn't reach)
			local name = "Error"
			txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootRowVariable',
    			                              args={depth=depth, item=name, p=0, hidep=1, noimg=1} }
    	end
    	
	end
	
	return txt
	
end

-- mainline code
local module = {}
local json = mw.text.jsonDecode(module_frame:expandTemplate{title="User:Horblegorble/Sandbox/Template/LootData"})

module.drops = function(frame)
	-- generates drops table for an entity
	
	-- handle args
	-- local entity = tostring(frame.args[1])
	-- local loot_page = "User:"..entity.."Loot"
	-- local json = mw.text.jsonDecode(frame:expandTemplate{title=loot_page})
	
	-- get entity name
	-- local page_sections = {}
	-- for idx, section in ipairs(str_split_iter(frame.args[1])) do
	-- 	page_sections[idx] = section	
	-- end
	-- local entity = page_sections[#page_sections]
	local entity = frame.args[1]
	-- find data entry for entity
	local data = false
	for _, entry in ipairs(json) do
		if entry[1] == entity then
			data = entry[2]
			break
		end
	end
	if not data then
		return "entity not found in loot data"
	end
	
	-- table start
    local txt = frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootHeaderVariable'}
	
	-- do the work
	txt = process(frame, txt, data, 0, 1.0, false)
	
	-- table end
    txt = txt .. frame:expandTemplate{title='User:Horblegorble/Sandbox/Template/LootEnd'}
    
    return txt
end

module.sources = function(frame)
	-- generates drop sources table for an item
	
end

return module
Cookies help us deliver our services. By using our services, you agree to our use of cookies.