warframe

Database for WARFRAME's Conclave weapon stat data.

Google docs on Conclave weapon stats: https://docs.google.com/spreadsheets/d/1q2BcFDKtIz_P5RC1b0cH0JUVP_UEgyDasjQq9Ck4kV0/edit?usp=sharing

Last updated: Sat, 10 Dec 2022 00:20:54 +0000 (UTC) by User:Cephalon Scientia

Attack Data Schema

	{
		AttackName = "Normal Attack",
		AmmoCost = 0.5,
		BurstCount = 1,
		Damage = { Impact = 1, Puncture = 1, Slash = 1 },
		FireRate = 1.0,
		Falloff = { StartRange = 400, EndRange = 600, Reduction = 0.2 },
		ShotType = "Hit-Scan",
		ShotSpeed = 80,
		Trigger = "Semi-Auto"
	},
Key/Column Name Data Type Required? Explanation/Description Example(s)
AttackName String Name of attack; defaults to "Normal Attack" "Normal Attack" or "AoE Explosion"
AmmoCost Number (float) Ammo consumed on a single attack input; defaults to 1 0.5 or 10
AmmoType String Type of ammo pickups that replenishes ammo reserves; "None" for battery weapons and "Energy" for those that use Warframe energy "Sniper"
BurstCount Number (integer) For burst-fire weapons, the number of shots per burst; for attacks that shoot bursts that scale off magazine size (e.g Pandero Pandero), use the base magazine amount as the burst count 4
BurstDelay Number (float) For burst-fire weapons, the time in seconds between each burst; omit this for attacks that shoot bursts that scale off magazine size as reload time is the delay effectively 0.04
BurstFireRate Number (float) For burst-fire weapons, the fire rate of weapon during burst 9.09
Damage Table (map of floats) ✔️ Table of damage types that the weapon deals and their individual damage values. Possible keys: Impact, Puncture, Slash, Cold, Electricity, Heat, Toxin, Blast, Corrosive, Gas, Magnetic, Radiation, Viral, Void, and MinProgenitorBonus (random element for Kuva/Tenet weapons) { Impact = 100, Puncture = 25, Slash = 30 }
ChargeTime Number (float) For charged attacks, the base charge time for a fully charged attack 0.5
EffectDuration Number (float) For special attacks, the time in seconds that a special effect lasts for (e.g. Pox Pox's toxin clouds or Zenistar Zenistar's disc) 5
ExplosionDelay Number (float) For AoE attacks, the time in seconds between initial shot and explosion; the same as "Embedded Delay" stat in-game 0.5
Falloff Table (map of floats) Attack's base Damage Falloff stats; includes starting distance in meters when falloff multiplier comes into play, ending distance in meters when falloff multipler is at max reduction, and the maximum damage reduction as a decimal { StartRange = 0, EndRange = 5, Reduction = 0.5 }
FireRate Number (float) ✔️ Attack's base Fire Rate or Attack Speed 6.5
ForcedProcs Table (array of strings) Attack's forced procs, if any { "Impact", "Slash" }
IsSilent Boolean Whether or not an attack has a silent Noise Level; defaults to false true
Multishot Number (integer) Attack's base Multishot value; defaults to 1 10
PunchThrough Number (float) Attack's base Punch Through value in meters; defaults to 0 1.5
Radius Number (float) For AoE attacks, the base radius of area of effect in meters 5
Range Number (float) For maximum range of a particular attack in meters 40
ShotType String ✔️ Attack's shot type (e.g. "Hit-Scan", "Projectile", "Discharge" for beam/continuous weapons, and "AoE" for area of effects) Projectile
ShotSpeed Number (integer) For projectile attacks, attack's projectile speed 50
Trigger String For weapons with multiple Trigger Types, attack's trigger type "Semi-Auto"

Gun Entry Schema

