Module:WeaponData/weapon

-- -- temp weapon type to classes mapping local weaponClasses = { ["Assault Rifle"] = {"Combat Medic"}, ["Carbine"] = {"Light Assault", "Engineer"}, ["Heavy Gun"] = {"Heavy Assault"}, ["LMG"] = {"Heavy Assault"}, ["Rocket Launcher"] = {"Heavy Assault"}, ["Shotgun"] = {"Light Assault", "Combat Medic", "Engineer", "Heavy Assault"}, ["Sniper Rifle"] = {"Infiltrator"}, ["SMG"] = {"Infiltrator", "Light Assault", "Combat Medic", "Engineer", "Heavy Assault"}, ["Scout Rifle"] = {"Infiltrator", "Combat Medic", "Engineer", "Heavy Assault"}, -- Sidearms ["Pistol"] = {"Infiltrator", "Light Assault", "Combat Medic", "Engineer", "Heavy Assault"}, ["Sidearm"] = {"Infiltrator", "Light Assault", "Combat Medic", "Engineer", "Heavy Assault"}, }

-- special access functions for data, allowing for default values, calculated values, special fields that aren't in the data, etc. local get = {}

function get:id return self.id end

function get:name return self.name end

function get:description return self.description end

function get:cert_cost return self.cert_cost end

function get:dc_cost return self.dc_cost end

function get:weapon_type return self.weapon_type end

function get:classes return self.classes or weaponClasses[self.weapon_type] end

function get:faction return self.faction end

function get:fire_modes return self.fire_modes end

function get:range return self.range end

function get:aim_move_speed_multiplier return self.stats and self.stats.move_modifier end

function get:equip_time return self.stats and self.stats.equip_ms end

function get:headshot_multiplier return self.stats and self.stats.damage_head_multiplier end

function get:fire_rate return self.stats and (self.stats.fire_rate		or self.stats.fire_refire_ms and math.floor((60000 / self.stats.fire_refire_ms) + 0.5)) end

function get:max_damage return self.stats and self.stats.max_damage end

function get:max_damage_range return self.stats and self.stats.max_damage_range end

function get:min_damage return self.stats and self.stats.min_damage end

function get:min_damage_range return self.stats and self.stats.min_damage_range end

function get:muzzle_velocity return self.stats and self.stats.muzzle_velocity end

function get:short_reload return self.stats and self.stats.short_reload end

function get:long_reload return self.stats and self.stats.long_reload end

function get:magazine_size return self.stats and (self.stats.magazine_size		or self.stats.clip_size) end

function get:ammunition return self.stats and (self.stats.ammunition		or self.stats.capacity) end

function get:hip_accuracy(stance) if stance then return self.stats and self.stats.hip_accuracy[stance] else return self.stats and self.stats.hip_accuracy end end

function get:aim_accuracy(stance) if stance then return self.stats and self.stats.aim_accuracy[stance] else return self.stats and self.stats.aim_accuracy end end

function get:min_vertical_recoil return self.stats and self.stats.recoil_magnitude_min end

function get:max_vertical_recoil return self.stats and self.stats.recoil_magnitude_max end

function get:min_horizontal_recoil return self.stats and self.stats.recoil_horizontal_min end

function get:max_horizontal_recoil return self.stats and self.stats.recoil_horizontal_max end

function get:horizontal_recoil_tolerance return self.stats and self.stats.recoil_horizontal_tolerance end

function get:min_recoil_angle return self.stats and self.stats.recoil_angle_min end

function get:max_recoil_angle return self.stats and self.stats.recoil_angle_max end

function get:recoil_bias if self.stats and self.stats.recoil_angle_min and self.stats.recoil_angle_max then local cmp = self.stats.recoil_angle_min + self.stats.recoil_angle_max if cmp == 0 then return "← = →" elseif cmp > 0 then return "→" elseif cmp < 0 then return "←" end else return nil end end

function get:recoil_decrease return self.stats and self.stats.recoil_recovery_rate end

function get:first_shot_recoil_multiplier return self.stats and self.stats.recoil_first_shot_modifier end

-- heat function get:isHeatWeapon return self.stats and self.stats.heat_threshold ~= nil end

function get:heat_recovery return self.stats and self.stats.heat_bleed_off_rate end function get:heat_recovery_delay return self.stats and self.stats.heat_recovery_delay_ms end function get:overheat_penalty return self.stats and self.stats.heat_overheat_penalty_ms end

function get:heat_per_shot return self.stats and self.stats.heat_per_shot end

function get:heat_capacity return self.stats and (self.stats.heat_threshold		or self.stats.heat_capacity) end

function get:heat_short_reload if self.stats and self.stats.heat_per_shot and self.stats.heat_bleed_off_rate and self.stats.heat_recovery_delay_ms then return string.format("", math.floor((1000 * self.stats.heat_per_shot / self.stats.heat_bleed_off_rate) + 0.5) / 1000, self.stats.heat_recovery_delay_ms / 1000) else return nil end end

function get:heat_long_reload return self.stats and string.format("%.3f", self.stats.heat_overheat_penalty_ms / 1000) -- if self.stats.heat_recovery_delay_ms and self.stats.heat_threshold and self.stats.heat_bleed_off_rate then -- 	return string.format("%.3f", (self.stats.heat_recovery_delay_ms + math.floor((1000 * self.stats.heat_threshold / self.stats.heat_bleed_off_rate) + 0.5)) / 1000) -- else -- 	return nil -- end end

function get:heat_magazine_size if self.stats and self.stats.heat_per_shot and self.stats.heat_threshold then return string.format("", self.stats.heat_per_shot, math.ceil(self.stats.heat_threshold / self.stats.heat_per_shot)) else return nil end end

local Weapon = {}

-- checks Weapon object weaponName against data name to check if variant function Weapon:get(field, ...) if self[1] ~= get["name"](self) then return self:getVariant(self[1], field, unpack(arg)) end return self:getBase(field, unpack(arg)) end

-- any values inside variant should override the main values function Weapon:getVariant(variant, ...) return variant and self["variants"] and self["variants"][variant] and self["variants"][variant] and Weapon.getBase(self["variants"][variant], unpack(arg))	-- looks in variants for variant overrides or self:getBase(unpack(arg))				-- falls back to base values end

function Weapon:getBase(field, ...) return get[field] and get[field](self, unpack(arg)) 	-- looks in get for a special access function or self[field]											-- falls back to value stored in data or (self["stats"] and self["stats"][field])				-- checks stats table as well end

function Weapon:isHeatWeapon return get.isHeatWeapon(self) end

-- Weapon object constructor -- @param weapon		weapon name (can be variant name) -- @param dataModule	data module page title or data table object for override; optional - defaults to weapon's data module function Weapon:new(weapon, dataModule) local o = {} -- local weaponData = mw.loadData("Module:WeaponData/data/ ")\ local weaponData local weaponName = weapon if type(dataModule) == "table" then weaponData = dataModule else weaponData = mw.loadData(type(dataModule) == "string" and (dataModule:find("^Module:") and dataModule or ("Module:WeaponData/data/" .. dataModule)) or dataModule or ("Module:WeaponData/data/" .. weapon))[weapon] end setmetatable(o, {		__index = function (t, k) return k==1 and weaponName or self[k] or weaponData[k] end,		__newindex = weaponData,	}) return o end

return Weapon --