["Long Gun Weapon Name"] = {
	Accuracy = 100,
    Attacks = {
		{
			AttackName = "Normal",
			AmmoCost = 0.5,
			BurstCount = 1,
			Damage = { Impact = 1, Puncture = 1, Slash = 1 },
			FireRate = 1.0,
			Falloff = { StartRange = 400, EndRange = 600, Reduction = 0.2 },
			HeadshotMultiplier = 2,
			ShotType = "Hit-Scan",
			ShotSpeed = 100,
			Trigger = "Semi-Auto"
 		}
	},
	Introduced = "",
    Link = "Page Name",
	Magazine = 1,
	MaxAmmo = 540,
	Reload = 1,
	ReloadStyle = "Regenerate",
	SniperComboMin = 1,
	SniperComboReset = 1,
	Spool = 5,
	Trigger = "Semi-Auto",
	Traits = { "Grineer" },
	Users = { },
	Zoom = { "2.0x", "4.0x" }
},
Key/Column Name Data Type Required? Explanation/Description Example(s)
Accuracy Number (float) ✔️ Gun's base Accuracy value 100
Attacks Table ✔️ Contains attack data for the weapon See #Attack Data Schema
Class String Weapon class for modding or a subclass of the weapon in its equip slot; in the case of Exalted Weapons, it is just "Exalted Weapon" "Sniper Rifle"
ExilusPolarity String Polarity on Exilus slot "Madurai"
Family String Weapon family that it belongs to, corresponding to the Riven Mod compatibility "Latron"
HeadshotMultiplier Number (float) ✔️ Damage multiplier on headshots 2
Image String Image file name of the weapon as uploaded to the wiki CrpBFG.png
Introduced String The game version in which the weapon was first introduced in the global build of WARFRAME "30.5" or "Specters of the Rail"
Link String ✔️ Page/article link to the weapon on the wiki "Conclave:Artemis Bow (Weapon)"
Magazine Number (integer) ✔️ Gun's base magazine size 45
Mastery Number (integer) Mastery Rank requirement 5
MaxAmmo Number (integer) ✔️ Gun's base maximum reserve ammo (this excludes magazine size) 210
Name String Weapon's name "Primary Vermisplicer Chamber"
Polarities Table (array of strings) Full names of the weapon's non-Universal polarities { "Naramon", "Madurai" }
Reload Number (float) ✔️ Gun's base reload time in seconds 3.5
ReloadDelay Number (float) For rechargeable/battery weapons, the time in seconds after firing before magazine 'recharges' or is replenished 0.5
ReloadRate Number (float) For rechargeable/battery weapons, the rate at which magazine 'recharges' or is replenished per second 40
ReloadStyle String Gun's unique reload type for weapons like Cycron Cycron or Corinth Corinth "Regenerate" or "ByRound"
Slot String The weapon slot that the weapon can be equipped on; in the case of Exalted Weapons, it is just their modding class "Primary"
SniperComboMin Number (integer) For sniper rifles, the minimum number of hits to gain combo bonus 1
SniperComboReset Number (integer) For sniper rifles, the number of seconds after last hit before combo number goes down 3
Spool Number (integer) For auto-spool weapons, number of shots until weapon reaches max fire rate 5
Trigger String ✔️ Gun's Trigger Type "Auto" or "Auto / Burst"
Traits Table (array of strings) Gun's categorical traits { "Grineer", "Wraith" }
Zoom Table (array of strings) The levels of zoom that the gun offers { "2.0x", "4.5x" }

Melee Entry Schema

["Melee Weapon Name"] = {
	Attacks = {
    	{
			Damage = { Impact = 1, Puncture = 1, Slash = 1 },
			FireRate = 1
		}
	},
	FollowThrough = 0.7,
	HeavyAttack = 1284,
	HeavySlamAttack = 1070,
	HeavyRadialDmg = 1070,
	HeavySlamRadius = 8,
	Introduced = "",
	MeleeRange = 3,
	SlamAttack = 642,
	SlamElement = "Heat",
	SlamRadialDmg = 214,
	SlamRadialElement = "Heat",
	SlamRadialProcs = { "Heat" },
	SlamRadius = 7,
	SlideAttack = 1,
	StancePolarity = "V",
	Traits = { "Tenno" },
},
Key/Column Name Data Type Required? Explanation/Description Example(s)
Attacks Table ✔️ Contains attack data for the weapon See #Attack Data Schema
Class String Weapon class for modding or a subclass of the weapon in its equip slot; in the case of Exalted Weapons, it is just "Exalted Weapon" "Nikana"
Family String Weapon family that it belongs to, corresponding to the Riven Mod compatibility "Machete"
FollowThrough Number (float) ✔️ Melee's base follow through multiplier as a decimal 0.6
HeavyAttack Number (float) ✔️ Melee's base heavy attack damage 1284
HeavySlamAttack Number (float) ✔️ Melee's base heavy slam direct hit damage 1070
HeavyRadialDmg Number (float) ✔️ Melee's base heavy slam radial attack damage 1070
HeavySlamRadius Number (integer) ✔️ Melee's base heavy slam radius in meters 8
Image String Image file name of the weapon as uploaded to the wiki CrpBFG.png
Introduced String The game version in which the weapon was first introduced in the global build of WARFRAME "30.5" or "Specters of the Rail"
Link String ✔️ Page/article link to the weapon on the wiki "Exalted Blade (Weapon)"
Mastery Number (integer) Mastery Rank requirement 5
MeleeRange Number (float) ✔️ Melee's base attack range in meters 2
Name String Weapon's name "Galatine Prime"
Polarities Table (array of strings) Full names of the weapon's non-Universal polarities { "Naramon", "Madurai" }
SlamAttack Number (float) ✔️ Melee's base normal slam direct hit damage 642
SlamElement String Melee's base normal slam direct hit damage type "Heat"
SlamRadialDmg Number (float) ✔️ Melee's base normal slam radial damage 214
SlamRadialElement String Melee's base normal slam radial attack damage type "Heat"
SlamRadialProcs Table (array of strings) Melee's base normal slam radial attack forced proc(s) { "Heat" }
SlamRadius Number (integer) ✔️ Melee's base normal slam radius in meters 7
SlideAttack Number (float) ✔️ Melee's base slide attack damage 100
SlamElement String Melee's base slide attack damage type "Toxin"
Slot String The weapon slot that the weapon can be equipped on; in the case of Exalted Weapons, it is just their modding class "Melee"
StancePolarity String Polarity on Stance slot "Madurai"
Traits Table (array of strings) Gun's categorical traits { "Grineer", "Wraith" }

For Module Use

Key/Column Name Data Type Required? Explanation/Description Example(s)
_IgnoreEntry Boolean For module use, indicates that this weapon table entry is special and should ignored when parsing table entries true
_IgnoreInCSV Boolean For module use, indicates that this weapon table entry should be ignored when outputting CSV (via Module:Weapons/csv) true
_TooltipAttackDisplay Number For module use, tells what table entry in Attack table to use when processing weapon tooltips and comparing weapon variants in Comparison sections; 1 will be used if no value is assigned 4

Horizontal Partitions (and where to update data)

Weapon Data


---	WARFRAME Conclave weapon database to be used on the wiki.
--	
--	@module			weapons/data
--	@alias			data
--	@attribution	[[User:FINNER|FINNER]]
--	@attribution	[[User:Cephalon Scientia|Cephalon Scientia]]
--	@attribution	Everyone who contributes to adding new data or updating existing values in database
--	@require		[[Module:Table]]
---	@require		[[Module:LuaSerializer]]
--	@release		stable
--	<nowiki>

-- TODO: Since horizontal partitions are accessed programmatically, this means
-- that this module can be tailored to serve specific user localizations.
-- All we need to do is to add a locale flag in here set to mw.getCurrentFrame():preprocess('{{int:Custom-lang}}'), 
-- a separate translation table (likely JSON) for mapping canonical internal names to localized names, 
-- and replace the Name key/Trigger key/index key with the localized counterpart.
-- In theory, any database access by requiring this module should contain the 
-- proper localization based on user's interface language setting.

local Table = require('Module:Table')

local data = {}

local MODULE_LOCALIZATION = mw.site.namespaces[828].name

local PVE_DATA_NAME = 'Weapons/data'

-- Conclave weapon entries will omit some fields that are shared with PvE counterpart.
-- Persist shared data in here when Conclave weapon entry is indexed
local SHARED_KEYS = {
	'Class', 'Conclave', 'ExilusPolarity', 'Family', 'Image', 'Introduced',
	'IsSilent', 'Mastery', 'Name', 'Polarities', 'StancePolarity', 'Slot',
	'Tradable', 'Traits'
}

local CONCLAVE_SLOTS = { 'primary', 'secondary', 'melee' }

local SLOTS_MAP = {
	primary = 'primary',
	secondary = 'secondary',
	melee = 'melee',

	-- Commented out are currently unused for Conclave
	-- archwing = 'archwing',
	-- ['arch-gun'] = 'archwing',
	-- ['arch-melee'] = 'archwing',
	-- ['arch-gun (atmosphere)'] = 'archwing',

	-- companion = 'companion',
	-- ['robotic'] = 'companion',
	-- ['hound'] = 'companion',

	-- railjack = 'railjack',
	-- ['railjack turret'] = 'railjack',
	-- ['railjack ordnance'] = 'railjack',

	-- modular = 'modular',
	-- ['amp'] = 'modular',
	-- ['kitgun'] = 'modular',
	-- ['zaw'] = 'modular',

	-- misc = 'misc',
	-- ['emplacement'] = 'misc',
	-- ['gear'] = 'misc',
	-- ['nech-melee'] = 'misc',
	-- ['unique'] = 'misc',
	-- ['vehicle'] = 'misc',
}

---	Copy of https://github.com/wikimedia/mediawiki-extensions-Scribunto/blob/master/includes/Engines/LuaCommon/lualib/mw.lua#L665
--	so that we preserve read-only access of modified Conclave weapon entries which had to 
--	add additional data from their respective PvE entry
--	TODO: Move this function to a different module for other modules to use? Like in [[Module:Table]]?
--	@param			{table} data Data to access
--	@param			{table|nil} seen Table of already-seen tables.
--	@param			{string} name Name of calling function
--	@return			table
local function dataWrapper(data, seen, name)
	local t = {}
	seen = seen or { [data] = t }

	local function pairsfunc(s, k)
		k = next(data, k)
		if k ~= nil then
			return k, t[k]
		end
		return nil
	end

	local function ipairsfunc(s, i)
		i = i + 1
		if data[i] ~= nil then
			return i, t[i]
		end
		return -- no nil to match default ipairs()
	end

	local mt = {
		mw_loadData = true,
		__index = function (tt, k)
			assert(t == tt)
			local v = data[k]
			if type( v ) == 'table' then
				seen[v] = seen[v] or dataWrapper(v, seen, name)
				return seen[v]
			end
			return v
		end,
		__newindex = function (t, k, v)
			error("table from " .. name .. " is read-only", 2)
		end,
		__pairs = function (tt)
			assert(t == tt)
			return pairsfunc, t, nil
		end,
		__ipairs = function (tt)
			assert(t == tt)
			return ipairsfunc, t, 0
		end,
	}
	-- This is just to make setmetatable() fail
	mt.__metatable = mt

	return setmetatable(t, mt)
end

-- Defining default metatable values
local dbMetatable = {
	-- Page title of database
	_pageName = 'Weapons/Conclave/data',
}
dbMetatable._pageTitle = MODULE_LOCALIZATION..':'..dbMetatable._pageName

---	Defining custom looping behavior with pairs() to iterate over multiple 
--	partitions while acting as one database table.
--	@function		data.__pairs
--	@param			{table} self Table self-reference
--	@return			{function} Iterator function
--	@return			{table} Contains key-pair values of slot names to corresponding horizontal partition
dbMetatable.__pairs = function(self)
		local temp = {}
		local slots = CONCLAVE_SLOTS
		
		for i, slot in ipairs(slots) do
			temp[i] = mw.loadData(getmetatable(self)._pageTitle..'/'..slot)
		end
		
		function next(t, key)
			return pairs(t)(t, key)
		end

		function __next(t, key)
			if not key then
				return next(t[1])
			else
				for i = 1, #t - 1 do
					if t[i][key] then
						if next(t[i], key) then
							return next(t[i], key)
						else
							return next(t[i + 1])
						end
					end
				end
				return next(t[#t], key)
			end
		end

		return __next, temp, nil
	end

---	Supporting indexing by slot name (returns array of weapon entries) or weapon name
--	(returns a weapon entry).
--	@function		data.__index
--	@param			{table} self Table self-reference
--	@param			{string} key Index key
--	@return			{table}
dbMetatable.__index = function(self, key)
		if (type(key) == 'number') then return nil end
		
		-- Indexing by slot
		local slot = SLOTS_MAP[key:lower()]
		if key and slot then
			local ConclaveWeaponData = require(getmetatable(self)._pageTitle..'/'..slot)
			local WeaponData = require(MODULE_LOCALIZATION..':'..PVE_DATA_NAME..'/'..slot)
			-- Adding shared key-value pairs from M:Weapons/data
			Table.copyKeyValues(ConclaveWeaponData, WeaponData, SHARED_KEYS)
			return ConclaveWeaponData
		end
		
		local slots = CONCLAVE_SLOTS
		
		-- Indexing by weapon name
		local weapon
		for _, slot in ipairs(slots) do
			weapon = require(getmetatable(self)._pageTitle..'/'..slot)[key]
			
			if weapon then
				-- Adding some shared fields from PVE entry to PVP
				-- Tables returned by require() are not read-only, unlike mw.loadData()
				coopWeaponEntry = require(MODULE_LOCALIZATION..':'..PVE_DATA_NAME..'/'..slot)[key]
				for _, sharedKey in ipairs(SHARED_KEYS) do
					-- If a shared key is explicitly present in Conclave weapon entry, assume
					-- that value is overrided; don't replace it
					if (weapon[sharedKey] == nil) then
						weapon[sharedKey] = coopWeaponEntry[sharedKey]
					end
				end
				
				return dataWrapper(weapon, nil, 'modified PvP weapon entry from [[Module:Weapons/Conclave/data]]')
			end
		end
		return nil
	end

---	For changing which type of database to pull data from.
--	If you want to switch to a different database in the same script, must require()
--	a new instance of M:Weapons/data.
--	@function		__call
--	@usage			require('Module:Weapons/data')
--	@param			{table} self Table self-reference
--	@param			{table} args Argument table
--	@return			{table} Database table
dbMetatable.__call = function(self, args)
		-- Define logic for additional named arguments before the return statement
		-- TODO: We can take advantage of calling a database table by adding additional arguments
		-- for filtering out content.
		return self
	end

---	Serializes database tables into a single string with no functions and metatables.
--	@function		__tostring
--	@param			{table} self Table self-reference
--	@return			{string} Serialized database
dbMetatable.__tostring = function(self)
		return require('Module:LuaSerializer')._serialize(getmetatable(self)._pageName)
	end

setmetatable(data, dbMetatable)

return data