From 7311d01c5d5330df520aeaca20018add495f3897 Mon Sep 17 00:00:00 2001 From: XNTEABDSC <2364400855@qq.com> Date: Wed, 26 Nov 2025 17:15:39 +0800 Subject: [PATCH 1/3] better_comm_system_1 --- LuaRules/Configs/dynamic_comm_defs.lua | 1808 ++--------------- LuaRules/Gadgets/unit_commander_upgrade.lua | 29 +- LuaRules/Gadgets/unit_shield_charge.lua | 561 ++--- LuaUI/Configs/startup_info_selector.lua | 13 +- gamedata/modularcomms/chassises/assult.lua | 245 +++ gamedata/modularcomms/chassises/chicken.lua | 250 +++ gamedata/modularcomms/chassises/knight.lua | 246 +++ gamedata/modularcomms/chassises/recon.lua | 227 +++ gamedata/modularcomms/chassises/strike.lua | 238 +++ gamedata/modularcomms/chassises/support.lua | 230 +++ gamedata/modularcomms/chassises/template.txt | 17 + gamedata/modularcomms/chassises_all_defs.lua | 14 + gamedata/modularcomms/clonedefs.lua | 186 +- .../dyncomm_chassis_generator.lua | 197 +- gamedata/modularcomms/dyncomms_predefined.lua | 75 +- gamedata/modularcomms/functions.lua | 4 +- gamedata/modularcomms/moduledefs.lua | 22 + .../modules/all_vanilla_modules.lua | 1491 ++++++++++++++ .../modularcomms/modules/chickenbioarmor.lua | 38 + .../modules/chickenbioarmorheavy.lua | 42 + gamedata/modularcomms/modules/chickenclaw.lua | 35 + .../modules/chickenflamethrower.lua | 34 + gamedata/modularcomms/modules/chickengoo.lua | 45 + .../modularcomms/modules/chickenshield.lua | 46 + .../modularcomms/modules/chickenspike.lua | 35 + .../modularcomms/modules/chickenspores.lua | 34 + .../modules/commweapon_beamlaser.lua | 43 + .../modules/commweapon_flamethrower.lua | 45 + .../modules/commweapon_heatray.lua | 44 + .../modules/commweapon_heavymachinegun.lua | 46 + .../modules/commweapon_lightninggun.lua | 46 + .../modules/commweapon_lparticlebeam.lua | 46 + .../modules/commweapon_missilelauncher.lua | 45 + .../modules/commweapon_riotcannon.lua | 46 + .../modules/commweapon_rocketlauncher.lua | 46 + .../modules/commweapon_shotgun.lua | 46 + gamedata/modularcomms/modules/template.txt | 25 + gamedata/modularcomms/modules_all_defs.lua | 14 + gamedata/modularcomms/staticcomms.lua | 29 +- gamedata/modularcomms/unitdefgen.lua | 5 +- gamedata/modularcomms/weapons/chickenclaw.lua | 31 + .../weapons/chickenflamethrower.lua | 56 + gamedata/modularcomms/weapons/chickengoo.lua | 43 + .../modularcomms/weapons/chickenshield.lua | 32 + .../modularcomms/weapons/chickenspike.lua | 41 + .../modularcomms/weapons/chickenspores.lua | 48 + modularCommAPI/api_modularcomms.lua | 5 +- 47 files changed, 4633 insertions(+), 2311 deletions(-) create mode 100644 gamedata/modularcomms/chassises/assult.lua create mode 100644 gamedata/modularcomms/chassises/chicken.lua create mode 100644 gamedata/modularcomms/chassises/knight.lua create mode 100644 gamedata/modularcomms/chassises/recon.lua create mode 100644 gamedata/modularcomms/chassises/strike.lua create mode 100644 gamedata/modularcomms/chassises/support.lua create mode 100644 gamedata/modularcomms/chassises/template.txt create mode 100644 gamedata/modularcomms/chassises_all_defs.lua create mode 100644 gamedata/modularcomms/modules/all_vanilla_modules.lua create mode 100644 gamedata/modularcomms/modules/chickenbioarmor.lua create mode 100644 gamedata/modularcomms/modules/chickenbioarmorheavy.lua create mode 100644 gamedata/modularcomms/modules/chickenclaw.lua create mode 100644 gamedata/modularcomms/modules/chickenflamethrower.lua create mode 100644 gamedata/modularcomms/modules/chickengoo.lua create mode 100644 gamedata/modularcomms/modules/chickenshield.lua create mode 100644 gamedata/modularcomms/modules/chickenspike.lua create mode 100644 gamedata/modularcomms/modules/chickenspores.lua create mode 100644 gamedata/modularcomms/modules/commweapon_beamlaser.lua create mode 100644 gamedata/modularcomms/modules/commweapon_flamethrower.lua create mode 100644 gamedata/modularcomms/modules/commweapon_heatray.lua create mode 100644 gamedata/modularcomms/modules/commweapon_heavymachinegun.lua create mode 100644 gamedata/modularcomms/modules/commweapon_lightninggun.lua create mode 100644 gamedata/modularcomms/modules/commweapon_lparticlebeam.lua create mode 100644 gamedata/modularcomms/modules/commweapon_missilelauncher.lua create mode 100644 gamedata/modularcomms/modules/commweapon_riotcannon.lua create mode 100644 gamedata/modularcomms/modules/commweapon_rocketlauncher.lua create mode 100644 gamedata/modularcomms/modules/commweapon_shotgun.lua create mode 100644 gamedata/modularcomms/modules/template.txt create mode 100644 gamedata/modularcomms/modules_all_defs.lua create mode 100644 gamedata/modularcomms/weapons/chickenclaw.lua create mode 100644 gamedata/modularcomms/weapons/chickenflamethrower.lua create mode 100644 gamedata/modularcomms/weapons/chickengoo.lua create mode 100644 gamedata/modularcomms/weapons/chickenshield.lua create mode 100644 gamedata/modularcomms/weapons/chickenspike.lua create mode 100644 gamedata/modularcomms/weapons/chickenspores.lua diff --git a/LuaRules/Configs/dynamic_comm_defs.lua b/LuaRules/Configs/dynamic_comm_defs.lua index 900c9091d0..b8f2d36114 100644 --- a/LuaRules/Configs/dynamic_comm_defs.lua +++ b/LuaRules/Configs/dynamic_comm_defs.lua @@ -1,6 +1,8 @@ -- mission editor compatibility Spring.GetModOptions = Spring.GetModOptions or function() return {} end - +local ModularCommDefsShared_={} +ModularCommDefsShared=ModularCommDefsShared_ +ModularCommDefsShared=nil local skinDefs local SKIN_FILE = "LuaRules/Configs/dynamic_comm_skins.lua" if VFS.FileExists(SKIN_FILE) then @@ -8,8 +10,8 @@ if VFS.FileExists(SKIN_FILE) then else skinDefs = {} end - -local LEVEL_BOUND = math.floor(tonumber(Spring.GetModOptions().max_com_level or 0)) +---@type integer? +local LEVEL_BOUND = math.floor(tonumber(Spring.GetModOptions().max_com_level or 0)--[[@as integer]]) if LEVEL_BOUND <= 0 then LEVEL_BOUND = nil -- unlimited else @@ -24,19 +26,23 @@ if (Spring.GetModOptions) then local modOptions = Spring.GetModOptions() if modOptions then if modOptions.hpmult and modOptions.hpmult ~= 1 then - HP_MULT = modOptions.hpmult + HP_MULT = tonumber(modOptions.hpmult)--[[@as number]] end end end +ModularCommDefsShared_.HP_MULT=HP_MULT +ModularCommDefsShared_.COST_MULT=COST_MULT local moduleImagePath = "unitpics/" +ModularCommDefsShared_.moduleImagePath=moduleImagePath local disableResurrect = (Spring.GetModOptions().disableresurrect == 1) or (Spring.GetModOptions().disableresurrect == "1") - +ModularCommDefsShared_.disableResurrect=disableResurrect ------------------------------------------------------------------------ -- Module Definitions ------------------------------------------------------------------------ -- For autogenerating expensive advanced versions +--[=[ local basicWeapons = { ["commweapon_beamlaser"] = true, ["commweapon_flamethrower"] = true, @@ -49,921 +55,94 @@ local basicWeapons = { ["commweapon_rocketlauncher"] = true, ["commweapon_shotgun"] = true, } +ModularCommDefsShared_.basicWeapons=basicWeapons +]=] +local forAllChassisModules={ + "nullmodule","nullbasicweapon","nulladvweapon","nulldualbasicweapon" +} local moduleDefNames = {} -local moduleDefNamesAllList = {} -local chassisList = {"recon", "strike", "assault", "support", "knight"} +ModularCommDefsShared_.moduleDefNames=moduleDefNames +local moduleDefNamesToIDs = {} +ModularCommDefsShared_.moduleDefNamesToIDs=moduleDefNamesToIDs -local moduleDefs = { - -- Empty Module Slots - { - name = "nullmodule", - humanName = "No Module", - description = "No Module", - image = "LuaUI/Images/dynamic_comm_menu/cross.png", - limit = false, - emptyModule = true, - cost = 0, - requireLevel = 0, - slotType = "module", - }, - { - name = "nullbasicweapon", - humanName = "No Weapon", - description = "No Weapon", - image = "LuaUI/Images/dynamic_comm_menu/cross.png", - limit = false, - emptyModule = true, - requireChassis = {"knight"}, - cost = 0, - requireLevel = 0, - slotType = "basic_weapon", - }, - { - name = "nulladvweapon", - humanName = "No Weapon", - description = "No Weapon", - image = "LuaUI/Images/dynamic_comm_menu/cross.png", - limit = false, - emptyModule = true, - cost = 0 * COST_MULT, - requireLevel = 0, - slotType = "adv_weapon", - }, - { - name = "nulldualbasicweapon", - humanName = "No Weapon", - description = "No Weapon", - image = "LuaUI/Images/dynamic_comm_menu/cross.png", - limit = false, - emptyModule = true, - cost = 0 * COST_MULT, - requireLevel = 0, - slotType = "dual_basic_weapon", - }, - - -- Weapons - { - name = "commweapon_beamlaser", - humanName = "Beam Laser", - description = "Beam Laser: An effective short-range cutting tool", - image = moduleImagePath .. "commweapon_beamlaser.png", - limit = 2, - cost = 0, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - if not sharedData.weapon1 then - sharedData.weapon1 = "commweapon_beamlaser" - else - sharedData.weapon2 = "commweapon_beamlaser" - end - end - }, - { - name = "commweapon_flamethrower", - humanName = "Flamethrower", - description = "Flamethrower: Good for deep-frying swarmers and large targets alike", - image = moduleImagePath .. "commweapon_flamethrower.png", - limit = 2, - cost = 0, - requireChassis = {"recon", "assault", "knight"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - if not sharedData.weapon1 then - sharedData.weapon1 = "commweapon_flamethrower" - else - sharedData.weapon2 = "commweapon_flamethrower" - end - end - }, - { - name = "commweapon_heatray", - humanName = "Heatray", - description = "Heatray: Rapidly melts anything at short range; steadily loses all of its damage over distance", - image = moduleImagePath .. "commweapon_heatray.png", - limit = 2, - cost = 0, - requireChassis = {"assault", "knight"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - if not sharedData.weapon1 then - sharedData.weapon1 = "commweapon_heatray" - else - sharedData.weapon2 = "commweapon_heatray" - end - end - }, - { - name = "commweapon_heavymachinegun", - humanName = "Machine Gun", - description = "Machine Gun: Close-in automatic weapon with AoE", - image = moduleImagePath .. "commweapon_heavymachinegun.png", - limit = 2, - cost = 0, - requireChassis = {"recon", "assault", "strike", "knight"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - local weaponName = (modules[moduleDefNamesAllList.conversion_disruptor[1]] and "commweapon_heavymachinegun_disrupt") or "commweapon_heavymachinegun" - if not sharedData.weapon1 then - sharedData.weapon1 = weaponName - else - sharedData.weapon2 = weaponName - end - end - }, - --{ - -- name = "commweapon_hpartillery", - -- humanName = "Plasma Artillery", - -- description = "Plasma Artillery", - -- image = moduleImagePath .. "commweapon_assaultcannon.png", - -- limit = 2, - -- cost = 300 * COST_MULT, - -- requireChassis = {"assault"}, - -- requireLevel = 3, - -- slotType = "adv_weapon", - -- applicationFunction = function (modules, sharedData) - -- if sharedData.noMoreWeapons then - -- return - -- end - -- local weaponName = (modules[moduleDefNames.weaponmod_napalm_warhead] and "commweapon_hpartillery_napalm") or "commweapon_hpartillery" - -- if not sharedData.weapon1 then - -- sharedData.weapon1 = weaponName - -- else - -- sharedData.weapon2 = weaponName - -- end - -- end - --}, - { - name = "commweapon_lightninggun", - humanName = "Lightning Rifle", - description = "Lightning Rifle: Paralyzes and damages annoying bugs", - image = moduleImagePath .. "commweapon_lightninggun.png", - limit = 2, - cost = 0, - requireChassis = {"recon", "support", "strike", "knight"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - local weaponName = (modules[moduleDefNamesAllList.weaponmod_stun_booster[1]] and "commweapon_lightninggun_improved") or "commweapon_lightninggun" - if not sharedData.weapon1 then - sharedData.weapon1 = weaponName - else - sharedData.weapon2 = weaponName - end - end - }, - { - name = "commweapon_lparticlebeam", - humanName = "Light Particle Beam", - description = "Light Particle Beam: Fast, light pulsed energy weapon", - image = moduleImagePath .. "commweapon_lparticlebeam.png", - limit = 2, - cost = 0, - requireChassis = {"support", "recon", "strike", "knight"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - local weaponName = (modules[moduleDefNamesAllList.conversion_disruptor[1]] and "commweapon_disruptor") or "commweapon_lparticlebeam" - if not sharedData.weapon1 then - sharedData.weapon1 = weaponName - else - sharedData.weapon2 = weaponName - end - end - }, - { - name = "commweapon_missilelauncher", - humanName = "Missile Launcher", - description = "Missile Launcher: Lightweight seeker missile with good range", - image = moduleImagePath .. "commweapon_missilelauncher.png", - limit = 2, - cost = 0, - requireChassis = {"support", "strike", "knight"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - if not sharedData.weapon1 then - sharedData.weapon1 = "commweapon_missilelauncher" - else - sharedData.weapon2 = "commweapon_missilelauncher" - end - end - }, - { - name = "commweapon_riotcannon", - humanName = "Riot Cannon", - description = "Riot Cannon: The weapon of choice for crowd control", - image = moduleImagePath .. "commweapon_riotcannon.png", - limit = 2, - cost = 0, - requireChassis = {"assault", "knight"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - local weaponName = (modules[moduleDefNamesAllList.weaponmod_napalm_warhead[1]] and "commweapon_riotcannon_napalm") or "commweapon_riotcannon" - if not sharedData.weapon1 then - sharedData.weapon1 = weaponName - else - sharedData.weapon2 = weaponName - end - end - }, - { - name = "commweapon_rocketlauncher", - humanName = "Rocket Launcher", - description = "Rocket Launcher: Medium-range, low-velocity hitter", - image = moduleImagePath .. "commweapon_rocketlauncher.png", - limit = 2, - cost = 0, - requireChassis = {"assault", "knight"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - local weaponName = (modules[moduleDefNamesAllList.weaponmod_napalm_warhead[1]] and "commweapon_rocketlauncher_napalm") or "commweapon_rocketlauncher" - if not sharedData.weapon1 then - sharedData.weapon1 = weaponName - else - sharedData.weapon2 = weaponName - end - end - }, - { - name = "commweapon_shotgun", - humanName = "Shotgun", - description = "Shotgun: Can hammer a single large target or shred several small ones", - image = moduleImagePath .. "commweapon_shotgun.png", - limit = 2, - cost = 0, - requireChassis = {"recon", "support", "strike", "knight"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - local weaponName = (modules[moduleDefNamesAllList.conversion_disruptor[1]] and "commweapon_shotgun_disrupt") or "commweapon_shotgun" - if not sharedData.weapon1 then - sharedData.weapon1 = weaponName - else - sharedData.weapon2 = weaponName - end - end - }, - { - name = "commweapon_hparticlebeam", - humanName = "Heavy Particle Beam", - description = "Heavy Particle Beam - Replaces other weapons. Short range, high-power beam weapon with moderate reload time", - image = moduleImagePath .. "conversion_hparticlebeam.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = {"support", "knight"}, - requireLevel = 1, - slotType = "adv_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - local weaponName = (modules[moduleDefNamesAllList.conversion_disruptor[1]] and "commweapon_heavy_disruptor") or "commweapon_hparticlebeam" - sharedData.weapon1 = weaponName - sharedData.weapon2 = nil - sharedData.noMoreWeapons = true - end - }, - { - name = "commweapon_shockrifle", - humanName = "Shock Rifle", - description = "Shock Rifle - Replaces other weapons. Long range sniper rifle", - image = moduleImagePath .. "conversion_shockrifle.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = {"support", "knight"}, - requireLevel = 1, - slotType = "adv_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - sharedData.weapon1 = "commweapon_shockrifle" - sharedData.weapon2 = nil - sharedData.noMoreWeapons = true - end - }, - { - name = "commweapon_clusterbomb", - humanName = "Cluster Bomb", - description = "Cluster Bomb - Manually fired burst of bombs.", - image = moduleImagePath .. "commweapon_clusterbomb.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = {"recon", "assault", "knight"}, - requireLevel = 3, - slotType = "adv_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - if not sharedData.weapon1 then - sharedData.weapon1 = "commweapon_clusterbomb" - else - sharedData.weapon2 = "commweapon_clusterbomb" - end - end - }, - { - name = "commweapon_concussion", - humanName = "Concussion Shell", - description = "Concussion Shell - Manually fired high impulse projectile.", - image = moduleImagePath .. "commweapon_concussion.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = {"recon", "knight"}, - requireLevel = 3, - slotType = "adv_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - if not sharedData.weapon1 then - sharedData.weapon1 = "commweapon_concussion" - else - sharedData.weapon2 = "commweapon_concussion" - end - end - }, - { - name = "commweapon_disintegrator", - humanName = "Disintegrator", - description = "Disintegrator - Manually fired weapon that destroys almost everything it touches.", - image = moduleImagePath .. "commweapon_disintegrator.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = {"assault", "strike", "knight"}, - requireLevel = 3, - slotType = "adv_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - if not sharedData.weapon1 then - sharedData.weapon1 = "commweapon_disintegrator" - else - sharedData.weapon2 = "commweapon_disintegrator" - end - end - }, - { - name = "commweapon_disruptorbomb", - humanName = "Disruptor Bomb", - description = "Disruptor Bomb - Manually fired bomb that slows enemies in a large area.", - image = moduleImagePath .. "commweapon_disruptorbomb.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = {"recon", "support", "strike", "knight"}, - requireLevel = 3, - slotType = "adv_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - if not sharedData.weapon1 then - sharedData.weapon1 = "commweapon_disruptorbomb" - else - sharedData.weapon2 = "commweapon_disruptorbomb" - end - end - }, - { - name = "commweapon_multistunner", - humanName = "Multistunner", - description = "Multistunner - Manually fired sustained burst of lightning.", - image = moduleImagePath .. "commweapon_multistunner.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = {"support", "recon", "strike", "knight"}, - requireLevel = 3, - slotType = "adv_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - local weaponName = (modules[moduleDefNamesAllList.weaponmod_stun_booster[1]] and "commweapon_multistunner_improved") or "commweapon_multistunner" - if not sharedData.weapon1 then - sharedData.weapon1 = weaponName - else - sharedData.weapon2 = weaponName - end - end - }, - { - name = "commweapon_napalmgrenade", - humanName = "Hellfire Grenade", - description = "Hellfire Grenade - Manually fired bomb that inflames a large area.", - image = moduleImagePath .. "commweapon_napalmgrenade.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = {"assault", "recon", "knight"}, - requireLevel = 3, - slotType = "adv_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - if not sharedData.weapon1 then - sharedData.weapon1 = "commweapon_napalmgrenade" - else - sharedData.weapon2 = "commweapon_napalmgrenade" - end - end - }, - { - name = "commweapon_slamrocket", - humanName = "S.L.A.M. Rocket", - description = "S.L.A.M. Rocket - Manually fired miniature tactical nuke.", - image = moduleImagePath .. "commweapon_slamrocket.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = {"assault", "knight"}, - requireLevel = 3, - slotType = "adv_weapon", - applicationFunction = function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - if not sharedData.weapon1 then - sharedData.weapon1 = "commweapon_slamrocket" - else - sharedData.weapon2 = "commweapon_slamrocket" - end - end - }, - - -- Unique Modules - { - name = "econ", - humanName = "Vanguard Economy Pack", - description = "Vanguard Economy Pack - A vital part of establishing a beachhead, this module is equipped by all new commanders to kickstart their economy. Provides 4 metal income and 6 energy income.", - image = moduleImagePath .. "module_energy_cell.png", - limit = 1, - unequipable = true, - cost = 100 * COST_MULT, - requireLevel = 0, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.metalIncome = (sharedData.metalIncome or 0) + 4 - sharedData.energyIncome = (sharedData.energyIncome or 0) + 6 - end - }, - { - name = "commweapon_personal_shield", - humanName = "Personal Shield", - description = "Personal Shield - A small, protective bubble shield.", - image = moduleImagePath .. "module_personal_shield.png", - limit = 1, - cost = 300 * COST_MULT, - prohibitingModules = {"module_personal_cloak"}, - requireLevel = 2, - slotType = "module", - applicationFunction = function (modules, sharedData) - -- Do not override area shield - sharedData.shield = sharedData.shield or "commweapon_personal_shield" - end - }, - { - name = "commweapon_areashield", - humanName = "Area Shield", - description = "Area Shield - Projects a large shield. Replaces Personal Shield.", - image = moduleImagePath .. "module_areashield.png", - limit = 1, - cost = 250 * COST_MULT, - requireChassis = {"assault", "support", "knight"}, - requireOneOf = {"commweapon_personal_shield"}, - prohibitingModules = {"module_personal_cloak"}, - requireLevel = 3, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.shield = "commweapon_areashield" - end - }, - { - name = "weaponmod_napalm_warhead", - humanName = "Napalm Warhead", - description = "Napalm Warhead - Riot Cannon and Rocket Launcher set targets on fire. Reduced direct damage.", - image = moduleImagePath .. "weaponmod_napalm_warhead.png", - limit = 1, - cost = 350 * COST_MULT, - requireChassis = {"assault", "knight"}, - requireOneOf = { - "commweapon_rocketlauncher", "commweapon_rocketlauncher_adv", - "commweapon_riotcannon", "commweapon_riotcannon_adv", - "commweapon_hpartillery"}, - requireLevel = 2, - slotType = "module", - }, - { - name = "conversion_disruptor", - humanName = "Disruptor Ammo", - description = "Disruptor Ammo - Heavy Machine Gun, Shotgun and Particle Beams deal slow damage. Reduced direct damage.", - image = moduleImagePath .. "weaponmod_disruptor_ammo.png", - limit = 1, - cost = 300 * COST_MULT, - requireChassis = {"strike", "recon", "support", "knight"}, - requireOneOf = { - "commweapon_heavymachinegun", "commweapon_heavymachinegun_adv", - "commweapon_shotgun", "commweapon_shotgun_adv", - "commweapon_lparticlebeam", "commweapon_lparticlebeam_adv", - "commweapon_hparticlebeam" - }, - requireLevel = 2, - slotType = "module", - }, - { - name = "weaponmod_stun_booster", - humanName = "Flux Amplifier", - description = "Flux Amplifier - Improves EMP duration and strength of Lightning Rifle and Multistunner.", - image = moduleImagePath .. "weaponmod_stun_booster.png", - limit = 1, - cost = 300 * COST_MULT, - requireChassis = {"support", "strike", "recon", "knight"}, - requireOneOf = { - "commweapon_lightninggun", "commweapon_lightninggun_adv", - "commweapon_multistunner" - }, - requireLevel = 2, - slotType = "module", - }, - { - name = "module_jammer", - humanName = "Radar Jammer", - description = "Radar Jammer - Hide the radar signals of nearby units.", - image = moduleImagePath .. "module_jammer.png", - limit = 1, - cost = 200 * COST_MULT, - requireLevel = 2, - slotType = "module", - applicationFunction = function (modules, sharedData) - if not sharedData.cloakFieldRange then - sharedData.radarJammingRange = 500 - end - end - }, - { - name = "module_radarnet", - humanName = "Field Radar", - description = "Field Radar - Attaches a basic radar system.", - image = moduleImagePath .. "module_fieldradar.png", - limit = 1, - cost = 75 * COST_MULT, - requireLevel = 1, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.radarRange = 1800 - end - }, - { - name = "module_personal_cloak", - humanName = "Personal Cloak", - description = "Personal Cloak - A personal cloaking device. Reduces total speed by 12%.", - image = moduleImagePath .. "module_personal_cloak.png", - limit = 1, - cost = 400 * COST_MULT, - prohibitingModules = {"commweapon_personal_shield", "commweapon_areashield"}, - requireLevel = 2, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.decloakDistance = math.max(sharedData.decloakDistance or 0, 150) - sharedData.personalCloak = true - sharedData.speedMultPost = (sharedData.speedMultPost or 1) - 0.12 - end - }, - { - name = "module_cloak_field", - humanName = "Cloaking Field", - description = "Cloaking Field - Cloaks all nearby units.", - image = moduleImagePath .. "module_cloak_field.png", - limit = 1, - cost = 600 * COST_MULT, - requireChassis = {"support", "strike", "knight"}, - requireOneOf = {"module_jammer"}, - requireLevel = 3, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.areaCloak = true - sharedData.decloakDistance = 180 - sharedData.cloakFieldRange = 320 - sharedData.cloakFieldUpkeep = 15 - sharedData.cloakFieldRecloakRate = 800 -- UI only, update in unit_commander_upgrade - sharedData.radarJammingRange = 320 - end - }, - { - name = "module_resurrect", - humanName = "Lazarus Device", - description = "Lazarus Device - Upgrade nanolathe to allow resurrection.", - image = moduleImagePath .. "module_resurrect.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = disableResurrect and {} or {"support", "knight"}, - requireLevel = 2, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.canResurrect = true - end - }, - { - name = "module_jumpjet", - humanName = "Jumpjets", - description = "Jumpjets - Leap over obstacles and out of danger. Each High Powered Servos reduces jump reload by 1s.", - image = moduleImagePath .. "module_jumpjet.png", - limit = 1, - cost = 400 * COST_MULT, - requireChassis = {"knight"}, - requireLevel = 3, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.canJump = true - end - }, - - -- Repeat Modules - { - name = "module_companion_drone", - humanName = "Companion Drone", - description = "Companion Drone - Commander spawns protective drones. Limit: 5", - image = moduleImagePath .. "module_companion_drone.png", - limit = 5, - cost = 200 * COST_MULT, - requireLevel = 2, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.drones = (sharedData.drones or 0) + 1 - end - }, - { - name = "module_battle_drone", - humanName = "Battle Drone", - description = "Battle Drone - Commander spawns heavy drones. Limit: 5, Requires Companion Drone", - image = moduleImagePath .. "module_battle_drone.png", - limit = 5, - cost = 350 * COST_MULT, - requireChassis = {"assault", "support", "knight"}, - requireOneOf = {"module_companion_drone"}, - requireLevel = 3, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.droneheavyslows = (sharedData.droneheavyslows or 0) + 1 - end - }, - { - name = "module_autorepair", - humanName = "Autorepair", - description = "Autorepair - Commander self-repairs at +" .. 12*HP_MULT .. " hp/s. Reduces Health by " .. 100*HP_MULT .. ". Limit: 5", - image = moduleImagePath .. "module_autorepair.png", - limit = 5, - cost = 150 * COST_MULT, - requireLevel = 1, - requireChassis = {"strike", "knight"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12*HP_MULT - sharedData.healthBonus = (sharedData.healthBonus or 0) - 100*HP_MULT - end - }, - { - name = "module_autorepair", - humanName = "Autorepair", - description = "Autorepair - Commander self-repairs at +" .. 10*HP_MULT .. " hp/s. Reduces Health by " .. 100*HP_MULT .. ". Limit: 5", - image = moduleImagePath .. "module_autorepair.png", - limit = 5, - cost = 150 * COST_MULT, - requireLevel = 1, - requireChassis = {"assault", "recon", "support"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 10*HP_MULT - sharedData.healthBonus = (sharedData.healthBonus or 0) - 100*HP_MULT - end - }, - { - name = "module_ablative_armor", - humanName = "Ablative Armour Plates", - description = "Ablative Armour Plates - Provides " .. 750*HP_MULT .. " health. Limit: 5", - image = moduleImagePath .. "module_ablative_armor.png", - limit = 5, - cost = 150 * COST_MULT, - requireLevel = 1, - requireChassis = {"assault", "knight"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.healthBonus = (sharedData.healthBonus or 0) + 750*HP_MULT - end - }, - { - name = "module_heavy_armor", - humanName = "High Density Plating", - description = "High Density Plating - Provides " .. 2000*HP_MULT .. " health but reduces total speed by 2%. " .. - "Limit: 5, Requires Ablative Armour Plates", - image = moduleImagePath .. "module_heavy_armor.png", - limit = 5, - cost = 400 * COST_MULT, - requireOneOf = {"module_ablative_armor"}, - requireLevel = 2, - requireChassis = {"assault", "knight"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.healthBonus = (sharedData.healthBonus or 0) + 2000*HP_MULT - sharedData.speedMultPost = (sharedData.speedMultPost or 1) - 0.02 - end - }, - { - name = "module_ablative_armor", - humanName = "Ablative Armour Plates", - description = "Ablative Armour Plates - Provides " .. 600*HP_MULT .. " health. Limit: 5", - image = moduleImagePath .. "module_ablative_armor.png", - limit = 5, - cost = 150 * COST_MULT, - requireLevel = 1, - requireChassis = {"strike", "recon", "support"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.healthBonus = (sharedData.healthBonus or 0) + 600*HP_MULT - end - }, - { - name = "module_heavy_armor", - humanName = "High Density Plating", - description = "High Density Plating - Provides " .. 1600*HP_MULT .. " health but reduces total speed by 2%. " .. - "Limit: 5, Requires Ablative Armour Plates", - image = moduleImagePath .. "module_heavy_armor.png", - limit = 5, - cost = 400 * COST_MULT, - requireOneOf = {"module_ablative_armor"}, - requireLevel = 2, - requireChassis = {"strike", "recon", "support"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.healthBonus = (sharedData.healthBonus or 0) + 1600*HP_MULT - sharedData.speedMultPost = (sharedData.speedMultPost or 1) - 0.02 - end - }, - { - name = "module_dmg_booster", - humanName = "Damage Booster", - description = "Damage Booster - Increases damage by 15% but reduces total speed by 2%. Limit: 5", - image = moduleImagePath .. "module_dmg_booster.png", - limit = 5, - cost = 150 * COST_MULT, - requireLevel = 1, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.damageMult = (sharedData.damageMult or 1) + 0.15 - sharedData.speedMultPost = (sharedData.speedMultPost or 1) - 0.02 - end - }, - { - name = "module_high_power_servos", - humanName = "High Power Servos", - description = "High Power Servos - Increases speed by 4 and reduced jump cooldown by 1s. Limit: 5", - image = moduleImagePath .. "module_high_power_servos.png", - limit = 5, - cost = 200 * COST_MULT, - requireLevel = 1, - requireChassis = {"recon", "knight"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.speedMod = (sharedData.speedMod or 0) + 4 - sharedData.jumpReloadMod = (sharedData.jumpReloadMod or 0) - 1 - end - }, - { - name = "module_high_power_servos", - humanName = "High Power Servos", - description = "High Power Servos - Increases speed by 3.5. Limit: 5", - image = moduleImagePath .. "module_high_power_servos.png", - limit = 5, - cost = 200 * COST_MULT, - requireLevel = 1, - requireChassis = {"strike", "assault", "support"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.speedMod = (sharedData.speedMod or 0) + 3.5 - end - }, - { - name = "module_adv_targeting", - humanName = "Adv. Targeting System", - description = "Advanced Targeting System - Increases range by 7.5% but reduces total speed by 3%. Limit: 5", - image = moduleImagePath .. "module_adv_targeting.png", - limit = 5, - cost = 200 * COST_MULT, - requireLevel = 1, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.rangeMult = (sharedData.rangeMult or 1) + 0.075 - sharedData.speedMultPost = (sharedData.speedMultPost or 1) - 0.03 - end - }, - { - name = "module_adv_nano", - humanName = "CarRepairer's Nanolathe", - description = "CarRepairer's Nanolathe - Increases build power by 6. Limit: 5", - image = moduleImagePath .. "module_adv_nano.png", - limit = 5, - cost = 200 * COST_MULT, - requireLevel = 1, - requireChassis = {"support"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 6 + +ModularCommDefsShared_.applicationFunctionApplyWeapon=function (GetWeaponName) + return function (modules, sharedData) + if sharedData.noMoreWeapons then + return end - }, - { - name = "module_adv_nano", - humanName = "CarRepairer's Nanolathe", - description = "CarRepairer's Nanolathe - Increases build power by 5. Limit: 5", - image = moduleImagePath .. "module_adv_nano.png", - limit = 5, - cost = 200 * COST_MULT, - requireLevel = 1, - requireChassis = {"strike", "assault", "knight"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 5 + if not sharedData.weapon1 then + sharedData.weapon1 = GetWeaponName(modules,sharedData) + else + sharedData.weapon2 = GetWeaponName(modules,sharedData) end - }, - { - name = "module_adv_nano", - humanName = "CarRepairer's Nanolathe", - description = "CarRepairer's Nanolathe - Increases build power by 4. Limit: 5", - image = moduleImagePath .. "module_adv_nano.png", - limit = 5, - cost = 200 * COST_MULT, - requireLevel = 1, - requireChassis = {"recon"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 4 + end +end + +ModularCommDefsShared_.applicationFunctionApplyNoMoreWeapon=function (GetWeaponName) + return function (modules, sharedData) + if sharedData.noMoreWeapons then + return end - }, + local weaponName = GetWeaponName(modules,sharedData) + sharedData.weapon1 = weaponName + sharedData.weapon2 = nil + sharedData.noMoreWeapons = true + end +end +ModularCommDefsShared_.UnitDefNames=UnitDefNames +ModularCommDefsShared_.GenAdvWeaponModule=function (def) - -- Decorative Modules - { - name = "banner_overhead", - humanName = "Banner", - description = "Banner", - image = moduleImagePath .. "module_ablative_armor.png", - limit = 1, - cost = 0, - requireLevel = 0, - slotType = "decoration", - applicationFunction = function (modules, sharedData) - sharedData.bannerOverhead = true + local newDef = Spring.Utilities.CopyTable(def, true) + newDef.name = newDef.name .. "_adv" + newDef.slotType = "dual_basic_weapon" + newDef.cost = 350 * COST_MULT + return newDef +end +local moduleDefs = {} +local SharedEnv={ModularCommDefsShared=ModularCommDefsShared_,UnitDefNames=UnitDefNames} + +setmetatable(SharedEnv,{__index=getfenv()}) + +local modulesalldefs=VFS.Include("gamedata/modularcomms/modules_all_defs.lua") +--local moduleFiles=VFS.DirList("gamedata/modularcomms/modules", "*.lua") or {} + +for i = 1, #modulesalldefs do + local new_moduleDefs = modulesalldefs[i].dynamic_comm_def(ModularCommDefsShared_) + for key, moduleDef in pairs(new_moduleDefs) do + moduleDefs[#moduleDefs+1]=moduleDef + local def=moduleDef + if def.isBasicWeapon then + local newDef = Spring.Utilities.CopyTable(def, true) + newDef.name = newDef.name .. "_adv" + newDef.slotType = "dual_basic_weapon" + newDef.cost = 350 * COST_MULT + moduleDefs[#moduleDefs + 1] = newDef end - } -} + end +end --- Add second versions of basic weapons -for i = 1, #moduleDefs do - local def = moduleDefs[i] - if basicWeapons[def.name] then - local newDef = Spring.Utilities.CopyTable(def, true) - newDef.name = newDef.name .. "_adv" - newDef.slotType = "dual_basic_weapon" - newDef.cost = 350 * COST_MULT - moduleDefs[#moduleDefs + 1] = newDef +do + local i=1 + while(i<=#moduleDefs)do + local md=moduleDefs[i] + if(md.hardcodedID and i~=md.hardcodedID) then + local b=md.hardcodedID + local mdb=moduleDefs[b] + if mdb.hardcodedID and mdb.hardcodedID==b then + error("Both " .. md.name .. " and " .. mdb.name .. " has same hardcodedID " .. b) + end + moduleDefs[i],moduleDefs[b]=moduleDefs[b],md + else + i=i+1 + end end end +-- Add second versions of basic weapons + + --[[ Stochastic check for module IDs, not perfect but should do its job. See the error message below. ]] @@ -997,20 +176,88 @@ for name, data in pairs(skinDefs) do end for i = 1, #moduleDefs do - local data = moduleDefNamesAllList[moduleDefs[i].name] or {} + local data = moduleDefNamesToIDs[moduleDefs[i].name] or {} data[#data + 1] = i - moduleDefNamesAllList[moduleDefs[i].name] = data + moduleDefNamesToIDs[moduleDefs[i].name] = data +end + +local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") + +local chassisList={} +for _,v in pairs(chassisAllDefs) do + local k=v.dynamic_comm_defs_name + moduleDefNames[k] = {} + chassisList[#chassisList+1]=k end -for i = 1, #chassisList do - moduleDefNames[chassisList[i]] = {} + + +for _, moudleName in pairs(forAllChassisModules) do + moduleDefs[moduleDefNamesToIDs[moudleName][1]].requireChassis=chassisList +end + +local function FindModule(moduleName,requireChassis) + local ids=moduleDefNamesToIDs[moduleName] + if not ids then + Spring.Echo("Warning: module " ..moduleName .. " not found") + return nil + end + for _, moduleID in pairs(ids) do + local moduleDef=moduleDefs[moduleID] + if not requireChassis then + return moduleDef + else + local foundAll=true + for _, requireChassisNeeded in pairs(requireChassis) do + local found=false + for _, requireChassisHas in pairs(moduleDef.requireChassis) do + if requireChassisHas==requireChassisNeeded then + found=true + break + end + end + if not found then + foundAll=false + break + end + end + if foundAll then + return moduleDef + end + end + end + return nil +end + +ModularCommDefsShared_.FindModule=FindModule + +for _,v in pairs(chassisAllDefs) do + local moduleIdentities=v.dynamic_comm_defs_modules + if moduleIdentities then + for _, moduleIdentity in pairs(moduleIdentities) do + local moduleDef=FindModule(moduleIdentity.name,moduleIdentity.requireChassis) + if moduleDef then + moduleDef.requireChassis[#moduleDef.requireChassis+1] = v.dynamic_comm_defs_name + else + Spring.Echo("Warning: module " ..moduleIdentity.name .. " not found") + end + end + end end for i = 1, #moduleDefs do local data = moduleDefs[i] local allowedChassis = moduleDefs[i].requireChassis or chassisList for j = 1, #allowedChassis do - moduleDefNames[allowedChassis[j]][data.name] = i + local chassisName=allowedChassis[j] + local mdn_=moduleDefNames[chassisName] + if not mdn_ then + Spring.Echo("Error: dynamic_comm_defs.lua: missing chassis " .. tostring(chassisName) .. " for module " .. tostring(data.name)) + + else + mdn_[data.name] = i + end + end end @@ -1030,32 +277,9 @@ end -- if a commander has a an area shield and a personal shield it should return the -- clone which was given those modules. -local function GetReconCloneModulesString(modulesByDefID) - return (modulesByDefID[moduleDefNames.recon.commweapon_personal_shield] or 0) -end -local function GetSupportCloneModulesString(modulesByDefID) - return (modulesByDefID[moduleDefNames.support.commweapon_personal_shield] or 0) .. - (modulesByDefID[moduleDefNames.support.commweapon_areashield] or 0) .. - (modulesByDefID[moduleDefNames.support.module_resurrect] or 0) -end -local function GetAssaultCloneModulesString(modulesByDefID) - return (modulesByDefID[moduleDefNames.assault.commweapon_personal_shield] or 0) .. - (modulesByDefID[moduleDefNames.assault.commweapon_areashield] or 0) -end -local function GetStrikeCloneModulesString(modulesByDefID) - return (modulesByDefID[moduleDefNames.strike.commweapon_personal_shield] or 0) .. - (modulesByDefID[moduleDefNames.strike.commweapon_areashield] or 0) -end - -local function GetKnightCloneModulesString(modulesByDefID) - return (modulesByDefID[moduleDefNames.knight.commweapon_personal_shield] or 0) .. - (modulesByDefID[moduleDefNames.knight.commweapon_areashield] or 0) .. - (modulesByDefID[moduleDefNames.knight.module_resurrect] or 0) .. - (modulesByDefID[moduleDefNames.knight.module_jumpjet] or 0) -end local morphCosts = { 50, @@ -1064,7 +288,7 @@ local morphCosts = { 200, 250, } - +ModularCommDefsShared_.morphCosts=morphCosts local morphBuildPower = { 5, 7.5, @@ -1072,691 +296,43 @@ local morphBuildPower = { 12.5, 15 } - +ModularCommDefsShared_.morphBuildPower=morphBuildPower local function extraLevelCostFunction(level) return level * 50 * COST_MULT end +ModularCommDefsShared_.extraLevelCostFunction=extraLevelCostFunction + +ModularCommDefsShared_.GetCloneModuleString=function (chassis,listOfCloneModules) + return function (modulesByDefID) + local res="" + for key, value in pairs(listOfCloneModules) do + res=res .. (modulesByDefID[moduleDefNames[chassis][value]] or 0) + end + return res + end +end + +do + + ModularCommDefsShared_.morphUnitDefFunction=function (name,GetCloneModuleString) + return function (lv) + return function (modulesByDefID) + + return UnitDefNames[name .. lv .. "_" .. GetCloneModuleString(modulesByDefID)].id + end + end + end +end local chassisDefs = { - { - name = "strike", - humanName = "Strike", - baseUnitDef = UnitDefNames and UnitDefNames["dynstrike0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - secondPeashooter = false, - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike0"].id - end, - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 8 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike1_" .. GetStrikeCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.strike.commweapon_beamlaser, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike2_" .. GetStrikeCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 16 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike3_" .. GetStrikeCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.strike.commweapon_beamlaser_adv, - slotAllows = {"dual_basic_weapon", "adv_weapon"}, - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 20 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike4_" .. GetStrikeCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 25 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike5_" .. GetStrikeCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - }, - }, - } - }, - { - name = "recon", - humanName = "Recon", - baseUnitDef = UnitDefNames and UnitDefNames["dynrecon0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon0"].id - end, - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon1_" .. GetReconCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.recon.commweapon_beamlaser, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon2_" .. GetReconCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon3_" .. GetReconCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.recon.commweapon_disruptorbomb, - slotAllows = "adv_weapon", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon4_" .. GetReconCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon5_" .. GetReconCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - }, - }, - } - }, - { - name = "support", - humanName = "Engineer", - baseUnitDef = UnitDefNames and UnitDefNames["dynsupport0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport0"].id - end, - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 2 - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport1_" .. GetSupportCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.support.commweapon_beamlaser, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 4 - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport2_" .. GetSupportCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 6 - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport3_" .. GetSupportCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.support.commweapon_disruptorbomb, - slotAllows = "adv_weapon", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4], - chassisApplicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 9 - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport4_" .. GetSupportCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5], - chassisApplicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 12 - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport5_" .. GetSupportCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - }, - }, - } - }, - { - name = "assault", - humanName = "Guardian", - baseUnitDef = UnitDefNames and UnitDefNames["dynassault0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - secondPeashooter = false, - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 1 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault0"].id - end, - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 1 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault1_" .. GetAssaultCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.commweapon_beamlaser, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 2 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault2_" .. GetAssaultCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 2 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault3_" .. GetAssaultCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.commweapon_beamlaser_adv, - slotAllows = {"dual_basic_weapon", "adv_weapon"}, - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 2 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault4_" .. GetAssaultCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 3 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault5_" .. GetAssaultCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - } - }, - { - name = "knight", - humanName = "Knight", - baseUnitDef = UnitDefNames and UnitDefNames["dynknight0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - notSelectable = (Spring.GetModOptions().campaign_chassis ~= "1"), - secondPeashooter = true, - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - -- Level 1 is the same as level 0 in stats and has support for clone modules (such as shield). - return UnitDefNames["dynknight1_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 8 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynknight1_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.knight.commweapon_beamlaser, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynknight2_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 16 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynknight3_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.knight.commweapon_beamlaser_adv, - slotAllows = {"dual_basic_weapon", "adv_weapon"}, - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 20 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynknight4_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 25 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynknight5_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - }, - }, - } - }, } +for i = 1, #chassisAllDefs do + local chassisDef = chassisAllDefs[i].dynamic_comm_defs(ModularCommDefsShared_) + chassisDefs[#chassisDefs+1]=chassisDef +end + local chassisDefByBaseDef = {} if UnitDefNames then for i = 1, #chassisDefs do @@ -1793,7 +369,7 @@ for i = 1, #moduleDefs do if data.requireOneOf then local newRequire = {} for j = 1, #data.requireOneOf do - local reqModuleIDs = moduleDefNamesAllList[data.requireOneOf[j]] + local reqModuleIDs = moduleDefNamesToIDs[data.requireOneOf[j]] if reqModuleIDs then for i = 1, #reqModuleIDs do newRequire[#newRequire + 1] = reqModuleIDs[i] @@ -1807,7 +383,7 @@ for i = 1, #moduleDefs do if data.prohibitingModules then local newProhibit = {} for j = 1, #data.prohibitingModules do - local reqModuleIDs = moduleDefNamesAllList[data.prohibitingModules[j]] + local reqModuleIDs = moduleDefNamesToIDs[data.prohibitingModules[j]] if reqModuleIDs then for i = 1, #reqModuleIDs do newProhibit[#newProhibit + 1] = reqModuleIDs[i] diff --git a/LuaRules/Gadgets/unit_commander_upgrade.lua b/LuaRules/Gadgets/unit_commander_upgrade.lua index bff337bbaa..d062d7759d 100644 --- a/LuaRules/Gadgets/unit_commander_upgrade.lua +++ b/LuaRules/Gadgets/unit_commander_upgrade.lua @@ -83,8 +83,8 @@ local function ApplyWeaponData(unitID, weapon1, weapon2, shield, rangeMult, dama end end - weapon1 = weapon1 or "commweapon_beamlaser" local chassis = Spring.GetUnitRulesParam(unitID, "comm_chassis") + weapon1 = weapon1 or (chassis and chassisDefs[chassis] and chassisDefs[chassis].initWeapon) or "commweapon_beamlaser" if chassis and chassisDefs[chassis] and chassisDefs[chassis].secondPeashooter and (not weapon2) and Spring.GetUnitRulesParam(unitID, "comm_level") > 2 then weapon2 = "commweapon_beamlaser" @@ -101,6 +101,7 @@ end local function ApplyModuleEffects(unitID, data, totalCost, images) local ud = UnitDefs[Spring.GetUnitDefID(unitID)] + local newAttributesEffect = {} newAttributesEffect.cost = totalCost / ud.metalCost @@ -152,8 +153,9 @@ local function ApplyModuleEffects(unitID, data, totalCost, images) data.energyIncome = (data.energyIncome or 0) if buildPowerMult ~= 1 then - -- Needs to use the new system so static can be set, to display properly on the UI. + newAttributesEffect.build = buildPowerMult + end if data.metalIncome and GG.Overdrive then @@ -162,11 +164,19 @@ local function ApplyModuleEffects(unitID, data, totalCost, images) GG.Overdrive.AddUnitResourceGeneration(unitID, data.metalIncome, data.energyIncome, true) end + ---@type false|number local newHealth = false + if data.healthBonus then local health, maxHealth = Spring.GetUnitHealth(unitID) + newHealth = math.max(health + data.healthBonus, 1) + + newAttributesEffect = newAttributesEffect or {} + newAttributesEffect.healthAdd = data.healthBonus + + end if data.skinOverride then @@ -197,15 +207,24 @@ local function ApplyModuleEffects(unitID, data, totalCost, images) end local _, maxHealth = Spring.GetUnitHealth(unitID) + + ApplyWeaponData(unitID, data.weapon1, data.weapon2, data.shield, data.rangeMult, data.damageMult) if newAttributesEffect then + newAttributesEffect.static = true + GG.Attributes.AddEffect(unitID, "comm_upgrade", newAttributesEffect) + if newHealth then + Spring.SetUnitHealth(unitID, newHealth) -- Override scaled health change from GG.Attributes + end + end + -- Do this all the time as it will be needed almost always. GG.UpdateUnitAttributes(unitID) end @@ -279,6 +298,7 @@ local function InitializeDynamicCommander(unitID, level, chassis, totalCost, nam Spring.SetUnitRulesParam(unitID, "comm_level", level, INLOS) Spring.SetUnitRulesParam(unitID, "comm_chassis", chassis, INLOS) Spring.SetUnitRulesParam(unitID, "comm_name", name, INLOS) + Spring.SetUnitRulesParam(unitID, "comm_baseUnitDefID", baseUnitDefID, INLOS) Spring.SetUnitRulesParam(unitID, "comm_baseWreckID", baseWreckID, INLOS) Spring.SetUnitRulesParam(unitID, "comm_baseHeapID", baseHeapID, INLOS) @@ -291,6 +311,7 @@ local function InitializeDynamicCommander(unitID, level, chassis, totalCost, nam Spring.SetUnitRulesParam(unitID, "comm_staticLevel", staticLevel, INLOS) end + -- Set module unitRulesParams -- Decorations are kept seperate from other module types. -- basic_weapon, adv_weapon and module all count as modules. @@ -418,11 +439,13 @@ local function Upgrades_CreateStarterDyncomm(dyncommID, x, y, z, facing, teamID, local commProfileInfo = GG.ModularCommAPI.GetCommProfileInfo(dyncommID) local chassisDefID = chassisDefNames[commProfileInfo.chassis] if not chassisDefID then - Spring.Echo("Incorrect dynamic comm chassis", commProfileInfo.chassis) + + Spring.Echo("Incorrect dynamic comm chassis", commProfileInfo.chassis, "dyncommID: " .. dyncommID) return false end local chassisData = chassisDefs[chassisDefID] + if chassisData.notSelectable and not staticLevel then Spring.Echo("Chassis not selectable", commProfileInfo.chassis) return false diff --git a/LuaRules/Gadgets/unit_shield_charge.lua b/LuaRules/Gadgets/unit_shield_charge.lua index 6da2fc9b7f..9a6e9751fe 100644 --- a/LuaRules/Gadgets/unit_shield_charge.lua +++ b/LuaRules/Gadgets/unit_shield_charge.lua @@ -2,277 +2,292 @@ -------------------------------------------------------------------------------- function gadget:GetInfo() - return { - name = "Shield Charge", - desc = "Reimplementation of charging for shields. Intended for attributes and priority support.", - author = "Google Frog", - date = "16 August 2015", - license = "GNU GPL, v2 or later", - layer = -1, - enabled = true -- loaded by default? - } -end - --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- - -if (not gadgetHandler:IsSyncedCode()) then - return false -- no unsynced code -end - -include("LuaRules/Configs/constants.lua") - --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- - -local PERIOD = 2 - -local spGetUnitShieldState = Spring.GetUnitShieldState -local spSetUnitShieldState = Spring.SetUnitShieldState - -local spGetUnitIsStunned = Spring.GetUnitIsStunned -local spUseUnitResource = Spring.UseUnitResource -local spGetUnitRulesParam = Spring.GetUnitRulesParam -local spSetUnitRulesParam = Spring.SetUnitRulesParam -local losTable = {inlos = true} - -local unitMap = {} -local unitList = {} -local unitCount = 0 - -local shieldUnitDefID = {} -local shieldCommWeaponDefID = {} - -local function LoadShieldWeaponDef(shieldWep) - local wcp = shieldWep.customParams - local def = { - maxCharge = shieldWep.shieldPower, - chargePerUpdate = PERIOD*tonumber(wcp.shield_rate)/TEAM_SLOWUPDATE_RATE, - startPower = wcp.shieldstartingpower and tonumber(wcp.shieldstartingpower), - slowImmune = wcp.slow_immune and true or false, - dieOnEmpty = wcp.die_on_empty and true or false, + return { + name = "Shield Charge", + desc = "Reimplementation of charging for shields. Intended for attributes and priority support.", + author = "Google Frog", + date = "16 August 2015", + license = "GNU GPL, v2 or later", + layer = -1, + enabled = true -- loaded by default? } - if wcp.shield_rate_charge then - def.chargeRateChange = PERIOD*PERIOD*tonumber(wcp.shield_rate_charge)/(TEAM_SLOWUPDATE_RATE * TEAM_SLOWUPDATE_RATE) - end - if wcp.shield_drain and tonumber(wcp.shield_drain) > 0 then - def.perUpdateCost = PERIOD*tonumber(wcp.shield_drain)/TEAM_SLOWUPDATE_RATE - def.perSecondCost = tonumber(wcp.shield_drain) - def.rechargeDelay = wcp.shield_recharge_delay and tonumber(wcp.shield_recharge_delay) - end - return def -end - -for unitDefID = 1, #UnitDefs do - local ud = UnitDefs[unitDefID] - if ud.shieldWeaponDef and not ud.customParams.dynamic_comm then - local shieldWep = WeaponDefs[ud.shieldWeaponDef] - if shieldWep.customParams then - shieldUnitDefID[unitDefID] = LoadShieldWeaponDef(shieldWep) - end - end -end - -local commShieldDefs = { - WeaponDefNames["commweapon_areashield"], - WeaponDefNames["commweapon_personal_shield"], -} - -for i = 1, #commShieldDefs do - local wd = commShieldDefs[i] - shieldCommWeaponDefID[wd.id] = LoadShieldWeaponDef(wd) -end - --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- --- Unit Updating - -local function IsShieldEnabled(unitID) - local enabled, charge = spGetUnitShieldState(unitID) - if not enabled then - return false - end - local stunned_or_inbuild, stunned, inbuild = spGetUnitIsStunned(unitID) - if stunned_or_inbuild then - return false - end - local att_enabled = (spGetUnitRulesParam(unitID, "att_shieldDisabled") ~= 1) - return att_enabled, charge -end - -local function GetChargeRate(unitID) - return (GG.att_ShieldRegenChange[unitID] or 1) -end - -function gadget:GameFrame(n) - if n%PERIOD ~= 0 then - return - end - - local updatePriority = (n % TEAM_SLOWUPDATE_RATE == 0) - local setParam = ((n % 30) == 8) - local toDestroy = false - - for i = 1, unitCount do - local data = unitList[i] - local unitID = data.unitID - - local enabled, charge = IsShieldEnabled(unitID) - local def = data.def - local hitTime = Spring.GetUnitRulesParam(unitID, "shieldHitFrame") or -999999 - local currTime = Spring.GetGameFrame() - local inCooldown = false - if def.rechargeDelay then - local remainingTime = hitTime + def.rechargeDelay * 30 - currTime - inCooldown = (remainingTime >= 0) - if (setParam or currTime - hitTime < 3) and remainingTime > -70 then - spSetUnitRulesParam(unitID, "shieldRegenTimer", remainingTime, losTable) - end - end - - local chargeRate = def.chargePerUpdate - if def.chargeRateChange then - chargeRate = (Spring.GetUnitRulesParam(unitID, "shield_rate_override") or def.chargePerUpdate) + def.chargeRateChange - Spring.SetUnitRulesParam(unitID, "shield_rate_override", chargeRate, losTable) - end - - local maxCharge = def.maxCharge * (GG.att_ShieldMaxMult[unitID] or 1) - if enabled and (charge < maxCharge or chargeRate < 0) and not inCooldown and spGetUnitRulesParam(unitID, "shieldChargeDisabled") ~= 1 then - -- Get changed charge rate based on slow - local newChargeRate = (def.slowImmune and 1) or GetChargeRate(unitID) - - if data.resTable then - if data.oldChargeRate ~= newChargeRate then - GG.StartMiscPriorityResourcing(unitID, def.perSecondCost*newChargeRate, true) - - data.oldChargeRate = newChargeRate - data.resTable.e = def.perUpdateCost*newChargeRate - end - end - - -- Deal with overflow - local chargeAdd = newChargeRate*chargeRate - if charge + chargeAdd > maxCharge then - local overProportion = 1 - (charge + chargeAdd - maxCharge)/chargeAdd - if data.resTable then - data.resTable.e = data.resTable.e*overProportion - data.oldChargeRate = false -- Reset resTable on next full charge - end - chargeAdd = chargeAdd*overProportion - end - - if charge + chargeAdd <= 0 then - chargeAdd = -charge - if def.dieOnEmpty then - toDestroy = toDestroy or {} - toDestroy[#toDestroy + 1] = unitID - end - end - - -- Check if the change can be carried out - if (not data.resTable) or ((GG.AllowMiscPriorityBuildStep(unitID, data.teamID, true, data.resTable) and spUseUnitResource(unitID, data.resTable))) then - spSetUnitShieldState(unitID, data.shieldNum, charge + chargeAdd) - end - end - - -- Drain shields on paralysis etc.. - if enabled ~= data.enabled then - if def.dieOnEmpty and (not enabled) then - toDestroy = toDestroy or {} - toDestroy[#toDestroy + 1] = unitID - end - if not enabled then - spSetUnitShieldState(unitID, -1, 0) - end - data.enabled = enabled - end - end - - if toDestroy then - for i = 1, #toDestroy do - local unitID = toDestroy[i] - Spring.DestroyUnit(unitID, true) - end - end -end - --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- --- Unit Tracking - -function gadget:UnitCreated(unitID, unitDefID, teamID) - if unitMap[unitID] then - return - end - if shieldUnitDefID[unitDefID] and shieldUnitDefID[unitDefID].perUpdateCost then - GG.AddMiscPriorityUnit(unitID) - end - local commShieldDefID = GG.Upgrades_UnitShieldDef and GG.Upgrades_UnitShieldDef(unitID) - if commShieldDefID and shieldCommWeaponDefID[commShieldDefID] and shieldCommWeaponDefID[commShieldDefID].perUpdateCost then - GG.AddMiscPriorityUnit(unitID) - end -end - -function gadget:UnitFinished(unitID, unitDefID, teamID) - local commShieldDefID = GG.Upgrades_UnitShieldDef and GG.Upgrades_UnitShieldDef(unitID) - if ((shieldUnitDefID[unitDefID] and not UnitDefs[unitDefID].customParams.dynamic_comm) or commShieldDefID) and not unitMap[unitID] then - local def = shieldUnitDefID[unitDefID] - if commShieldDefID then - def = shieldCommWeaponDefID[commShieldDefID] - if not def then - return - end - end - local shieldNum = (GG.Upgrades_UnitShieldDef and select(2, GG.Upgrades_UnitShieldDef(unitID))) or -1 - if def.startPower then - spSetUnitShieldState(unitID, shieldNum, def.startPower) - end - unitCount = unitCount + 1 - local data = { - unitID = unitID, - index = unitCount, - unitDefID = unitDefID, - teamID = teamID, - resTable = def.perUpdateCost and { - m = 0, - e = def.perUpdateCost - }, - shieldNum = shieldNum, - def = def - } - - unitList[unitCount] = data - unitMap[unitID] = data - end -end - -function gadget:UnitDestroyed(unitID, unitDefID, teamID) - if unitMap[unitID] then - local index = unitMap[unitID].index - - unitList[unitCount].index = index - unitList[index] = unitList[unitCount] - - unitList[unitCount] = nil - unitMap[unitID] = nil - unitCount = unitCount - 1 - end -end - -function gadget:UnitTaken(unitID, unitDefID, oldTeamID, teamID) - if unitMap[unitID] then - unitMap[unitID].teamID = teamID - end -end - -function gadget:Initialize() - for _, unitID in ipairs(Spring.GetAllUnits()) do - local unitDefID = Spring.GetUnitDefID(unitID) - local teamID = Spring.GetUnitTeam(unitID) - gadget:UnitCreated(unitID, unitDefID, teamID) - gadget:UnitFinished(unitID, unitDefID, teamID) - end -end - --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- + end + + -------------------------------------------------------------------------------- + -------------------------------------------------------------------------------- + + if (not gadgetHandler:IsSyncedCode()) then + return false -- no unsynced code + end + + include("LuaRules/Configs/constants.lua") + + ---@diagnostic disable-next-line: undefined-global + local TEAM_SLOWUPDATE_RATE=TEAM_SLOWUPDATE_RATE + -------------------------------------------------------------------------------- + -------------------------------------------------------------------------------- + + local PERIOD = 2 + + local spGetUnitShieldState = Spring.GetUnitShieldState + local spSetUnitShieldState = Spring.SetUnitShieldState + + local spGetUnitIsStunned = Spring.GetUnitIsStunned + local spUseUnitResource = Spring.UseUnitResource + local spGetUnitRulesParam = Spring.GetUnitRulesParam + local spSetUnitRulesParam = Spring.SetUnitRulesParam + local losTable = {inlos = true} + + local unitMap = {} + local unitList = {} + local unitCount = 0 + + local shieldUnitDefID = {} + local shieldCommWeaponDefID = {} + + local function LoadShieldWeaponDef(shieldWep) + local wcp = shieldWep.customParams + local def = { + maxCharge = shieldWep.shieldPower, + chargePerUpdate = PERIOD*tonumber(wcp.shield_rate)/TEAM_SLOWUPDATE_RATE, + startPower = wcp.shieldstartingpower and tonumber(wcp.shieldstartingpower), + slowImmune = wcp.slow_immune and true or false, + dieOnEmpty = wcp.die_on_empty and true or false, + } + if wcp.shield_rate_charge then + def.chargeRateChange = PERIOD*PERIOD*tonumber(wcp.shield_rate_charge)/(TEAM_SLOWUPDATE_RATE * TEAM_SLOWUPDATE_RATE) + end + if wcp.shield_drain and tonumber(wcp.shield_drain) > 0 then + def.perUpdateCost = PERIOD*tonumber(wcp.shield_drain)/TEAM_SLOWUPDATE_RATE + def.perSecondCost = tonumber(wcp.shield_drain) + def.rechargeDelay = wcp.shield_recharge_delay and tonumber(wcp.shield_recharge_delay) + end + return def + end + + for unitDefID = 1, #UnitDefs do + local ud = UnitDefs[unitDefID] + if ud.shieldWeaponDef and not ud.customParams.dynamic_comm then + local shieldWep = WeaponDefs[ud.shieldWeaponDef] + if shieldWep.customParams then + shieldUnitDefID[unitDefID] = LoadShieldWeaponDef(shieldWep) + end + end + end + + local commShieldDefs = { + --WeaponDefNames["commweapon_areashield"], + --WeaponDefNames["commweapon_personal_shield"], + --WeaponDefNames["commweapon_chickenshield"] + } + + local weaponsList = VFS.DirList("gamedata/modularcomms/weapons", "*.lua") or {} + for i = 1, #weaponsList do + local name, array = VFS.Include(weaponsList[i]) + local wd=WeaponDefNames[name] + if wd.type == [[Shield]] then + commShieldDefs[#commShieldDefs+1]=wd + end + end + + + for i = 1, #commShieldDefs do + local wd = commShieldDefs[i] + shieldCommWeaponDefID[wd.id] = LoadShieldWeaponDef(wd) + end + + -------------------------------------------------------------------------------- + -------------------------------------------------------------------------------- + -- Unit Updating + + local function IsShieldEnabled(unitID) + local enabled, charge = spGetUnitShieldState(unitID) + if not enabled then + return false + end + local stunned_or_inbuild, stunned, inbuild = spGetUnitIsStunned(unitID) + if stunned_or_inbuild then + return false + end + local att_enabled = (spGetUnitRulesParam(unitID, "att_shieldDisabled") ~= 1) + return att_enabled, charge + end + + local function GetChargeRate(unitID) + return (GG.att_ShieldRegenChange[unitID] or 1) + end + + function gadget:GameFrame(n) + if n%PERIOD ~= 0 then + return + end + + local updatePriority = (n % TEAM_SLOWUPDATE_RATE == 0) + local setParam = ((n % 30) == 8) + ---@type false|table + local toDestroy = false + + for i = 1, unitCount do + local data = unitList[i] + local unitID = data.unitID + + local enabled, charge = IsShieldEnabled(unitID) + local def = data.def + local hitTime = Spring.GetUnitRulesParam(unitID, "shieldHitFrame") or -999999 + local currTime = Spring.GetGameFrame() + local inCooldown = false + if def.rechargeDelay then + local remainingTime = hitTime + def.rechargeDelay * 30 - currTime + inCooldown = (remainingTime >= 0) + if (setParam or currTime - hitTime < 3) and remainingTime > -70 then + spSetUnitRulesParam(unitID, "shieldRegenTimer", remainingTime, losTable) + end + end + + local chargeRate = def.chargePerUpdate + if def.chargeRateChange then + chargeRate = (Spring.GetUnitRulesParam(unitID, "shield_rate_override") or def.chargePerUpdate) + def.chargeRateChange + Spring.SetUnitRulesParam(unitID, "shield_rate_override", chargeRate, losTable) + end + + local maxCharge = def.maxCharge * (GG.att_ShieldMaxMult[unitID] or 1) + if enabled and (charge < maxCharge or chargeRate < 0) and not inCooldown and spGetUnitRulesParam(unitID, "shieldChargeDisabled") ~= 1 then + -- Get changed charge rate based on slow + local newChargeRate = (def.slowImmune and 1) or GetChargeRate(unitID) + + if data.resTable then + if data.oldChargeRate ~= newChargeRate then + GG.StartMiscPriorityResourcing(unitID, def.perSecondCost*newChargeRate, true) + + data.oldChargeRate = newChargeRate + data.resTable.e = def.perUpdateCost*newChargeRate + end + end + + -- Deal with overflow + local chargeAdd = newChargeRate*chargeRate + if charge + chargeAdd > maxCharge then + local overProportion = 1 - (charge + chargeAdd - maxCharge)/chargeAdd + if data.resTable then + data.resTable.e = data.resTable.e*overProportion + data.oldChargeRate = false -- Reset resTable on next full charge + end + chargeAdd = chargeAdd*overProportion + end + + if charge + chargeAdd <= 0 then + chargeAdd = -charge + if def.dieOnEmpty then + toDestroy = toDestroy or {} + toDestroy[#toDestroy + 1] = unitID + end + end + + -- Check if the change can be carried out + if (not data.resTable) or ((GG.AllowMiscPriorityBuildStep(unitID, data.teamID, true, data.resTable) and spUseUnitResource(unitID, data.resTable))) then + spSetUnitShieldState(unitID, data.shieldNum, charge + chargeAdd) + end + end + + -- Drain shields on paralysis etc.. + if enabled ~= data.enabled then + if def.dieOnEmpty and (not enabled) then + toDestroy = toDestroy or {} + toDestroy[#toDestroy + 1] = unitID + end + if not enabled then + spSetUnitShieldState(unitID, -1, 0) + end + data.enabled = enabled + end + end + + if toDestroy then + for i = 1, #toDestroy do + local unitID = toDestroy[i] + Spring.DestroyUnit(unitID, true) + end + end + end + + -------------------------------------------------------------------------------- + -------------------------------------------------------------------------------- + -- Unit Tracking + + function gadget:UnitCreated(unitID, unitDefID, teamID) + if unitMap[unitID] then + return + end + if shieldUnitDefID[unitDefID] and shieldUnitDefID[unitDefID].perUpdateCost then + GG.AddMiscPriorityUnit(unitID) + end + local commShieldDefID = GG.Upgrades_UnitShieldDef and GG.Upgrades_UnitShieldDef(unitID) + if commShieldDefID and shieldCommWeaponDefID[commShieldDefID] and shieldCommWeaponDefID[commShieldDefID].perUpdateCost then + GG.AddMiscPriorityUnit(unitID) + end + end + + function gadget:UnitFinished(unitID, unitDefID, teamID) + local commShieldDefID = GG.Upgrades_UnitShieldDef and GG.Upgrades_UnitShieldDef(unitID) + if ((shieldUnitDefID[unitDefID] and not UnitDefs[unitDefID].customParams.dynamic_comm) or commShieldDefID) and not unitMap[unitID] then + local def = shieldUnitDefID[unitDefID] + if commShieldDefID then + def = shieldCommWeaponDefID[commShieldDefID] + if not def then + return + end + end + local shieldNum = (GG.Upgrades_UnitShieldDef and select(2, GG.Upgrades_UnitShieldDef(unitID))) or -1 + if def.startPower then + spSetUnitShieldState(unitID, shieldNum, def.startPower) + end + unitCount = unitCount + 1 + local data = { + unitID = unitID, + index = unitCount, + unitDefID = unitDefID, + teamID = teamID, + resTable = def.perUpdateCost and { + m = 0, + e = def.perUpdateCost + }, + shieldNum = shieldNum, + def = def + } + + unitList[unitCount] = data + unitMap[unitID] = data + end + end + + function gadget:UnitDestroyed(unitID, unitDefID, teamID) + if unitMap[unitID] then + local index = unitMap[unitID].index + + unitList[unitCount].index = index + unitList[index] = unitList[unitCount] + + unitList[unitCount] = nil + unitMap[unitID] = nil + unitCount = unitCount - 1 + end + end + + function gadget:UnitTaken(unitID, unitDefID, oldTeamID, teamID) + if unitMap[unitID] then + unitMap[unitID].teamID = teamID + end + end + + function gadget:Initialize() + for _, unitID in ipairs(Spring.GetAllUnits()) do + local unitDefID = Spring.GetUnitDefID(unitID) + local teamID = Spring.GetUnitTeam(unitID) + gadget:UnitCreated(unitID, unitDefID, teamID) + gadget:UnitFinished(unitID, unitDefID, teamID) + end + end + + -------------------------------------------------------------------------------- + -------------------------------------------------------------------------------- + \ No newline at end of file diff --git a/LuaUI/Configs/startup_info_selector.lua b/LuaUI/Configs/startup_info_selector.lua index 7831e83766..25bc94e251 100644 --- a/LuaUI/Configs/startup_info_selector.lua +++ b/LuaUI/Configs/startup_info_selector.lua @@ -40,10 +40,18 @@ local chassisImages = { support = "LuaUI/Images/startup_info_selector/chassis_commsupport.png", assault = "LuaUI/Images/startup_info_selector/chassis_benzcom.png", strike = "LuaUI/Images/startup_info_selector/chassis_commstrike.png", - knight = "LuaUI/Images/startup_info_selector/chassis_cremcom.png" + knight = "LuaUI/Images/startup_info_selector/chassis_cremcom.png", } -local moduleDefs, emptyModules, chassisDefs, upgradeUtilities, chassisDefByBaseDef, moduleDefNames, chassisDefNames = VFS.Include("LuaRules/Configs/dynamic_comm_defs.lua") + +local moduleDefs, chassisDefs, upgradeUtilities, LEVEL_BOUND , chassisDefByBaseDef, moduleDefNames, chassisDefNames = VFS.Include("LuaRules/Configs/dynamic_comm_defs.lua") + +-- chassisDefs.chassisImage +---@cast chassisDefs table +---@cast moduleDefNames table +for key, value in pairs(chassisDefs) do + chassisImages[value.name]=value.chassisImage or chassisImages[value.name] +end local colorWeapon = "\255\255\32\32" local colorConversion = "\255\255\96\0" @@ -86,6 +94,7 @@ local function GetCommSelectTemplate(num, data) tooltip = "Select "..data.name..WriteTooltip(commProfileID), image = chassisImages[data.chassis], cmd = "customcomm:"..commProfileID, +---@diagnostic disable-next-line: undefined-global unitname = comm1Name, commProfile = commProfileID, trainer = string.find(commProfileID, "trainer") ~= nil, -- FIXME should probably be in the def table diff --git a/gamedata/modularcomms/chassises/assult.lua b/gamedata/modularcomms/chassises/assult.lua new file mode 100644 index 0000000000..8cdc6439b4 --- /dev/null +++ b/gamedata/modularcomms/chassises/assult.lua @@ -0,0 +1,245 @@ +return { + clonedefs={ + dynassault1 = { + dynassault0 = { + level = 0, + customparams = {shield_emit_height = 32.5}, + }, + dynassault2 = { + level = 2, + collisionvolumescales = [[50 60 50]], + mainstats = {health = 5000, objectname = "benzcom2.s3o"}, + customparams = {modelradius = [[30]], shield_emit_height = 35.75}, + wreckmodel = "benzcom2_wreck.s3o", + }, + dynassault3 = { + level = 3, + collisionvolumescales = [[55 65 55]], + mainstats = {health = 5700, objectname = "benzcom3.s3o",}, + customparams = {modelradius = [[33]], shield_emit_height = 39}, + wreckmodel = "benzcom3_wreck.s3o", + }, + dynassault4 = { + level = 4, + collisionvolumescales = [[58 68 58]], + mainstats = {health = 6600, objectname = "benzcom4.s3o",}, + customparams = {modelradius = [[34]], shield_emit_height = 40.625}, + wreckmodel = "benzcom4_wreck.s3o", + }, + dynassault5 = { + level = 5, + collisionvolumescales = [[60 71 60]], + mainstats = {health = 7600, objectname = "benzcom5.s3o",}, + customparams = {modelradius = [[36]], shield_emit_height = 42.25}, + wreckmodel = "benzcom5_wreck.s3o", + }, + }, + }, + dynamic_comm_defs_name="assault", + dynamic_comm_defs=function(shared) + + shared=ModularCommDefsShared or shared + local extraLevelCostFunction=shared.extraLevelCostFunction + local morphBuildPower=shared.morphBuildPower + local morphCosts=shared.morphCosts + local COST_MULT=shared.COST_MULT + local GetCloneModuleString=shared.GetCloneModuleString + local morphUnitDefFunction=shared.morphUnitDefFunction + local moduleDefNames=shared.moduleDefNames + + local function GetAssaultCloneModulesString(modulesByDefID) + return (modulesByDefID[moduleDefNames.assault.commweapon_personal_shield] or 0) .. + (modulesByDefID[moduleDefNames.assault.commweapon_areashield] or 0) + end + + return { + name = "assault", + humanName = "Guardian", + baseUnitDef = UnitDefNames and UnitDefNames["dynassault0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + secondPeashooter = false, + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 1 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault0"].id + end, + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 1 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault1_" .. GetAssaultCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.commweapon_beamlaser, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 2 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault2_" .. GetAssaultCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 2 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault3_" .. GetAssaultCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.commweapon_beamlaser_adv, + slotAllows = {"dual_basic_weapon", "adv_weapon"}, + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 2 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault4_" .. GetAssaultCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 3 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault5_" .. GetAssaultCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, + dyncomm_chassis_generator={ + name = "dynassault1", + weapons = { + "commweapon_peashooter", + "commweapon_rocketlauncher", -- 430 + "commweapon_rocketlauncher_napalm", -- 430 + "commweapon_rocketlauncher", -- 430 + "commweapon_rocketlauncher_napalm", -- 430 + "commweapon_beamlaser", + "commweapon_heatray", + "commweapon_heavymachinegun", + "commweapon_flamethrower", + "commweapon_riotcannon", + "commweapon_riotcannon_napalm", + "commweapon_peashooter", + "commweapon_beamlaser", + "commweapon_heatray", + "commweapon_heavymachinegun", + "commweapon_flamethrower", + "commweapon_riotcannon", + "commweapon_riotcannon_napalm", + "commweapon_hpartillery", + "commweapon_hpartillery_napalm", + "commweapon_disintegrator", + "commweapon_napalmgrenade", + "commweapon_slamrocket", + "commweapon_clusterbomb", + -- Space for shield + } + }, + dyncomms_predefined={ + dyntrainer_assault = { + name = "Guardian", + chassis = "assault", + modules = { + {"commweapon_heavymachinegun", "module_radarnet"}, + {"module_ablative_armor", "module_autorepair"}, + {"commweapon_shotgun", "commweapon_personal_shield", "module_heavy_armor"}, + {"module_dmg_booster", "module_dmg_booster", "module_heavy_armor"}, + {"conversion_disruptor","module_dmg_booster", "module_heavy_armor"}, + }, + --decorations = {"banner_overhead"}, + --images = {overhead = "166"} + }, + }, + staticcomms={ + "dynassault", + {{0, 0}, {1, 0}, {1, 1}, {1, 1}, {1, 1}}, + {"module_personal_shield", "module_areashield"} + } +} \ No newline at end of file diff --git a/gamedata/modularcomms/chassises/chicken.lua b/gamedata/modularcomms/chassises/chicken.lua new file mode 100644 index 0000000000..59e46a4826 --- /dev/null +++ b/gamedata/modularcomms/chassises/chicken.lua @@ -0,0 +1,250 @@ + +local nomainstates={ + collisionvolumescales=true, + modelradius=true, + explodeas=true, + selfdestructas=true, + footprintx=true, + footprintz=true, + movementclass=true +} +return { + clonedefs={ + dynchicken1 = { + dynchicken0 = { + level = 0, + customparams = {shield_emit_height = 30}, + nomainstats=nomainstates, + }, + dynchicken2 = { + level = 2, + mainstats = {health = 4600}, + customparams = {def_scale=1.2}, + nomainstats=nomainstates, + }, + dynchicken3 = { + level = 3, + mainstats = {health = 5200}, + customparams = {def_scale=1.4}, + nomainstats=nomainstates, + }, + dynchicken4 = { + level = 4, + mainstats = {health = 5800}, + customparams = {def_scale=1.6}, + nomainstats=nomainstates, + }, + dynchicken5 = { + level = 5, + mainstats = {health = 6400}, + customparams = {def_scale=1.7}, + nomainstats=nomainstates, + }, + }, + }, + dynamic_comm_defs_name="chicken", + dynamic_comm_defs_modules={ + { + name = "commweapon_personal_shield", + }, + { + name = "module_radarnet", + }, + { + requireChassis = { + "support", + }, + name = "module_resurrect", + }, + { + name = "module_dmg_booster", + },{ + requireChassis = { + "assault", + }, + name = "module_high_power_servos", + }, + { + name = "module_adv_targeting", + },{ + requireChassis = { + [1] = "recon", + }, + name = "module_adv_nano", + },{ + name = "banner_overhead", + }, + }, + dynamic_comm_defs=function(shared) + shared=ModularCommDefsShared or shared + local extraLevelCostFunction=shared.extraLevelCostFunction + local morphBuildPower=shared.morphBuildPower + local morphCosts=shared.morphCosts + local COST_MULT=shared.COST_MULT + local GetCloneModuleString=shared.GetCloneModuleString + local morphUnitDefFunction=shared.morphUnitDefFunction + local mymorphUnitDefFunction=morphUnitDefFunction("dynchicken",GetCloneModuleString("chicken",{ + "commweapon_personal_shield","commweapon_chickenshield" + })) + local moduleDefNames=shared.moduleDefNames + + return { + name = "chicken", + humanName = "Chicken", + baseUnitDef = UnitDefNames and UnitDefNames["dynchicken0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + secondPeashooter = false, + chassisImage="unitpics/chickenbroodqueen.png", + initWeapon="commweapon_chickenspores", + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = mymorphUnitDefFunction(1), + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 8 + end, + morphUnitDefFunction = mymorphUnitDefFunction(1), + upgradeSlots = { + { + defaultModule = moduleDefNames.chicken.commweapon_chickenspores, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.chicken.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12 + end, + morphUnitDefFunction = mymorphUnitDefFunction(2), + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 16 + end, + morphUnitDefFunction = mymorphUnitDefFunction(3), + upgradeSlots = { + { + defaultModule = moduleDefNames.chicken.commweapon_beamlaser_adv, + slotAllows = {"dual_basic_weapon", "adv_weapon"}, + }, + { + defaultModule = moduleDefNames.chicken.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.chicken.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 20 + end, + morphUnitDefFunction = mymorphUnitDefFunction(4), + upgradeSlots = { + { + defaultModule = moduleDefNames.chicken.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.chicken.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.chicken.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 25 + end, + morphUnitDefFunction = mymorphUnitDefFunction(5), + upgradeSlots = { + { + defaultModule = moduleDefNames.chicken.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.chicken.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.chicken.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, + dyncomm_chassis_generator={ + name="dynchicken1", + weapons={ + --"commweapon_beamlaser", + "commweapon_chickenclaw", + "commweapon_chickenclaw", + "commweapon_chickengoo", + "commweapon_chickenspike", + "commweapon_chickenspike", + "commweapon_chickenspores", + "commweapon_chickenspores", + "commweapon_chickenflamethrower", + "commweapon_chickenflamethrower", + --"commweapon_personal_shield", + } + }, + dyncomms_predefined={ + dyntrainer_chicken = { + name = "Chicken", + chassis = "chicken", + + modules = { -- all null because nabs want to personalize + {"nullbasicweapon", "nullmodule"}, + {"nullmodule", "nullmodule"}, + {"nulladvweapon", "nullmodule", "nullmodule"}, + {"nullmodule", "nullmodule", "nullmodule"}, + {"nullmodule", "nullmodule", "nullmodule"}, + }, + } + }, + staticcomms={ +"dynchicken", + {{0,0}, {1,0}, {1,1}, {1,1}, {1,1}}, + {"module_personal_shield","module_chickenshield"} + } +} \ No newline at end of file diff --git a/gamedata/modularcomms/chassises/knight.lua b/gamedata/modularcomms/chassises/knight.lua new file mode 100644 index 0000000000..78222c2993 --- /dev/null +++ b/gamedata/modularcomms/chassises/knight.lua @@ -0,0 +1,246 @@ +return { + clonedefs={ + dynknight1 = { + dynknight0 = { + level = 0, + customparams = {shield_emit_height = 30}, + }, + dynknight2 = { + level = 2, + mainstats = {health = 4600, objectname = "cremcom2.s3o", collisionvolumescales = [[50 55 50]],}, + customparams = {modelradius = [[28]], shield_emit_height = 33}, + wreckmodel = "cremcom2_dead.s3o", + }, + dynknight3 = { + level = 3, + mainstats = {health = 5200, objectname = "cremcom3.s3o", collisionvolumescales = [[55 60 55]],}, + customparams = {modelradius = [[30]], shield_emit_height = 36}, + wreckmodel = "cremcom3_dead.s3o", + }, + dynknight4 = { + level = 4, + mainstats = {health = 5800, objectname = "cremcom4.s3o", collisionvolumescales = [[60 65 60]],}, + customparams = {modelradius = [[33]], shield_emit_height = 37.5}, + wreckmodel = "cremcom4_dead.s3o", + }, + dynknight5 = { + level = 5, + mainstats = {health = 6400, objectname = "cremcom5.s3o", collisionvolumescales = [[65 70 65]],}, + customparams = {modelradius = [[35]], shield_emit_height = 39}, + wreckmodel = "cremcom5_dead.s3o", + }, + }, + }, + dyncomm_chassis_generator={ + name = "dynknight1", + weapons = { + -- Aiming from earlier weapons is overridden by later + "commweapon_peashooter", + "commweapon_rocketlauncher", -- 430 + "commweapon_rocketlauncher_napalm", -- 430 + "commweapon_missilelauncher", -- 415 + "commweapon_hparticlebeam", -- 390 + "commweapon_beamlaser", -- 330 + "commweapon_lightninggun", -- 300 + "commweapon_lightninggun_improved", -- 300 + "commweapon_lparticlebeam", -- 300 + "commweapon_riotcannon", -- 300 + "commweapon_riotcannon_napalm", -- 300 + "commweapon_disruptor", -- 300 + "commweapon_heatray", -- 300 + "commweapon_shotgun", -- 290 + "commweapon_shotgun_disrupt", -- 290 + "commweapon_heavymachinegun", -- 285 + "commweapon_heavymachinegun_disrupt", -- 285 + "commweapon_flamethrower", -- 270 + "commweapon_multistunner", + "commweapon_multistunner_improved", + "commweapon_peashooter", + "commweapon_hpartillery", + "commweapon_hpartillery_napalm", + "commweapon_disintegrator", + "commweapon_napalmgrenade", + "commweapon_slamrocket", + "commweapon_disruptorbomb", + "commweapon_concussion", + "commweapon_clusterbomb", + "commweapon_shockrifle", + -- Space for shield + } + }, + dynamic_comm_defs_name="knight", + dynamic_comm_defs=function(shared) + + shared=ModularCommDefsShared or shared + local extraLevelCostFunction=shared.extraLevelCostFunction + local morphBuildPower=shared.morphBuildPower + local morphCosts=shared.morphCosts + local COST_MULT=shared.COST_MULT + local GetCloneModuleString=shared.GetCloneModuleString + local morphUnitDefFunction=shared.morphUnitDefFunction + local moduleDefNames=shared.moduleDefNames + + + local function GetKnightCloneModulesString(modulesByDefID) + return (modulesByDefID[moduleDefNames.knight.commweapon_personal_shield] or 0) .. + (modulesByDefID[moduleDefNames.knight.commweapon_areashield] or 0) .. + (modulesByDefID[moduleDefNames.knight.module_resurrect] or 0) .. + (modulesByDefID[moduleDefNames.knight.module_jumpjet] or 0) + end + + return { + name = "knight", + humanName = "Knight", + baseUnitDef = UnitDefNames and UnitDefNames["dynknight0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + notSelectable = (Spring.GetModOptions().campaign_chassis ~= "1"), + secondPeashooter = true, + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + -- Level 1 is the same as level 0 in stats and has support for clone modules (such as shield). + return UnitDefNames["dynknight1_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 8 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynknight1_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.knight.commweapon_beamlaser, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynknight2_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 16 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynknight3_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.knight.commweapon_beamlaser_adv, + slotAllows = {"dual_basic_weapon", "adv_weapon"}, + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 20 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynknight4_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 25 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynknight5_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, + dyncomms_predefined={ + dyntrainer_knight={ + name = "Campaign", + chassis = "knight", + + modules = { -- all null because nabs want to personalize + {"nullbasicweapon", "nullmodule"}, + {"nullmodule", "nullmodule"}, + {"nulladvweapon", "nullmodule", "nullmodule"}, + {"nullmodule", "nullmodule", "nullmodule"}, + {"nullmodule", "nullmodule", "nullmodule"}, + }, + } + }, + staticcomms={ +"dynknight", + {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, + {"module_personal_shield", "module_areashield", "module_resurrect", "module_jumpjet"} + } +} \ No newline at end of file diff --git a/gamedata/modularcomms/chassises/recon.lua b/gamedata/modularcomms/chassises/recon.lua new file mode 100644 index 0000000000..22604acc19 --- /dev/null +++ b/gamedata/modularcomms/chassises/recon.lua @@ -0,0 +1,227 @@ +return { + clonedefs={ + dynrecon1 = { + dynrecon0 = { + level = 0, + customparams = {shield_emit_height = 30}, + }, + dynrecon2 = { + level = 2, + mainstats = {health = 3400, objectname = "commrecon2.s3o", aimposoffset = [[0 12 0]]}, + customparams = {shield_emit_height = 33, jump_reload = 20, jump_speed = 4.75}, + wreckmodel = "commrecon2_dead.s3o", + }, + dynrecon3 = { + level = 3, + mainstats = {health = 3600, objectname = "commrecon3.s3o", aimposoffset = [[0 14 0]]}, + customparams = {shield_emit_height = 36, jump_reload = 20, jump_speed = 5}, + wreckmodel = "commrecon3_dead.s3o", + }, + dynrecon4 = { + level = 4, + mainstats = {health = 3800, objectname = "commrecon4.s3o", aimposoffset = [[0 16 0]]}, + customparams = {shield_emit_height = 37.5, jump_reload = 18, jump_speed = 5.25}, + wreckmodel = "commrecon4_dead.s3o", + }, + dynrecon5 = { + level = 5, + mainstats = {health = 4000, objectname = "commrecon5.s3o", aimposoffset = [[0 18 0]]}, + customparams = {shield_emit_height = 39, jump_reload = 16, jump_speed = 5.5}, + wreckmodel = "commrecon5_dead.s3o", + }, + }, + }, + dynamic_comm_defs_name="recon", + dynamic_comm_defs=function(shared) + + shared=ModularCommDefsShared or shared + local extraLevelCostFunction=shared.extraLevelCostFunction + local morphBuildPower=shared.morphBuildPower + local morphCosts=shared.morphCosts + local COST_MULT=shared.COST_MULT + local GetCloneModuleString=shared.GetCloneModuleString + local morphUnitDefFunction=shared.morphUnitDefFunction + local moduleDefNames=shared.moduleDefNames + + local function GetReconCloneModulesString(modulesByDefID) + return (modulesByDefID[moduleDefNames.recon.commweapon_personal_shield] or 0) + end + + return { + name = "recon", + humanName = "Recon", + baseUnitDef = UnitDefNames and UnitDefNames["dynrecon0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon0"].id + end, + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon1_" .. GetReconCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.recon.commweapon_beamlaser, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon2_" .. GetReconCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon3_" .. GetReconCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.recon.commweapon_disruptorbomb, + slotAllows = "adv_weapon", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon4_" .. GetReconCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon5_" .. GetReconCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, + + dyncomm_chassis_generator={ + name = "dynrecon1", + weapons = { + "commweapon_peashooter", + "commweapon_beamlaser", + "commweapon_lparticlebeam", + "commweapon_disruptor", + "commweapon_shotgun", + "commweapon_shotgun_disrupt", + "commweapon_lightninggun", + "commweapon_lightninggun_improved", + "commweapon_flamethrower", + "commweapon_heavymachinegun", + "commweapon_heavymachinegun_disrupt", + "commweapon_multistunner", + "commweapon_multistunner_improved", + "commweapon_napalmgrenade", + "commweapon_clusterbomb", + "commweapon_disruptorbomb", + "commweapon_concussion", + -- Space for shield + } + }, + dyncomms_predefined={ + dyntrainer_recon = { + name = "Recon", + chassis = "recon", + modules = { + {"commweapon_heavymachinegun", "module_radarnet"}, + {"module_ablative_armor", "module_autorepair"}, + {"commweapon_clusterbomb", "commweapon_personal_shield", "module_ablative_armor"}, + {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, + {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, + }, + --decorations = {"skin_recon_dark", "banner_overhead"}, + --images = {overhead = "184"} + }, + }, + staticcomms={ + "dynrecon", + {{0}, {1}, {1}, {1}, {1}}, + {"module_personal_shield"} + } +} \ No newline at end of file diff --git a/gamedata/modularcomms/chassises/strike.lua b/gamedata/modularcomms/chassises/strike.lua new file mode 100644 index 0000000000..d59dca6f47 --- /dev/null +++ b/gamedata/modularcomms/chassises/strike.lua @@ -0,0 +1,238 @@ +return { + clonedefs={ + dynstrike1 = { + dynstrike0 = { + level = 0, + customparams = {shield_emit_height = 38}, + }, + dynstrike2 = { + level = 2, + mainstats = {health = 4600, objectname = "strikecom_1.dae", collisionvolumescales = [[50 55 50]],}, + customparams = {modelradius = [[28]], shield_emit_height = 41.8}, + wreckmodel = "strikecom_dead_1.dae", + }, + dynstrike3 = { + level = 3, + mainstats = {health = 5200, objectname = "strikecom_2.dae", collisionvolumescales = [[55 60 55]],}, + customparams = {modelradius = [[30]], shield_emit_height = 45.6}, + wreckmodel = "strikecom_dead_2.dae", + }, + dynstrike4 = { + level = 4, + mainstats = {health = 5800, objectname = "strikecom_3.dae", collisionvolumescales = [[58 66 58]],}, + customparams = {modelradius = [[33]], shield_emit_height = 47.5}, + wreckmodel = "strikecom_dead_3.dae", + }, + dynstrike5 = { + level = 5, + mainstats = {health = 6400, objectname = "strikecom_4.dae", collisionvolumescales = [[60 72 60]],}, + customparams = {modelradius = [[36]], shield_emit_height = 49.4}, + wreckmodel = "strikecom_dead_4.dae", + }, + } + }, + dynamic_comm_defs_name="strike", + dynamic_comm_defs=function(shared) + + shared=ModularCommDefsShared or shared + local extraLevelCostFunction=shared.extraLevelCostFunction + local morphBuildPower=shared.morphBuildPower + local morphCosts=shared.morphCosts + local COST_MULT=shared.COST_MULT + local GetCloneModuleString=shared.GetCloneModuleString + local morphUnitDefFunction=shared.morphUnitDefFunction + local moduleDefNames=shared.moduleDefNames + + + local function GetStrikeCloneModulesString(modulesByDefID) + return (modulesByDefID[moduleDefNames.strike.commweapon_personal_shield] or 0) .. + (modulesByDefID[moduleDefNames.strike.commweapon_areashield] or 0) + end + + return { + name = "strike", + humanName = "Strike", + baseUnitDef = UnitDefNames and UnitDefNames["dynstrike0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + secondPeashooter = false, + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike0"].id + end, + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 8 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike1_" .. GetStrikeCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.strike.commweapon_beamlaser, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike2_" .. GetStrikeCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 16 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike3_" .. GetStrikeCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.strike.commweapon_beamlaser_adv, + slotAllows = {"dual_basic_weapon", "adv_weapon"}, + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 20 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike4_" .. GetStrikeCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 25 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike5_" .. GetStrikeCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, + dyncomm_chassis_generator={ + name = "dynstrike1", + weapons = { + "commweapon_peashooter", + "commweapon_missilelauncher", -- 415 + "commweapon_missilelauncher", -- 415 + "commweapon_beamlaser", + "commweapon_lparticlebeam", + "commweapon_shotgun", + "commweapon_shotgun_disrupt", + "commweapon_disruptor", + "commweapon_heavymachinegun", + "commweapon_heavymachinegun_disrupt", + "commweapon_lightninggun", + "commweapon_lightninggun_improved", + "commweapon_peashooter", + "commweapon_beamlaser", + "commweapon_lparticlebeam", + "commweapon_shotgun", + "commweapon_shotgun_disrupt", + "commweapon_disruptor", + "commweapon_heavymachinegun", + "commweapon_heavymachinegun_disrupt", + "commweapon_lightninggun", + "commweapon_lightninggun_improved", + "commweapon_multistunner", + "commweapon_multistunner_improved", + "commweapon_disruptorbomb", + "commweapon_disintegrator", + -- Space for shield + } + }, + dyncomms_predefined={ + dyntrainer_strike = { + name = "Strike", + chassis = "strike", + modules = { + {"commweapon_heavymachinegun", "module_radarnet"}, + {"module_ablative_armor", "module_autorepair"}, + {"commweapon_lightninggun", "module_personal_cloak", "module_ablative_armor"}, + {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, + {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, + }, + --decorations = {"banner_overhead"}, + --images = {overhead = "184"} + }, + }, + staticcomms={ + "dynstrike", + {{0, 0}, {1, 0}, {1, 1}, {1, 1}, {1, 1}}, + {"module_personal_shield", "module_areashield"} + } +} \ No newline at end of file diff --git a/gamedata/modularcomms/chassises/support.lua b/gamedata/modularcomms/chassises/support.lua new file mode 100644 index 0000000000..08241cf196 --- /dev/null +++ b/gamedata/modularcomms/chassises/support.lua @@ -0,0 +1,230 @@ +return { + clonedefs={ + dynsupport1 = { + dynsupport0 = { + level = 0, + customparams = {shield_emit_height = 36, builddistance = 220}, + }, + dynsupport2 = { + level = 2, + mainstats = {health = 4000, objectname = "commsupport2.s3o", aimposoffset = [[0 17 0]], builddistance = 244}, + customparams = {shield_emit_height = 39.6}, + wreckmodel = "commsupport2_dead.s3o", + }, + dynsupport3 = { + level = 3, + mainstats = {health = 4300, objectname = "commsupport3.s3o", aimposoffset = [[0 19 0]], builddistance = 256}, + customparams = {shield_emit_height = 43.62}, + wreckmodel = "commsupport3_dead.s3o", + }, + dynsupport4 = { + level = 4, + mainstats = {health = 4600, objectname = "commsupport4.s3o", aimposoffset = [[0 22 0]], builddistance = 268}, + customparams = {shield_emit_height = 45}, + wreckmodel = "commsupport4_dead.s3o", + }, + dynsupport5 = { + level = 5, + mainstats = {health = 5000, objectname = "commsupport5.s3o", aimposoffset = [[0 25 0]], builddistance = 280}, + customparams = {shield_emit_height = 46.48}, + wreckmodel = "commsupport5_dead.s3o", + }, + }, + }, + dynamic_comm_defs_name="support", + dynamic_comm_defs=function(shared) + + shared=ModularCommDefsShared or shared + local extraLevelCostFunction=shared.extraLevelCostFunction + local morphBuildPower=shared.morphBuildPower + local morphCosts=shared.morphCosts + local COST_MULT=shared.COST_MULT + local GetCloneModuleString=shared.GetCloneModuleString + local morphUnitDefFunction=shared.morphUnitDefFunction + local moduleDefNames=shared.moduleDefNames + + local function GetSupportCloneModulesString(modulesByDefID) + return (modulesByDefID[moduleDefNames.support.commweapon_personal_shield] or 0) .. + (modulesByDefID[moduleDefNames.support.commweapon_areashield] or 0) .. + (modulesByDefID[moduleDefNames.support.module_resurrect] or 0) + end + + return { + name = "support", + humanName = "Engineer", + baseUnitDef = UnitDefNames and UnitDefNames["dynsupport0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport0"].id + end, + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function (modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 2 + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport1_" .. GetSupportCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.support.commweapon_beamlaser, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 4 + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport2_" .. GetSupportCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function (modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 6 + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport3_" .. GetSupportCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.support.commweapon_disruptorbomb, + slotAllows = "adv_weapon", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4], + chassisApplicationFunction = function (modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 9 + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport4_" .. GetSupportCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5], + chassisApplicationFunction = function (modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 12 + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport5_" .. GetSupportCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, + dyncomm_chassis_generator={ + name = "dynsupport1", + weapons = { + "commweapon_peashooter", + "commweapon_beamlaser", + "commweapon_shotgun", + "commweapon_shotgun_disrupt", + "commweapon_lparticlebeam", + "commweapon_disruptor", + "commweapon_hparticlebeam", + "commweapon_heavy_disruptor", + "commweapon_lightninggun", + "commweapon_lightninggun_improved", + "commweapon_missilelauncher", + "commweapon_shockrifle", + "commweapon_multistunner", + "commweapon_multistunner_improved", + "commweapon_disruptorbomb", + -- Space for shield + } + }, + dyncomms_predefined={ + dyntrainer_support = { + name = "Engineer", + chassis = "support", + modules = { + {"commweapon_lparticlebeam", "module_radarnet"}, + {"module_ablative_armor", "module_autorepair"}, + {"commweapon_hparticlebeam", "module_personal_cloak", "module_adv_nano"}, + {"module_dmg_booster", "module_adv_targeting", "module_adv_targeting"}, + {"module_adv_targeting", "module_adv_nano", "module_resurrect"}, + }, + --decorations = {"skin_support_hotrod"}, + }, + }, + staticcomms={ +"dynsupport", + {{0, 0, 0}, {1, 0, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + {"module_personal_shield", "module_areashield", "module_resurrect"} + } +} \ No newline at end of file diff --git a/gamedata/modularcomms/chassises/template.txt b/gamedata/modularcomms/chassises/template.txt new file mode 100644 index 0000000000..a572ef9f80 --- /dev/null +++ b/gamedata/modularcomms/chassises/template.txt @@ -0,0 +1,17 @@ +return { + clonedefs={ + + }, + dynamic_comm_defs=function(shared) + + end, + dyncomm_chassis_generator={ + + }, + dyncomms_predefined={ + + }, + staticcomms={ + + } +} \ No newline at end of file diff --git a/gamedata/modularcomms/chassises_all_defs.lua b/gamedata/modularcomms/chassises_all_defs.lua new file mode 100644 index 0000000000..130d4be48e --- /dev/null +++ b/gamedata/modularcomms/chassises_all_defs.lua @@ -0,0 +1,14 @@ + +if not Spring.ModularCommAPI then + Spring.ModularCommAPI={} +end +if not Spring.ModularCommAPI.Chassises then + local Chassises={} + Spring.ModularCommAPI.Chassises=Chassises + local chassisFiles=VFS.DirList("gamedata/modularcomms/chassises", "*.lua") or {} + for i = 1, #chassisFiles do + local chassisDef = VFS.Include(chassisFiles[i]) + Chassises[#Chassises+1]=chassisDef + end +end +return Spring.ModularCommAPI.Chassises \ No newline at end of file diff --git a/gamedata/modularcomms/clonedefs.lua b/gamedata/modularcomms/clonedefs.lua index 397ea74f82..5f9a4f42f5 100644 --- a/gamedata/modularcomms/clonedefs.lua +++ b/gamedata/modularcomms/clonedefs.lua @@ -246,162 +246,20 @@ local copy = { wreckmodel = "strikecom_dead_4.dae", }, }, - dynstrike1 = { - dynstrike0 = { - level = 0, - customparams = {shield_emit_height = 38}, - }, - dynstrike2 = { - level = 2, - mainstats = {health = 4600, objectname = "strikecom_1.dae", collisionvolumescales = [[50 55 50]],}, - customparams = {modelradius = [[28]], shield_emit_height = 41.8}, - wreckmodel = "strikecom_dead_1.dae", - }, - dynstrike3 = { - level = 3, - mainstats = {health = 5200, objectname = "strikecom_2.dae", collisionvolumescales = [[55 60 55]],}, - customparams = {modelradius = [[30]], shield_emit_height = 45.6}, - wreckmodel = "strikecom_dead_2.dae", - }, - dynstrike4 = { - level = 4, - mainstats = {health = 5800, objectname = "strikecom_3.dae", collisionvolumescales = [[58 66 58]],}, - customparams = {modelradius = [[33]], shield_emit_height = 47.5}, - wreckmodel = "strikecom_dead_3.dae", - }, - dynstrike5 = { - level = 5, - mainstats = {health = 6400, objectname = "strikecom_4.dae", collisionvolumescales = [[60 72 60]],}, - customparams = {modelradius = [[36]], shield_emit_height = 49.4}, - wreckmodel = "strikecom_dead_4.dae", - }, - }, - dynrecon1 = { - dynrecon0 = { - level = 0, - customparams = {shield_emit_height = 30}, - }, - dynrecon2 = { - level = 2, - mainstats = {health = 3400, objectname = "commrecon2.s3o", aimposoffset = [[0 12 0]]}, - customparams = {shield_emit_height = 33, jump_reload = 20, jump_speed = 4.75}, - wreckmodel = "commrecon2_dead.s3o", - }, - dynrecon3 = { - level = 3, - mainstats = {health = 3600, objectname = "commrecon3.s3o", aimposoffset = [[0 14 0]]}, - customparams = {shield_emit_height = 36, jump_reload = 20, jump_speed = 5}, - wreckmodel = "commrecon3_dead.s3o", - }, - dynrecon4 = { - level = 4, - mainstats = {health = 3800, objectname = "commrecon4.s3o", aimposoffset = [[0 16 0]]}, - customparams = {shield_emit_height = 37.5, jump_reload = 18, jump_speed = 5.25}, - wreckmodel = "commrecon4_dead.s3o", - }, - dynrecon5 = { - level = 5, - mainstats = {health = 4000, objectname = "commrecon5.s3o", aimposoffset = [[0 18 0]]}, - customparams = {shield_emit_height = 39, jump_reload = 16, jump_speed = 5.5}, - wreckmodel = "commrecon5_dead.s3o", - }, - }, - dynsupport1 = { - dynsupport0 = { - level = 0, - customparams = {shield_emit_height = 36, builddistance = 220}, - }, - dynsupport2 = { - level = 2, - mainstats = {health = 4000, objectname = "commsupport2.s3o", aimposoffset = [[0 17 0]], builddistance = 244}, - customparams = {shield_emit_height = 39.6}, - wreckmodel = "commsupport2_dead.s3o", - }, - dynsupport3 = { - level = 3, - mainstats = {health = 4300, objectname = "commsupport3.s3o", aimposoffset = [[0 19 0]], builddistance = 256}, - customparams = {shield_emit_height = 43.62}, - wreckmodel = "commsupport3_dead.s3o", - }, - dynsupport4 = { - level = 4, - mainstats = {health = 4600, objectname = "commsupport4.s3o", aimposoffset = [[0 22 0]], builddistance = 268}, - customparams = {shield_emit_height = 45}, - wreckmodel = "commsupport4_dead.s3o", - }, - dynsupport5 = { - level = 5, - mainstats = {health = 5000, objectname = "commsupport5.s3o", aimposoffset = [[0 25 0]], builddistance = 280}, - customparams = {shield_emit_height = 46.48}, - wreckmodel = "commsupport5_dead.s3o", - }, - }, - dynassault1 = { - dynassault0 = { - level = 0, - customparams = {shield_emit_height = 32.5}, - }, - dynassault2 = { - level = 2, - collisionvolumescales = [[50 60 50]], - mainstats = {health = 5000, objectname = "benzcom2.s3o"}, - customparams = {modelradius = [[30]], shield_emit_height = 35.75}, - wreckmodel = "benzcom2_wreck.s3o", - }, - dynassault3 = { - level = 3, - collisionvolumescales = [[55 65 55]], - mainstats = {health = 5700, objectname = "benzcom3.s3o",}, - customparams = {modelradius = [[33]], shield_emit_height = 39}, - wreckmodel = "benzcom3_wreck.s3o", - }, - dynassault4 = { - level = 4, - collisionvolumescales = [[58 68 58]], - mainstats = {health = 6600, objectname = "benzcom4.s3o",}, - customparams = {modelradius = [[34]], shield_emit_height = 40.625}, - wreckmodel = "benzcom4_wreck.s3o", - }, - dynassault5 = { - level = 5, - collisionvolumescales = [[60 71 60]], - mainstats = {health = 7600, objectname = "benzcom5.s3o",}, - customparams = {modelradius = [[36]], shield_emit_height = 42.25}, - wreckmodel = "benzcom5_wreck.s3o", - }, - }, - dynknight1 = { - dynknight0 = { - level = 0, - customparams = {shield_emit_height = 30}, - }, - dynknight2 = { - level = 2, - mainstats = {health = 4600, objectname = "cremcom2.s3o", collisionvolumescales = [[50 55 50]],}, - customparams = {modelradius = [[28]], shield_emit_height = 33}, - wreckmodel = "cremcom2_dead.s3o", - }, - dynknight3 = { - level = 3, - mainstats = {health = 5200, objectname = "cremcom3.s3o", collisionvolumescales = [[55 60 55]],}, - customparams = {modelradius = [[30]], shield_emit_height = 36}, - wreckmodel = "cremcom3_dead.s3o", - }, - dynknight4 = { - level = 4, - mainstats = {health = 5800, objectname = "cremcom4.s3o", collisionvolumescales = [[60 65 60]],}, - customparams = {modelradius = [[33]], shield_emit_height = 37.5}, - wreckmodel = "cremcom4_dead.s3o", - }, - dynknight5 = { - level = 5, - mainstats = {health = 6400, objectname = "cremcom5.s3o", collisionvolumescales = [[65 70 65]],}, - customparams = {modelradius = [[35]], shield_emit_height = 39}, - wreckmodel = "cremcom5_dead.s3o", - }, - }, } +local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") + +for i = 1, #chassisAllDefs do + local chassisDef = chassisAllDefs[i].clonedefs + for key, value in pairs(chassisDef) do + copy[key]=value + end +end +--[=[ +VFS.Include("LuaRules/Utilities/wacky_utils.lua") +local utils=Spring.Utilities.wacky_utils +]=] for sourceName, copyTable in pairs(copy) do for cloneName, stats in pairs(copyTable) do -- some further modification @@ -409,10 +267,12 @@ for sourceName, copyTable in pairs(copy) do UnitDefs[cloneName].unitname = cloneName if stats.level > 0 then - + stats.nomainstats=stats.nomainstats or {} -- copy from by-level table for statName, value in pairs(statsByLevel.mainstats[stats.level]) do - UnitDefs[cloneName][statName] = value + if not stats.nomainstats[statName] then + UnitDefs[cloneName][statName] = value + end end --for statName, value in pairs(statsByLevel.customparams[stats.level]) do -- UnitDefs[cloneName].customparams[statName] = value @@ -427,12 +287,14 @@ for sourceName, copyTable in pairs(copy) do end UnitDefs[cloneName].trackwidth = UnitDefs[cloneName].trackwidth * (0.9 + 0.1*(stats.level)) -- features - UnitDefs[cloneName].featuredefs.dead.object = stats.wreckmodel - UnitDefs[cloneName].featuredefs.dead.footprintx = UnitDefs[cloneName].footprintx - UnitDefs[cloneName].featuredefs.dead.footprintz = UnitDefs[cloneName].footprintz - UnitDefs[cloneName].featuredefs.heap.object = stats.heapmodel - UnitDefs[cloneName].featuredefs.heap.footprintx = UnitDefs[cloneName].footprintx - UnitDefs[cloneName].featuredefs.heap.footprintz = UnitDefs[cloneName].footprintz + if UnitDefs[cloneName].featuredefs then + UnitDefs[cloneName].featuredefs.dead.object = stats.wreckmodel or UnitDefs[cloneName].featuredefs.dead.object + UnitDefs[cloneName].featuredefs.dead.footprintx = UnitDefs[cloneName].footprintx + UnitDefs[cloneName].featuredefs.dead.footprintz = UnitDefs[cloneName].footprintz + UnitDefs[cloneName].featuredefs.heap.object = stats.heapmodel or UnitDefs[cloneName].featuredefs.heap.object + UnitDefs[cloneName].featuredefs.heap.footprintx = UnitDefs[cloneName].footprintx + UnitDefs[cloneName].featuredefs.heap.footprintz = UnitDefs[cloneName].footprintz + end end UnitDefs[cloneName].customparams.level = stats.level diff --git a/gamedata/modularcomms/dyncomm_chassis_generator.lua b/gamedata/modularcomms/dyncomm_chassis_generator.lua index eee059fc67..c991f30f43 100644 --- a/gamedata/modularcomms/dyncomm_chassis_generator.lua +++ b/gamedata/modularcomms/dyncomm_chassis_generator.lua @@ -1,149 +1,14 @@ local chassisDefs = { - { - name = "dynstrike1", - weapons = { - "commweapon_peashooter", - "commweapon_missilelauncher", -- 415 - "commweapon_missilelauncher", -- 415 - "commweapon_beamlaser", - "commweapon_lparticlebeam", - "commweapon_shotgun", - "commweapon_shotgun_disrupt", - "commweapon_disruptor", - "commweapon_heavymachinegun", - "commweapon_heavymachinegun_disrupt", - "commweapon_lightninggun", - "commweapon_lightninggun_improved", - "commweapon_peashooter", - "commweapon_beamlaser", - "commweapon_lparticlebeam", - "commweapon_shotgun", - "commweapon_shotgun_disrupt", - "commweapon_disruptor", - "commweapon_heavymachinegun", - "commweapon_heavymachinegun_disrupt", - "commweapon_lightninggun", - "commweapon_lightninggun_improved", - "commweapon_multistunner", - "commweapon_multistunner_improved", - "commweapon_disruptorbomb", - "commweapon_disintegrator", - -- Space for shield - } - }, - { - name = "dynrecon1", - weapons = { - "commweapon_peashooter", - "commweapon_beamlaser", - "commweapon_lparticlebeam", - "commweapon_disruptor", - "commweapon_shotgun", - "commweapon_shotgun_disrupt", - "commweapon_lightninggun", - "commweapon_lightninggun_improved", - "commweapon_flamethrower", - "commweapon_heavymachinegun", - "commweapon_heavymachinegun_disrupt", - "commweapon_multistunner", - "commweapon_multistunner_improved", - "commweapon_napalmgrenade", - "commweapon_clusterbomb", - "commweapon_disruptorbomb", - "commweapon_concussion", - -- Space for shield - } - }, - { - name = "dynsupport1", - weapons = { - "commweapon_peashooter", - "commweapon_beamlaser", - "commweapon_shotgun", - "commweapon_shotgun_disrupt", - "commweapon_lparticlebeam", - "commweapon_disruptor", - "commweapon_hparticlebeam", - "commweapon_heavy_disruptor", - "commweapon_lightninggun", - "commweapon_lightninggun_improved", - "commweapon_missilelauncher", - "commweapon_shockrifle", - "commweapon_multistunner", - "commweapon_multistunner_improved", - "commweapon_disruptorbomb", - -- Space for shield - } - }, - { - name = "dynassault1", - weapons = { - "commweapon_peashooter", - "commweapon_rocketlauncher", -- 430 - "commweapon_rocketlauncher_napalm", -- 430 - "commweapon_rocketlauncher", -- 430 - "commweapon_rocketlauncher_napalm", -- 430 - "commweapon_beamlaser", - "commweapon_heatray", - "commweapon_heavymachinegun", - "commweapon_flamethrower", - "commweapon_riotcannon", - "commweapon_riotcannon_napalm", - "commweapon_peashooter", - "commweapon_beamlaser", - "commweapon_heatray", - "commweapon_heavymachinegun", - "commweapon_flamethrower", - "commweapon_riotcannon", - "commweapon_riotcannon_napalm", - "commweapon_hpartillery", - "commweapon_hpartillery_napalm", - "commweapon_disintegrator", - "commweapon_napalmgrenade", - "commweapon_slamrocket", - "commweapon_clusterbomb", - -- Space for shield - } - }, - { - name = "dynknight1", - weapons = { - -- Aiming from earlier weapons is overridden by later - "commweapon_peashooter", - "commweapon_rocketlauncher", -- 430 - "commweapon_rocketlauncher_napalm", -- 430 - "commweapon_missilelauncher", -- 415 - "commweapon_hparticlebeam", -- 390 - "commweapon_beamlaser", -- 330 - "commweapon_lightninggun", -- 300 - "commweapon_lightninggun_improved", -- 300 - "commweapon_lparticlebeam", -- 300 - "commweapon_riotcannon", -- 300 - "commweapon_riotcannon_napalm", -- 300 - "commweapon_disruptor", -- 300 - "commweapon_heatray", -- 300 - "commweapon_shotgun", -- 290 - "commweapon_shotgun_disrupt", -- 290 - "commweapon_heavymachinegun", -- 285 - "commweapon_heavymachinegun_disrupt", -- 285 - "commweapon_flamethrower", -- 270 - "commweapon_multistunner", - "commweapon_multistunner_improved", - "commweapon_peashooter", - "commweapon_hpartillery", - "commweapon_hpartillery_napalm", - "commweapon_disintegrator", - "commweapon_napalmgrenade", - "commweapon_slamrocket", - "commweapon_disruptorbomb", - "commweapon_concussion", - "commweapon_clusterbomb", - "commweapon_shockrifle", - -- Space for shield - } - }, + } +local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") + +for i = 1, #chassisAllDefs do + local chassisDef = chassisAllDefs[i].dyncomm_chassis_generator + chassisDefs[#chassisDefs+1]=chassisDef +end + local commanderCost = 1100 local statOverrides = { @@ -160,27 +25,31 @@ local statOverrides = { for i = 1, #chassisDefs do local name = chassisDefs[i].name local unitDef = UnitDefs[name] - - for wreckName, wreckDef in pairs(unitDef.featuredefs) do - wreckDef.metal = commanderCost * (wreckName == "heap" and 0.2 or 0.4) - wreckDef.reclaimtime = wreckDef.metal - end - - for key, data in pairs(statOverrides) do - unitDef[key] = data - end - - for j = 1, 7 do - unitDef.sfxtypes.explosiongenerators[j] = unitDef.sfxtypes.explosiongenerators[j] or [[custom:NONE]] + if unitDef then + for wreckName, wreckDef in pairs(unitDef.featuredefs or {}) do + wreckDef.metal = commanderCost * (wreckName == "heap" and 0.2 or 0.4) + wreckDef.reclaimtime = wreckDef.metal + end + + for key, data in pairs(statOverrides) do + unitDef[key] = data + end + + for j = 1, 7 do + unitDef.sfxtypes.explosiongenerators[j] = unitDef.sfxtypes.explosiongenerators[j] or [[custom:NONE]] + end + + for num = 1, #chassisDefs[i].weapons do + local weaponName = chassisDefs[i].weapons[num] + DynamicApplyWeapon(unitDef, weaponName, num) + end + + if #chassisDefs[i].weapons > 31 then + -- Limit of 31 for shield space. + Spring.Echo("Too many commander weapons on:", name, "Limit is 31, found weapons:", #chassisDefs[i].weapons) + end + else + Spring.Log("gamedata/modularcomms/dyncomm_chassis_generator.lua","error","UnitDef " .. name .. " Not Found") end - for num = 1, #chassisDefs[i].weapons do - local weaponName = chassisDefs[i].weapons[num] - DynamicApplyWeapon(unitDef, weaponName, num) - end - - if #chassisDefs[i].weapons > 31 then - -- Limit of 31 for shield space. - Spring.Echo("Too many commander weapons on:", name, "Limit is 31, found weapons:", #chassisDefs[i].weapons) - end end diff --git a/gamedata/modularcomms/dyncomms_predefined.lua b/gamedata/modularcomms/dyncomms_predefined.lua index 05fd7eeb52..dcd742f0e1 100644 --- a/gamedata/modularcomms/dyncomms_predefined.lua +++ b/gamedata/modularcomms/dyncomms_predefined.lua @@ -1,55 +1,8 @@ local ret = { - dyntrainer_strike = { - name = "Strike", - chassis = "strike", - modules = { - {"commweapon_heavymachinegun", "module_radarnet"}, - {"module_ablative_armor", "module_autorepair"}, - {"commweapon_lightninggun", "module_personal_cloak", "module_ablative_armor"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - }, - --decorations = {"banner_overhead"}, - --images = {overhead = "184"} - }, - dyntrainer_recon = { - name = "Recon", - chassis = "recon", - modules = { - {"commweapon_heavymachinegun", "module_radarnet"}, - {"module_ablative_armor", "module_autorepair"}, - {"commweapon_clusterbomb", "commweapon_personal_shield", "module_ablative_armor"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - }, - --decorations = {"skin_recon_dark", "banner_overhead"}, - --images = {overhead = "184"} - }, - dyntrainer_support = { - name = "Engineer", - chassis = "support", - modules = { - {"commweapon_lparticlebeam", "module_radarnet"}, - {"module_ablative_armor", "module_autorepair"}, - {"commweapon_hparticlebeam", "module_personal_cloak", "module_adv_nano"}, - {"module_dmg_booster", "module_adv_targeting", "module_adv_targeting"}, - {"module_adv_targeting", "module_adv_nano", "module_resurrect"}, - }, - --decorations = {"skin_support_hotrod"}, - }, - dyntrainer_assault = { - name = "Guardian", - chassis = "assault", - modules = { - {"commweapon_heavymachinegun", "module_radarnet"}, - {"module_ablative_armor", "module_autorepair"}, - {"commweapon_shotgun", "commweapon_personal_shield", "module_heavy_armor"}, - {"module_dmg_booster", "module_dmg_booster", "module_heavy_armor"}, - {"conversion_disruptor","module_dmg_booster", "module_heavy_armor"}, - }, - --decorations = {"banner_overhead"}, - --images = {overhead = "166"} - }, + + + + dynhub_strike = { name = "Strike Support", notStarter = true, @@ -195,19 +148,15 @@ local ret = { }, } -if Spring.GetModOptions and Spring.GetModOptions().campaign_chassis == "1" then - ret.dyntrainer_knight = { - name = "Campaign", - chassis = "knight", +local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") - modules = { -- all null because nabs want to personalize - {"nullbasicweapon", "nullmodule"}, - {"nullmodule", "nullmodule"}, - {"nulladvweapon", "nullmodule", "nullmodule"}, - {"nullmodule", "nullmodule", "nullmodule"}, - {"nullmodule", "nullmodule", "nullmodule"}, - }, - } +for i = 1, #chassisAllDefs do + local chassisDef = chassisAllDefs[i].dyncomms_predefined + for key, value in pairs(chassisDef) do + ret[key]=value + end end + + return ret diff --git a/gamedata/modularcomms/functions.lua b/gamedata/modularcomms/functions.lua index 49d82adae4..0d8738fd63 100644 --- a/gamedata/modularcomms/functions.lua +++ b/gamedata/modularcomms/functions.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: lowercase-global function lowerkeys(t) local tn = {} for i,v in pairs(t) do @@ -60,6 +61,7 @@ function ApplyWeapon(unitDef, weapon, replace, forceslot) local slot = tonumber(wcp.slot) or 5 local isDgun = (tonumber(wcp.slot) == 3) local altslot = tonumber(wcp.altslot or 3) + ---@cast altslot number local dualwield = false if (not isDgun) and unitDef.customparams.alreadyhasweapon and not replace then -- dual wield @@ -148,7 +150,7 @@ function ModifyWeaponDamage(unitDef, factor, includeCustomParams) if unitDef.customparams.dynamic_comm then -- Fix the format (FIXME: use v.name all along) for i,v in pairs(unitDef.weapons) do - v.name = v.def + v.name = v.name or v.def v.def = nil end else diff --git a/gamedata/modularcomms/moduledefs.lua b/gamedata/modularcomms/moduledefs.lua index 571decebf5..db07d19b44 100644 --- a/gamedata/modularcomms/moduledefs.lua +++ b/gamedata/modularcomms/moduledefs.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: lowercase-global -------------------------------------------------------------------------------- -- system functions -------------------------------------------------------------------------------- @@ -755,6 +756,27 @@ upgrades = { } } +include = include or VFS.Include + +local modulesdefs=include("gamedata/modularcomms/modules_all_defs.lua") + +for i = 1, #modulesdefs do + local moduleDefs = modulesdefs[i].moduledef + for key, value in pairs(moduleDefs) do + upgrades[key]=value + end +end + +--[=[ +local moduleFiles=VFS.DirList("gamedata/modularcomms/modules_moduledefs", "*.lua") or {} + +for i = 1, #moduleFiles do + local moduleDefs = VFS.Include(moduleFiles[i]) + for key, value in pairs(moduleDefs) do + upgrades[key]=value + end +end +]=] decorations = { skin_recon_dark = { func = function(unitDef) diff --git a/gamedata/modularcomms/modules/all_vanilla_modules.lua b/gamedata/modularcomms/modules/all_vanilla_modules.lua new file mode 100644 index 0000000000..44545f2ebd --- /dev/null +++ b/gamedata/modularcomms/modules/all_vanilla_modules.lua @@ -0,0 +1,1491 @@ +local MergeTable=Spring.Utilities.MergeTable +return{ + moduledef={ + -- weapons + -- note that context menu CRASHES if you don't put them here! + + commweapon_peashooter = { + name = "Peashooter", + description = "Basic self-defence weapon", + }, + + commweapon_assaultcannon = { + name = "Assault Cannon", + description = "Conventional plasma cannon with decent range", + }, + commweapon_beamlaser = { + name = "Beam Laser", + description = "An effective short-range cutting tool", + }, + commweapon_flamethrower = { + name = "Flamethrower", + description = "Perfect for well-done barbecues", + }, + commweapon_gaussrifle = { + name = "Gauss Rifle", + description = "Precise armor-piercing weapon", + }, + commweapon_heavymachinegun = { + name = "Heavy Machine Gun", + description = "Close-in automatic weapon with AoE", + }, + commweapon_heatray = { + name = "Heat Ray", + description = "Rapidly melts anything at short range; loses damage over distance", + }, + commweapon_lightninggun = { + name = "Lightning Gun", + description = "Paralyzes and damages annoying bugs", + }, + commweapon_lparticlebeam = { + name = "Light Particle Beam", + description = "Fires rapid medium-range pulses", + }, + commweapon_hparticlebeam = { + name = "Heavy Particle Beam", + description = "Ranged high-energy pulse weapon", + }, + commweapon_massdriver = { + name = "Mass Driver", + description = "High-velocity hunting rifle", + }, + commweapon_missilelauncher = { + name = "Missile Launcher", + description = "Fires light seeker missiles with good range", + }, + commweapon_partillery = { + name = "Plasma Artillery", + description = "Long-range artillery gun", + }, + commweapon_riotcannon = { + name = "Riot Cannon", + description = "The weapon of choice for crowd control", + }, + commweapon_rocketlauncher = { + name = "Rocket Launcher", + description = "Medium-range low-velocity hitter", + }, + commweapon_shotgun = { + name = "Shotgun", + description = "Can hammer a single large target or shred many small ones", + }, + commweapon_shotlaser = { + name = "Laser shotgun", + description = "Shotgun but shoots nerd-ass lasers instead of GLOWING HOT BALLS OF STEEL", + }, + commweapon_slowbeam = { + name = "Slowing Beam", + description = "Slows an enemy's movement and firing rate; non-lethal", + }, + commweapon_sonicgun = { + name = "Sonic Blaster", + description = "Short-range weapon that works when dry or wet", + }, + commweapon_torpedo = { + name = "Torpedo", + description = "Fires a torpedo effective against waterborne targets", + }, + + -- dguns + commweapon_concussion = { + name = "Concussion Shot", + description = "Extended range weapon with AoE and impulse", + }, + commweapon_clusterbomb = { + name = "Cluster Bomb", + description = "Hammers multiple units in a wide line", + }, + commweapon_disintegrator = { + name = "Disintegrator Gun", + description = "Short-range weapon that vaporizes anything in its path", + }, + commweapon_disruptorbomb = { + name = "Disruptor Bomb", + description = "Damages and slows units in a large area", + }, + commweapon_multistunner = { + name = "Multi-Stunner", + description = "Briefly disables multiple targets in an area", + }, + commweapon_napalmgrenade = { + name = "Hellfire Grenade", + description = "Sets a moderate area ablaze", + }, + commweapon_slamrocket = { + name = "S.L.A.M.", + description = "Long-range weapon with a lethal punch", + }, + commweapon_sunburst = { + name = "Sunburst Cannon", + description = "Ruins a single target's day with a medium-range high-energy burst", + }, + + -- conversion kits + conversion_disruptor = { + name = "Disruptor Beam", + description = "Slow Beam: +33% reload time, +250 real damage", + func = function(unitDef) + ReplaceWeapon(unitDef, "commweapon_slowbeam", "commweapon_disruptor") + end, + }, + conversion_shockrifle = { + name = "Shock Rifle", + description = "Light Particle Beam: Convert to a long-range sniper rifle", + func = function(unitDef) + ReplaceWeapon(unitDef, "commweapon_lparticlebeam", "commweapon_shockrifle") + end, + }, + conversion_partillery = { + name = "Plasma Artillery", + description = "Assault Cannon: Convert to a light artillery gun", + func = function(unitDef) + ReplaceWeapon(unitDef, "commweapon_assaultcannon", "commweapon_partillery") + --unitDef.hightrajectory = 1 + end, + }, + conversion_hparticlebeam = { + name = "Heavy Particle Beam", + description = "Light Particle Beam: Convert to an extended range rifle weapon", + func = function(unitDef) + ReplaceWeapon(unitDef, "commweapon_lparticlebeam", "commweapon_hparticlebeam") + end, + }, + + -- weapon mods + weaponmod_antiair = { + name = "Anti-Air Kit", + description = "Beam Laser/Riot Cannon/Missile Launcher: Convert to anti-air weapons", + func = function(unitDef) + for i,v in pairs(weapons) do + local id = v.customparams.idstring + if (id == "commweapon_riotcannon") then + ReplaceWeapon(unitDef, "commweapon_riotcannon", "commweapon_flakcannon") + ReplaceWeapon(unitDef, "commweapon_riotcannon", "commweapon_flakcannon") + elseif (id == "commweapon_beamlaser") then + ReplaceWeapon(unitDef, "commweapon_beamlaser", "commweapon_aalaser") + ReplaceWeapon(unitDef, "commweapon_beamlaser", "commweapon_aalaser") + elseif (id == "commweapon_missilelauncher") then + ReplaceWeapon(unitDef, "commweapon_missilelauncher", "commweapon_aamissile") + ReplaceWeapon(unitDef, "commweapon_missilelauncher", "commweapon_aamissile") + end + end + end + }, + weaponmod_autoflechette = { + name = "Autoflechette", + description = "Shotgun: -25% projectiles, -40% reload time", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + if v.customparams.idstring == "commweapon_shotgun" then + v.customparams.misceffect = nil + v.projectiles = v.projectiles * 0.75 + v.reloadtime = v.reloadtime * 0.6 + --break + end + end + end, + }, + weaponmod_disruptor_ammo = { + name = "Disruptor Ammo", + description = "Shotgun/Heavy Machine Gun/Shock Rifle: +40% slow damage", + func = function(unitDef) + local permitted = { + commweapon_shotgun = true, + commweapon_gaussrifle = true, + commweapon_heavymachinegun = true, + commweapon_shockrifle = true, + } + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + local wcp = v.customparams + local id = wcp.idstring + if permitted[id] then + wcp.timeslow_damagefactor = "0.4" + v.rgbcolor = [[0.9 0.1 0.9]] + if id == "commweapon_shotgun" or id == "commweapon_heavymachinegun" then + v.explosiongenerator = [[custom:BEAMWEAPON_HIT_PURPLE]] + elseif id == "commweapon_gaussrifle" then + v.explosiongenerator = [[custom:GAUSS_HIT_M_PURPLE]] + end -- no visual effect on shock rifle + if i == "commweapon_shotgun_green" or i == "commweapon_heavymachinegun_lime" then + v.rgbcolor = "0 1 0.7" + v.explosiongenerator = [[custom:BEAMWEAPON_HIT_TURQUOISE]] + end + end + end + end, + }, + weaponmod_high_frequency_beam = { + name = "High Frequency Beam", + description = " +15% damage and range to Beam Laser/Slow Beam/Disruptor Beam/Light Particle Beam/Heavy Particle Beam", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + local permitted = { + commweapon_beamlaser = true, + commweapon_slowbeam = true, + commweapon_disruptor = true, + commweapon_lparticlebeam = true, + commweapon_hparticlebeam = true, + } + for i,v in pairs(weapons) do + if permitted[v.customparams.idstring] then + v.range = v.range * 1.15 + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 1.15 + end + end + end + end, + }, + weaponmod_railaccel = { + name = "Rail Accelerator", + description = "Gauss Rifle: +10% damage, +20% range", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + local id = v.customparams.idstring + if id == "commweapon_gaussrifle" or id == "commweapon_massdriver" then + v.range = v.range * 1.2 + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 1.1 + end + end + end + end, + }, + weaponmod_high_caliber_barrel = { + name = "High Caliber Barrel", + description = "Shotgun/Riot Cannon/Assault Cannon/Plasma Artillery: +150% damage, +100% reload time", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + local permitted = { + commweapon_assaultcannon = true, + commweapon_shotgun = true, + commweapon_gaussrifle = true, + commweapon_partillery = true, + commweapon_partillery_napalm = true, + commweapon_riotcannon = true, + } + for i,v in pairs(weapons) do + local id = v.customparams.idstring + if permitted[id] then + if not (id == "commweapon_partillery" or id == "commweapon_partillery_napalm") then + v.reloadtime = v.reloadtime * 2 + v.customparams.highcaliber = true + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 2.5 + end + else + ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_hpartillery") + ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_hpartillery") + ReplaceWeapon(unitDef, "commweapon_partillery_napalm", "commweapon_hpartillery_napalm") + ReplaceWeapon(unitDef, "commweapon_partillery_napalm", "commweapon_hpartillery_napalm") + end + end + end + end, + }, + weaponmod_standoff_rocket = { + name = "Standoff Rocket", + description = "Rocket/Missile Launcher: +50% range, +25% damage, +50% reload time", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + local id = v.customparams.idstring + if id == "commweapon_rocketlauncher" then + v.range = v.range * 1.5 + v.reloadtime = v.reloadtime * 1.5 + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 1.25 + end + v.model = [[wep_m_dragonsfang.s3o]] + v.soundhitvolume = 8 + v.soundstart = [[weapon/missile/missile2_fire_bass]] + v.soundstartvolume = 7 + --break + elseif id == "commweapon_missilelauncher" then + v.range = v.range * 1.5 + v.reloadtime = v.reloadtime * 1.5 + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 1.25 + end + v.model = [[wep_m_phoenix.s3o]] + v.soundhitvolume = 5 + v.soundstart = [[weapon/missile/missile_fire7]] + v.soundstartvolume = 3 + end + end + end, + }, + weaponmod_stun_booster = { + name = "Flux Amplifier", + description = "Lightning Gun: +25% paralyze damage, +2s paralyzetime", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + if v.customparams.idstring == "commweapon_lightninggun" then + v.customparams.extra_damage = v.customparams.extra_damage * 1.25 + v.paralyzetime = v.paralyzetime + 2 + end + end + end, + }, + weaponmod_napalm_warhead = { + name = "Napalm Warhead", + description = "Riot Cannon/Plasma Artillery/Rocket Launcher: Reduced direct damage, sets target on fire", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + local permitted = { + commweapon_partillery = true, + commweapon_hpartillery = true, + commweapon_rocketlauncher = true, + commweapon_riotcannon = true, + } + for i,v in pairs(weapons) do + local id = v.customparams.idstring + if permitted[id] then + if (id == "commweapon_riotcannon") then -- -20% damage + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 0.8 + end + v.customparams.burntime = "420" + v.rgbcolor = [[1 0.3 0.1]] + elseif (id == "commweapon_hpartillery") then -- -90% damage, 256 AoE, firewalker effect + ReplaceWeapon(unitDef, "commweapon_hpartillery", "commweapon_hpartillery_napalm") + ReplaceWeapon(unitDef, "commweapon_hpartillery", "commweapon_hpartillery_napalm") + elseif (id == "commweapon_partillery") then -- -25% damage, 128 AoE + ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_partillery_napalm") + ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_partillery_napalm") + else -- -25% damage, 128 AoE + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 0.75 + end + v.customparams.burntime = "450" + v.areaofeffect = 128 + end + + if (id == "commweapon_riotcannon") or (id == "commweapon_rocketlauncher") then + v.explosiongenerator = [[custom:napalm_koda]] + v.customparams.burnchance = "1" + v.soundhit = [[weapon/burn_mixed]] + end + v.customparams.setunitsonfire = "1" + end + end + end, + }, + weaponmod_flame_enhancer = { + name = "Long-Burn Napalm", + description = "Flamethrower/Napalm Warhead: +40% on-fire time", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + if v.customparams.burntime then + v.customparams.burntime = v.customparams.burntime * 1.4 + end + if v.customparams.idstring == "commweapon_hpartillery_napalm" then + v.customparams.area_damage_duration = v.customparams.area_damage_duration * 1.4 + v.explosiongenerator = "custom:napalm_firewalker_long" + end + end + end, + order = 3.1, + }, + weaponmod_plasma_containment = { + name = "Plasma Containment Field", + description = "Heat Ray/Riot Cannon: +30% range", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + local id = v.customparams.idstring + if id == "commweapon_heatray" then + v.range = v.range * 1.3 + elseif id == "commweapon_riotcannon" then + v.range = v.range * 1.3 + end + end + end, + }, + + -- modules + module_ablative_armor = { + name = "Ablative Armor Plates", + description = "Adds 600 HP", + func = function(unitDef) + unitDef.health = unitDef.health + 600 + end, + }, + module_adv_targeting = { + name = "Advanced Targeting System", + description = "Extends range of all weapons by 10%", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + v.customparams.rangemod = v.customparams.rangemod + 0.1 + end + end, + }, + module_adv_nano = { + name = "CarRepairer's Nanolathe", + description = "Adds +5 metal/s build speed", + func = function(unitDef) + if unitDef.workertime then unitDef.workertime = unitDef.workertime + 5 end + --if unitDef.builddistance then unitDef.builddistance = unitDef.builddistance + 60 end + end, + }, + module_autorepair = { + name = "Autorepair System", + description = "Self-repairs 10 HP/s", + func = function(unitDef) + unitDef.autoheal = (unitDef.autoheal or 0) + 10 + end, + }, + module_companion_drone = { + name = "Companion Drone", + description = "Spawns a pair of attack drones", + func = function(unitDef) + unitDef.customparams.drones = unitDef.customparams.drones or {} + unitDef.customparams.drones[#unitDef.customparams.drones+1] = "module_companion_drone" + end, + }, + module_battle_drone = { + name = "Battle Drone", + description = "Spawns an advanced combat drone", + func = function(unitDef) + unitDef.customparams.drones = unitDef.customparams.drones or {} + unitDef.customparams.drones[#unitDef.customparams.drones+1] = "module_battle_drone" + end, + }, + module_dmg_booster = { + name = "Damage Booster", + description = "Increases damage of all weapons by 10%", + func = function(unitDef) + if unitDef.customparams.dynamic_comm then + -- Weapondefs are static + unitDef.customparams.damagemod = (unitDef.customparams.damagemod or 0) + 1 + else + -- Weapondefs stored in unitdef + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + v.customparams.damagemod = (v.customparams.damagemod or 0) + 0.1 + end + end + end, + }, + module_burst_loader = { + name = "Burst Loader", + description = "+1 burst, +70% reload time", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + local id = v.customparams.idstring + -- linear rather than exponential increase with stacking + v.reloadtime = v.reloadtime or 1 + local previousCount = v.customparams.burstloaders or 0 + local baseReload = v.reloadtime / (1 + 0.7*previousCount) + if id == "commweapon_beamlaser" or id == "commweapon_disruptor" or id == "commweapon_slowbeam" then + -- v.beamtime = v.beamtime + 10 -- beamlaser has 0.1, it's in seconds + v.corethickness = v.corethickness + v.corethickness/(previousCount + 1) + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg + dmg/(previousCount + 1) + end + elseif id == "commweapon_shotgun" then + v.burst = (v.burst or 1) + 3 + v.sprayangle = (v.sprayangle or 0) + 256 + v.reloadtime = v.reloadtime + baseReload * 0.7 + else + v.burstrate = (v.burstrate or 0.1 ) + v.reloadtime = v.reloadtime + baseReload * 0.7 + v.burst = (v.burst or 1) + 1 + v.sprayangle = (v.sprayangle or 0) + 256 + end + v.customparams.burstloaders = previousCount + 1 + end + end, + }, + module_energy_cell = { + name = "Energy Cell", + description = "Compact fuel cells that produce +6 energy", + func = function(unitDef) + unitDef.energymake = (unitDef.energymake or 0) + 6 + end, + }, + module_fieldradar = { + name = "Field Radar Module", + description = "Basic radar system with 1800 range", + func = function(unitDef) + unitDef.radardistance = (unitDef.radardistance or 0) + if unitDef.radardistance < 1800 then + unitDef.radardistance = 1800 + end + if (not unitDef.radaremitheight) or unitDef.radaremitheight < 100 then + unitDef.radaremitheight = 24 + end + end, + }, + module_heavy_armor = { + name = "High Density Plating", + description = "Adds 1600 HP, slows comm by +10%", + func = function(unitDef, attributeMods) + unitDef.health = unitDef.health + 1600 + attributeMods.speed = attributeMods.speed - 0.1 + end, + }, + module_high_power_servos = { + name = "High Power Servos", + description = "More powerful leg actuators increase speed by 10% of base", + func = function(unitDef, attributeMods) + attributeMods.speed = attributeMods.speed + 0.1 + end, + }, + module_personal_cloak = { + name = "Personal Cloak", + description = "Cloaks the commander", + func = function(unitDef) + unitDef.cancloak = true + unitDef.cloakcost = unitDef.cloakcost or 5 + unitDef.mincloakdistance = math.max(150, unitDef.mincloakdistance or 0) + if unitDef.cloakcost > 5 then + unitDef.cloakcost = 5 + end + unitDef.cloakcostmoving = unitDef.cloakcostmoving or 10 + if unitDef.cloakcostmoving > 10 then + unitDef.cloakcostmoving = 10 + end + end, + }, + module_personal_shield = { + name = "Personal Shield", + order = 5, + description = "Generates a small bubble shield", + func = function(unitDef) + if unitDef.customparams.dynamic_comm then + DynamicApplyWeapon(unitDef, "commweapon_personal_shield", #unitDef.weapons + 1) + else + ApplyWeapon(unitDef, "commweapon_personal_shield", 4) + end + end, + }, + + module_resurrect = { + name = "Lazarus Device", + description = "Enables resurrection of wrecks", + func = function(unitDef) + unitDef.canresurrect = true + end, + }, + + module_jumpjet = { + name = "Jumpjet", + description = "Allows the commander to jump", + func = function(unitDef) + unitDef.customparams.canjump = 1 + unitDef.customparams.jump_range = 400 + unitDef.customparams.jump_speed = 6 + unitDef.customparams.jump_reload = 20 + unitDef.customparams.jump_from_midair = 1 + end, + }, + + module_areashield = { + name = "Area Shield", + order = 6, + description = "A bubble shield that protects surrounding units within 350 m", + func = function(unitDef) + --ApplyWeapon(unitDef, "commweapon_areashield", 2) + + if unitDef.customparams.dynamic_comm then + DynamicApplyWeapon(unitDef, "commweapon_areashield", #unitDef.weapons) -- not +1 so as to replace personal + else + ReplaceWeapon(unitDef, "commweapon_personal_shield", "commweapon_areashield") + end + + unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} + table.insert(unitDef.customparams.lups_unit_fxs, "commAreaShield") + end, + }, + module_cloak_field = { + name = "Cloaking Field", + description = "Cloaks all friendly units within 350 m", + func = function(unitDef) + unitDef.mincloakdistance = math.max(150, unitDef.mincloakdistance or 0) + unitDef.onoffable = true + unitDef.radarDistanceJam = (unitDef.radarDistanceJam and unitDef.radarDistanceJam > 350 and unitDef.radarDistanceJam) or 350 + unitDef.customparams.area_cloak = "1" + unitDef.customparams.area_cloak_upkeep = "15" + unitDef.customparams.area_cloak_radius = "350" + unitDef.customparams.area_cloak_decloak_distance = "75" + end, + }, + module_jammer = { + name = "Radar Jammer", + description = "Masks radar signals of all units within 500 m", + func = function(unitDef) + unitDef.radardistancejam = 500 + unitDef.activatewhenbuilt = true + unitDef.onoffable = true + end, + }, + + module_jump_booster = { + name = "Dragonfly Booster", + description = "Increases jump range and height", + func = function(unitDef) + unitDef.customparams.jumpclass = "commrecon2" + end, + }, + + module_radarnet = { + name = "Integrated Radar Network", + description = "Reduces radar wobble for all units", + func = function(unitDef) + unitDef.isTargetingUpgrade = true + unitDef.activatewhenbuilt = true + end, + }, + + module_ultralight_hull = { + name = "Ultralight Hull", + description = "-1200 HP, +25% speed", + func = function(unitDef, attributeMods) + unitDef.health = unitDef.health - 1200 + attributeMods.speed = attributeMods.speed + 0.25 + end, + }, + module_weapon_hicharge = { + name = "Weapon Hi-Charger", + description = "-1000 HP, +40% damage", + func = function(unitDef, attributeMods) + unitDef.health = unitDef.health - 1000 + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + v.customparams.damagemod = v.customparams.damagemod + 0.4 + end + end, + }, + -- modules that use a weapon slot + module_guardian_armor = { + name = "Guardian Defence System", + description = "Adds 100% HP (including other modules); self-repairs 20 HP/s", + func = function(unitDef, attributeMods) + attributeMods.health = attributeMods.health + 1 + unitDef.autoheal = (unitDef.autoheal or 0) + 20 + end, + useWeaponSlot = true, + }, + + module_superspeed = { + name = "Marathon Motion Control", + description = "Increases speed by 50% of base", + func = function(unitDef, attributeMods) + attributeMods.speed = attributeMods.speed + 0.5 + end, + useWeaponSlot = true, + }, + + module_longshot = { + name = "Longshot Fire Control", + description = "Extends range of all weapons by 40%", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + for i,v in pairs(weapons) do + v.customparams.rangemod = v.customparams.rangemod + 0.4 + end + end, + useWeaponSlot = true, + }, + + module_super_nano = { + name = "Engineer's Revenge", + description = "Adds 20 metal/s build speed and 200 build range", + func = function(unitDef) + if unitDef.workertime then unitDef.workertime = unitDef.workertime + 20 end + if unitDef.builddistance then unitDef.builddistance = unitDef.builddistance + 200 end + end, + useWeaponSlot = true, + }, + + -- deprecated + module_improved_optics = { + name = "Improved Optics", + description = "Increases sight distance by 100 m", + func = function(unitDef) + unitDef.sightdistance = unitDef.sightdistance + 100 + end, + }, + module_repair_field = { + name = "Repair Field", + description = "Passively repairs all friendly units within 450 m", + func = function(unitDef) + unitDef.customparams.repairaura_preset = "module_repairfield" + end, + }, + + -- secret stuff! + module_econ = { + name = "Economy Package", + description = "Produces +2 energy and metal", + func = function(unitDef) + unitDef.energymake = (unitDef.energymake or 0) + 2 + unitDef.metalmake = (unitDef.metalmake or 0) + 2 + end, + }, + + conversion_lazor = { + name = "Uberlazor", + description = "LOLOLOL", + func = function(unitDef) + ReplaceWeapon(unitDef, "commweapon_beamlaser", "commweapon_hparticlebeam") + end, + } + }, + dynamic_comm_def=function (shared) + + local HP_MULT=shared.HP_MULT + local COST_MULT=shared.COST_MULT + local moduleImagePath=shared.moduleImagePath + local moduleDefNamesToIDs=shared.moduleDefNamesToIDs + local disableResurrect=shared.disableResurrect + local basicChassis={"recon", "strike", "assault", "support", "knight"} + local moduleDefs = { + -- Empty Module Slots + { + name = "nullmodule", + humanName = "No Module", + description = "No Module", + image = "LuaUI/Images/dynamic_comm_menu/cross.png", + limit = false, + emptyModule = true, + cost = 0, + requireLevel = 0, + slotType = "module", + hardcodedID=1, + }, + { + name = "nullbasicweapon", + humanName = "No Weapon", + description = "No Weapon", + image = "LuaUI/Images/dynamic_comm_menu/cross.png", + limit = false, + emptyModule = true, + requireChassis = {"knight"}, + cost = 0, + requireLevel = 0, + slotType = "basic_weapon", + hardcodedID=2, + }, + { + name = "nulladvweapon", + humanName = "No Weapon", + description = "No Weapon", + image = "LuaUI/Images/dynamic_comm_menu/cross.png", + limit = false, + emptyModule = true, + cost = 0 * COST_MULT, + requireLevel = 0, + slotType = "adv_weapon", + hardcodedID=3, + }, + { + name = "nulldualbasicweapon", + humanName = "No Weapon", + description = "No Weapon", + image = "LuaUI/Images/dynamic_comm_menu/cross.png", + limit = false, + emptyModule = true, + cost = 0 * COST_MULT, + requireLevel = 0, + slotType = "dual_basic_weapon", + hardcodedID=4, + }, + + -- Weapons + + + + --{ + -- name = "commweapon_hpartillery", + -- humanName = "Plasma Artillery", + -- description = "Plasma Artillery", + -- image = moduleImagePath .. "commweapon_assaultcannon.png", + -- limit = 2, + -- cost = 300 * COST_MULT, + -- requireChassis = {"assault"}, + -- requireLevel = 3, + -- slotType = "adv_weapon", + -- applicationFunction = function (modules, sharedData) + -- if sharedData.noMoreWeapons then + -- return + -- end + -- local weaponName = (modules[moduleDefNames.weaponmod_napalm_warhead] and "commweapon_hpartillery_napalm") or "commweapon_hpartillery" + -- if not sharedData.weapon1 then + -- sharedData.weapon1 = weaponName + -- else + -- sharedData.weapon2 = weaponName + -- end + -- end + --}, + + + + + + + { + name = "commweapon_hparticlebeam", + humanName = "Heavy Particle Beam", + description = "Heavy Particle Beam - Replaces other weapons. Short range, high-power beam weapon with moderate reload time", + image = moduleImagePath .. "conversion_hparticlebeam.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = {"support", "knight"}, + requireLevel = 1, + slotType = "adv_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + local weaponName = (modules[moduleDefNamesToIDs.conversion_disruptor[1]] and "commweapon_heavy_disruptor") or "commweapon_hparticlebeam" + sharedData.weapon1 = weaponName + sharedData.weapon2 = nil + sharedData.noMoreWeapons = true + end, + hardcodedID=15 + }, + { + name = "commweapon_shockrifle", + humanName = "Shock Rifle", + description = "Shock Rifle - Replaces other weapons. Long range sniper rifle", + image = moduleImagePath .. "conversion_shockrifle.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = {"support", "knight"}, + requireLevel = 1, + slotType = "adv_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + sharedData.weapon1 = "commweapon_shockrifle" + sharedData.weapon2 = nil + sharedData.noMoreWeapons = true + end, + hardcodedID=16 + }, + { + name = "commweapon_clusterbomb", + humanName = "Cluster Bomb", + description = "Cluster Bomb - Manually fired burst of bombs.", + image = moduleImagePath .. "commweapon_clusterbomb.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = {"recon", "assault", "knight"}, + requireLevel = 3, + slotType = "adv_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + if not sharedData.weapon1 then + sharedData.weapon1 = "commweapon_clusterbomb" + else + sharedData.weapon2 = "commweapon_clusterbomb" + end + end, + hardcodedID=17 + }, + { + name = "commweapon_concussion", + humanName = "Concussion Shell", + description = "Concussion Shell - Manually fired high impulse projectile.", + image = moduleImagePath .. "commweapon_concussion.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = {"recon", "knight"}, + requireLevel = 3, + slotType = "adv_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + if not sharedData.weapon1 then + sharedData.weapon1 = "commweapon_concussion" + else + sharedData.weapon2 = "commweapon_concussion" + end + end, + hardcodedID=18 + }, + { + name = "commweapon_disintegrator", + humanName = "Disintegrator", + description = "Disintegrator - Manually fired weapon that destroys almost everything it touches.", + image = moduleImagePath .. "commweapon_disintegrator.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = {"assault", "strike", "knight"}, + requireLevel = 3, + slotType = "adv_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + if not sharedData.weapon1 then + sharedData.weapon1 = "commweapon_disintegrator" + else + sharedData.weapon2 = "commweapon_disintegrator" + end + end, + hardcodedID=19 + }, + { + name = "commweapon_disruptorbomb", + humanName = "Disruptor Bomb", + description = "Disruptor Bomb - Manually fired bomb that slows enemies in a large area.", + image = moduleImagePath .. "commweapon_disruptorbomb.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = {"recon", "support", "strike", "knight"}, + requireLevel = 3, + slotType = "adv_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + if not sharedData.weapon1 then + sharedData.weapon1 = "commweapon_disruptorbomb" + else + sharedData.weapon2 = "commweapon_disruptorbomb" + end + end, + hardcodedID=20 + }, + { + name = "commweapon_multistunner", + humanName = "Multistunner", + description = "Multistunner - Manually fired sustained burst of lightning.", + image = moduleImagePath .. "commweapon_multistunner.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = {"support", "recon", "strike", "knight"}, + requireLevel = 3, + slotType = "adv_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + local weaponName = (modules[moduleDefNamesToIDs.weaponmod_stun_booster[1]] and "commweapon_multistunner_improved") or "commweapon_multistunner" + if not sharedData.weapon1 then + sharedData.weapon1 = weaponName + else + sharedData.weapon2 = weaponName + end + end, + hardcodedID=21 + }, + { + name = "commweapon_napalmgrenade", + humanName = "Hellfire Grenade", + description = "Hellfire Grenade - Manually fired bomb that inflames a large area.", + image = moduleImagePath .. "commweapon_napalmgrenade.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = {"assault", "recon", "knight"}, + requireLevel = 3, + slotType = "adv_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + if not sharedData.weapon1 then + sharedData.weapon1 = "commweapon_napalmgrenade" + else + sharedData.weapon2 = "commweapon_napalmgrenade" + end + end, + hardcodedID=22 + }, + { + name = "commweapon_slamrocket", + humanName = "S.L.A.M. Rocket", + description = "S.L.A.M. Rocket - Manually fired miniature tactical nuke.", + image = moduleImagePath .. "commweapon_slamrocket.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = {"assault", "knight"}, + requireLevel = 3, + slotType = "adv_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + if not sharedData.weapon1 then + sharedData.weapon1 = "commweapon_slamrocket" + else + sharedData.weapon2 = "commweapon_slamrocket" + end + end, + hardcodedID=23 + }, + + -- Unique Modules + { + name = "econ", + humanName = "Vanguard Economy Pack", + description = "Vanguard Economy Pack - A vital part of establishing a beachhead, this module is equipped by all new commanders to kickstart their economy. Provides 4 metal income and 6 energy income.", + image = moduleImagePath .. "module_energy_cell.png", + limit = 1, + unequipable = true, + cost = 100 * COST_MULT, + requireLevel = 0, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.metalIncome = (sharedData.metalIncome or 0) + 4 + sharedData.energyIncome = (sharedData.energyIncome or 0) + 6 + end, + hardcodedID=24 + }, + { + name = "commweapon_personal_shield", + humanName = "Personal Shield", + description = "Personal Shield - A small, protective bubble shield.", + image = moduleImagePath .. "module_personal_shield.png", + limit = 1, + cost = 300 * COST_MULT, + prohibitingModules = {"module_personal_cloak"}, + requireLevel = 2, + slotType = "module", + applicationFunction = function (modules, sharedData) + -- Do not override area shield + sharedData.shield = sharedData.shield or "commweapon_personal_shield" + end, + hardcodedID=25 + }, + { + name = "commweapon_areashield", + humanName = "Area Shield", + description = "Area Shield - Projects a large shield. Replaces Personal Shield.", + image = moduleImagePath .. "module_areashield.png", + limit = 1, + cost = 250 * COST_MULT, + requireChassis = {"assault", "support", "knight"}, + requireOneOf = {"commweapon_personal_shield"}, + prohibitingModules = {"module_personal_cloak"}, + requireLevel = 3, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.shield = "commweapon_areashield" + end, + hardcodedID=26 + }, + { + name = "weaponmod_napalm_warhead", + humanName = "Napalm Warhead", + description = "Napalm Warhead - Riot Cannon and Rocket Launcher set targets on fire. Reduced direct damage.", + image = moduleImagePath .. "weaponmod_napalm_warhead.png", + limit = 1, + cost = 350 * COST_MULT, + requireChassis = {"assault", "knight"}, + requireOneOf = { + "commweapon_rocketlauncher", "commweapon_rocketlauncher_adv", + "commweapon_riotcannon", "commweapon_riotcannon_adv", + "commweapon_hpartillery"}, + requireLevel = 2, + slotType = "module", + hardcodedID=27 + }, + { + name = "conversion_disruptor", + humanName = "Disruptor Ammo", + description = "Disruptor Ammo - Heavy Machine Gun, Shotgun and Particle Beams deal slow damage. Reduced direct damage.", + image = moduleImagePath .. "weaponmod_disruptor_ammo.png", + limit = 1, + cost = 300 * COST_MULT, + requireChassis = {"strike", "recon", "support", "knight"}, + requireOneOf = { + "commweapon_heavymachinegun", "commweapon_heavymachinegun_adv", + "commweapon_shotgun", "commweapon_shotgun_adv", + "commweapon_lparticlebeam", "commweapon_lparticlebeam_adv", + "commweapon_hparticlebeam" + }, + requireLevel = 2, + slotType = "module", + hardcodedID=28 + }, + { + name = "weaponmod_stun_booster", + humanName = "Flux Amplifier", + description = "Flux Amplifier - Improves EMP duration and strength of Lightning Rifle and Multistunner.", + image = moduleImagePath .. "weaponmod_stun_booster.png", + limit = 1, + cost = 300 * COST_MULT, + requireChassis = {"support", "strike", "recon", "knight"}, + requireOneOf = { + "commweapon_lightninggun", "commweapon_lightninggun_adv", + "commweapon_multistunner" + }, + requireLevel = 2, + slotType = "module", + hardcodedID=29 + }, + { + name = "module_jammer", + humanName = "Radar Jammer", + description = "Radar Jammer - Hide the radar signals of nearby units.", + image = moduleImagePath .. "module_jammer.png", + limit = 1, + cost = 200 * COST_MULT, + requireLevel = 2, + slotType = "module", + applicationFunction = function (modules, sharedData) + if not sharedData.cloakFieldRange then + sharedData.radarJammingRange = 500 + end + end, + hardcodedID=30 + }, + { + name = "module_radarnet", + humanName = "Field Radar", + description = "Field Radar - Attaches a basic radar system.", + image = moduleImagePath .. "module_fieldradar.png", + limit = 1, + cost = 75 * COST_MULT, + requireLevel = 1, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.radarRange = 1800 + end, + hardcodedID=31 + }, + { + name = "module_personal_cloak", + humanName = "Personal Cloak", + description = "Personal Cloak - A personal cloaking device. Reduces total speed by 12%.", + image = moduleImagePath .. "module_personal_cloak.png", + limit = 1, + cost = 400 * COST_MULT, + prohibitingModules = {"commweapon_personal_shield", "commweapon_areashield"}, + requireLevel = 2, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.decloakDistance = math.max(sharedData.decloakDistance or 0, 150) + sharedData.personalCloak = true + sharedData.speedMultPost = (sharedData.speedMultPost or 1) - 0.12 + end, + hardcodedID=32 + }, + { + name = "module_cloak_field", + humanName = "Cloaking Field", + description = "Cloaking Field - Cloaks all nearby units.", + image = moduleImagePath .. "module_cloak_field.png", + limit = 1, + cost = 600 * COST_MULT, + requireChassis = {"support", "strike", "knight"}, + requireOneOf = {"module_jammer"}, + requireLevel = 3, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.areaCloak = true + sharedData.decloakDistance = 180 + sharedData.cloakFieldRange = 320 + sharedData.cloakFieldUpkeep = 15 + sharedData.cloakFieldRecloakRate = 800 -- UI only, update in unit_commander_upgrade + sharedData.radarJammingRange = 320 + end, + hardcodedID=33 + }, + { + name = "module_resurrect", + humanName = "Lazarus Device", + description = "Lazarus Device - Upgrade nanolathe to allow resurrection.", + image = moduleImagePath .. "module_resurrect.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = disableResurrect and {} or {"support", "knight"}, + requireLevel = 2, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.canResurrect = true + end, + hardcodedID=34 + }, + { + name = "module_jumpjet", + humanName = "Jumpjets", + description = "Jumpjets - Leap over obstacles and out of danger. Each High Powered Servos reduces jump reload by 1s.", + image = moduleImagePath .. "module_jumpjet.png", + limit = 1, + cost = 400 * COST_MULT, + requireChassis = {"knight"}, + requireLevel = 3, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.canJump = true + end, + hardcodedID=35 + }, + + -- Repeat Modules + { + name = "module_companion_drone", + humanName = "Companion Drone", + description = "Companion Drone - Commander spawns protective drones. Limit: 5", + image = moduleImagePath .. "module_companion_drone.png", + limit = 5, + cost = 200 * COST_MULT, + requireLevel = 2, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.drones = (sharedData.drones or 0) + 1 + end, + hardcodedID=36 + }, + { + name = "module_battle_drone", + humanName = "Battle Drone", + description = "Battle Drone - Commander spawns heavy drones. Limit: 5, Requires Companion Drone", + image = moduleImagePath .. "module_battle_drone.png", + limit = 5, + cost = 350 * COST_MULT, + requireChassis = {"assault", "support", "knight"}, + requireOneOf = {"module_companion_drone"}, + requireLevel = 3, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.droneheavyslows = (sharedData.droneheavyslows or 0) + 1 + end, + hardcodedID=37 + }, + { + name = "module_autorepair", + humanName = "Autorepair", + description = "Autorepair - Commander self-repairs at +" .. 12*HP_MULT .. " hp/s. Reduces Health by " .. 100*HP_MULT .. ". Limit: 5", + image = moduleImagePath .. "module_autorepair.png", + limit = 5, + cost = 150 * COST_MULT, + requireLevel = 1, + requireChassis = {"strike", "knight"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12*HP_MULT + sharedData.healthBonus = (sharedData.healthBonus or 0) - 100*HP_MULT + end, + hardcodedID=38 + }, + { + name = "module_autorepair", + humanName = "Autorepair", + description = "Autorepair - Commander self-repairs at +" .. 10*HP_MULT .. " hp/s. Reduces Health by " .. 100*HP_MULT .. ". Limit: 5", + image = moduleImagePath .. "module_autorepair.png", + limit = 5, + cost = 150 * COST_MULT, + requireLevel = 1, + requireChassis = {"assault", "recon", "support"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 10*HP_MULT + sharedData.healthBonus = (sharedData.healthBonus or 0) - 100*HP_MULT + end, + hardcodedID=39 + }, + { + name = "module_ablative_armor", + humanName = "Ablative Armour Plates", + description = "Ablative Armour Plates - Provides " .. 750*HP_MULT .. " health. Limit: 5", + image = moduleImagePath .. "module_ablative_armor.png", + limit = 5, + cost = 150 * COST_MULT, + requireLevel = 1, + requireChassis = {"assault", "knight"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.healthBonus = (sharedData.healthBonus or 0) + 750*HP_MULT + end, + hardcodedID=40 + }, + { + name = "module_heavy_armor", + humanName = "High Density Plating", + description = "High Density Plating - Provides " .. 2000*HP_MULT .. " health but reduces total speed by 2%. " .. + "Limit: 5, Requires Ablative Armour Plates", + image = moduleImagePath .. "module_heavy_armor.png", + limit = 5, + cost = 400 * COST_MULT, + requireOneOf = {"module_ablative_armor"}, + requireLevel = 2, + requireChassis = {"assault", "knight"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.healthBonus = (sharedData.healthBonus or 0) + 2000*HP_MULT + sharedData.speedMultPost = (sharedData.speedMultPost or 1) - 0.02 + end, + hardcodedID=41 + }, + { + name = "module_ablative_armor", + humanName = "Ablative Armour Plates", + description = "Ablative Armour Plates - Provides " .. 600*HP_MULT .. " health. Limit: 5", + image = moduleImagePath .. "module_ablative_armor.png", + limit = 5, + cost = 150 * COST_MULT, + requireLevel = 1, + requireChassis = {"strike", "recon", "support"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.healthBonus = (sharedData.healthBonus or 0) + 600*HP_MULT + end, + hardcodedID=42 + }, + { + name = "module_heavy_armor", + humanName = "High Density Plating", + description = "High Density Plating - Provides " .. 1600*HP_MULT .. " health but reduces total speed by 2%. " .. + "Limit: 5, Requires Ablative Armour Plates", + image = moduleImagePath .. "module_heavy_armor.png", + limit = 5, + cost = 400 * COST_MULT, + requireOneOf = {"module_ablative_armor"}, + requireLevel = 2, + requireChassis = {"strike", "recon", "support"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.healthBonus = (sharedData.healthBonus or 0) + 1600*HP_MULT + sharedData.speedMultPost = (sharedData.speedMultPost or 1) - 0.02 + end, + hardcodedID=43 + }, + { + name = "module_dmg_booster", + humanName = "Damage Booster", + description = "Damage Booster - Increases damage by 15% but reduces total speed by 2%. Limit: 5", + image = moduleImagePath .. "module_dmg_booster.png", + limit = 5, + cost = 150 * COST_MULT, + requireLevel = 1, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.damageMult = (sharedData.damageMult or 1) + 0.15 + sharedData.speedMultPost = (sharedData.speedMultPost or 1) - 0.02 + end, + hardcodedID=44 + }, + { + name = "module_high_power_servos", + humanName = "High Power Servos", + description = "High Power Servos - Increases speed by 4 and reduced jump cooldown by 1s. Limit: 5", + image = moduleImagePath .. "module_high_power_servos.png", + limit = 5, + cost = 200 * COST_MULT, + requireLevel = 1, + requireChassis = {"recon", "knight"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.speedMod = (sharedData.speedMod or 0) + 4 + sharedData.jumpReloadMod = (sharedData.jumpReloadMod or 0) - 1 + end, + hardcodedID=45 + }, + { + name = "module_high_power_servos", + humanName = "High Power Servos", + description = "High Power Servos - Increases speed by 3.5. Limit: 5", + image = moduleImagePath .. "module_high_power_servos.png", + limit = 5, + cost = 200 * COST_MULT, + requireLevel = 1, + requireChassis = {"strike", "assault", "support"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.speedMod = (sharedData.speedMod or 0) + 3.5 + end, + hardcodedID=46 + }, + { + name = "module_adv_targeting", + humanName = "Adv. Targeting System", + description = "Advanced Targeting System - Increases range by 7.5% but reduces total speed by 3%. Limit: 5", + image = moduleImagePath .. "module_adv_targeting.png", + limit = 5, + cost = 200 * COST_MULT, + requireLevel = 1, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.rangeMult = (sharedData.rangeMult or 1) + 0.075 + sharedData.speedMultPost = (sharedData.speedMultPost or 1) - 0.03 + end, + hardcodedID=47 + }, + { + name = "module_adv_nano", + humanName = "CarRepairer's Nanolathe", + description = "CarRepairer's Nanolathe - Increases build power by 6. Limit: 5", + image = moduleImagePath .. "module_adv_nano.png", + limit = 5, + cost = 200 * COST_MULT, + requireLevel = 1, + requireChassis = {"support"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 6 + end, + hardcodedID=48 + }, + { + name = "module_adv_nano", + humanName = "CarRepairer's Nanolathe", + description = "CarRepairer's Nanolathe - Increases build power by 5. Limit: 5", + image = moduleImagePath .. "module_adv_nano.png", + limit = 5, + cost = 200 * COST_MULT, + requireLevel = 1, + requireChassis = {"strike", "assault", "knight"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 5 + end, + hardcodedID=49 + }, + { + name = "module_adv_nano", + humanName = "CarRepairer's Nanolathe", + description = "CarRepairer's Nanolathe - Increases build power by 4. Limit: 5", + image = moduleImagePath .. "module_adv_nano.png", + limit = 5, + cost = 200 * COST_MULT, + requireLevel = 1, + requireChassis = {"recon"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 4 + end, + hardcodedID=50 + }, + -- Decorative Modules + { + name = "banner_overhead", + humanName = "Banner", + description = "Banner", + image = moduleImagePath .. "module_ablative_armor.png", + limit = 1, + cost = 0, + requireLevel = 0, + slotType = "decoration", + applicationFunction = function (modules, sharedData) + sharedData.bannerOverhead = true + end, + hardcodedID=51 + }, + + } + for key, value in pairs(moduleDefs) do + if not value.requireChassis then + value.requireChassis=basicChassis + end + end + + return moduleDefs + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenbioarmor.lua b/gamedata/modularcomms/modules/chickenbioarmor.lua new file mode 100644 index 0000000000..efeb12df28 --- /dev/null +++ b/gamedata/modularcomms/modules/chickenbioarmor.lua @@ -0,0 +1,38 @@ +local hp=500 +local rep=5 +local humanName="Bio Armor" +local description= "Bio Armor - Give " .. hp .. " hp and " .. rep .. " hp/s repair. Limit: 10" +return { + moduledef={ + module_chickenbioarmor={ + name=humanName, + description=description, + func = function(unitDef) + unitDef.health = unitDef.health + hp + unitDef.autoheal = (unitDef.autoheal or 0) + rep + end, + }, + + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared -- for luals + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + return {{ + name = "module_chickenbioarmor", + humanName = humanName, + description = description, + image = moduleImagePath .. "module_repair_field.png", + limit = 10, + cost = 150 * COST_MULT, + requireLevel = 1, + requireChassis = {"chicken","assault"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + rep*HP_MULT + sharedData.healthBonus = (sharedData.healthBonus or 0) + hp*HP_MULT + end + }} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenbioarmorheavy.lua b/gamedata/modularcomms/modules/chickenbioarmorheavy.lua new file mode 100644 index 0000000000..a12fda970e --- /dev/null +++ b/gamedata/modularcomms/modules/chickenbioarmorheavy.lua @@ -0,0 +1,42 @@ +local hp=1500 +local rep=10 +local speed=-0.04 +local humanName="Heavy Bio Armor" +local description= "Heavy Bio Armor - Give " .. hp .. " hp and " .. rep .. " hp/s repair and ".. speed*100 .. "% speed. Limit: 5" + +return { + moduledef={ + module_chickenbioarmor={ + name=humanName, + description=description, + func = function(unitDef,attributeMods) + unitDef.health = unitDef.health + hp + unitDef.autoheal = (unitDef.autoheal or 0) + rep + attributeMods.speed = attributeMods.speed + speed + end, + }, + + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared -- for luals + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + return {{ + name = "module_chickenbioarmor", + humanName = humanName, + description = description, + image = moduleImagePath .. "module_repair_field.png", + limit = 10, + cost = 150 * COST_MULT, + requireLevel = 2, + requireChassis = {"chicken","assault"}, + slotType = "module", + applicationFunction = function (modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + rep*HP_MULT + sharedData.healthBonus = (sharedData.healthBonus or 0) + hp*HP_MULT + sharedData.speedMultPost = (sharedData.speedMultPost or 1) + speed + end + }} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenclaw.lua b/gamedata/modularcomms/modules/chickenclaw.lua new file mode 100644 index 0000000000..18632da4a7 --- /dev/null +++ b/gamedata/modularcomms/modules/chickenclaw.lua @@ -0,0 +1,35 @@ + +local humanName="Chicken Claw" +local description= "Chicken Claw: CLUCK" + +return { + moduledef={ + commweapon_chickenclaw={ + name=humanName, + description=description, + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + + local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon + return {{ + name = "commweapon_chickenclaw", + humanName = humanName, + description = description, + image = moduleImagePath .. "chickena.png", + limit = 2, + cost = 0, + requireChassis = {"chicken"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = applicationFunctionApplyWeapon(function () + return "commweapon_chickenclaw" + end), + isBasicWeapon=true, + }} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenflamethrower.lua b/gamedata/modularcomms/modules/chickenflamethrower.lua new file mode 100644 index 0000000000..ff2ceabc75 --- /dev/null +++ b/gamedata/modularcomms/modules/chickenflamethrower.lua @@ -0,0 +1,34 @@ + +local humanName="Flame Thrower" +local description= "Flame Thrower" +return { + moduledef={ + commweapon_chickenflamethrower={ + name=humanName, + description=description, + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + + local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon + return {{ + name = "commweapon_chickenflamethrower", + humanName = humanName, + description = description, + image = moduleImagePath .. "commweapon_flamethrower.png", + limit = 2, + cost = 0, + requireChassis = {},-- bugged + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = applicationFunctionApplyWeapon(function () + return "commweapon_chickenflamethrower" + end), + isBasicWeapon=true, + }} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickengoo.lua b/gamedata/modularcomms/modules/chickengoo.lua new file mode 100644 index 0000000000..5a4a6ab7fb --- /dev/null +++ b/gamedata/modularcomms/modules/chickengoo.lua @@ -0,0 +1,45 @@ + +local humanName="Chicken Blob" +local description= humanName .. " - Blob, can only shot at front, replace other weapons" + +return { + moduledef={ + commweapon_chickengoo={ + name=humanName, + description=description, + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon + + return {{ + name = "commweapon_chickengoo", + humanName = humanName, + description = description, + image = moduleImagePath .. "commweapon_clusterbomb.png", + limit = 1, + cost = 0, + requireChassis = {"chicken"}, + requireLevel = 3, + slotType = "adv_weapon", + applicationFunction = applicationFunctionApplyWeapon(function () + return "commweapon_chickengoo" + end), + --[=[ + function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + local weaponName = "commweapon_chickengoo" + sharedData.weapon1 = weaponName + sharedData.weapon2 = nil + sharedData.noMoreWeapons = true + end,]=] + --isBasicWeapon=true, + }} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenshield.lua b/gamedata/modularcomms/modules/chickenshield.lua new file mode 100644 index 0000000000..a85114f8ab --- /dev/null +++ b/gamedata/modularcomms/modules/chickenshield.lua @@ -0,0 +1,46 @@ + +local humanName="Chicken Shield" +local description= humanName.." - Generates a weak but high regen shield" + +return { + moduledef={ + module_chickenshield={ + name=humanName, + description=description,order = 5, + func = function(unitDef) + if unitDef.customparams.dynamic_comm then +---@diagnostic disable-next-line: undefined-global + DynamicApplyWeapon(unitDef, "commweapon_chickenshield", #unitDef.weapons + 1) + else +---@diagnostic disable-next-line: undefined-global + ApplyWeapon(unitDef, "commweapon_chickenshield", 4) + end + end, + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + --local shared=ModularCommDefsShared + local moduleImagePath=shared.moduleImagePath + local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon + local COST_MULT=shared.COST_MULT + return {{ + name = "commweapon_chickenshield", + humanName = humanName, + description = description, + image = moduleImagePath .. "module_personal_shield.png", + limit = 1, + cost = 300 * COST_MULT, + prohibitingModules = {"module_personal_cloak"}, + requireOneOf = {"commweapon_personal_shield"}, + requireChassis = {"chicken"}, + requireLevel = 3, + slotType = "module", + + applicationFunction = function (modules, sharedData) + -- Do not override area shield + sharedData.shield = "commweapon_chickenshield" + end + }} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenspike.lua b/gamedata/modularcomms/modules/chickenspike.lua new file mode 100644 index 0000000000..d4bba52954 --- /dev/null +++ b/gamedata/modularcomms/modules/chickenspike.lua @@ -0,0 +1,35 @@ + +local humanName="Chicken Spike" +local description= "Chicken Spike: Mid range skirmish weapon, can onlt shot at front" + +return { + moduledef={ + commweapon_chickenspike={ + name=humanName, + description=description, + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + + local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon + return {{ + name = "commweapon_chickenspike", + humanName = humanName, + description = description, + image = moduleImagePath .. "chickens.png", + limit = 2, + cost = 0, + requireChassis = {"chicken"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = applicationFunctionApplyWeapon(function () + return "commweapon_chickenspike" + end), + isBasicWeapon=true, + }} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenspores.lua b/gamedata/modularcomms/modules/chickenspores.lua new file mode 100644 index 0000000000..71c67d0382 --- /dev/null +++ b/gamedata/modularcomms/modules/chickenspores.lua @@ -0,0 +1,34 @@ + +local humanName="Chicken Spores" +local description= "Chicken Spores: Chasing Projectile, x0.5 damage vs ground" +return { + moduledef={ + commweapon_chickenspores={ + name=humanName, + description=description, + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + + local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon + return {{ + name = "commweapon_chickenspores", + humanName = humanName, + description = description, + image = moduleImagePath .. "chickend.png", + limit = 2, + cost = 0, + requireChassis = {"chicken"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = applicationFunctionApplyWeapon(function () + return "commweapon_chickenspores" + end), + isBasicWeapon=true, + }} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/commweapon_beamlaser.lua b/gamedata/modularcomms/modules/commweapon_beamlaser.lua new file mode 100644 index 0000000000..540de7677e --- /dev/null +++ b/gamedata/modularcomms/modules/commweapon_beamlaser.lua @@ -0,0 +1,43 @@ +return{ + moduledef={ + commweapon_beamlaser={ + name="Beam Laser", + description="Beam Laser: An effective short-range cutting tool", + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + local moddef={ + name = "commweapon_beamlaser", + humanName = "Beam Laser", + description = "Beam Laser: An effective short-range cutting tool", + image = moduleImagePath .. "commweapon_beamlaser.png", + limit = 2, + cost = 0, + requireLevel = 1, + requireChassis={"recon", "strike", "assault", "support", "knight"}, + slotType = "basic_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + if not sharedData.weapon1 then + sharedData.weapon1 = "commweapon_beamlaser" + else + sharedData.weapon2 = "commweapon_beamlaser" + end + end, + hardcodedID=5, + } + local GenAdvWeaponModule=shared.GenAdvWeaponModule + local moddef2=GenAdvWeaponModule(moddef) + moddef2.hardcodedID=52 + --lazy remove(moddef2.requireChassis,"knight") + moddef2.requireChassis[#moddef2.requireChassis]=nil + --lazy remove(moddef2.requireChassis,"knight") + return {moddef,moddef2} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/commweapon_flamethrower.lua b/gamedata/modularcomms/modules/commweapon_flamethrower.lua new file mode 100644 index 0000000000..990b7f608b --- /dev/null +++ b/gamedata/modularcomms/modules/commweapon_flamethrower.lua @@ -0,0 +1,45 @@ +return{ + moduledef={ + commweapon_flamethrower={ + name="Flamethrower", + description="Flamethrower: Good for deep-frying swarmers and large targets alike", + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + + local moddef={ + name = "commweapon_flamethrower", + humanName = "Flamethrower", + description = "Flamethrower: Good for deep-frying swarmers and large targets alike", + image = moduleImagePath .. "commweapon_flamethrower.png", + limit = 2, + cost = 0, + requireChassis = {"recon", "assault", "knight"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + if not sharedData.weapon1 then + sharedData.weapon1 = "commweapon_flamethrower" + else + sharedData.weapon2 = "commweapon_flamethrower" + end + end, + hardcodedID=6, + } + local GenAdvWeaponModule=shared.GenAdvWeaponModule + local moddef2=GenAdvWeaponModule(moddef) + moddef2.hardcodedID=53 + --lazy remove(moddef2.requireChassis,"knight") + moddef2.requireChassis[#moddef2.requireChassis]=nil + --lazy remove(moddef2.requireChassis,"knight") + + return {moddef,moddef2} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/commweapon_heatray.lua b/gamedata/modularcomms/modules/commweapon_heatray.lua new file mode 100644 index 0000000000..abb09c0a17 --- /dev/null +++ b/gamedata/modularcomms/modules/commweapon_heatray.lua @@ -0,0 +1,44 @@ +return{ + moduledef={ + commweapon_heatray={ + name="Heatray", + description="Heatray: Rapidly melts anything at short range; steadily loses all of its damage over distance", + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + + local moddef={ + name = "commweapon_heatray", + humanName = "Heatray", + description = "Heatray: Rapidly melts anything at short range; steadily loses all of its damage over distance", + image = moduleImagePath .. "commweapon_heatray.png", + limit = 2, + cost = 0, + requireChassis = {"assault", "knight"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + if not sharedData.weapon1 then + sharedData.weapon1 = "commweapon_heatray" + else + sharedData.weapon2 = "commweapon_heatray" + end + end, + hardcodedID=7, + } + local GenAdvWeaponModule=shared.GenAdvWeaponModule + local moddef2=GenAdvWeaponModule(moddef) + moddef2.hardcodedID=54 + --lazy remove(moddef2.requireChassis,"knight") + moddef2.requireChassis[#moddef2.requireChassis]=nil + --lazy remove(moddef2.requireChassis,"knight") + return {moddef,moddef2} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/commweapon_heavymachinegun.lua b/gamedata/modularcomms/modules/commweapon_heavymachinegun.lua new file mode 100644 index 0000000000..3af7422ff1 --- /dev/null +++ b/gamedata/modularcomms/modules/commweapon_heavymachinegun.lua @@ -0,0 +1,46 @@ +return{ + moduledef={ + commweapon_heavymachinegun={ + name="Machine Gun", + description="Machine Gun: Close-in automatic weapon with AoE", + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + local moduleDefNamesToIDs=shared.moduleDefNamesToIDs + + local moddef={ + name = "commweapon_heavymachinegun", + humanName = "Machine Gun", + description = "Machine Gun: Close-in automatic weapon with AoE", + image = moduleImagePath .. "commweapon_heavymachinegun.png", + limit = 2, + cost = 0, + requireChassis = {"recon", "assault", "strike", "knight"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + local weaponName = (modules[moduleDefNamesToIDs.conversion_disruptor[1]] and "commweapon_heavymachinegun_disrupt") or "commweapon_heavymachinegun" + if not sharedData.weapon1 then + sharedData.weapon1 = weaponName + else + sharedData.weapon2 = weaponName + end + end, + hardcodedID=8 + } + local GenAdvWeaponModule=shared.GenAdvWeaponModule + local moddef2=GenAdvWeaponModule(moddef) + moddef2.hardcodedID=55 + --lazy remove(moddef2.requireChassis,"knight") + moddef2.requireChassis[#moddef2.requireChassis]=nil + --lazy remove(moddef2.requireChassis,"knight") + return {moddef,moddef2} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/commweapon_lightninggun.lua b/gamedata/modularcomms/modules/commweapon_lightninggun.lua new file mode 100644 index 0000000000..c4855c9b98 --- /dev/null +++ b/gamedata/modularcomms/modules/commweapon_lightninggun.lua @@ -0,0 +1,46 @@ +return{ + moduledef={ + commweapon_lightninggun={ + name="Lightning Rifle", + description="Lightning Rifle: Paralyzes and damages annoying bugs", + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + local moduleDefNamesToIDs=shared.moduleDefNamesToIDs + + local moddef={ + name = "commweapon_lightninggun", + humanName = "Lightning Rifle", + description = "Lightning Rifle: Paralyzes and damages annoying bugs", + image = moduleImagePath .. "commweapon_lightninggun.png", + limit = 2, + cost = 0, + requireChassis = {"recon", "support", "strike", "knight"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + local weaponName = (modules[moduleDefNamesToIDs.weaponmod_stun_booster[1]] and "commweapon_lightninggun_improved") or "commweapon_lightninggun" + if not sharedData.weapon1 then + sharedData.weapon1 = weaponName + else + sharedData.weapon2 = weaponName + end + end, + hardcodedID=9 + } + local GenAdvWeaponModule=shared.GenAdvWeaponModule + local moddef2=GenAdvWeaponModule(moddef) + moddef2.hardcodedID=56 + --lazy remove(moddef2.requireChassis,"knight") + moddef2.requireChassis[#moddef2.requireChassis]=nil + --lazy remove(moddef2.requireChassis,"knight") + return {moddef,moddef2} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/commweapon_lparticlebeam.lua b/gamedata/modularcomms/modules/commweapon_lparticlebeam.lua new file mode 100644 index 0000000000..218cac1633 --- /dev/null +++ b/gamedata/modularcomms/modules/commweapon_lparticlebeam.lua @@ -0,0 +1,46 @@ +return{ + moduledef={ + commweapon_lparticlebeam={ + name="Light Particle Beam", + description="Light Particle Beam: Fast, light pulsed energy weapon", + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + local moduleDefNamesToIDs=shared.moduleDefNamesToIDs + + local moddef={ + name = "commweapon_lparticlebeam", + humanName = "Light Particle Beam", + description = "Light Particle Beam: Fast, light pulsed energy weapon", + image = moduleImagePath .. "commweapon_lparticlebeam.png", + limit = 2, + cost = 0, + requireChassis = {"support", "recon", "strike", "knight"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + local weaponName = (modules[moduleDefNamesToIDs.conversion_disruptor[1]] and "commweapon_disruptor") or "commweapon_lparticlebeam" + if not sharedData.weapon1 then + sharedData.weapon1 = weaponName + else + sharedData.weapon2 = weaponName + end + end, + hardcodedID=10 + } + local GenAdvWeaponModule=shared.GenAdvWeaponModule + local moddef2=GenAdvWeaponModule(moddef) + moddef2.hardcodedID=57 + --lazy remove(moddef2.requireChassis,"knight") + moddef2.requireChassis[#moddef2.requireChassis]=nil + --lazy remove(moddef2.requireChassis,"knight") + return {moddef,moddef2} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/commweapon_missilelauncher.lua b/gamedata/modularcomms/modules/commweapon_missilelauncher.lua new file mode 100644 index 0000000000..7855eafa83 --- /dev/null +++ b/gamedata/modularcomms/modules/commweapon_missilelauncher.lua @@ -0,0 +1,45 @@ +return{ + moduledef={ + commweapon_missilelauncher={ + name="Missile Launcher", + description="Missile Launcher: Lightweight seeker missile with good range", + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + local moduleDefNamesToIDs=shared.moduleDefNamesToIDs + + local moddef={ + name = "commweapon_missilelauncher", + humanName = "Missile Launcher", + description = "Missile Launcher: Lightweight seeker missile with good range", + image = moduleImagePath .. "commweapon_missilelauncher.png", + limit = 2, + cost = 0, + requireChassis = {"support", "strike", "knight"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + if not sharedData.weapon1 then + sharedData.weapon1 = "commweapon_missilelauncher" + else + sharedData.weapon2 = "commweapon_missilelauncher" + end + end, + hardcodedID=11 + } + local GenAdvWeaponModule=shared.GenAdvWeaponModule + local moddef2=GenAdvWeaponModule(moddef) + moddef2.hardcodedID=58 + --lazy remove(moddef2.requireChassis,"knight") + moddef2.requireChassis[#moddef2.requireChassis]=nil + --lazy remove(moddef2.requireChassis,"knight") + return {moddef,moddef2} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/commweapon_riotcannon.lua b/gamedata/modularcomms/modules/commweapon_riotcannon.lua new file mode 100644 index 0000000000..f61f36fc5f --- /dev/null +++ b/gamedata/modularcomms/modules/commweapon_riotcannon.lua @@ -0,0 +1,46 @@ +return{ + moduledef={ + commweapon_riotcannon={ + name="Riot Cannon", + description="Riot Cannon: The weapon of choice for crowd control", + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + local moduleDefNamesToIDs=shared.moduleDefNamesToIDs + + local moddef={ + name = "commweapon_riotcannon", + humanName = "Riot Cannon", + description = "Riot Cannon: The weapon of choice for crowd control", + image = moduleImagePath .. "commweapon_riotcannon.png", + limit = 2, + cost = 0, + requireChassis = {"assault", "knight"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + local weaponName = (modules[moduleDefNamesToIDs.weaponmod_napalm_warhead[1]] and "commweapon_riotcannon_napalm") or "commweapon_riotcannon" + if not sharedData.weapon1 then + sharedData.weapon1 = weaponName + else + sharedData.weapon2 = weaponName + end + end, + hardcodedID=12 + } + local GenAdvWeaponModule=shared.GenAdvWeaponModule + local moddef2=GenAdvWeaponModule(moddef) + moddef2.hardcodedID=59 + --lazy remove(moddef2.requireChassis,"knight") + moddef2.requireChassis[#moddef2.requireChassis]=nil + --lazy remove(moddef2.requireChassis,"knight") + return {moddef,moddef2} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/commweapon_rocketlauncher.lua b/gamedata/modularcomms/modules/commweapon_rocketlauncher.lua new file mode 100644 index 0000000000..d1aadd3a5f --- /dev/null +++ b/gamedata/modularcomms/modules/commweapon_rocketlauncher.lua @@ -0,0 +1,46 @@ +return{ + moduledef={ + commweapon_rocketlauncher={ + name="Rocket Launcher", + description="Rocket Launcher: Medium-range, low-velocity hitter", + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + local moduleDefNamesToIDs=shared.moduleDefNamesToIDs + + local moddef={ + name = "commweapon_rocketlauncher", + humanName = "Rocket Launcher", + description = "Rocket Launcher: Medium-range, low-velocity hitter", + image = moduleImagePath .. "commweapon_rocketlauncher.png", + limit = 2, + cost = 0, + requireChassis = {"assault", "knight"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + local weaponName = (modules[moduleDefNamesToIDs.weaponmod_napalm_warhead[1]] and "commweapon_rocketlauncher_napalm") or "commweapon_rocketlauncher" + if not sharedData.weapon1 then + sharedData.weapon1 = weaponName + else + sharedData.weapon2 = weaponName + end + end, + hardcodedID=13 + } + local GenAdvWeaponModule=shared.GenAdvWeaponModule + local moddef2=GenAdvWeaponModule(moddef) + moddef2.hardcodedID=60 + --lazy remove(moddef2.requireChassis,"knight") + moddef2.requireChassis[#moddef2.requireChassis]=nil + --lazy remove(moddef2.requireChassis,"knight") + return {moddef,moddef2} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/commweapon_shotgun.lua b/gamedata/modularcomms/modules/commweapon_shotgun.lua new file mode 100644 index 0000000000..3455ce0afe --- /dev/null +++ b/gamedata/modularcomms/modules/commweapon_shotgun.lua @@ -0,0 +1,46 @@ +return{ + moduledef={ + commweapon_shotgun={ + name="Shotgun", + description="Shotgun: Can hammer a single large target or shred several small ones", + } + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + local moduleDefNamesToIDs=shared.moduleDefNamesToIDs + + local moddef={ + name = "commweapon_shotgun", + humanName = "Shotgun", + description = "Shotgun: Can hammer a single large target or shred several small ones", + image = moduleImagePath .. "commweapon_shotgun.png", + limit = 2, + cost = 0, + requireChassis = {"recon", "support", "strike", "knight"}, + requireLevel = 1, + slotType = "basic_weapon", + applicationFunction = function (modules, sharedData) + if sharedData.noMoreWeapons then + return + end + local weaponName = (modules[moduleDefNamesToIDs.conversion_disruptor[1]] and "commweapon_shotgun_disrupt") or "commweapon_shotgun" + if not sharedData.weapon1 then + sharedData.weapon1 = weaponName + else + sharedData.weapon2 = weaponName + end + end, + hardcodedID=14 + } + local GenAdvWeaponModule=shared.GenAdvWeaponModule + local moddef2=GenAdvWeaponModule(moddef) + moddef2.hardcodedID=61 + --lazy remove(moddef2.requireChassis,"knight") + moddef2.requireChassis[#moddef2.requireChassis]=nil + --lazy remove(moddef2.requireChassis,"knight") + return {moddef,moddef2} + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/template.txt b/gamedata/modularcomms/modules/template.txt new file mode 100644 index 0000000000..8a316068ed --- /dev/null +++ b/gamedata/modularcomms/modules/template.txt @@ -0,0 +1,25 @@ + +local humanName="" +local description= "" + +return { + moduledef={ + modulename={ + name=humanName, + description=description, + } + + }, + dynamic_comm_def=function (shared) + shared=ModularCommDefsShared or shared + local moduleImagePath=shared.moduleImagePath + local COST_MULT=shared.COST_MULT + local HP_MULT=shared.HP_MULT + return { + { + humanName = humanName, + description = description, + } + } + end +} \ No newline at end of file diff --git a/gamedata/modularcomms/modules_all_defs.lua b/gamedata/modularcomms/modules_all_defs.lua new file mode 100644 index 0000000000..b7481edc07 --- /dev/null +++ b/gamedata/modularcomms/modules_all_defs.lua @@ -0,0 +1,14 @@ + +if not Spring.ModularCommAPI then + Spring.ModularCommAPI={} +end +if not Spring.ModularCommAPI.Modules then + local Modules={} + Spring.ModularCommAPI.Modules=Modules + local moduleFiles=VFS.DirList("gamedata/modularcomms/modules", "*.lua") or {} + for i = 1, #moduleFiles do + local moduleDef = VFS.Include(moduleFiles[i]) + Modules[#Modules+1]=moduleDef + end +end +return Spring.ModularCommAPI.Modules \ No newline at end of file diff --git a/gamedata/modularcomms/staticcomms.lua b/gamedata/modularcomms/staticcomms.lua index 01859284cc..6ca8a4a2a0 100644 --- a/gamedata/modularcomms/staticcomms.lua +++ b/gamedata/modularcomms/staticcomms.lua @@ -218,31 +218,14 @@ end -------------------------------------------------------------------------------------- -- Must match dynamic_comm_defs.lua around line 800 (top of the chassis defs) -------------------------------------------------------------------------------------- -MakeCommanderChassisClones("dynrecon", - {{0}, {1}, {1}, {1}, {1}}, - {"module_personal_shield"} -) -MakeCommanderChassisClones("dynsupport", - {{0, 0, 0}, {1, 0, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, - {"module_personal_shield", "module_areashield", "module_resurrect"} -) +local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") -MakeCommanderChassisClones("dynassault", - {{0, 0}, {1, 0}, {1, 1}, {1, 1}, {1, 1}}, - {"module_personal_shield", "module_areashield"} -) - -MakeCommanderChassisClones("dynstrike", - {{0, 0}, {1, 0}, {1, 1}, {1, 1}, {1, 1}}, - {"module_personal_shield", "module_areashield"} -) - --- All modules may be available at any level, depending on campaign layout. -MakeCommanderChassisClones("dynknight", - {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - {"module_personal_shield", "module_areashield", "module_resurrect", "module_jumpjet"} -) +for i = 1, #chassisAllDefs do + local staticcommsDef=chassisAllDefs[i].staticcomms + local name,levelLimits,modules = staticcommsDef[1],staticcommsDef[2],staticcommsDef[3] + MakeCommanderChassisClones(name,levelLimits,modules) +end --[[ for name,stats in pairs(comms) do diff --git a/gamedata/modularcomms/unitdefgen.lua b/gamedata/modularcomms/unitdefgen.lua index 6b2bb1915a..c494f5d080 100644 --- a/gamedata/modularcomms/unitdefgen.lua +++ b/gamedata/modularcomms/unitdefgen.lua @@ -10,7 +10,7 @@ Spring.Utilities = Spring.Utilities or {} VFS.Include("LuaRules/Utilities/base64.lua") -Spring.Log = Spring.Log or function() end +Spring.Log = Spring.Log or function(...) end -------------------------------------------------------------------------------- -- HOW IT WORKS: -- First, it makes unitdefs as specified by the decoded modoption string, one for each unique comm type. @@ -96,7 +96,7 @@ local function GenerateLevel0DyncommsAndWrecks() local unitName = commProfile.baseUnitName local chassis = commProfile.chassis - local mappedChassis = legacyToDyncommChassisMap[chassis] or "assault" + local mappedChassis = legacyToDyncommChassisMap[chassis]-- or "assault" if mappedChassis then chassis = mappedChassis end @@ -148,6 +148,7 @@ end -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- +---@diagnostic disable-next-line: lowercase-global commDefs = {} --holds precedurally generated comm defs local function ProcessComm(name, config) diff --git a/gamedata/modularcomms/weapons/chickenclaw.lua b/gamedata/modularcomms/weapons/chickenclaw.lua new file mode 100644 index 0000000000..50e2722a9f --- /dev/null +++ b/gamedata/modularcomms/weapons/chickenclaw.lua @@ -0,0 +1,31 @@ +return "commweapon_chickenclaw",{ + name = [[Chicken Claws]], + areaOfEffect = 28, + craterBoost = 1, + craterMult = 0, + + customParams={ + + is_unit_weapon = 1, + }, + + damage = { + default = 600, + }, + + explosionGenerator = [[custom:NONE]], + impulseBoost = 0, + impulseFactor = 1, + interceptedByShieldType = 0, + noSelfDamage = true, + range = 140, + reloadtime = 1, + size = 0, + soundStart = [[chickens/bigchickenbreath]], + targetborder = 1, + tolerance = 8000, + --turret = true, + waterWeapon = true, + weaponType = [[Cannon]], + weaponVelocity = 600, + } \ No newline at end of file diff --git a/gamedata/modularcomms/weapons/chickenflamethrower.lua b/gamedata/modularcomms/weapons/chickenflamethrower.lua new file mode 100644 index 0000000000..37b3e0bb76 --- /dev/null +++ b/gamedata/modularcomms/weapons/chickenflamethrower.lua @@ -0,0 +1,56 @@ +local name = "commweapon_chickenflamethrower" +local weaponDef = { + name = [[Flame Thrower]], + areaOfEffect = 64, + avoidGround = false, + avoidFeature = false, + cegTag = [[flamer]], + collideFeature = false, + collideGround = false, + craterBoost = 0, + craterMult = 0, + + customParams = { + is_unit_weapon = 1, + --muzzleEffectFire = [[custom:RAIDMUZZLE]], + flamethrower = [[1]], + setunitsonfire = "1", + burnchance = "0.4", -- Per-impact + burntime = [[450]], + + light_camera_height = 2800, + light_color = [[0.6 0.39 0.18]], + light_radius = 260, + light_fade_time = 10, + light_beam_mult_frames = 5, + light_beam_mult = 5, + reaim_time = 1, + }, + + damage = { + default = 12.5, + }, + + explosionGenerator = [[custom:SMOKE]], + fallOffRate = 1, + fireStarter = 100, + heightMod = 1, + impulseBoost = 0, + impulseFactor = 0, + interceptedByShieldType = 1, + noExplode = true, + noSelfDamage = true, + range = 270, + reloadtime = 5/30, + rgbColor = [[1 1 1]], + soundStart = [[weapon/flamethrower]], + soundTrigger = true, + texture1 = [[flame]], + thickness = 0, + tolerance = 8000, + turret = false, + weaponType = [[LaserCannon]], + weaponVelocity = 800, +} + +return name, weaponDef diff --git a/gamedata/modularcomms/weapons/chickengoo.lua b/gamedata/modularcomms/weapons/chickengoo.lua new file mode 100644 index 0000000000..22811e6eb4 --- /dev/null +++ b/gamedata/modularcomms/weapons/chickengoo.lua @@ -0,0 +1,43 @@ +return "commweapon_chickengoo",{ + name = [[Blob]], + areaOfEffect = 200, + burst = 8, + burstrate = 0.033, + cegTag = [[queen_trail]], + craterBoost = 0, + craterMult = 0, + highTrajectory = 2, + + customParams = { + is_unit_weapon = 1, + light_radius = 0, + slot=3, + manualfire = 1, + reaim_time = 1, + }, + + damage = { + default = 600, + }, + + explosionGenerator = [[custom:large_green_goo]], + impulseBoost = 0, + impulseFactor = 0.4, + intensity = 0.7, + interceptedByShieldType = 1, + noSelfDamage = true, + proximityPriority = -4, + range = 550, + reloadtime = 15, + rgbColor = [[0.2 0.6 0]], + size = 8, + sizeDecay = 0, + soundStart = [[chickens/bigchickenroar]], + sprayAngle = 6100, + tolerance = 5000, + turret = false, + weaponType = [[Cannon]], + waterWeapon = true, + weaponVelocity = 600, + commandFire = true, + } \ No newline at end of file diff --git a/gamedata/modularcomms/weapons/chickenshield.lua b/gamedata/modularcomms/weapons/chickenshield.lua new file mode 100644 index 0000000000..b0ed916ced --- /dev/null +++ b/gamedata/modularcomms/weapons/chickenshield.lua @@ -0,0 +1,32 @@ +return "commweapon_chickenshield",{ + name = [[Shield]], + customParams={ + slot="2", + shield_rate=180, + }, + + damage = { + default = 10, + }, + + exteriorShield = true, + impulseFactor = 0, + interceptedByShieldType = 1, + shieldAlpha = 0.15, + shieldBadColor = [[1.0 1 0.1 1]], + shieldGoodColor = [[0.1 1.0 0.1 1]], + shieldInterceptType = 3, + shieldPower = 2500, + shieldPowerRegen = 180, + shieldPowerRegenEnergy = 0, + shieldRadius = 300, + shieldRepulser = false, + smartShield = true, + visibleShield = false, + visibleShieldRepulse = false, + --texture1 = [[wakelarge]], + --visibleShield = true, + --visibleShieldHitFrames = 30, + --visibleShieldRepulse = false, + weaponType = [[Shield]], + } \ No newline at end of file diff --git a/gamedata/modularcomms/weapons/chickenspike.lua b/gamedata/modularcomms/weapons/chickenspike.lua new file mode 100644 index 0000000000..e674125ad8 --- /dev/null +++ b/gamedata/modularcomms/weapons/chickenspike.lua @@ -0,0 +1,41 @@ +return "commweapon_chickenspike",{ + name = [[Spike]], + areaOfEffect = 16, + avoidFeature = true, + avoidFriendly = true, + burnblow = true, + cegTag = [[small_green_goo]], + collideFeature = true, + collideFriendly = true, + craterBoost = 0, + craterMult = 0, + + customParams = { + is_unit_weapon = 1, + light_radius = 0, + }, + + damage = { + default = 225, + planes = 225, + }, + + explosionGenerator = [[custom:EMG_HIT]], + impactOnly = true, + impulseBoost = 0, + impulseFactor = 0.4, + interceptedByShieldType = 2, + model = [[spike.s3o]], + range = 460, + reloadtime = 1, + soundHit = [[chickens/spike_hit]], + soundStart = [[chickens/spike_fire]], + startVelocity = 320, + subMissile = 1, + turret = false, + waterWeapon = true, + weaponAcceleration = 100, + weaponType = [[Cannon]], + weaponVelocity = 280, + tolerance=8000, + } \ No newline at end of file diff --git a/gamedata/modularcomms/weapons/chickenspores.lua b/gamedata/modularcomms/weapons/chickenspores.lua new file mode 100644 index 0000000000..e3b4a294ba --- /dev/null +++ b/gamedata/modularcomms/weapons/chickenspores.lua @@ -0,0 +1,48 @@ +return "commweapon_chickenspores",{ + name = [[Spores]], + areaOfEffect = 24, + avoidFriendly = false, + burst = 8, + burstrate = 0.1, + collideFriendly = false, + craterBoost = 0, + craterMult = 0, + + customParams = { + is_unit_weapon = 1, + light_radius = 0, + }, + + damage = { + default = 85, + planes = 85*2, + }, + + dance = 60, + explosionGenerator = [[custom:NONE]], + fireStarter = 0, + flightTime = 5, + groundbounce = 1, + heightmod = 0.5, + impactOnly = true, + impulseBoost = 0, + impulseFactor = 0.4, + interceptedByShieldType = 2, + model = [[chickeneggpink.s3o]], + noSelfDamage = true, + range = 300, + reloadtime = 4, + smokeTrail = true, + startVelocity = 100, + texture1 = [[]], + texture2 = [[sporetrail]], + tolerance = 10000, + tracks = true, + turnRate = 24000, + turret = true, + waterweapon = true, + weaponAcceleration = 100, + weaponType = [[MissileLauncher]], + weaponVelocity = 500, + wobble = 32000, + } \ No newline at end of file diff --git a/modularCommAPI/api_modularcomms.lua b/modularCommAPI/api_modularcomms.lua index 68b52a9a9a..167741a98e 100644 --- a/modularCommAPI/api_modularcomms.lua +++ b/modularCommAPI/api_modularcomms.lua @@ -140,7 +140,7 @@ local function LoadCommData() -- Convert chassis to correct names. for profileID, profile in pairs(newCommProfilesByProfileID) do - profile.chassis = legacyToDyncommChassisMap[profile.chassis] + profile.chassis = legacyToDyncommChassisMap[profile.chassis] or profile.chassis end for i = 1, #UnitDefs do @@ -157,13 +157,14 @@ local function LoadCommData() legacyModulesByUnitDefName[UnitDefs[i].name] = {raw = modulesRaw, human = modulesHuman} end end - + return newCommData, newCommProfilesByProfileID, newCommProfileIDsByPlayerID, newProfileIDByBaseDefID end -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- local function GetCommProfileInfo(commProfileID) + return commProfilesByProfileID[commProfileID] end From 6cfda3ceca909e5a0af8997415745f2df8cadaa3 Mon Sep 17 00:00:00 2001 From: XNTEABDSC <2364400855@qq.com> Date: Wed, 26 Nov 2025 17:25:35 +0800 Subject: [PATCH 2/3] make knight notSelectable --- gamedata/modularcomms/chassises/knight.lua | 2 +- gamedata/modularcomms/dyncomms_predefined.lua | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gamedata/modularcomms/chassises/knight.lua b/gamedata/modularcomms/chassises/knight.lua index 78222c2993..0b01a2719d 100644 --- a/gamedata/modularcomms/chassises/knight.lua +++ b/gamedata/modularcomms/chassises/knight.lua @@ -228,7 +228,7 @@ return { dyntrainer_knight={ name = "Campaign", chassis = "knight", - + notSelectable = (Spring.GetModOptions().campaign_chassis ~= "1"), modules = { -- all null because nabs want to personalize {"nullbasicweapon", "nullmodule"}, {"nullmodule", "nullmodule"}, diff --git a/gamedata/modularcomms/dyncomms_predefined.lua b/gamedata/modularcomms/dyncomms_predefined.lua index dcd742f0e1..61fefb1eb8 100644 --- a/gamedata/modularcomms/dyncomms_predefined.lua +++ b/gamedata/modularcomms/dyncomms_predefined.lua @@ -153,7 +153,9 @@ local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") for i = 1, #chassisAllDefs do local chassisDef = chassisAllDefs[i].dyncomms_predefined for key, value in pairs(chassisDef) do - ret[key]=value + if not value.notSelectable then + ret[key]=value + end end end From c92da6371c8ee12ea13c2e01d475c0c3c813dbbf Mon Sep 17 00:00:00 2001 From: XNTEABDSC <2364400855@qq.com> Date: Fri, 28 Nov 2025 12:59:08 +0800 Subject: [PATCH 3/3] formatted, and remove global ModularCommDefsShared --- LuaRules/Configs/dynamic_comm_defs.lua | 197 ++-- LuaRules/Gadgets/unit_commander_upgrade.lua | 271 +++--- LuaUI/Configs/startup_info_selector.lua | 44 +- gamedata/modularcomms/chassises/assult.lua | 484 +++++----- gamedata/modularcomms/chassises/chicken.lua | 250 ----- gamedata/modularcomms/chassises/knight.lua | 483 +++++----- gamedata/modularcomms/chassises/recon.lua | 445 +++++---- gamedata/modularcomms/chassises/strike.lua | 467 +++++----- gamedata/modularcomms/chassises/support.lua | 453 +++++---- gamedata/modularcomms/chassises_all_defs.lua | 19 +- gamedata/modularcomms/clonedefs.lua | 164 ++-- .../dyncomm_chassis_generator.lua | 17 +- gamedata/modularcomms/dyncomms_predefined.lua | 134 +-- gamedata/modularcomms/moduledefs.lua | 870 +++++++++--------- .../modularcomms/modules/chickenbioarmor.lua | 38 - .../modules/chickenbioarmorheavy.lua | 42 - gamedata/modularcomms/modules/chickenclaw.lua | 35 - .../modules/chickenflamethrower.lua | 34 - gamedata/modularcomms/modules/chickengoo.lua | 45 - .../modularcomms/modules/chickenshield.lua | 46 - .../modularcomms/modules/chickenspike.lua | 35 - .../modularcomms/modules/chickenspores.lua | 34 - gamedata/modularcomms/modules_all_defs.lua | 19 +- gamedata/modularcomms/staticcomms.lua | 403 ++++---- gamedata/modularcomms/unitdefgen.lua | 126 +-- gamedata/modularcomms/weapons/chickenclaw.lua | 31 - .../weapons/chickenflamethrower.lua | 56 -- gamedata/modularcomms/weapons/chickengoo.lua | 43 - .../modularcomms/weapons/chickenshield.lua | 32 - .../modularcomms/weapons/chickenspike.lua | 41 - .../modularcomms/weapons/chickenspores.lua | 48 - modularCommAPI/api_modularcomms.lua | 60 +- 32 files changed, 2328 insertions(+), 3138 deletions(-) delete mode 100644 gamedata/modularcomms/chassises/chicken.lua delete mode 100644 gamedata/modularcomms/modules/chickenbioarmor.lua delete mode 100644 gamedata/modularcomms/modules/chickenbioarmorheavy.lua delete mode 100644 gamedata/modularcomms/modules/chickenclaw.lua delete mode 100644 gamedata/modularcomms/modules/chickenflamethrower.lua delete mode 100644 gamedata/modularcomms/modules/chickengoo.lua delete mode 100644 gamedata/modularcomms/modules/chickenshield.lua delete mode 100644 gamedata/modularcomms/modules/chickenspike.lua delete mode 100644 gamedata/modularcomms/modules/chickenspores.lua delete mode 100644 gamedata/modularcomms/weapons/chickenclaw.lua delete mode 100644 gamedata/modularcomms/weapons/chickenflamethrower.lua delete mode 100644 gamedata/modularcomms/weapons/chickengoo.lua delete mode 100644 gamedata/modularcomms/weapons/chickenshield.lua delete mode 100644 gamedata/modularcomms/weapons/chickenspike.lua delete mode 100644 gamedata/modularcomms/weapons/chickenspores.lua diff --git a/LuaRules/Configs/dynamic_comm_defs.lua b/LuaRules/Configs/dynamic_comm_defs.lua index b8f2d36114..209902949d 100644 --- a/LuaRules/Configs/dynamic_comm_defs.lua +++ b/LuaRules/Configs/dynamic_comm_defs.lua @@ -1,8 +1,9 @@ -- mission editor compatibility Spring.GetModOptions = Spring.GetModOptions or function() return {} end -local ModularCommDefsShared_={} -ModularCommDefsShared=ModularCommDefsShared_ -ModularCommDefsShared=nil +---@class ModularCommDefsShared +local ModularCommDefsShared = {} +-- ModularCommDefsShared=ModularCommDefsShared_ +-- ModularCommDefsShared=nil local skinDefs local SKIN_FILE = "LuaRules/Configs/dynamic_comm_skins.lua" if VFS.FileExists(SKIN_FILE) then @@ -11,9 +12,9 @@ else skinDefs = {} end ---@type integer? -local LEVEL_BOUND = math.floor(tonumber(Spring.GetModOptions().max_com_level or 0)--[[@as integer]]) +local LEVEL_BOUND = math.floor(tonumber(Spring.GetModOptions().max_com_level or 0) --[[@as integer]]) if LEVEL_BOUND <= 0 then - LEVEL_BOUND = nil -- unlimited + LEVEL_BOUND = nil -- unlimited else LEVEL_BOUND = LEVEL_BOUND - 1 -- UI counts from 1 but internals count from 0 end @@ -26,17 +27,18 @@ if (Spring.GetModOptions) then local modOptions = Spring.GetModOptions() if modOptions then if modOptions.hpmult and modOptions.hpmult ~= 1 then - HP_MULT = tonumber(modOptions.hpmult)--[[@as number]] + HP_MULT = tonumber(modOptions.hpmult) --[[@as number]] end end end -ModularCommDefsShared_.HP_MULT=HP_MULT -ModularCommDefsShared_.COST_MULT=COST_MULT +ModularCommDefsShared.HP_MULT = HP_MULT +ModularCommDefsShared.COST_MULT = COST_MULT local moduleImagePath = "unitpics/" -ModularCommDefsShared_.moduleImagePath=moduleImagePath -local disableResurrect = (Spring.GetModOptions().disableresurrect == 1) or (Spring.GetModOptions().disableresurrect == "1") -ModularCommDefsShared_.disableResurrect=disableResurrect +ModularCommDefsShared.moduleImagePath = moduleImagePath +local disableResurrect = (Spring.GetModOptions().disableresurrect == 1) or +(Spring.GetModOptions().disableresurrect == "1") +ModularCommDefsShared.disableResurrect = disableResurrect ------------------------------------------------------------------------ -- Module Definitions ------------------------------------------------------------------------ @@ -58,42 +60,41 @@ local basicWeapons = { ModularCommDefsShared_.basicWeapons=basicWeapons ]=] -local forAllChassisModules={ - "nullmodule","nullbasicweapon","nulladvweapon","nulldualbasicweapon" +local forAllChassisModules = { + "nullmodule", "nullbasicweapon", "nulladvweapon", "nulldualbasicweapon" } local moduleDefNames = {} -ModularCommDefsShared_.moduleDefNames=moduleDefNames +ModularCommDefsShared.moduleDefNames = moduleDefNames local moduleDefNamesToIDs = {} -ModularCommDefsShared_.moduleDefNamesToIDs=moduleDefNamesToIDs +ModularCommDefsShared.moduleDefNamesToIDs = moduleDefNamesToIDs -ModularCommDefsShared_.applicationFunctionApplyWeapon=function (GetWeaponName) - return function (modules, sharedData) +ModularCommDefsShared.applicationFunctionApplyWeapon = function(GetWeaponName) + return function(modules, sharedData) if sharedData.noMoreWeapons then return end if not sharedData.weapon1 then - sharedData.weapon1 = GetWeaponName(modules,sharedData) + sharedData.weapon1 = GetWeaponName(modules, sharedData) else - sharedData.weapon2 = GetWeaponName(modules,sharedData) + sharedData.weapon2 = GetWeaponName(modules, sharedData) end end end -ModularCommDefsShared_.applicationFunctionApplyNoMoreWeapon=function (GetWeaponName) - return function (modules, sharedData) +ModularCommDefsShared.applicationFunctionApplyNoMoreWeapon = function(GetWeaponName) + return function(modules, sharedData) if sharedData.noMoreWeapons then return end - local weaponName = GetWeaponName(modules,sharedData) + local weaponName = GetWeaponName(modules, sharedData) sharedData.weapon1 = weaponName sharedData.weapon2 = nil sharedData.noMoreWeapons = true end end -ModularCommDefsShared_.UnitDefNames=UnitDefNames -ModularCommDefsShared_.GenAdvWeaponModule=function (def) - +ModularCommDefsShared.UnitDefNames = UnitDefNames +ModularCommDefsShared.GenAdvWeaponModule = function(def) local newDef = Spring.Utilities.CopyTable(def, true) newDef.name = newDef.name .. "_adv" newDef.slotType = "dual_basic_weapon" @@ -101,18 +102,18 @@ ModularCommDefsShared_.GenAdvWeaponModule=function (def) return newDef end local moduleDefs = {} -local SharedEnv={ModularCommDefsShared=ModularCommDefsShared_,UnitDefNames=UnitDefNames} +-- local SharedEnv={ModularCommDefsShared=ModularCommDefsShared_,UnitDefNames=UnitDefNames} -setmetatable(SharedEnv,{__index=getfenv()}) +-- setmetatable(SharedEnv,{__index=getfenv()}) -local modulesalldefs=VFS.Include("gamedata/modularcomms/modules_all_defs.lua") +local modulesalldefs = VFS.Include("gamedata/modularcomms/modules_all_defs.lua") --local moduleFiles=VFS.DirList("gamedata/modularcomms/modules", "*.lua") or {} for i = 1, #modulesalldefs do - local new_moduleDefs = modulesalldefs[i].dynamic_comm_def(ModularCommDefsShared_) + local new_moduleDefs = modulesalldefs[i].dynamic_comm_def(ModularCommDefsShared) for key, moduleDef in pairs(new_moduleDefs) do - moduleDefs[#moduleDefs+1]=moduleDef - local def=moduleDef + moduleDefs[#moduleDefs + 1] = moduleDef + local def = moduleDef if def.isBasicWeapon then local newDef = Spring.Utilities.CopyTable(def, true) newDef.name = newDef.name .. "_adv" @@ -124,18 +125,18 @@ for i = 1, #modulesalldefs do end do - local i=1 - while(i<=#moduleDefs)do - local md=moduleDefs[i] - if(md.hardcodedID and i~=md.hardcodedID) then - local b=md.hardcodedID - local mdb=moduleDefs[b] - if mdb.hardcodedID and mdb.hardcodedID==b then + local i = 1 + while (i <= #moduleDefs) do + local md = moduleDefs[i] + if (md.hardcodedID and i ~= md.hardcodedID) then + local b = md.hardcodedID + local mdb = moduleDefs[b] + if mdb.hardcodedID and mdb.hardcodedID == b then error("Both " .. md.name .. " and " .. mdb.name .. " has same hardcodedID " .. b) end - moduleDefs[i],moduleDefs[b]=moduleDefs[b],md + moduleDefs[i], moduleDefs[b] = moduleDefs[b], md else - i=i+1 + i = i + 1 end end end @@ -146,15 +147,15 @@ end --[[ Stochastic check for module IDs, not perfect but should do its job. See the error message below. ]] -if moduleDefs[ 1].name ~= "nullmodule" -or moduleDefs[ 4].name ~= "nulldualbasicweapon" -or moduleDefs[10].name ~= "commweapon_lparticlebeam" -or moduleDefs[25].name ~= "commweapon_personal_shield" -or moduleDefs[42].name ~= "module_ablative_armor" -or moduleDefs[61].name ~= "commweapon_shotgun_adv" then +if moduleDefs[1].name ~= "nullmodule" + or moduleDefs[4].name ~= "nulldualbasicweapon" + or moduleDefs[10].name ~= "commweapon_lparticlebeam" + or moduleDefs[25].name ~= "commweapon_personal_shield" + or moduleDefs[42].name ~= "module_ablative_armor" + or moduleDefs[61].name ~= "commweapon_shotgun_adv" then Spring.Echo("MODULE IDs NEED TO STAY CONSTANT BECAUSE AI HARDCODES THEM.\n" - .. "SEE https://github.com/ZeroK-RTS/Zero-K/issues/4796 \n" - .. "REMEMBER TO CHANGE CircuitAI CONFIG IF MODIFYING THE LIST!") + .. "SEE https://github.com/ZeroK-RTS/Zero-K/issues/4796 \n" + .. "REMEMBER TO CHANGE CircuitAI CONFIG IF MODIFYING THE LIST!") Script.Kill() end @@ -166,10 +167,10 @@ for name, data in pairs(skinDefs) do image = moduleImagePath .. "module_ablative_armor.png", limit = 1, cost = 0, - requireChassis = {data.chassis}, + requireChassis = { data.chassis }, requireLevel = 0, slotType = "decoration", - applicationFunction = function (modules, sharedData) + applicationFunction = function(modules, sharedData) sharedData.skinOverride = name end } @@ -181,43 +182,43 @@ for i = 1, #moduleDefs do moduleDefNamesToIDs[moduleDefs[i].name] = data end -local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") +local chassisAllDefs = VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") -local chassisList={} -for _,v in pairs(chassisAllDefs) do - local k=v.dynamic_comm_defs_name +local chassisList = {} +for _, v in pairs(chassisAllDefs) do + local k = v.dynamic_comm_defs_name moduleDefNames[k] = {} - chassisList[#chassisList+1]=k + chassisList[#chassisList + 1] = k end for _, moudleName in pairs(forAllChassisModules) do - moduleDefs[moduleDefNamesToIDs[moudleName][1]].requireChassis=chassisList + moduleDefs[moduleDefNamesToIDs[moudleName][1]].requireChassis = chassisList end -local function FindModule(moduleName,requireChassis) - local ids=moduleDefNamesToIDs[moduleName] +local function FindModule(moduleName, requireChassis) + local ids = moduleDefNamesToIDs[moduleName] if not ids then - Spring.Echo("Warning: module " ..moduleName .. " not found") + Spring.Echo("Warning: module " .. moduleName .. " not found") return nil end for _, moduleID in pairs(ids) do - local moduleDef=moduleDefs[moduleID] + local moduleDef = moduleDefs[moduleID] if not requireChassis then return moduleDef else - local foundAll=true + local foundAll = true for _, requireChassisNeeded in pairs(requireChassis) do - local found=false + local found = false for _, requireChassisHas in pairs(moduleDef.requireChassis) do - if requireChassisHas==requireChassisNeeded then - found=true + if requireChassisHas == requireChassisNeeded then + found = true break end end if not found then - foundAll=false + foundAll = false break end end @@ -229,17 +230,17 @@ local function FindModule(moduleName,requireChassis) return nil end -ModularCommDefsShared_.FindModule=FindModule +ModularCommDefsShared.FindModule = FindModule -for _,v in pairs(chassisAllDefs) do - local moduleIdentities=v.dynamic_comm_defs_modules +for _, v in pairs(chassisAllDefs) do + local moduleIdentities = v.dynamic_comm_defs_modules if moduleIdentities then for _, moduleIdentity in pairs(moduleIdentities) do - local moduleDef=FindModule(moduleIdentity.name,moduleIdentity.requireChassis) + local moduleDef = FindModule(moduleIdentity.name, moduleIdentity.requireChassis) if moduleDef then - moduleDef.requireChassis[#moduleDef.requireChassis+1] = v.dynamic_comm_defs_name + moduleDef.requireChassis[#moduleDef.requireChassis + 1] = v.dynamic_comm_defs_name else - Spring.Echo("Warning: module " ..moduleIdentity.name .. " not found") + Spring.Echo("Warning: module " .. moduleIdentity.name .. " not found") end end end @@ -249,15 +250,14 @@ for i = 1, #moduleDefs do local data = moduleDefs[i] local allowedChassis = moduleDefs[i].requireChassis or chassisList for j = 1, #allowedChassis do - local chassisName=allowedChassis[j] - local mdn_=moduleDefNames[chassisName] + local chassisName = allowedChassis[j] + local mdn_ = moduleDefNames[chassisName] if not mdn_ then - Spring.Echo("Error: dynamic_comm_defs.lua: missing chassis " .. tostring(chassisName) .. " for module " .. tostring(data.name)) - + Spring.Echo("Error: dynamic_comm_defs.lua: missing chassis " .. + tostring(chassisName) .. " for module " .. tostring(data.name)) else mdn_[data.name] = i end - end end @@ -288,7 +288,7 @@ local morphCosts = { 200, 250, } -ModularCommDefsShared_.morphCosts=morphCosts +ModularCommDefsShared.morphCosts = morphCosts local morphBuildPower = { 5, 7.5, @@ -296,28 +296,26 @@ local morphBuildPower = { 12.5, 15 } -ModularCommDefsShared_.morphBuildPower=morphBuildPower +ModularCommDefsShared.morphBuildPower = morphBuildPower local function extraLevelCostFunction(level) return level * 50 * COST_MULT end -ModularCommDefsShared_.extraLevelCostFunction=extraLevelCostFunction +ModularCommDefsShared.extraLevelCostFunction = extraLevelCostFunction -ModularCommDefsShared_.GetCloneModuleString=function (chassis,listOfCloneModules) - return function (modulesByDefID) - local res="" +ModularCommDefsShared.GetCloneModuleString = function(chassis, listOfCloneModules) + return function(modulesByDefID) + local res = "" for key, value in pairs(listOfCloneModules) do - res=res .. (modulesByDefID[moduleDefNames[chassis][value]] or 0) + res = res .. (modulesByDefID[moduleDefNames[chassis][value]] or 0) end return res end end do - - ModularCommDefsShared_.morphUnitDefFunction=function (name,GetCloneModuleString) - return function (lv) - return function (modulesByDefID) - + ModularCommDefsShared.morphUnitDefFunction = function(name, GetCloneModuleString) + return function(lv) + return function(modulesByDefID) return UnitDefNames[name .. lv .. "_" .. GetCloneModuleString(modulesByDefID)].id end end @@ -329,8 +327,8 @@ local chassisDefs = { for i = 1, #chassisAllDefs do - local chassisDef = chassisAllDefs[i].dynamic_comm_defs(ModularCommDefsShared_) - chassisDefs[#chassisDefs+1]=chassisDef + local chassisDef = chassisAllDefs[i].dynamic_comm_defs(ModularCommDefsShared) + chassisDefs[#chassisDefs + 1] = chassisDef end local chassisDefByBaseDef = {} @@ -364,7 +362,7 @@ end -- Transform from human readable format into number indexed format for i = 1, #moduleDefs do local data = moduleDefs[i] - + -- Required modules are a list of moduleDefIDs if data.requireOneOf then local newRequire = {} @@ -378,7 +376,7 @@ for i = 1, #moduleDefs do end data.requireOneOf = newRequire end - + -- Prohibiting modules are a list of moduleDefIDs too if data.prohibitingModules then local newProhibit = {} @@ -392,7 +390,7 @@ for i = 1, #moduleDefs do end data.prohibitingModules = newProhibit end - + -- Required chassis is a map indexed by chassisDefID if data.requireChassis then local newRequire = {} @@ -424,7 +422,7 @@ for i = 1, #chassisDefs do local slotData = levelData.upgradeSlots[k] if type(slotData.slotAllows) == "string" then slotData.empty = emptyModules[slotData.slotAllows] - slotData.slotAllows = {[slotData.slotAllows] = true} + slotData.slotAllows = { [slotData.slotAllows] = true } else local newSlotAllows = {} slotData.empty = emptyModules[slotData.slotAllows[1]] @@ -455,10 +453,10 @@ end local function ModuleIsValid(level, chassis, slotAllows, moduleDefID, alreadyOwned, alreadyOwned2) local data = moduleDefs[moduleDefID] if (not slotAllows[data.slotType]) or (data.requireLevel or 0) > level or - (data.requireChassis and (not data.requireChassis[chassis])) or data.unequipable then + (data.requireChassis and (not data.requireChassis[chassis])) or data.unequipable then return false end - + -- Check that requirements are met if data.requireOneOf then local foundRequirement = false @@ -475,7 +473,7 @@ local function ModuleIsValid(level, chassis, slotAllows, moduleDefID, alreadyOwn return false end end - + -- Check that nothing prohibits this module if data.prohibitingModules then for j = 1, #data.prohibitingModules do @@ -485,7 +483,6 @@ local function ModuleIsValid(level, chassis, slotAllows, moduleDefID, alreadyOwn return false end end - end -- cheapass hack to prevent cremcom dual wielding same weapon (not supported atm) @@ -534,7 +531,7 @@ local function GetUnitDefShield(unitDefNameOrID, shieldName) for num = 1, #wepTable do local wd = WeaponDefs[wepTable[num].weaponDef] if wd.type == "Shield" then - local weaponName = string.sub(wd.name, (string.find(wd.name,"commweapon") or 0), 100) + local weaponName = string.sub(wd.name, (string.find(wd.name, "commweapon") or 0), 100) if weaponName == shieldName then return wd.id, num end @@ -563,7 +560,7 @@ if ECHO_MODULES_FOR_CIRCUIT then Spring.Echo("Modules for", chassis) local printList = {} for name, chassisDefID in pairs(chassisModules) do - printList[#printList + 1] = {chassisDefID, name} + printList[#printList + 1] = { chassisDefID, name } end table.sort(printList, SortFunc) for i = 1, #printList do diff --git a/LuaRules/Gadgets/unit_commander_upgrade.lua b/LuaRules/Gadgets/unit_commander_upgrade.lua index d062d7759d..dadb140421 100644 --- a/LuaRules/Gadgets/unit_commander_upgrade.lua +++ b/LuaRules/Gadgets/unit_commander_upgrade.lua @@ -1,13 +1,13 @@ function gadget:GetInfo() - return { - name = "Commander Upgrade", - desc = "", - author = "Google Frog", - date = "30 December 2015", - license = "GNU GPL, v2 or later", - layer = 1, - enabled = true -- loaded by default? - } + return { + name = "Commander Upgrade", + desc = "", + author = "Google Frog", + date = "30 December 2015", + license = "GNU GPL, v2 or later", + layer = 1, + enabled = true -- loaded by default? + } end -------------------------------------------------------------------------------- @@ -15,19 +15,20 @@ end --SYNCED if (not gadgetHandler:IsSyncedCode()) then - return + return end include("LuaRules/Configs/constants.lua") -local INLOS = {inlos = true} +local INLOS = { inlos = true } local interallyCreatedUnit = false local internalCreationUpgradeDef local internalCreationModuleEffectData local unitCreatedShield, unitCreatedShieldNum, unitCreatedCloak, unitCreatedJammingRange, unitCreatedCloakShield, unitCreatedWeaponNums -local moduleDefs, chassisDefs, upgradeUtilities, LEVEL_BOUND, chassisDefByBaseDef, moduleDefNames, chassisDefNames = include("LuaRules/Configs/dynamic_comm_defs.lua") +local moduleDefs, chassisDefs, upgradeUtilities, LEVEL_BOUND, chassisDefByBaseDef, moduleDefNames, chassisDefNames = +include("LuaRules/Configs/dynamic_comm_defs.lua") -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- @@ -40,9 +41,9 @@ local commanderCloakShieldDef = { delay = 30, energy = 15, minrad = 64, - maxrad = 320, -- Update a number in dynamic_comm_defs + maxrad = 320, -- Update a number in dynamic_comm_defs recloakRate = 800, -- Update a number in dynamic_comm_defs - + growRate = 512, shrinkRate = 2048, selfCloak = true, @@ -82,19 +83,19 @@ local function ApplyWeaponData(unitID, weapon1, weapon2, shield, rangeMult, dama weapon1 = "commweapon_beamlaser" end end - + local chassis = Spring.GetUnitRulesParam(unitID, "comm_chassis") weapon1 = weapon1 or (chassis and chassisDefs[chassis] and chassisDefs[chassis].initWeapon) or "commweapon_beamlaser" - + if chassis and chassisDefs[chassis] and chassisDefs[chassis].secondPeashooter and (not weapon2) and Spring.GetUnitRulesParam(unitID, "comm_level") > 2 then weapon2 = "commweapon_beamlaser" end - + rangeMult = rangeMult or Spring.GetUnitRulesParam(unitID, "comm_range_mult") or 1 - Spring.SetUnitRulesParam(unitID, "comm_range_mult", rangeMult, INLOS) + Spring.SetUnitRulesParam(unitID, "comm_range_mult", rangeMult, INLOS) damageMult = damageMult or Spring.GetUnitRulesParam(unitID, "comm_damage_mult") or 1 - Spring.SetUnitRulesParam(unitID, "comm_damage_mult", damageMult, INLOS) - + Spring.SetUnitRulesParam(unitID, "comm_damage_mult", damageMult, INLOS) + local env = Spring.UnitScript.GetScriptEnv(unitID) Spring.UnitScript.CallAsUnit(unitID, env.dyncomm.UpdateWeapons, weapon1, weapon2, shield, rangeMult, damageMult) end @@ -104,24 +105,24 @@ local function ApplyModuleEffects(unitID, data, totalCost, images) local newAttributesEffect = {} newAttributesEffect.cost = totalCost / ud.metalCost - + -- Update ApplyModuleEffectsFromUnitRulesParams if any non-unitRulesParams changes are made. if data.speedMultPost or data.speedMod then - local speedMult = (data.speedMultPost or 1)*((data.speedMod or 0) + ud.speed)/ud.speed + local speedMult = (data.speedMultPost or 1) * ((data.speedMod or 0) + ud.speed) / ud.speed Spring.SetUnitRulesParam(unitID, "upgradesSpeedMult", speedMult, INLOS) end - + if data.jumpReloadMod then Spring.SetUnitRulesParam(unitID, "upgradesJumpReloadMod", data.jumpReloadMod, INLOS) if GG.SetJumpReloadMod then GG.SetJumpReloadMod(unitID, data.jumpReloadMod) end end - + if data.radarRange then Spring.SetUnitRulesParam(unitID, "radarRangeOverride", data.radarRange, INLOS) end - + if data.radarJammingRange then Spring.SetUnitRulesParam(unitID, "jammingRangeOverride", data.radarJammingRange, INLOS) Spring.SetUnitRulesParam(unitID, "comm_jamming_cost", COMMANDER_JAMMING_COST, INLOS) @@ -131,39 +132,37 @@ local function ApplyModuleEffects(unitID, data, totalCost, images) Spring.RemoveUnitCmdDesc(unitID, onOffCmd) end end - + if data.decloakDistance then Spring.SetUnitCloak(unitID, false, data.decloakDistance) Spring.SetUnitRulesParam(unitID, "comm_decloak_distance", data.decloakDistance, INLOS) end - + if data.personalCloak then Spring.SetUnitRulesParam(unitID, "comm_personal_cloak", 1, INLOS) end - + if data.areaCloak then Spring.SetUnitRulesParam(unitID, "comm_area_cloak", 1, INLOS) Spring.SetUnitRulesParam(unitID, "comm_area_cloak_upkeep", data.cloakFieldUpkeep, INLOS) Spring.SetUnitRulesParam(unitID, "comm_area_cloak_radius", data.cloakFieldRange, INLOS) Spring.SetUnitRulesParam(unitID, "comm_area_recloak_rate", data.cloakFieldRecloakRate, INLOS) end - - local buildPowerMult = ((data.bonusBuildPower or 0) + ud.buildSpeed)/ud.buildSpeed + + local buildPowerMult = ((data.bonusBuildPower or 0) + ud.buildSpeed) / ud.buildSpeed data.metalIncome = (data.metalIncome or 0) data.energyIncome = (data.energyIncome or 0) - - if buildPowerMult ~= 1 then + if buildPowerMult ~= 1 then newAttributesEffect.build = buildPowerMult - end - + if data.metalIncome and GG.Overdrive then Spring.SetUnitRulesParam(unitID, "comm_income_metal", data.metalIncome, INLOS) Spring.SetUnitRulesParam(unitID, "comm_income_energy", data.energyIncome, INLOS) GG.Overdrive.AddUnitResourceGeneration(unitID, data.metalIncome, data.energyIncome, true) end - + ---@type false|number local newHealth = false @@ -175,18 +174,16 @@ local function ApplyModuleEffects(unitID, data, totalCost, images) newAttributesEffect = newAttributesEffect or {} newAttributesEffect.healthAdd = data.healthBonus - - end - + if data.skinOverride then Spring.SetUnitRulesParam(unitID, "comm_texture", data.skinOverride, INLOS) end - + if data.bannerOverhead then Spring.SetUnitRulesParam(unitID, "comm_banner_overhead", images.overhead or "fakeunit", INLOS) end - + if data.drones or data.droneheavyslows then if data.drones then Spring.SetUnitRulesParam(unitID, "carrier_count_drone", data.drones, INLOS) @@ -198,31 +195,27 @@ local function ApplyModuleEffects(unitID, data, totalCost, images) GG.Drones_InitializeDynamicCarrier(unitID) end end - + if data.autorepairRate then Spring.SetUnitRulesParam(unitID, "comm_autorepair_rate", data.autorepairRate, INLOS) if GG.SetUnitIdleRegen then GG.SetUnitIdleRegen(unitID, 0, data.autorepairRate / 2) end end - + local _, maxHealth = Spring.GetUnitHealth(unitID) - - + + ApplyWeaponData(unitID, data.weapon1, data.weapon2, data.shield, data.rangeMult, data.damageMult) - - if newAttributesEffect then + if newAttributesEffect then newAttributesEffect.static = true GG.Attributes.AddEffect(unitID, "comm_upgrade", newAttributesEffect) if newHealth then - Spring.SetUnitHealth(unitID, newHealth) -- Override scaled health change from GG.Attributes - end - end -- Do this all the time as it will be needed almost always. @@ -236,40 +229,40 @@ local function ApplyModuleEffectsFromUnitRulesParams(unitID) Spring.RemoveUnitCmdDesc(unitID, onOffCmd) end end - + local decloakDist = Spring.GetUnitRulesParam(unitID, "comm_decloak_distance") if decloakDist then Spring.SetUnitCloak(unitID, false, decloakDist) end - + if GG.Overdrive then local mInc = Spring.GetUnitRulesParam(unitID, "comm_income_metal") local eInc = Spring.GetUnitRulesParam(unitID, "comm_income_energy") GG.Overdrive.AddUnitResourceGeneration(unitID, mInc or 0, eInc or 0, true, true) end - + if Spring.GetUnitRulesParam(unitID, "carrier_count_drone") or Spring.GetUnitRulesParam(unitID, "carrier_count_droneheavyslow") then if GG.Drones_InitializeDynamicCarrier then GG.Drones_InitializeDynamicCarrier(unitID) end end - + local autoRegen = Spring.GetUnitRulesParam(unitID, "comm_autorepair_rate") if autoRegen and GG.SetUnitIdleRegen then GG.SetUnitIdleRegen(unitID, 0, autoRegen / 2) end - + ApplyWeaponData(unitID, Spring.GetUnitRulesParam(unitID, "comm_weapon_name_1"), Spring.GetUnitRulesParam(unitID, "comm_weapon_name_2"), Spring.GetUnitRulesParam(unitID, "comm_shield_name")) - + -- Do this all the time as it will be needed almost always. GG.UpdateUnitAttributes(unitID) end local function GetModuleEffectsData(moduleList, level, chassis) local moduleByDefID = upgradeUtilities.ModuleListToByDefID(moduleList) - + local moduleEffectData = {} for i = 1, #moduleList do local moduleDef = moduleDefs[moduleList[i]] @@ -277,53 +270,55 @@ local function GetModuleEffectsData(moduleList, level, chassis) moduleDef.applicationFunction(moduleByDefID, moduleEffectData) end end - - local levelFunction = chassisDefs[chassis or 1].levelDefs[math.min(chassisDefs[chassis or 1].maxNormalLevel, level or 1)].chassisApplicationFunction + + local levelFunction = chassisDefs[chassis or 1].levelDefs + [math.min(chassisDefs[chassis or 1].maxNormalLevel, level or 1)].chassisApplicationFunction if levelFunction then levelFunction(moduleByDefID, moduleEffectData) end - + return moduleEffectData end -local function InitializeDynamicCommander(unitID, level, chassis, totalCost, name, baseUnitDefID, baseWreckID, baseHeapID, moduleList, moduleEffectData, images, profileID, staticLevel) +local function InitializeDynamicCommander(unitID, level, chassis, totalCost, name, baseUnitDefID, baseWreckID, baseHeapID, + moduleList, moduleEffectData, images, profileID, staticLevel) -- This function sets the UnitRulesParams and updates the unit attributes after -- a commander has been created. This can either happen internally due to a request -- to spawn a commander or with rezz/construction/spawning. if not moduleEffectData then moduleEffectData = GetModuleEffectsData(moduleList, level, chassis) end - + -- Start setting required unitRulesParams - Spring.SetUnitRulesParam(unitID, "comm_level", level, INLOS) - Spring.SetUnitRulesParam(unitID, "comm_chassis", chassis, INLOS) - Spring.SetUnitRulesParam(unitID, "comm_name", name, INLOS) - + Spring.SetUnitRulesParam(unitID, "comm_level", level, INLOS) + Spring.SetUnitRulesParam(unitID, "comm_chassis", chassis, INLOS) + Spring.SetUnitRulesParam(unitID, "comm_name", name, INLOS) + Spring.SetUnitRulesParam(unitID, "comm_baseUnitDefID", baseUnitDefID, INLOS) - Spring.SetUnitRulesParam(unitID, "comm_baseWreckID", baseWreckID, INLOS) - Spring.SetUnitRulesParam(unitID, "comm_baseHeapID", baseHeapID, INLOS) - + Spring.SetUnitRulesParam(unitID, "comm_baseWreckID", baseWreckID, INLOS) + Spring.SetUnitRulesParam(unitID, "comm_baseHeapID", baseHeapID, INLOS) + if profileID then - Spring.SetUnitRulesParam(unitID, "comm_profileID", profileID, INLOS) + Spring.SetUnitRulesParam(unitID, "comm_profileID", profileID, INLOS) end - + if staticLevel then -- unmorphable - Spring.SetUnitRulesParam(unitID, "comm_staticLevel", staticLevel, INLOS) + Spring.SetUnitRulesParam(unitID, "comm_staticLevel", staticLevel, INLOS) end - - + + -- Set module unitRulesParams -- Decorations are kept seperate from other module types. -- basic_weapon, adv_weapon and module all count as modules. - local counts = {module = 0, decoration = 0} + local counts = { module = 0, decoration = 0 } for i = 1, #moduleList do local moduleDefID = moduleList[i] SetUnitRulesModule(unitID, counts, moduleDefID) end SetUnitRulesModuleCounts(unitID, counts) - + ApplyModuleEffects(unitID, moduleEffectData, totalCost, images or {}) - + if staticLevel then -- Newly created commander, set to full health local _, maxHealth = Spring.GetUnitHealth(unitID) @@ -334,26 +329,26 @@ end local function Upgrades_CreateUpgradedUnit(defName, x, y, z, face, unitTeam, isBeingBuilt, upgradeDef) -- Calculate Module effects local moduleEffectData = GetModuleEffectsData(upgradeDef.moduleList, upgradeDef.level, upgradeDef.chassis) - + -- Create Unit, set appropriate global data first -- These variables are set such that other gadgets can notice the effect -- within UnitCreated. if moduleEffectData.shield then unitCreatedShield, unitCreatedShieldNum = upgradeUtilities.GetUnitDefShield(defName, moduleEffectData.shield) end - + if moduleEffectData.personalCloak then unitCreatedCloak = true end - + if moduleEffectData.radarJammingRange then unitCreatedJammingRange = COMMANDER_JAMMING_COST end - + if moduleEffectData.areaCloak then unitCreatedCloakShield = true end - + unitCreatedWeaponNums = {} if moduleEffectData.weapon1 then unitCreatedWeaponNums[moduleEffectData.weapon1] = 1 @@ -364,19 +359,19 @@ local function Upgrades_CreateUpgradedUnit(defName, x, y, z, face, unitTeam, isB if moduleEffectData.shield then unitCreatedWeaponNums[moduleEffectData.shield] = 3 end - + interallyCreatedUnit = true - + internalCreationUpgradeDef = upgradeDef internalCreationModuleEffectData = moduleEffectData - + local unitID = Spring.CreateUnit(defName, x, y, z, face, unitTeam, isBeingBuilt) - + -- Unset the variables which need to be present at unit creation interallyCreatedUnit = false internalCreationUpgradeDef = nil internalCreationModuleEffectData = nil - + unitCreatedShield = nil unitCreatedShieldNum = nil unitCreatedShield = nil @@ -384,15 +379,16 @@ local function Upgrades_CreateUpgradedUnit(defName, x, y, z, face, unitTeam, isB unitCreatedJammingRange = nil unitCreatedCloakShield = nil unitCreatedWeaponNums = nil - + if not unitID then return false end - + return unitID end -local function CreateStaticCommander(dyncommID, commProfileInfo, moduleList, moduleCost, x, y, z, facing, teamID, targetLevel) +local function CreateStaticCommander(dyncommID, commProfileInfo, moduleList, moduleCost, x, y, z, facing, teamID, + targetLevel) local chassisName = commProfileInfo.chassis local chassisModuleDefs = moduleDefNames[chassisName] or {} for i = 0, targetLevel do @@ -407,14 +403,14 @@ local function CreateStaticCommander(dyncommID, commProfileInfo, moduleList, mod end end end - + local moduleByDefID = upgradeUtilities.ModuleListToByDefID(moduleList) - + local chassisDefID = chassisDefNames[commProfileInfo.chassis] local chassisData = chassisDefs[chassisDefID] local chassisLevel = math.min(chassisData.maxNormalLevel, targetLevel) local unitDefID = chassisData.levelDefs[chassisLevel].morphUnitDefFunction(moduleByDefID) - + local upgradeDef = { level = targetLevel, staticLevel = targetLevel, @@ -428,9 +424,9 @@ local function CreateStaticCommander(dyncommID, commProfileInfo, moduleList, mod images = commProfileInfo.images, profileID = dyncommID, } - + local unitID = Upgrades_CreateUpgradedUnit(unitDefID, x, y, z, facing, teamID, false, upgradeDef) - + return unitID end @@ -439,27 +435,26 @@ local function Upgrades_CreateStarterDyncomm(dyncommID, x, y, z, facing, teamID, local commProfileInfo = GG.ModularCommAPI.GetCommProfileInfo(dyncommID) local chassisDefID = chassisDefNames[commProfileInfo.chassis] if not chassisDefID then - Spring.Echo("Incorrect dynamic comm chassis", commProfileInfo.chassis, "dyncommID: " .. dyncommID) return false end - + local chassisData = chassisDefs[chassisDefID] - + if chassisData.notSelectable and not staticLevel then Spring.Echo("Chassis not selectable", commProfileInfo.chassis) return false end - + local baseUnitDefID = commProfileInfo.baseUnitDefID or chassisData.baseUnitDef - + local chassisModuleDefs = moduleDefNames[commProfileInfo.chassis] or {} - local moduleList = {chassisModuleDefs.econ, chassisModuleDefs.module_radarnet} + local moduleList = { chassisModuleDefs.econ, chassisModuleDefs.module_radarnet } local moduleCost = 0 for i = 1, #moduleList do moduleCost = moduleCost + moduleDefs[moduleList[i]].cost end - + if commProfileInfo.decorations then for i = 1, #commProfileInfo.decorations do local decName = commProfileInfo.decorations[i] @@ -468,11 +463,12 @@ local function Upgrades_CreateStarterDyncomm(dyncommID, x, y, z, facing, teamID, end end end - + if staticLevel then - return CreateStaticCommander(dyncommID, commProfileInfo, moduleList, moduleCost, x, y, z, facing, teamID, staticLevel) + return CreateStaticCommander(dyncommID, commProfileInfo, moduleList, moduleCost, x, y, z, facing, teamID, + staticLevel) end - + local upgradeDef = { level = 0, chassis = chassisDefID, @@ -485,9 +481,9 @@ local function Upgrades_CreateStarterDyncomm(dyncommID, x, y, z, facing, teamID, images = commProfileInfo.images, profileID = dyncommID } - + local unitID = Upgrades_CreateUpgradedUnit(baseUnitDefID, x, y, z, facing, teamID, false, upgradeDef) - + return unitID end @@ -495,7 +491,7 @@ function gadget:UnitCreated(unitID, unitDefID, unitTeam) if Spring.GetUnitRulesParam(unitID, "comm_level") then return end - + if interallyCreatedUnit then InitializeDynamicCommander( unitID, @@ -514,12 +510,12 @@ function gadget:UnitCreated(unitID, unitDefID, unitTeam) ) return end - + local profileID = GG.ModularCommAPI.GetProfileIDByBaseDefID(unitDefID) if profileID then local commProfileInfo = GG.ModularCommAPI.GetCommProfileInfo(profileID) local chassisModuleDefs = moduleDefNames[commProfileInfo.chassis] or {} - + -- Add decorations local moduleList = {} if commProfileInfo.decorations then @@ -530,7 +526,7 @@ function gadget:UnitCreated(unitID, unitDefID, unitTeam) end end end - + InitializeDynamicCommander( unitID, 0, @@ -547,10 +543,10 @@ function gadget:UnitCreated(unitID, unitDefID, unitTeam) ) return end - + if chassisDefByBaseDef[unitDefID] then local chassisData = chassisDefs[chassisDefByBaseDef[unitDefID]] - + InitializeDynamicCommander( unitID, 0, @@ -575,30 +571,30 @@ local function Upgrades_GetValidAndMorphAttributes(unitID, params) if #params <= 4 then return false end - + local pLevel = params[1] local pChassis = params[2] local pAlreadyCount = params[3] local pNewCount = params[4] - + if #params ~= 4 + pAlreadyCount + pNewCount then return false end - + if Spring.GetUnitRulesParam(unitID, "comm_staticLevel") then return false end - + -- Make sure level and chassis match. local level = Spring.GetUnitRulesParam(unitID, "comm_level") local chassis = Spring.GetUnitRulesParam(unitID, "comm_chassis") if level ~= pLevel or chassis ~= pChassis then return false end - + local newLevel = level + 1 local newLevelBounded = math.min(chassisDefs[chassis].maxNormalLevel, level + 1) - + -- If unbounded level is disallowed then the comm might be invalid if LEVEL_BOUND and newLevel > LEVEL_BOUND then return false @@ -611,51 +607,51 @@ local function Upgrades_GetValidAndMorphAttributes(unitID, params) pAlreadyOwned[i] = params[index] index = index + 1 end - + -- Find the modules which are already owned local alreadyOwned = {} local fullModuleList = {} - + local moduleCount = Spring.GetUnitRulesParam(unitID, "comm_module_count") for i = 1, moduleCount do local module = Spring.GetUnitRulesParam(unitID, "comm_module_" .. i) alreadyOwned[#alreadyOwned + 1] = module fullModuleList[#fullModuleList + 1] = module end - + -- Strictly speaking sort is not required. It is for leniency table.sort(alreadyOwned) table.sort(pAlreadyOwned) - + -- alreadyOwned does not contain decoration modules so pAlreadyOwned -- should not contain decoration modules. The check fails if pAlreadyOwned -- contains decorations. if not upgradeUtilities.ModuleSetsAreIdentical(alreadyOwned, pAlreadyOwned) then return false end - + -- Check the validity of the new module set local pNewModules = {} for i = 1, pNewCount do pNewModules[#pNewModules + 1] = params[index] index = index + 1 end - + -- Finish the full modules list -- Empty module slots do not make it into this list - for i = 1, #pNewModules do + for i = 1, #pNewModules do if not moduleDefs[pNewModules[i]].emptyModule then fullModuleList[#fullModuleList + 1] = pNewModules[i] end end - + local modulesByDefID = upgradeUtilities.ModuleListToByDefID(fullModuleList) - + -- Determine Cost and check that the new modules are valid. local levelDefs = chassisDefs[chassis].levelDefs[newLevelBounded] local slotDefs = levelDefs.upgradeSlots local cost = 0 - + for i = 1, #pNewModules do local moduleDefID = pNewModules[i] if upgradeUtilities.ModuleIsValid(newLevelBounded, chassis, slotDefs[i].slotAllows, moduleDefID, modulesByDefID) then @@ -664,7 +660,7 @@ local function Upgrades_GetValidAndMorphAttributes(unitID, params) return false end end - + -- Add Decorations, they are modules but not part of the previous checks. -- Assumed to be valid here because they cannot be added by this function. local decCount = Spring.GetUnitRulesParam(unitID, "comm_decoration_count") @@ -672,25 +668,25 @@ local function Upgrades_GetValidAndMorphAttributes(unitID, params) local decoration = Spring.GetUnitRulesParam(unitID, "comm_decoration_" .. i) fullModuleList[#fullModuleList + 1] = decoration end - + local images = {} local bannerOverhead = Spring.GetUnitRulesParam(unitID, "comm_banner_overhead") if bannerOverhead then images.overhead = bannerOverhead end - + -- The command is now known to be valid. Construct the morphDef. - + if newLevel ~= newLevelBounded then cost = cost + chassisDefs[chassis].extraLevelCostFunction(newLevel) else cost = cost + levelDefs.morphBaseCost end local targetUnitDefID = levelDefs.morphUnitDefFunction(modulesByDefID) - - local morphTime = cost/levelDefs.morphBuildPower + + local morphTime = cost / levelDefs.morphBuildPower local increment = (1 / (30 * morphTime)) - + local morphDef = { upgradeDef = { name = Spring.GetUnitRulesParam(unitID, "comm_name"), @@ -717,7 +713,7 @@ local function Upgrades_GetValidAndMorphAttributes(unitID, params) cmd = nil, -- for completeness facing = nil, } - + return true, targetUnitDefID, morphDef end @@ -755,12 +751,11 @@ function gadget:Initialize() GG.Upgrades_CreateUpgradedUnit = Upgrades_CreateUpgradedUnit GG.Upgrades_CreateStarterDyncomm = Upgrades_CreateStarterDyncomm GG.Upgrades_GetValidAndMorphAttributes = Upgrades_GetValidAndMorphAttributes - + -- load active units for _, unitID in ipairs(Spring.GetAllUnits()) do local unitDefID = Spring.GetUnitDefID(unitID) local teamID = Spring.GetUnitTeam(unitID) gadget:UnitCreated(unitID, unitDefID, teamID) end - end diff --git a/LuaUI/Configs/startup_info_selector.lua b/LuaUI/Configs/startup_info_selector.lua index 25bc94e251..16b6795949 100644 --- a/LuaUI/Configs/startup_info_selector.lua +++ b/LuaUI/Configs/startup_info_selector.lua @@ -7,7 +7,8 @@ local function ReturnFalse() return false end -local noCustomComms = ((Spring.GetModOptions().commandertypes == nil or Spring.GetModOptions().commandertypes == '') and true) or false +local noCustomComms = ((Spring.GetModOptions().commandertypes == nil or Spring.GetModOptions().commandertypes == '') and true) or +false local function ReturnNoCustomComms() return noCustomComms end @@ -20,13 +21,13 @@ local optionData = {} local commDataOrdered = {} local numComms = 0 -for profileID, data in pairs( WG.ModularCommAPI.GetPlayerCommProfiles(Spring.GetMyPlayerID(), true)) do +for profileID, data in pairs(WG.ModularCommAPI.GetPlayerCommProfiles(Spring.GetMyPlayerID(), true)) do numComms = numComms + 1 commDataOrdered[numComms] = data commDataOrdered[numComms].profileID = profileID end --Spring.Echo("wololo", "Player " .. Spring.GetMyPlayerID() .. " has " .. numComms .. " comms") -table.sort(commDataOrdered, function(a,b) return a.profileID < b.profileID end) +table.sort(commDataOrdered, function(a, b) return a.profileID < b.profileID end) local chassisImages = { armcom = "LuaUI/Images/startup_info_selector/chassis_armcom.png", @@ -35,7 +36,7 @@ local chassisImages = { commsupport = "LuaUI/Images/startup_info_selector/chassis_commsupport.png", benzcom = "LuaUI/Images/startup_info_selector/chassis_benzcom.png", cremcom = "LuaUI/Images/startup_info_selector/chassis_cremcom.png", - + recon = "LuaUI/Images/startup_info_selector/chassis_commrecon.png", support = "LuaUI/Images/startup_info_selector/chassis_commsupport.png", assault = "LuaUI/Images/startup_info_selector/chassis_benzcom.png", @@ -44,13 +45,14 @@ local chassisImages = { } -local moduleDefs, chassisDefs, upgradeUtilities, LEVEL_BOUND , chassisDefByBaseDef, moduleDefNames, chassisDefNames = VFS.Include("LuaRules/Configs/dynamic_comm_defs.lua") +local moduleDefs, chassisDefs, upgradeUtilities, LEVEL_BOUND, chassisDefByBaseDef, moduleDefNames, chassisDefNames = VFS +.Include("LuaRules/Configs/dynamic_comm_defs.lua") -- chassisDefs.chassisImage ---@cast chassisDefs table ---@cast moduleDefNames table for key, value in pairs(chassisDefs) do - chassisImages[value.name]=value.chassisImage or chassisImages[value.name] + chassisImages[value.name] = value.chassisImage or chassisImages[value.name] end local colorWeapon = "\255\255\32\32" @@ -61,25 +63,25 @@ local colorModule = "\255\128\128\255" local function WriteTooltip(profileID) local commData = WG.ModularCommAPI.GetCommProfileInfo(profileID) local str = '' - for i=1,#commData.modules do - str = str .. "\nLEVEL "..(i + 1) .. "\n\tModules:" -- TODO calculate metal cost + for i = 1, #commData.modules do + str = str .. "\nLEVEL " .. (i + 1) .. "\n\tModules:" -- TODO calculate metal cost for j, modulename in pairs(commData.modules[i]) do local chassisModuleDefs = moduleDefNames[commData.chassis] or {} if chassisModuleDefs[modulename] then local moduleDef = moduleDefs[chassisModuleDefs[modulename]] local substr = moduleDef.humanName - + -- assign color if (modulename):find("commweapon_") then - substr = colorWeapon..substr + substr = colorWeapon .. substr elseif (modulename):find("conversion_") then - substr = colorConversion..substr + substr = colorConversion .. substr elseif (modulename):find("weaponmod_") then - substr = colorWeaponMod..substr + substr = colorWeaponMod .. substr else - substr = colorModule..substr + substr = colorModule .. substr end - str = str.."\n\t\t"..substr.."\008" + str = str .. "\n\t\t" .. substr .. "\008" end end end @@ -88,18 +90,18 @@ end local function GetCommSelectTemplate(num, data) local commProfileID = data.profileID - + local option = { name = data.name, - tooltip = "Select "..data.name..WriteTooltip(commProfileID), + tooltip = "Select " .. data.name .. WriteTooltip(commProfileID), image = chassisImages[data.chassis], - cmd = "customcomm:"..commProfileID, ----@diagnostic disable-next-line: undefined-global + cmd = "customcomm:" .. commProfileID, + ---@diagnostic disable-next-line: undefined-global unitname = comm1Name, commProfile = commProfileID, - trainer = string.find(commProfileID, "trainer") ~= nil, -- FIXME should probably be in the def table + trainer = string.find(commProfileID, "trainer") ~= nil, -- FIXME should probably be in the def table } - + return option end @@ -109,7 +111,7 @@ end local i = 0 for i = 1, numComms do local option = GetCommSelectTemplate(i, commDataOrdered[i]) - optionData[#optionData+1] = option + optionData[#optionData + 1] = option end diff --git a/gamedata/modularcomms/chassises/assult.lua b/gamedata/modularcomms/chassises/assult.lua index 8cdc6439b4..7afc6dcdf8 100644 --- a/gamedata/modularcomms/chassises/assult.lua +++ b/gamedata/modularcomms/chassises/assult.lua @@ -1,245 +1,245 @@ return { - clonedefs={ - dynassault1 = { - dynassault0 = { - level = 0, - customparams = {shield_emit_height = 32.5}, - }, - dynassault2 = { - level = 2, - collisionvolumescales = [[50 60 50]], - mainstats = {health = 5000, objectname = "benzcom2.s3o"}, - customparams = {modelradius = [[30]], shield_emit_height = 35.75}, - wreckmodel = "benzcom2_wreck.s3o", - }, - dynassault3 = { - level = 3, - collisionvolumescales = [[55 65 55]], - mainstats = {health = 5700, objectname = "benzcom3.s3o",}, - customparams = {modelradius = [[33]], shield_emit_height = 39}, - wreckmodel = "benzcom3_wreck.s3o", - }, - dynassault4 = { - level = 4, - collisionvolumescales = [[58 68 58]], - mainstats = {health = 6600, objectname = "benzcom4.s3o",}, - customparams = {modelradius = [[34]], shield_emit_height = 40.625}, - wreckmodel = "benzcom4_wreck.s3o", - }, - dynassault5 = { - level = 5, - collisionvolumescales = [[60 71 60]], - mainstats = {health = 7600, objectname = "benzcom5.s3o",}, - customparams = {modelradius = [[36]], shield_emit_height = 42.25}, - wreckmodel = "benzcom5_wreck.s3o", - }, - }, - }, - dynamic_comm_defs_name="assault", - dynamic_comm_defs=function(shared) - - shared=ModularCommDefsShared or shared - local extraLevelCostFunction=shared.extraLevelCostFunction - local morphBuildPower=shared.morphBuildPower - local morphCosts=shared.morphCosts - local COST_MULT=shared.COST_MULT - local GetCloneModuleString=shared.GetCloneModuleString - local morphUnitDefFunction=shared.morphUnitDefFunction - local moduleDefNames=shared.moduleDefNames + clonedefs = { + dynassault1 = { + dynassault0 = { + level = 0, + customparams = { shield_emit_height = 32.5 }, + }, + dynassault2 = { + level = 2, + collisionvolumescales = [[50 60 50]], + mainstats = { health = 5000, objectname = "benzcom2.s3o" }, + customparams = { modelradius = [[30]], shield_emit_height = 35.75 }, + wreckmodel = "benzcom2_wreck.s3o", + }, + dynassault3 = { + level = 3, + collisionvolumescales = [[55 65 55]], + mainstats = { health = 5700, objectname = "benzcom3.s3o", }, + customparams = { modelradius = [[33]], shield_emit_height = 39 }, + wreckmodel = "benzcom3_wreck.s3o", + }, + dynassault4 = { + level = 4, + collisionvolumescales = [[58 68 58]], + mainstats = { health = 6600, objectname = "benzcom4.s3o", }, + customparams = { modelradius = [[34]], shield_emit_height = 40.625 }, + wreckmodel = "benzcom4_wreck.s3o", + }, + dynassault5 = { + level = 5, + collisionvolumescales = [[60 71 60]], + mainstats = { health = 7600, objectname = "benzcom5.s3o", }, + customparams = { modelradius = [[36]], shield_emit_height = 42.25 }, + wreckmodel = "benzcom5_wreck.s3o", + }, + }, + }, + dynamic_comm_defs_name = "assault", + ---@param shared ModularCommDefsShared + dynamic_comm_defs = function(shared) + + local extraLevelCostFunction = shared.extraLevelCostFunction + local morphBuildPower = shared.morphBuildPower + local morphCosts = shared.morphCosts + local COST_MULT = shared.COST_MULT + local GetCloneModuleString = shared.GetCloneModuleString + local morphUnitDefFunction = shared.morphUnitDefFunction + local moduleDefNames = shared.moduleDefNames - local function GetAssaultCloneModulesString(modulesByDefID) - return (modulesByDefID[moduleDefNames.assault.commweapon_personal_shield] or 0) .. - (modulesByDefID[moduleDefNames.assault.commweapon_areashield] or 0) - end + local function GetAssaultCloneModulesString(modulesByDefID) + return (modulesByDefID[moduleDefNames.assault.commweapon_personal_shield] or 0) .. + (modulesByDefID[moduleDefNames.assault.commweapon_areashield] or 0) + end - return { - name = "assault", - humanName = "Guardian", - baseUnitDef = UnitDefNames and UnitDefNames["dynassault0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - secondPeashooter = false, - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 1 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault0"].id - end, - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 1 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault1_" .. GetAssaultCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.commweapon_beamlaser, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 2 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault2_" .. GetAssaultCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 2 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault3_" .. GetAssaultCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.commweapon_beamlaser_adv, - slotAllows = {"dual_basic_weapon", "adv_weapon"}, - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 2 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault4_" .. GetAssaultCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - sharedData.drones = (sharedData.drones or 0) + 3 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynassault5_" .. GetAssaultCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - } - } - end, - dyncomm_chassis_generator={ - name = "dynassault1", - weapons = { - "commweapon_peashooter", - "commweapon_rocketlauncher", -- 430 - "commweapon_rocketlauncher_napalm", -- 430 - "commweapon_rocketlauncher", -- 430 - "commweapon_rocketlauncher_napalm", -- 430 - "commweapon_beamlaser", - "commweapon_heatray", - "commweapon_heavymachinegun", - "commweapon_flamethrower", - "commweapon_riotcannon", - "commweapon_riotcannon_napalm", - "commweapon_peashooter", - "commweapon_beamlaser", - "commweapon_heatray", - "commweapon_heavymachinegun", - "commweapon_flamethrower", - "commweapon_riotcannon", - "commweapon_riotcannon_napalm", - "commweapon_hpartillery", - "commweapon_hpartillery_napalm", - "commweapon_disintegrator", - "commweapon_napalmgrenade", - "commweapon_slamrocket", - "commweapon_clusterbomb", - -- Space for shield - } - }, - dyncomms_predefined={ - dyntrainer_assault = { - name = "Guardian", - chassis = "assault", - modules = { - {"commweapon_heavymachinegun", "module_radarnet"}, - {"module_ablative_armor", "module_autorepair"}, - {"commweapon_shotgun", "commweapon_personal_shield", "module_heavy_armor"}, - {"module_dmg_booster", "module_dmg_booster", "module_heavy_armor"}, - {"conversion_disruptor","module_dmg_booster", "module_heavy_armor"}, - }, - --decorations = {"banner_overhead"}, - --images = {overhead = "166"} - }, - }, - staticcomms={ - "dynassault", - {{0, 0}, {1, 0}, {1, 1}, {1, 1}, {1, 1}}, - {"module_personal_shield", "module_areashield"} - } -} \ No newline at end of file + return { + name = "assault", + humanName = "Guardian", + baseUnitDef = UnitDefNames and UnitDefNames["dynassault0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + secondPeashooter = false, + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 1 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault0"].id + end, + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 1 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault1_" .. GetAssaultCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.commweapon_beamlaser, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 2 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault2_" .. GetAssaultCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 2 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault3_" .. GetAssaultCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.commweapon_beamlaser_adv, + slotAllows = { "dual_basic_weapon", "adv_weapon" }, + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 2 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault4_" .. GetAssaultCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + sharedData.drones = (sharedData.drones or 0) + 3 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynassault5_" .. GetAssaultCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.assault.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, + dyncomm_chassis_generator = { + name = "dynassault1", + weapons = { + "commweapon_peashooter", + "commweapon_rocketlauncher", -- 430 + "commweapon_rocketlauncher_napalm", -- 430 + "commweapon_rocketlauncher", -- 430 + "commweapon_rocketlauncher_napalm", -- 430 + "commweapon_beamlaser", + "commweapon_heatray", + "commweapon_heavymachinegun", + "commweapon_flamethrower", + "commweapon_riotcannon", + "commweapon_riotcannon_napalm", + "commweapon_peashooter", + "commweapon_beamlaser", + "commweapon_heatray", + "commweapon_heavymachinegun", + "commweapon_flamethrower", + "commweapon_riotcannon", + "commweapon_riotcannon_napalm", + "commweapon_hpartillery", + "commweapon_hpartillery_napalm", + "commweapon_disintegrator", + "commweapon_napalmgrenade", + "commweapon_slamrocket", + "commweapon_clusterbomb", + -- Space for shield + } + }, + dyncomms_predefined = { + dyntrainer_assault = { + name = "Guardian", + chassis = "assault", + modules = { + { "commweapon_heavymachinegun", "module_radarnet" }, + { "module_ablative_armor", "module_autorepair" }, + { "commweapon_shotgun", "commweapon_personal_shield", "module_heavy_armor" }, + { "module_dmg_booster", "module_dmg_booster", "module_heavy_armor" }, + { "conversion_disruptor", "module_dmg_booster", "module_heavy_armor" }, + }, + --decorations = {"banner_overhead"}, + --images = {overhead = "166"} + }, + }, + staticcomms = { + "dynassault", + { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 1, 1 }, { 1, 1 } }, + { "module_personal_shield", "module_areashield" } + } +} diff --git a/gamedata/modularcomms/chassises/chicken.lua b/gamedata/modularcomms/chassises/chicken.lua deleted file mode 100644 index 59e46a4826..0000000000 --- a/gamedata/modularcomms/chassises/chicken.lua +++ /dev/null @@ -1,250 +0,0 @@ - -local nomainstates={ - collisionvolumescales=true, - modelradius=true, - explodeas=true, - selfdestructas=true, - footprintx=true, - footprintz=true, - movementclass=true -} -return { - clonedefs={ - dynchicken1 = { - dynchicken0 = { - level = 0, - customparams = {shield_emit_height = 30}, - nomainstats=nomainstates, - }, - dynchicken2 = { - level = 2, - mainstats = {health = 4600}, - customparams = {def_scale=1.2}, - nomainstats=nomainstates, - }, - dynchicken3 = { - level = 3, - mainstats = {health = 5200}, - customparams = {def_scale=1.4}, - nomainstats=nomainstates, - }, - dynchicken4 = { - level = 4, - mainstats = {health = 5800}, - customparams = {def_scale=1.6}, - nomainstats=nomainstates, - }, - dynchicken5 = { - level = 5, - mainstats = {health = 6400}, - customparams = {def_scale=1.7}, - nomainstats=nomainstates, - }, - }, - }, - dynamic_comm_defs_name="chicken", - dynamic_comm_defs_modules={ - { - name = "commweapon_personal_shield", - }, - { - name = "module_radarnet", - }, - { - requireChassis = { - "support", - }, - name = "module_resurrect", - }, - { - name = "module_dmg_booster", - },{ - requireChassis = { - "assault", - }, - name = "module_high_power_servos", - }, - { - name = "module_adv_targeting", - },{ - requireChassis = { - [1] = "recon", - }, - name = "module_adv_nano", - },{ - name = "banner_overhead", - }, - }, - dynamic_comm_defs=function(shared) - shared=ModularCommDefsShared or shared - local extraLevelCostFunction=shared.extraLevelCostFunction - local morphBuildPower=shared.morphBuildPower - local morphCosts=shared.morphCosts - local COST_MULT=shared.COST_MULT - local GetCloneModuleString=shared.GetCloneModuleString - local morphUnitDefFunction=shared.morphUnitDefFunction - local mymorphUnitDefFunction=morphUnitDefFunction("dynchicken",GetCloneModuleString("chicken",{ - "commweapon_personal_shield","commweapon_chickenshield" - })) - local moduleDefNames=shared.moduleDefNames - - return { - name = "chicken", - humanName = "Chicken", - baseUnitDef = UnitDefNames and UnitDefNames["dynchicken0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - secondPeashooter = false, - chassisImage="unitpics/chickenbroodqueen.png", - initWeapon="commweapon_chickenspores", - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = mymorphUnitDefFunction(1), - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 8 - end, - morphUnitDefFunction = mymorphUnitDefFunction(1), - upgradeSlots = { - { - defaultModule = moduleDefNames.chicken.commweapon_chickenspores, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.chicken.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12 - end, - morphUnitDefFunction = mymorphUnitDefFunction(2), - upgradeSlots = { - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.assault.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 16 - end, - morphUnitDefFunction = mymorphUnitDefFunction(3), - upgradeSlots = { - { - defaultModule = moduleDefNames.chicken.commweapon_beamlaser_adv, - slotAllows = {"dual_basic_weapon", "adv_weapon"}, - }, - { - defaultModule = moduleDefNames.chicken.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.chicken.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 20 - end, - morphUnitDefFunction = mymorphUnitDefFunction(4), - upgradeSlots = { - { - defaultModule = moduleDefNames.chicken.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.chicken.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.chicken.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 25 - end, - morphUnitDefFunction = mymorphUnitDefFunction(5), - upgradeSlots = { - { - defaultModule = moduleDefNames.chicken.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.chicken.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.chicken.nullmodule, - slotAllows = "module", - }, - }, - }, - } - } - end, - dyncomm_chassis_generator={ - name="dynchicken1", - weapons={ - --"commweapon_beamlaser", - "commweapon_chickenclaw", - "commweapon_chickenclaw", - "commweapon_chickengoo", - "commweapon_chickenspike", - "commweapon_chickenspike", - "commweapon_chickenspores", - "commweapon_chickenspores", - "commweapon_chickenflamethrower", - "commweapon_chickenflamethrower", - --"commweapon_personal_shield", - } - }, - dyncomms_predefined={ - dyntrainer_chicken = { - name = "Chicken", - chassis = "chicken", - - modules = { -- all null because nabs want to personalize - {"nullbasicweapon", "nullmodule"}, - {"nullmodule", "nullmodule"}, - {"nulladvweapon", "nullmodule", "nullmodule"}, - {"nullmodule", "nullmodule", "nullmodule"}, - {"nullmodule", "nullmodule", "nullmodule"}, - }, - } - }, - staticcomms={ -"dynchicken", - {{0,0}, {1,0}, {1,1}, {1,1}, {1,1}}, - {"module_personal_shield","module_chickenshield"} - } -} \ No newline at end of file diff --git a/gamedata/modularcomms/chassises/knight.lua b/gamedata/modularcomms/chassises/knight.lua index 0b01a2719d..666e768dd0 100644 --- a/gamedata/modularcomms/chassises/knight.lua +++ b/gamedata/modularcomms/chassises/knight.lua @@ -1,246 +1,245 @@ return { - clonedefs={ - dynknight1 = { - dynknight0 = { - level = 0, - customparams = {shield_emit_height = 30}, - }, - dynknight2 = { - level = 2, - mainstats = {health = 4600, objectname = "cremcom2.s3o", collisionvolumescales = [[50 55 50]],}, - customparams = {modelradius = [[28]], shield_emit_height = 33}, - wreckmodel = "cremcom2_dead.s3o", - }, - dynknight3 = { - level = 3, - mainstats = {health = 5200, objectname = "cremcom3.s3o", collisionvolumescales = [[55 60 55]],}, - customparams = {modelradius = [[30]], shield_emit_height = 36}, - wreckmodel = "cremcom3_dead.s3o", - }, - dynknight4 = { - level = 4, - mainstats = {health = 5800, objectname = "cremcom4.s3o", collisionvolumescales = [[60 65 60]],}, - customparams = {modelradius = [[33]], shield_emit_height = 37.5}, - wreckmodel = "cremcom4_dead.s3o", - }, - dynknight5 = { - level = 5, - mainstats = {health = 6400, objectname = "cremcom5.s3o", collisionvolumescales = [[65 70 65]],}, - customparams = {modelradius = [[35]], shield_emit_height = 39}, - wreckmodel = "cremcom5_dead.s3o", - }, - }, - }, - dyncomm_chassis_generator={ - name = "dynknight1", - weapons = { - -- Aiming from earlier weapons is overridden by later - "commweapon_peashooter", - "commweapon_rocketlauncher", -- 430 - "commweapon_rocketlauncher_napalm", -- 430 - "commweapon_missilelauncher", -- 415 - "commweapon_hparticlebeam", -- 390 - "commweapon_beamlaser", -- 330 - "commweapon_lightninggun", -- 300 - "commweapon_lightninggun_improved", -- 300 - "commweapon_lparticlebeam", -- 300 - "commweapon_riotcannon", -- 300 - "commweapon_riotcannon_napalm", -- 300 - "commweapon_disruptor", -- 300 - "commweapon_heatray", -- 300 - "commweapon_shotgun", -- 290 - "commweapon_shotgun_disrupt", -- 290 - "commweapon_heavymachinegun", -- 285 - "commweapon_heavymachinegun_disrupt", -- 285 - "commweapon_flamethrower", -- 270 - "commweapon_multistunner", - "commweapon_multistunner_improved", - "commweapon_peashooter", - "commweapon_hpartillery", - "commweapon_hpartillery_napalm", - "commweapon_disintegrator", - "commweapon_napalmgrenade", - "commweapon_slamrocket", - "commweapon_disruptorbomb", - "commweapon_concussion", - "commweapon_clusterbomb", - "commweapon_shockrifle", - -- Space for shield - } - }, - dynamic_comm_defs_name="knight", - dynamic_comm_defs=function(shared) - - shared=ModularCommDefsShared or shared - local extraLevelCostFunction=shared.extraLevelCostFunction - local morphBuildPower=shared.morphBuildPower - local morphCosts=shared.morphCosts - local COST_MULT=shared.COST_MULT - local GetCloneModuleString=shared.GetCloneModuleString - local morphUnitDefFunction=shared.morphUnitDefFunction - local moduleDefNames=shared.moduleDefNames + clonedefs = { + dynknight1 = { + dynknight0 = { + level = 0, + customparams = { shield_emit_height = 30 }, + }, + dynknight2 = { + level = 2, + mainstats = { health = 4600, objectname = "cremcom2.s3o", collisionvolumescales = [[50 55 50]], }, + customparams = { modelradius = [[28]], shield_emit_height = 33 }, + wreckmodel = "cremcom2_dead.s3o", + }, + dynknight3 = { + level = 3, + mainstats = { health = 5200, objectname = "cremcom3.s3o", collisionvolumescales = [[55 60 55]], }, + customparams = { modelradius = [[30]], shield_emit_height = 36 }, + wreckmodel = "cremcom3_dead.s3o", + }, + dynknight4 = { + level = 4, + mainstats = { health = 5800, objectname = "cremcom4.s3o", collisionvolumescales = [[60 65 60]], }, + customparams = { modelradius = [[33]], shield_emit_height = 37.5 }, + wreckmodel = "cremcom4_dead.s3o", + }, + dynknight5 = { + level = 5, + mainstats = { health = 6400, objectname = "cremcom5.s3o", collisionvolumescales = [[65 70 65]], }, + customparams = { modelradius = [[35]], shield_emit_height = 39 }, + wreckmodel = "cremcom5_dead.s3o", + }, + }, + }, + dyncomm_chassis_generator = { + name = "dynknight1", + weapons = { + -- Aiming from earlier weapons is overridden by later + "commweapon_peashooter", + "commweapon_rocketlauncher", -- 430 + "commweapon_rocketlauncher_napalm", -- 430 + "commweapon_missilelauncher", -- 415 + "commweapon_hparticlebeam", -- 390 + "commweapon_beamlaser", -- 330 + "commweapon_lightninggun", -- 300 + "commweapon_lightninggun_improved", -- 300 + "commweapon_lparticlebeam", -- 300 + "commweapon_riotcannon", -- 300 + "commweapon_riotcannon_napalm", -- 300 + "commweapon_disruptor", -- 300 + "commweapon_heatray", -- 300 + "commweapon_shotgun", -- 290 + "commweapon_shotgun_disrupt", -- 290 + "commweapon_heavymachinegun", -- 285 + "commweapon_heavymachinegun_disrupt", -- 285 + "commweapon_flamethrower", -- 270 + "commweapon_multistunner", + "commweapon_multistunner_improved", + "commweapon_peashooter", + "commweapon_hpartillery", + "commweapon_hpartillery_napalm", + "commweapon_disintegrator", + "commweapon_napalmgrenade", + "commweapon_slamrocket", + "commweapon_disruptorbomb", + "commweapon_concussion", + "commweapon_clusterbomb", + "commweapon_shockrifle", + -- Space for shield + } + }, + dynamic_comm_defs_name = "knight", + ---@param shared ModularCommDefsShared + dynamic_comm_defs = function(shared) + local extraLevelCostFunction = shared.extraLevelCostFunction + local morphBuildPower = shared.morphBuildPower + local morphCosts = shared.morphCosts + local COST_MULT = shared.COST_MULT + local GetCloneModuleString = shared.GetCloneModuleString + local morphUnitDefFunction = shared.morphUnitDefFunction + local moduleDefNames = shared.moduleDefNames - local function GetKnightCloneModulesString(modulesByDefID) - return (modulesByDefID[moduleDefNames.knight.commweapon_personal_shield] or 0) .. - (modulesByDefID[moduleDefNames.knight.commweapon_areashield] or 0) .. - (modulesByDefID[moduleDefNames.knight.module_resurrect] or 0) .. - (modulesByDefID[moduleDefNames.knight.module_jumpjet] or 0) - end + local function GetKnightCloneModulesString(modulesByDefID) + return (modulesByDefID[moduleDefNames.knight.commweapon_personal_shield] or 0) .. + (modulesByDefID[moduleDefNames.knight.commweapon_areashield] or 0) .. + (modulesByDefID[moduleDefNames.knight.module_resurrect] or 0) .. + (modulesByDefID[moduleDefNames.knight.module_jumpjet] or 0) + end - return { - name = "knight", - humanName = "Knight", - baseUnitDef = UnitDefNames and UnitDefNames["dynknight0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - notSelectable = (Spring.GetModOptions().campaign_chassis ~= "1"), - secondPeashooter = true, - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - -- Level 1 is the same as level 0 in stats and has support for clone modules (such as shield). - return UnitDefNames["dynknight1_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 8 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynknight1_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.knight.commweapon_beamlaser, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynknight2_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 16 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynknight3_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.knight.commweapon_beamlaser_adv, - slotAllows = {"dual_basic_weapon", "adv_weapon"}, - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 20 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynknight4_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 25 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynknight5_" .. GetKnightCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.knight.nullmodule, - slotAllows = "module", - }, - }, - }, - } - } - end, - dyncomms_predefined={ - dyntrainer_knight={ - name = "Campaign", - chassis = "knight", - notSelectable = (Spring.GetModOptions().campaign_chassis ~= "1"), - modules = { -- all null because nabs want to personalize - {"nullbasicweapon", "nullmodule"}, - {"nullmodule", "nullmodule"}, - {"nulladvweapon", "nullmodule", "nullmodule"}, - {"nullmodule", "nullmodule", "nullmodule"}, - {"nullmodule", "nullmodule", "nullmodule"}, - }, - } - }, - staticcomms={ -"dynknight", - {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, - {"module_personal_shield", "module_areashield", "module_resurrect", "module_jumpjet"} - } -} \ No newline at end of file + return { + name = "knight", + humanName = "Knight", + baseUnitDef = UnitDefNames and UnitDefNames["dynknight0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + notSelectable = (Spring.GetModOptions().campaign_chassis ~= "1"), + secondPeashooter = true, + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + -- Level 1 is the same as level 0 in stats and has support for clone modules (such as shield). + return UnitDefNames["dynknight1_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 8 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynknight1_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.knight.commweapon_beamlaser, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynknight2_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 16 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynknight3_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.knight.commweapon_beamlaser_adv, + slotAllows = { "dual_basic_weapon", "adv_weapon" }, + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 20 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynknight4_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 25 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynknight5_" .. GetKnightCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.knight.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, + dyncomms_predefined = { + dyntrainer_knight = { + name = "Campaign", + chassis = "knight", + notSelectable = (Spring.GetModOptions().campaign_chassis ~= "1"), + modules = { -- all null because nabs want to personalize + { "nullbasicweapon", "nullmodule" }, + { "nullmodule", "nullmodule" }, + { "nulladvweapon", "nullmodule", "nullmodule" }, + { "nullmodule", "nullmodule", "nullmodule" }, + { "nullmodule", "nullmodule", "nullmodule" }, + }, + } + }, + staticcomms = { + "dynknight", + { { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 } }, + { "module_personal_shield", "module_areashield", "module_resurrect", "module_jumpjet" } + } +} diff --git a/gamedata/modularcomms/chassises/recon.lua b/gamedata/modularcomms/chassises/recon.lua index 22604acc19..170bfa28de 100644 --- a/gamedata/modularcomms/chassises/recon.lua +++ b/gamedata/modularcomms/chassises/recon.lua @@ -1,227 +1,226 @@ return { - clonedefs={ - dynrecon1 = { - dynrecon0 = { - level = 0, - customparams = {shield_emit_height = 30}, - }, - dynrecon2 = { - level = 2, - mainstats = {health = 3400, objectname = "commrecon2.s3o", aimposoffset = [[0 12 0]]}, - customparams = {shield_emit_height = 33, jump_reload = 20, jump_speed = 4.75}, - wreckmodel = "commrecon2_dead.s3o", - }, - dynrecon3 = { - level = 3, - mainstats = {health = 3600, objectname = "commrecon3.s3o", aimposoffset = [[0 14 0]]}, - customparams = {shield_emit_height = 36, jump_reload = 20, jump_speed = 5}, - wreckmodel = "commrecon3_dead.s3o", - }, - dynrecon4 = { - level = 4, - mainstats = {health = 3800, objectname = "commrecon4.s3o", aimposoffset = [[0 16 0]]}, - customparams = {shield_emit_height = 37.5, jump_reload = 18, jump_speed = 5.25}, - wreckmodel = "commrecon4_dead.s3o", - }, - dynrecon5 = { - level = 5, - mainstats = {health = 4000, objectname = "commrecon5.s3o", aimposoffset = [[0 18 0]]}, - customparams = {shield_emit_height = 39, jump_reload = 16, jump_speed = 5.5}, - wreckmodel = "commrecon5_dead.s3o", - }, - }, - }, - dynamic_comm_defs_name="recon", - dynamic_comm_defs=function(shared) - - shared=ModularCommDefsShared or shared - local extraLevelCostFunction=shared.extraLevelCostFunction - local morphBuildPower=shared.morphBuildPower - local morphCosts=shared.morphCosts - local COST_MULT=shared.COST_MULT - local GetCloneModuleString=shared.GetCloneModuleString - local morphUnitDefFunction=shared.morphUnitDefFunction - local moduleDefNames=shared.moduleDefNames + clonedefs = { + dynrecon1 = { + dynrecon0 = { + level = 0, + customparams = { shield_emit_height = 30 }, + }, + dynrecon2 = { + level = 2, + mainstats = { health = 3400, objectname = "commrecon2.s3o", aimposoffset = [[0 12 0]] }, + customparams = { shield_emit_height = 33, jump_reload = 20, jump_speed = 4.75 }, + wreckmodel = "commrecon2_dead.s3o", + }, + dynrecon3 = { + level = 3, + mainstats = { health = 3600, objectname = "commrecon3.s3o", aimposoffset = [[0 14 0]] }, + customparams = { shield_emit_height = 36, jump_reload = 20, jump_speed = 5 }, + wreckmodel = "commrecon3_dead.s3o", + }, + dynrecon4 = { + level = 4, + mainstats = { health = 3800, objectname = "commrecon4.s3o", aimposoffset = [[0 16 0]] }, + customparams = { shield_emit_height = 37.5, jump_reload = 18, jump_speed = 5.25 }, + wreckmodel = "commrecon4_dead.s3o", + }, + dynrecon5 = { + level = 5, + mainstats = { health = 4000, objectname = "commrecon5.s3o", aimposoffset = [[0 18 0]] }, + customparams = { shield_emit_height = 39, jump_reload = 16, jump_speed = 5.5 }, + wreckmodel = "commrecon5_dead.s3o", + }, + }, + }, + dynamic_comm_defs_name = "recon", + ---@param shared ModularCommDefsShared + dynamic_comm_defs = function(shared) + local extraLevelCostFunction = shared.extraLevelCostFunction + local morphBuildPower = shared.morphBuildPower + local morphCosts = shared.morphCosts + local COST_MULT = shared.COST_MULT + local GetCloneModuleString = shared.GetCloneModuleString + local morphUnitDefFunction = shared.morphUnitDefFunction + local moduleDefNames = shared.moduleDefNames - local function GetReconCloneModulesString(modulesByDefID) - return (modulesByDefID[moduleDefNames.recon.commweapon_personal_shield] or 0) - end + local function GetReconCloneModulesString(modulesByDefID) + return (modulesByDefID[moduleDefNames.recon.commweapon_personal_shield] or 0) + end - return { - name = "recon", - humanName = "Recon", - baseUnitDef = UnitDefNames and UnitDefNames["dynrecon0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon0"].id - end, - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon1_" .. GetReconCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.recon.commweapon_beamlaser, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon2_" .. GetReconCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon3_" .. GetReconCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.recon.commweapon_disruptorbomb, - slotAllows = "adv_weapon", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon4_" .. GetReconCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynrecon5_" .. GetReconCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.recon.nullmodule, - slotAllows = "module", - }, - }, - }, - } - } - end, + return { + name = "recon", + humanName = "Recon", + baseUnitDef = UnitDefNames and UnitDefNames["dynrecon0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon0"].id + end, + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon1_" .. GetReconCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.recon.commweapon_beamlaser, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon2_" .. GetReconCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon3_" .. GetReconCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.recon.commweapon_disruptorbomb, + slotAllows = "adv_weapon", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon4_" .. GetReconCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynrecon5_" .. GetReconCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.recon.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, - dyncomm_chassis_generator={ - name = "dynrecon1", - weapons = { - "commweapon_peashooter", - "commweapon_beamlaser", - "commweapon_lparticlebeam", - "commweapon_disruptor", - "commweapon_shotgun", - "commweapon_shotgun_disrupt", - "commweapon_lightninggun", - "commweapon_lightninggun_improved", - "commweapon_flamethrower", - "commweapon_heavymachinegun", - "commweapon_heavymachinegun_disrupt", - "commweapon_multistunner", - "commweapon_multistunner_improved", - "commweapon_napalmgrenade", - "commweapon_clusterbomb", - "commweapon_disruptorbomb", - "commweapon_concussion", - -- Space for shield - } - }, - dyncomms_predefined={ - dyntrainer_recon = { - name = "Recon", - chassis = "recon", - modules = { - {"commweapon_heavymachinegun", "module_radarnet"}, - {"module_ablative_armor", "module_autorepair"}, - {"commweapon_clusterbomb", "commweapon_personal_shield", "module_ablative_armor"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - }, - --decorations = {"skin_recon_dark", "banner_overhead"}, - --images = {overhead = "184"} - }, - }, - staticcomms={ - "dynrecon", - {{0}, {1}, {1}, {1}, {1}}, - {"module_personal_shield"} - } -} \ No newline at end of file + dyncomm_chassis_generator = { + name = "dynrecon1", + weapons = { + "commweapon_peashooter", + "commweapon_beamlaser", + "commweapon_lparticlebeam", + "commweapon_disruptor", + "commweapon_shotgun", + "commweapon_shotgun_disrupt", + "commweapon_lightninggun", + "commweapon_lightninggun_improved", + "commweapon_flamethrower", + "commweapon_heavymachinegun", + "commweapon_heavymachinegun_disrupt", + "commweapon_multistunner", + "commweapon_multistunner_improved", + "commweapon_napalmgrenade", + "commweapon_clusterbomb", + "commweapon_disruptorbomb", + "commweapon_concussion", + -- Space for shield + } + }, + dyncomms_predefined = { + dyntrainer_recon = { + name = "Recon", + chassis = "recon", + modules = { + { "commweapon_heavymachinegun", "module_radarnet" }, + { "module_ablative_armor", "module_autorepair" }, + { "commweapon_clusterbomb", "commweapon_personal_shield", "module_ablative_armor" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, + }, + --decorations = {"skin_recon_dark", "banner_overhead"}, + --images = {overhead = "184"} + }, + }, + staticcomms = { + "dynrecon", + { { 0 }, { 1 }, { 1 }, { 1 }, { 1 } }, + { "module_personal_shield" } + } +} diff --git a/gamedata/modularcomms/chassises/strike.lua b/gamedata/modularcomms/chassises/strike.lua index d59dca6f47..45b67743bc 100644 --- a/gamedata/modularcomms/chassises/strike.lua +++ b/gamedata/modularcomms/chassises/strike.lua @@ -1,238 +1,237 @@ return { - clonedefs={ - dynstrike1 = { - dynstrike0 = { - level = 0, - customparams = {shield_emit_height = 38}, - }, - dynstrike2 = { - level = 2, - mainstats = {health = 4600, objectname = "strikecom_1.dae", collisionvolumescales = [[50 55 50]],}, - customparams = {modelradius = [[28]], shield_emit_height = 41.8}, - wreckmodel = "strikecom_dead_1.dae", - }, - dynstrike3 = { - level = 3, - mainstats = {health = 5200, objectname = "strikecom_2.dae", collisionvolumescales = [[55 60 55]],}, - customparams = {modelradius = [[30]], shield_emit_height = 45.6}, - wreckmodel = "strikecom_dead_2.dae", - }, - dynstrike4 = { - level = 4, - mainstats = {health = 5800, objectname = "strikecom_3.dae", collisionvolumescales = [[58 66 58]],}, - customparams = {modelradius = [[33]], shield_emit_height = 47.5}, - wreckmodel = "strikecom_dead_3.dae", - }, - dynstrike5 = { - level = 5, - mainstats = {health = 6400, objectname = "strikecom_4.dae", collisionvolumescales = [[60 72 60]],}, - customparams = {modelradius = [[36]], shield_emit_height = 49.4}, - wreckmodel = "strikecom_dead_4.dae", - }, - } - }, - dynamic_comm_defs_name="strike", - dynamic_comm_defs=function(shared) - - shared=ModularCommDefsShared or shared - local extraLevelCostFunction=shared.extraLevelCostFunction - local morphBuildPower=shared.morphBuildPower - local morphCosts=shared.morphCosts - local COST_MULT=shared.COST_MULT - local GetCloneModuleString=shared.GetCloneModuleString - local morphUnitDefFunction=shared.morphUnitDefFunction - local moduleDefNames=shared.moduleDefNames + clonedefs = { + dynstrike1 = { + dynstrike0 = { + level = 0, + customparams = { shield_emit_height = 38 }, + }, + dynstrike2 = { + level = 2, + mainstats = { health = 4600, objectname = "strikecom_1.dae", collisionvolumescales = [[50 55 50]], }, + customparams = { modelradius = [[28]], shield_emit_height = 41.8 }, + wreckmodel = "strikecom_dead_1.dae", + }, + dynstrike3 = { + level = 3, + mainstats = { health = 5200, objectname = "strikecom_2.dae", collisionvolumescales = [[55 60 55]], }, + customparams = { modelradius = [[30]], shield_emit_height = 45.6 }, + wreckmodel = "strikecom_dead_2.dae", + }, + dynstrike4 = { + level = 4, + mainstats = { health = 5800, objectname = "strikecom_3.dae", collisionvolumescales = [[58 66 58]], }, + customparams = { modelradius = [[33]], shield_emit_height = 47.5 }, + wreckmodel = "strikecom_dead_3.dae", + }, + dynstrike5 = { + level = 5, + mainstats = { health = 6400, objectname = "strikecom_4.dae", collisionvolumescales = [[60 72 60]], }, + customparams = { modelradius = [[36]], shield_emit_height = 49.4 }, + wreckmodel = "strikecom_dead_4.dae", + }, + } + }, + dynamic_comm_defs_name = "strike", + ---@param shared ModularCommDefsShared + dynamic_comm_defs = function(shared) + local extraLevelCostFunction = shared.extraLevelCostFunction + local morphBuildPower = shared.morphBuildPower + local morphCosts = shared.morphCosts + local COST_MULT = shared.COST_MULT + local GetCloneModuleString = shared.GetCloneModuleString + local morphUnitDefFunction = shared.morphUnitDefFunction + local moduleDefNames = shared.moduleDefNames - local function GetStrikeCloneModulesString(modulesByDefID) - return (modulesByDefID[moduleDefNames.strike.commweapon_personal_shield] or 0) .. - (modulesByDefID[moduleDefNames.strike.commweapon_areashield] or 0) - end + local function GetStrikeCloneModulesString(modulesByDefID) + return (modulesByDefID[moduleDefNames.strike.commweapon_personal_shield] or 0) .. + (modulesByDefID[moduleDefNames.strike.commweapon_areashield] or 0) + end - return { - name = "strike", - humanName = "Strike", - baseUnitDef = UnitDefNames and UnitDefNames["dynstrike0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - secondPeashooter = false, - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike0"].id - end, - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 8 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike1_" .. GetStrikeCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.strike.commweapon_beamlaser, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike2_" .. GetStrikeCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 16 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike3_" .. GetStrikeCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.strike.commweapon_beamlaser_adv, - slotAllows = {"dual_basic_weapon", "adv_weapon"}, - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 20 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike4_" .. GetStrikeCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 25 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynstrike5_" .. GetStrikeCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.strike.nullmodule, - slotAllows = "module", - }, - }, - }, - } - } - end, - dyncomm_chassis_generator={ - name = "dynstrike1", - weapons = { - "commweapon_peashooter", - "commweapon_missilelauncher", -- 415 - "commweapon_missilelauncher", -- 415 - "commweapon_beamlaser", - "commweapon_lparticlebeam", - "commweapon_shotgun", - "commweapon_shotgun_disrupt", - "commweapon_disruptor", - "commweapon_heavymachinegun", - "commweapon_heavymachinegun_disrupt", - "commweapon_lightninggun", - "commweapon_lightninggun_improved", - "commweapon_peashooter", - "commweapon_beamlaser", - "commweapon_lparticlebeam", - "commweapon_shotgun", - "commweapon_shotgun_disrupt", - "commweapon_disruptor", - "commweapon_heavymachinegun", - "commweapon_heavymachinegun_disrupt", - "commweapon_lightninggun", - "commweapon_lightninggun_improved", - "commweapon_multistunner", - "commweapon_multistunner_improved", - "commweapon_disruptorbomb", - "commweapon_disintegrator", - -- Space for shield - } - }, - dyncomms_predefined={ - dyntrainer_strike = { - name = "Strike", - chassis = "strike", - modules = { - {"commweapon_heavymachinegun", "module_radarnet"}, - {"module_ablative_armor", "module_autorepair"}, - {"commweapon_lightninggun", "module_personal_cloak", "module_ablative_armor"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - }, - --decorations = {"banner_overhead"}, - --images = {overhead = "184"} - }, - }, - staticcomms={ - "dynstrike", - {{0, 0}, {1, 0}, {1, 1}, {1, 1}, {1, 1}}, - {"module_personal_shield", "module_areashield"} - } -} \ No newline at end of file + return { + name = "strike", + humanName = "Strike", + baseUnitDef = UnitDefNames and UnitDefNames["dynstrike0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + secondPeashooter = false, + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike0"].id + end, + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 8 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike1_" .. GetStrikeCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.strike.commweapon_beamlaser, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 12 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike2_" .. GetStrikeCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 16 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike3_" .. GetStrikeCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.strike.commweapon_beamlaser_adv, + slotAllows = { "dual_basic_weapon", "adv_weapon" }, + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 20 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike4_" .. GetStrikeCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 25 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynstrike5_" .. GetStrikeCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.strike.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, + dyncomm_chassis_generator = { + name = "dynstrike1", + weapons = { + "commweapon_peashooter", + "commweapon_missilelauncher", -- 415 + "commweapon_missilelauncher", -- 415 + "commweapon_beamlaser", + "commweapon_lparticlebeam", + "commweapon_shotgun", + "commweapon_shotgun_disrupt", + "commweapon_disruptor", + "commweapon_heavymachinegun", + "commweapon_heavymachinegun_disrupt", + "commweapon_lightninggun", + "commweapon_lightninggun_improved", + "commweapon_peashooter", + "commweapon_beamlaser", + "commweapon_lparticlebeam", + "commweapon_shotgun", + "commweapon_shotgun_disrupt", + "commweapon_disruptor", + "commweapon_heavymachinegun", + "commweapon_heavymachinegun_disrupt", + "commweapon_lightninggun", + "commweapon_lightninggun_improved", + "commweapon_multistunner", + "commweapon_multistunner_improved", + "commweapon_disruptorbomb", + "commweapon_disintegrator", + -- Space for shield + } + }, + dyncomms_predefined = { + dyntrainer_strike = { + name = "Strike", + chassis = "strike", + modules = { + { "commweapon_heavymachinegun", "module_radarnet" }, + { "module_ablative_armor", "module_autorepair" }, + { "commweapon_lightninggun", "module_personal_cloak", "module_ablative_armor" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, + }, + --decorations = {"banner_overhead"}, + --images = {overhead = "184"} + }, + }, + staticcomms = { + "dynstrike", + { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 1, 1 }, { 1, 1 } }, + { "module_personal_shield", "module_areashield" } + } +} diff --git a/gamedata/modularcomms/chassises/support.lua b/gamedata/modularcomms/chassises/support.lua index 08241cf196..2142d4c4aa 100644 --- a/gamedata/modularcomms/chassises/support.lua +++ b/gamedata/modularcomms/chassises/support.lua @@ -1,230 +1,229 @@ return { - clonedefs={ - dynsupport1 = { - dynsupport0 = { - level = 0, - customparams = {shield_emit_height = 36, builddistance = 220}, - }, - dynsupport2 = { - level = 2, - mainstats = {health = 4000, objectname = "commsupport2.s3o", aimposoffset = [[0 17 0]], builddistance = 244}, - customparams = {shield_emit_height = 39.6}, - wreckmodel = "commsupport2_dead.s3o", - }, - dynsupport3 = { - level = 3, - mainstats = {health = 4300, objectname = "commsupport3.s3o", aimposoffset = [[0 19 0]], builddistance = 256}, - customparams = {shield_emit_height = 43.62}, - wreckmodel = "commsupport3_dead.s3o", - }, - dynsupport4 = { - level = 4, - mainstats = {health = 4600, objectname = "commsupport4.s3o", aimposoffset = [[0 22 0]], builddistance = 268}, - customparams = {shield_emit_height = 45}, - wreckmodel = "commsupport4_dead.s3o", - }, - dynsupport5 = { - level = 5, - mainstats = {health = 5000, objectname = "commsupport5.s3o", aimposoffset = [[0 25 0]], builddistance = 280}, - customparams = {shield_emit_height = 46.48}, - wreckmodel = "commsupport5_dead.s3o", - }, - }, - }, - dynamic_comm_defs_name="support", - dynamic_comm_defs=function(shared) - - shared=ModularCommDefsShared or shared - local extraLevelCostFunction=shared.extraLevelCostFunction - local morphBuildPower=shared.morphBuildPower - local morphCosts=shared.morphCosts - local COST_MULT=shared.COST_MULT - local GetCloneModuleString=shared.GetCloneModuleString - local morphUnitDefFunction=shared.morphUnitDefFunction - local moduleDefNames=shared.moduleDefNames + clonedefs = { + dynsupport1 = { + dynsupport0 = { + level = 0, + customparams = { shield_emit_height = 36, builddistance = 220 }, + }, + dynsupport2 = { + level = 2, + mainstats = { health = 4000, objectname = "commsupport2.s3o", aimposoffset = [[0 17 0]], builddistance = 244 }, + customparams = { shield_emit_height = 39.6 }, + wreckmodel = "commsupport2_dead.s3o", + }, + dynsupport3 = { + level = 3, + mainstats = { health = 4300, objectname = "commsupport3.s3o", aimposoffset = [[0 19 0]], builddistance = 256 }, + customparams = { shield_emit_height = 43.62 }, + wreckmodel = "commsupport3_dead.s3o", + }, + dynsupport4 = { + level = 4, + mainstats = { health = 4600, objectname = "commsupport4.s3o", aimposoffset = [[0 22 0]], builddistance = 268 }, + customparams = { shield_emit_height = 45 }, + wreckmodel = "commsupport4_dead.s3o", + }, + dynsupport5 = { + level = 5, + mainstats = { health = 5000, objectname = "commsupport5.s3o", aimposoffset = [[0 25 0]], builddistance = 280 }, + customparams = { shield_emit_height = 46.48 }, + wreckmodel = "commsupport5_dead.s3o", + }, + }, + }, + dynamic_comm_defs_name = "support", + ---@param shared ModularCommDefsShared + dynamic_comm_defs = function(shared) + local extraLevelCostFunction = shared.extraLevelCostFunction + local morphBuildPower = shared.morphBuildPower + local morphCosts = shared.morphCosts + local COST_MULT = shared.COST_MULT + local GetCloneModuleString = shared.GetCloneModuleString + local morphUnitDefFunction = shared.morphUnitDefFunction + local moduleDefNames = shared.moduleDefNames - local function GetSupportCloneModulesString(modulesByDefID) - return (modulesByDefID[moduleDefNames.support.commweapon_personal_shield] or 0) .. - (modulesByDefID[moduleDefNames.support.commweapon_areashield] or 0) .. - (modulesByDefID[moduleDefNames.support.module_resurrect] or 0) - end + local function GetSupportCloneModulesString(modulesByDefID) + return (modulesByDefID[moduleDefNames.support.commweapon_personal_shield] or 0) .. + (modulesByDefID[moduleDefNames.support.commweapon_areashield] or 0) .. + (modulesByDefID[moduleDefNames.support.module_resurrect] or 0) + end - return { - name = "support", - humanName = "Engineer", - baseUnitDef = UnitDefNames and UnitDefNames["dynsupport0"].id, - extraLevelCostFunction = extraLevelCostFunction, - maxNormalLevel = 5, - levelDefs = { - [0] = { - morphBuildPower = 5, - morphBaseCost = 0, - chassisApplicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport0"].id - end, - upgradeSlots = {}, - }, - [1] = { - morphBuildPower = morphBuildPower[1], - morphBaseCost = morphCosts[1], - chassisApplicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 2 - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport1_" .. GetSupportCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.support.commweapon_beamlaser, - slotAllows = "basic_weapon", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - }, - }, - [2] = { - morphBuildPower = morphBuildPower[2], - morphBaseCost = morphCosts[2] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 4 - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport2_" .. GetSupportCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - }, - }, - [3] = { - morphBuildPower = morphBuildPower[3], - morphBaseCost = morphCosts[3] * COST_MULT, - chassisApplicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 6 - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport3_" .. GetSupportCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.support.commweapon_disruptorbomb, - slotAllows = "adv_weapon", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - }, - }, - [4] = { - morphBuildPower = morphBuildPower[4], - morphBaseCost = morphCosts[4], - chassisApplicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 9 - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport4_" .. GetSupportCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - }, - }, - [5] = { - morphBuildPower = morphBuildPower[5], - morphBaseCost = morphCosts[5], - chassisApplicationFunction = function (modules, sharedData) - sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 12 - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 - end, - morphUnitDefFunction = function(modulesByDefID) - return UnitDefNames["dynsupport5_" .. GetSupportCloneModulesString(modulesByDefID)].id - end, - upgradeSlots = { - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - { - defaultModule = moduleDefNames.support.nullmodule, - slotAllows = "module", - }, - }, - }, - } - } - end, - dyncomm_chassis_generator={ - name = "dynsupport1", - weapons = { - "commweapon_peashooter", - "commweapon_beamlaser", - "commweapon_shotgun", - "commweapon_shotgun_disrupt", - "commweapon_lparticlebeam", - "commweapon_disruptor", - "commweapon_hparticlebeam", - "commweapon_heavy_disruptor", - "commweapon_lightninggun", - "commweapon_lightninggun_improved", - "commweapon_missilelauncher", - "commweapon_shockrifle", - "commweapon_multistunner", - "commweapon_multistunner_improved", - "commweapon_disruptorbomb", - -- Space for shield - } - }, - dyncomms_predefined={ - dyntrainer_support = { - name = "Engineer", - chassis = "support", - modules = { - {"commweapon_lparticlebeam", "module_radarnet"}, - {"module_ablative_armor", "module_autorepair"}, - {"commweapon_hparticlebeam", "module_personal_cloak", "module_adv_nano"}, - {"module_dmg_booster", "module_adv_targeting", "module_adv_targeting"}, - {"module_adv_targeting", "module_adv_nano", "module_resurrect"}, - }, - --decorations = {"skin_support_hotrod"}, - }, - }, - staticcomms={ -"dynsupport", - {{0, 0, 0}, {1, 0, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, - {"module_personal_shield", "module_areashield", "module_resurrect"} - } -} \ No newline at end of file + return { + name = "support", + humanName = "Engineer", + baseUnitDef = UnitDefNames and UnitDefNames["dynsupport0"].id, + extraLevelCostFunction = extraLevelCostFunction, + maxNormalLevel = 5, + levelDefs = { + [0] = { + morphBuildPower = 5, + morphBaseCost = 0, + chassisApplicationFunction = function(modules, sharedData) + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport0"].id + end, + upgradeSlots = {}, + }, + [1] = { + morphBuildPower = morphBuildPower[1], + morphBaseCost = morphCosts[1], + chassisApplicationFunction = function(modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 2 + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport1_" .. GetSupportCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.support.commweapon_beamlaser, + slotAllows = "basic_weapon", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + }, + }, + [2] = { + morphBuildPower = morphBuildPower[2], + morphBaseCost = morphCosts[2] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 4 + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport2_" .. GetSupportCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + }, + }, + [3] = { + morphBuildPower = morphBuildPower[3], + morphBaseCost = morphCosts[3] * COST_MULT, + chassisApplicationFunction = function(modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 6 + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport3_" .. GetSupportCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.support.commweapon_disruptorbomb, + slotAllows = "adv_weapon", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + }, + }, + [4] = { + morphBuildPower = morphBuildPower[4], + morphBaseCost = morphCosts[4], + chassisApplicationFunction = function(modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 9 + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport4_" .. GetSupportCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + }, + }, + [5] = { + morphBuildPower = morphBuildPower[5], + morphBaseCost = morphCosts[5], + chassisApplicationFunction = function(modules, sharedData) + sharedData.bonusBuildPower = (sharedData.bonusBuildPower or 0) + 12 + sharedData.autorepairRate = (sharedData.autorepairRate or 0) + 5 + end, + morphUnitDefFunction = function(modulesByDefID) + return UnitDefNames["dynsupport5_" .. GetSupportCloneModulesString(modulesByDefID)].id + end, + upgradeSlots = { + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + { + defaultModule = moduleDefNames.support.nullmodule, + slotAllows = "module", + }, + }, + }, + } + } + end, + dyncomm_chassis_generator = { + name = "dynsupport1", + weapons = { + "commweapon_peashooter", + "commweapon_beamlaser", + "commweapon_shotgun", + "commweapon_shotgun_disrupt", + "commweapon_lparticlebeam", + "commweapon_disruptor", + "commweapon_hparticlebeam", + "commweapon_heavy_disruptor", + "commweapon_lightninggun", + "commweapon_lightninggun_improved", + "commweapon_missilelauncher", + "commweapon_shockrifle", + "commweapon_multistunner", + "commweapon_multistunner_improved", + "commweapon_disruptorbomb", + -- Space for shield + } + }, + dyncomms_predefined = { + dyntrainer_support = { + name = "Engineer", + chassis = "support", + modules = { + { "commweapon_lparticlebeam", "module_radarnet" }, + { "module_ablative_armor", "module_autorepair" }, + { "commweapon_hparticlebeam", "module_personal_cloak", "module_adv_nano" }, + { "module_dmg_booster", "module_adv_targeting", "module_adv_targeting" }, + { "module_adv_targeting", "module_adv_nano", "module_resurrect" }, + }, + --decorations = {"skin_support_hotrod"}, + }, + }, + staticcomms = { + "dynsupport", + { { 0, 0, 0 }, { 1, 0, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } }, + { "module_personal_shield", "module_areashield", "module_resurrect" } + } +} diff --git a/gamedata/modularcomms/chassises_all_defs.lua b/gamedata/modularcomms/chassises_all_defs.lua index 130d4be48e..74020d97b2 100644 --- a/gamedata/modularcomms/chassises_all_defs.lua +++ b/gamedata/modularcomms/chassises_all_defs.lua @@ -1,14 +1,13 @@ - if not Spring.ModularCommAPI then - Spring.ModularCommAPI={} + Spring.ModularCommAPI = {} end if not Spring.ModularCommAPI.Chassises then - local Chassises={} - Spring.ModularCommAPI.Chassises=Chassises - local chassisFiles=VFS.DirList("gamedata/modularcomms/chassises", "*.lua") or {} - for i = 1, #chassisFiles do - local chassisDef = VFS.Include(chassisFiles[i]) - Chassises[#Chassises+1]=chassisDef - end + local Chassises = {} + Spring.ModularCommAPI.Chassises = Chassises + local chassisFiles = VFS.DirList("gamedata/modularcomms/chassises", "*.lua") or {} + for i = 1, #chassisFiles do + local chassisDef = VFS.Include(chassisFiles[i]) + Chassises[#Chassises + 1] = chassisDef + end end -return Spring.ModularCommAPI.Chassises \ No newline at end of file +return Spring.ModularCommAPI.Chassises diff --git a/gamedata/modularcomms/clonedefs.lua b/gamedata/modularcomms/clonedefs.lua index 5f9a4f42f5..5360da9e8d 100644 --- a/gamedata/modularcomms/clonedefs.lua +++ b/gamedata/modularcomms/clonedefs.lua @@ -3,35 +3,35 @@ local statsByLevel = { mainstats = { [2] = { - collisionvolumescales = [[50 59 50]], - modelradius = [[30]], + collisionvolumescales = [[50 59 50]], + modelradius = [[30]], }, [3] = { - collisionvolumescales = [[55 65 55]], - modelradius = [[33]], - explodeas = "estor_building", - selfdestructas = "estor_building", - footprintx = 3, - footprintz = 3, - movementclass = [[AKBOT3]], + collisionvolumescales = [[55 65 55]], + modelradius = [[33]], + explodeas = "estor_building", + selfdestructas = "estor_building", + footprintx = 3, + footprintz = 3, + movementclass = [[AKBOT3]], }, [4] = { - collisionvolumescales = [[60 70 60]], - modelradius = [[35]], - explodeas = "estor_building", - selfdestructas = "estor_building", - footprintx = 3, - footprintz = 3, - movementclass = [[AKBOT3]], + collisionvolumescales = [[60 70 60]], + modelradius = [[35]], + explodeas = "estor_building", + selfdestructas = "estor_building", + footprintx = 3, + footprintz = 3, + movementclass = [[AKBOT3]], }, [5] = { - collisionvolumescales = [[65 75 65]], - modelradius = [[38]], - explodeas = "estor_building", - selfdestructas = "estor_building", - footprintx = 3, - footprintz = 3, - movementclass = [[AKBOT3]], + collisionvolumescales = [[65 75 65]], + modelradius = [[38]], + explodeas = "estor_building", + selfdestructas = "estor_building", + footprintx = 3, + footprintz = 3, + movementclass = [[AKBOT3]], }, }, customparams = { @@ -49,26 +49,26 @@ local copy = { }, armcom2 = { level = 2, - mainstats = {health = 3000, autoheal = 12.5, objectname = "armcom2.s3o", collisionvolumescales = [[50 55 50]], aimposoffset = [[0 6 0]],}, - customparams = {modelradius = [[28]],}, + mainstats = { health = 3000, autoheal = 12.5, objectname = "armcom2.s3o", collisionvolumescales = [[50 55 50]], aimposoffset = [[0 6 0]], }, + customparams = { modelradius = [[28]], }, wreckmodel = "armcom2_dead.s3o", }, armcom3 = { level = 3, - mainstats = {health = 4000, autoheal = 20, objectname = "armcom3.s3o", collisionvolumescales = [[55 60 55]], aimposoffset = [[0 7 0]],}, - customparams = {modelradius = [[30]],}, + mainstats = { health = 4000, autoheal = 20, objectname = "armcom3.s3o", collisionvolumescales = [[55 60 55]], aimposoffset = [[0 7 0]], }, + customparams = { modelradius = [[30]], }, wreckmodel = "armcom3_dead.s3o", }, armcom4 = { level = 4, - mainstats = {health = 5000, autoheal = 27.5, objectname = "armcom4.s3o", collisionvolumescales = [[60 65 60]], aimposoffset = [[0 8 0]],}, - customparams = {modelradius = [[33]],}, + mainstats = { health = 5000, autoheal = 27.5, objectname = "armcom4.s3o", collisionvolumescales = [[60 65 60]], aimposoffset = [[0 8 0]], }, + customparams = { modelradius = [[33]], }, wreckmodel = "armcom4_dead.s3o", }, armcom5 = { level = 5, - mainstats = {health = 6000, autoheal = 35, objectname = "armcom5.s3o", collisionvolumescales = [[65 70 65]], aimposoffset = [[0 9 0]],}, - customparams = {modelradius = [[35]],}, + mainstats = { health = 6000, autoheal = 35, objectname = "armcom5.s3o", collisionvolumescales = [[65 70 65]], aimposoffset = [[0 9 0]], }, + customparams = { modelradius = [[35]], }, wreckmodel = "armcom5_dead.s3o", }, }, @@ -78,26 +78,26 @@ local copy = { }, corcom2 = { level = 2, - mainstats = {health = 3800, objectname = "corcomAlt2.s3o", aimposoffset = [[0 6 0]], }, - customparams = {damagebonus = "0.025"}, + mainstats = { health = 3800, objectname = "corcomAlt2.s3o", aimposoffset = [[0 6 0]], }, + customparams = { damagebonus = "0.025" }, wreckmodel = "corcom2_dead.s3o", }, corcom3 = { level = 3, - mainstats = {health = 4900, objectname = "corcomAlt3.s3o", aimposoffset = [[0 7 0]], }, - customparams = {damagebonus = "0.05"}, + mainstats = { health = 4900, objectname = "corcomAlt3.s3o", aimposoffset = [[0 7 0]], }, + customparams = { damagebonus = "0.05" }, wreckmodel = "corcom3_dead.s3o", }, corcom4 = { level = 4, - mainstats = {health = 6000, objectname = "corcomAlt4.s3o", aimposoffset = [[0 8 0]], }, - customparams = {damagebonus = "0.075"}, + mainstats = { health = 6000, objectname = "corcomAlt4.s3o", aimposoffset = [[0 8 0]], }, + customparams = { damagebonus = "0.075" }, wreckmodel = "corcom4_dead.s3o", }, corcom5 = { level = 5, - mainstats = {health = 7200, objectname = "corcomAlt5.s3o", aimposoffset = [[0 9 0]], }, - customparams = {damagebonus = "0.1"}, + mainstats = { health = 7200, objectname = "corcomAlt5.s3o", aimposoffset = [[0 9 0]], }, + customparams = { damagebonus = "0.1" }, wreckmodel = "corcom5_dead.s3o", }, }, @@ -107,25 +107,25 @@ local copy = { }, commrecon2 = { level = 2, - mainstats = {health = 2100, objectname = "commrecon2.s3o", aimposoffset = [[0 12 0]]}, + mainstats = { health = 2100, objectname = "commrecon2.s3o", aimposoffset = [[0 12 0]] }, customparams = {}, wreckmodel = "commrecon2_dead.s3o", }, commrecon3 = { level = 3, - mainstats = {health = 2600, objectname = "commrecon3.s3o", aimposoffset = [[0 14 0]]}, + mainstats = { health = 2600, objectname = "commrecon3.s3o", aimposoffset = [[0 14 0]] }, customparams = {}, wreckmodel = "commrecon3_dead.s3o", }, commrecon4 = { level = 4, - mainstats = {health = 3100, objectname = "commrecon4.s3o", aimposoffset = [[0 16 0]]}, + mainstats = { health = 3100, objectname = "commrecon4.s3o", aimposoffset = [[0 16 0]] }, customparams = {}, wreckmodel = "commrecon4_dead.s3o", }, commrecon5 = { level = 5, - mainstats = {health = 3600, objectname = "commrecon5.s3o", aimposoffset = [[0 18 0]]}, + mainstats = { health = 3600, objectname = "commrecon5.s3o", aimposoffset = [[0 18 0]] }, customparams = {}, wreckmodel = "commrecon5_dead.s3o", }, @@ -136,25 +136,25 @@ local copy = { }, commsupport2 = { level = 2, - mainstats = {health = 2500, workertime = 14, description = "Econ/Support Commander, Builds at 14 m/s", objectname = "commsupport2.s3o", aimposoffset = [[0 17 0]]}, + mainstats = { health = 2500, workertime = 14, description = "Econ/Support Commander, Builds at 14 m/s", objectname = "commsupport2.s3o", aimposoffset = [[0 17 0]] }, customparams = {}, wreckmodel = "commsupport2_dead.s3o", }, commsupport3 = { level = 3, - mainstats = {health = 3000, workertime = 16, description = "Econ/Support Commander, Builds at 16 m/s", objectname = "commsupport3.s3o", aimposoffset = [[0 19 0]],}, + mainstats = { health = 3000, workertime = 16, description = "Econ/Support Commander, Builds at 16 m/s", objectname = "commsupport3.s3o", aimposoffset = [[0 19 0]], }, customparams = {}, wreckmodel = "commsupport3_dead.s3o", }, commsupport4 = { level = 4, - mainstats = {health = 3700, workertime = 18, description = "Econ/Support Commander, Builds at 18 m/s", objectname = "commsupport4.s3o", aimposoffset = [[0 22 0]],}, + mainstats = { health = 3700, workertime = 18, description = "Econ/Support Commander, Builds at 18 m/s", objectname = "commsupport4.s3o", aimposoffset = [[0 22 0]], }, customparams = {}, wreckmodel = "commsupport4_dead.s3o", }, commsupport5 = { level = 5, - mainstats = {health = 4500, workertime = 20, description = "Econ/Support Commander, Builds at 20 m/s", objectname = "commsupport5.s3o", aimposoffset = [[0 25 0]],}, + mainstats = { health = 4500, workertime = 20, description = "Econ/Support Commander, Builds at 20 m/s", objectname = "commsupport5.s3o", aimposoffset = [[0 25 0]], }, customparams = {}, wreckmodel = "commsupport5_dead.s3o", }, @@ -165,26 +165,26 @@ local copy = { }, cremcom2 = { level = 2, - mainstats = {health = 3000, autoheal = 12.5, objectname = "cremcom2.s3o", collisionvolumescales = [[50 55 50]],}, - customparams = {modelradius = [[28]],}, + mainstats = { health = 3000, autoheal = 12.5, objectname = "cremcom2.s3o", collisionvolumescales = [[50 55 50]], }, + customparams = { modelradius = [[28]], }, wreckmodel = "cremcom2_dead.s3o", }, cremcom3 = { level = 3, - mainstats = {health = 4000, autoheal = 20, objectname = "cremcom3.s3o", collisionvolumescales = [[55 60 55]],}, - customparams = {modelradius = [[30]],}, + mainstats = { health = 4000, autoheal = 20, objectname = "cremcom3.s3o", collisionvolumescales = [[55 60 55]], }, + customparams = { modelradius = [[30]], }, wreckmodel = "cremcom3_dead.s3o", }, cremcom4 = { level = 4, - mainstats = {health = 5000, autoheal = 27.5, objectname = "cremcom4.s3o", collisionvolumescales = [[60 65 60]], }, - customparams = {modelradius = [[33]],}, + mainstats = { health = 5000, autoheal = 27.5, objectname = "cremcom4.s3o", collisionvolumescales = [[60 65 60]], }, + customparams = { modelradius = [[33]], }, wreckmodel = "cremcom4_dead.s3o", }, cremcom5 = { level = 5, - mainstats = {health = 6000, autoheal = 35, objectname = "cremcom5.s3o", collisionvolumescales = [[65 70 65]],}, - customparams = {modelradius = [[35]],}, + mainstats = { health = 6000, autoheal = 35, objectname = "cremcom5.s3o", collisionvolumescales = [[65 70 65]], }, + customparams = { modelradius = [[35]], }, wreckmodel = "cremcom5_dead.s3o", }, }, @@ -194,26 +194,26 @@ local copy = { }, benzcom2 = { level = 2, - mainstats = {health = 2700, objectname = "benzcom2.s3o"}, - customparams = {rangebonus = "0.075"}, + mainstats = { health = 2700, objectname = "benzcom2.s3o" }, + customparams = { rangebonus = "0.075" }, wreckmodel = "benzcom2_wreck.s3o", }, benzcom3 = { level = 3, - mainstats = {health = 3300, objectname = "benzcom3.s3o",}, - customparams = {rangebonus = "0.15"}, + mainstats = { health = 3300, objectname = "benzcom3.s3o", }, + customparams = { rangebonus = "0.15" }, wreckmodel = "benzcom3_wreck.s3o", }, benzcom4 = { level = 4, - mainstats = {health = 4000, objectname = "benzcom4.s3o",}, - customparams = {rangebonus = "0.225"}, + mainstats = { health = 4000, objectname = "benzcom4.s3o", }, + customparams = { rangebonus = "0.225" }, wreckmodel = "benzcom4_wreck.s3o", }, benzcom5 = { level = 5, - mainstats = {health = 4700, objectname = "benzcom5.s3o",}, - customparams = {rangebonus = "0.3"}, + mainstats = { health = 4700, objectname = "benzcom5.s3o", }, + customparams = { rangebonus = "0.3" }, wreckmodel = "benzcom5_wreck.s3o", }, }, @@ -223,37 +223,37 @@ local copy = { }, commstrike2 = { level = 2, - mainstats = {health = 3000, objectname = "strikecom_1.dae", collisionvolumescales = [[50 55 50]],}, - customparams = {modelradius = [[28]],}, + mainstats = { health = 3000, objectname = "strikecom_1.dae", collisionvolumescales = [[50 55 50]], }, + customparams = { modelradius = [[28]], }, wreckmodel = "strikecom_dead_1.dae", }, commstrike3 = { level = 3, - mainstats = {health = 4000, objectname = "strikecom_2.dae", collisionvolumescales = [[55 60 55]],}, - customparams = {modelradius = [[30]],}, + mainstats = { health = 4000, objectname = "strikecom_2.dae", collisionvolumescales = [[55 60 55]], }, + customparams = { modelradius = [[30]], }, wreckmodel = "strikecom_dead_2.dae", }, commstrike4 = { level = 4, - mainstats = {health = 5000, objectname = "strikecom_3.dae", collisionvolumescales = [[58 66 58]],}, - customparams = { modelradius = [[33]],}, + mainstats = { health = 5000, objectname = "strikecom_3.dae", collisionvolumescales = [[58 66 58]], }, + customparams = { modelradius = [[33]], }, wreckmodel = "strikecom_dead_3.dae", }, commstrike5 = { level = 5, - mainstats = {health = 6000, objectname = "strikecom_4.dae", collisionvolumescales = [[60 72 60]],}, - customparams = {modelradius = [[36]],}, + mainstats = { health = 6000, objectname = "strikecom_4.dae", collisionvolumescales = [[60 72 60]], }, + customparams = { modelradius = [[36]], }, wreckmodel = "strikecom_dead_4.dae", }, }, } -local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") +local chassisAllDefs = VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") for i = 1, #chassisAllDefs do local chassisDef = chassisAllDefs[i].clonedefs for key, value in pairs(chassisDef) do - copy[key]=value + copy[key] = value end end --[=[ @@ -265,9 +265,9 @@ for sourceName, copyTable in pairs(copy) do -- some further modification UnitDefs[cloneName] = CopyTable(UnitDefs[sourceName], true) UnitDefs[cloneName].unitname = cloneName - + if stats.level > 0 then - stats.nomainstats=stats.nomainstats or {} + stats.nomainstats = stats.nomainstats or {} -- copy from by-level table for statName, value in pairs(statsByLevel.mainstats[stats.level]) do if not stats.nomainstats[statName] then @@ -277,7 +277,7 @@ for sourceName, copyTable in pairs(copy) do --for statName, value in pairs(statsByLevel.customparams[stats.level]) do -- UnitDefs[cloneName].customparams[statName] = value --end - + -- copy from specific table for statName, value in pairs(stats.mainstats or {}) do UnitDefs[cloneName][statName] = value @@ -285,20 +285,22 @@ for sourceName, copyTable in pairs(copy) do for statName, value in pairs(stats.customparams or {}) do UnitDefs[cloneName].customparams[statName] = value end - UnitDefs[cloneName].trackwidth = UnitDefs[cloneName].trackwidth * (0.9 + 0.1*(stats.level)) + UnitDefs[cloneName].trackwidth = UnitDefs[cloneName].trackwidth * (0.9 + 0.1 * (stats.level)) -- features if UnitDefs[cloneName].featuredefs then - UnitDefs[cloneName].featuredefs.dead.object = stats.wreckmodel or UnitDefs[cloneName].featuredefs.dead.object + UnitDefs[cloneName].featuredefs.dead.object = stats.wreckmodel or + UnitDefs[cloneName].featuredefs.dead.object UnitDefs[cloneName].featuredefs.dead.footprintx = UnitDefs[cloneName].footprintx UnitDefs[cloneName].featuredefs.dead.footprintz = UnitDefs[cloneName].footprintz - UnitDefs[cloneName].featuredefs.heap.object = stats.heapmodel or UnitDefs[cloneName].featuredefs.heap.object + UnitDefs[cloneName].featuredefs.heap.object = stats.heapmodel or + UnitDefs[cloneName].featuredefs.heap.object UnitDefs[cloneName].featuredefs.heap.footprintx = UnitDefs[cloneName].footprintx UnitDefs[cloneName].featuredefs.heap.footprintz = UnitDefs[cloneName].footprintz end end - + UnitDefs[cloneName].customparams.level = stats.level UnitDefs[cloneName].name = (UnitDefs[cloneName].name) .. " - Level " .. stats.level - UnitDefs[cloneName].icontype = "commander"..stats.level + UnitDefs[cloneName].icontype = "commander" .. stats.level end end diff --git a/gamedata/modularcomms/dyncomm_chassis_generator.lua b/gamedata/modularcomms/dyncomm_chassis_generator.lua index c991f30f43..49c10f8417 100644 --- a/gamedata/modularcomms/dyncomm_chassis_generator.lua +++ b/gamedata/modularcomms/dyncomm_chassis_generator.lua @@ -1,12 +1,12 @@ local chassisDefs = { - + } -local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") +local chassisAllDefs = VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") for i = 1, #chassisAllDefs do local chassisDef = chassisAllDefs[i].dyncomm_chassis_generator - chassisDefs[#chassisDefs+1]=chassisDef + chassisDefs[#chassisDefs + 1] = chassisDef end local commanderCost = 1100 @@ -30,26 +30,25 @@ for i = 1, #chassisDefs do wreckDef.metal = commanderCost * (wreckName == "heap" and 0.2 or 0.4) wreckDef.reclaimtime = wreckDef.metal end - + for key, data in pairs(statOverrides) do unitDef[key] = data end - + for j = 1, 7 do unitDef.sfxtypes.explosiongenerators[j] = unitDef.sfxtypes.explosiongenerators[j] or [[custom:NONE]] end - + for num = 1, #chassisDefs[i].weapons do local weaponName = chassisDefs[i].weapons[num] DynamicApplyWeapon(unitDef, weaponName, num) end - + if #chassisDefs[i].weapons > 31 then -- Limit of 31 for shield space. Spring.Echo("Too many commander weapons on:", name, "Limit is 31, found weapons:", #chassisDefs[i].weapons) end else - Spring.Log("gamedata/modularcomms/dyncomm_chassis_generator.lua","error","UnitDef " .. name .. " Not Found") + Spring.Log("gamedata/modularcomms/dyncomm_chassis_generator.lua", "error", "UnitDef " .. name .. " Not Found") end - end diff --git a/gamedata/modularcomms/dyncomms_predefined.lua b/gamedata/modularcomms/dyncomms_predefined.lua index 61fefb1eb8..387aa91e5e 100644 --- a/gamedata/modularcomms/dyncomms_predefined.lua +++ b/gamedata/modularcomms/dyncomms_predefined.lua @@ -1,18 +1,18 @@ local ret = { - - - - + + + + dynhub_strike = { name = "Strike Support", notStarter = true, chassis = "strike", modules = { - {"commweapon_shotgun", "module_adv_targeting"}, - {"conversion_disruptor", "module_personal_cloak"}, - {"commweapon_heavymachinegun", "conversion_disruptor", "module_high_power_servos"}, - {"module_high_power_servos", "module_adv_targeting", "module_adv_targeting"}, - {"module_high_power_servos", "module_high_power_servos", "module_adv_targeting"}, + { "commweapon_shotgun", "module_adv_targeting" }, + { "conversion_disruptor", "module_personal_cloak" }, + { "commweapon_heavymachinegun", "conversion_disruptor", "module_high_power_servos" }, + { "module_high_power_servos", "module_adv_targeting", "module_adv_targeting" }, + { "module_high_power_servos", "module_high_power_servos", "module_adv_targeting" }, }, }, dynhub_recon = { @@ -20,11 +20,11 @@ local ret = { notStarter = true, chassis = "recon", modules = { - {"commweapon_shotgun", "module_radarnet"}, - {"module_ablative_armor", "module_personal_cloak"}, - {"commweapon_disruptorbomb", "conversion_disruptor", "module_high_power_servos"}, - {"module_high_power_servos", "module_high_power_servos", "module_adv_targeting"}, - {"module_high_power_servos", "module_high_power_servos", "module_adv_targeting"}, + { "commweapon_shotgun", "module_radarnet" }, + { "module_ablative_armor", "module_personal_cloak" }, + { "commweapon_disruptorbomb", "conversion_disruptor", "module_high_power_servos" }, + { "module_high_power_servos", "module_high_power_servos", "module_adv_targeting" }, + { "module_high_power_servos", "module_high_power_servos", "module_adv_targeting" }, }, }, dynhub_support = { @@ -32,11 +32,11 @@ local ret = { notStarter = true, chassis = "support", modules = { - {"commweapon_lightninggun", "module_adv_targeting"}, - {"module_resurrect", "module_personal_cloak"}, - {"commweapon_multistunner", "module_adv_nano", "weaponmod_stun_booster"}, - {"module_adv_nano", "module_adv_nano", "module_adv_targeting"}, - {"module_adv_nano", "module_adv_nano", "module_adv_targeting"}, + { "commweapon_lightninggun", "module_adv_targeting" }, + { "module_resurrect", "module_personal_cloak" }, + { "commweapon_multistunner", "module_adv_nano", "weaponmod_stun_booster" }, + { "module_adv_nano", "module_adv_nano", "module_adv_targeting" }, + { "module_adv_nano", "module_adv_nano", "module_adv_targeting" }, }, }, dynhub_assault = { @@ -44,117 +44,117 @@ local ret = { notStarter = true, chassis = "assault", modules = { - {"commweapon_riotcannon", "module_adv_targeting"}, - {"module_adv_targeting", "weaponmod_napalm_warhead"}, - {"commweapon_hpartillery", "module_adv_targeting", "module_dmg_booster"}, - {"module_adv_targeting", "module_adv_targeting", "module_dmg_booster"}, - {"module_adv_targeting", "module_adv_targeting", "module_dmg_booster"}, + { "commweapon_riotcannon", "module_adv_targeting" }, + { "module_adv_targeting", "weaponmod_napalm_warhead" }, + { "commweapon_hpartillery", "module_adv_targeting", "module_dmg_booster" }, + { "module_adv_targeting", "module_adv_targeting", "module_dmg_booster" }, + { "module_adv_targeting", "module_adv_targeting", "module_dmg_booster" }, }, }, dynfancy_recon = { name = "Recon Trainer", chassis = "recon", modules = { - {"commweapon_beamlaser", "module_ablative_armor"}, - {"module_high_power_servos", "commweapon_personal_shield"}, - {"commweapon_clusterbomb", "module_dmg_booster", "module_ablative_armor"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, + { "commweapon_beamlaser", "module_ablative_armor" }, + { "module_high_power_servos", "commweapon_personal_shield" }, + { "commweapon_clusterbomb", "module_dmg_booster", "module_ablative_armor" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, }, - decorations = {"skin_recon_dark"}, + decorations = { "skin_recon_dark" }, }, dynfancy_recon2 = { name = "Recon Trainer", chassis = "recon", modules = { - {"commweapon_beamlaser", "module_ablative_armor"}, - {"module_high_power_servos", "commweapon_personal_shield"}, - {"commweapon_clusterbomb", "module_dmg_booster", "module_ablative_armor"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, + { "commweapon_beamlaser", "module_ablative_armor" }, + { "module_high_power_servos", "commweapon_personal_shield" }, + { "commweapon_clusterbomb", "module_dmg_booster", "module_ablative_armor" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, }, - decorations = {"skin_recon_leopard", "banner_overhead"}, - images = {overhead = "184"} + decorations = { "skin_recon_leopard", "banner_overhead" }, + images = { overhead = "184" } }, - - + + dynfancy_support = { name = "Engineer Trainer", chassis = "support", modules = { - {"commweapon_beamlaser", "module_ablative_armor"}, + { "commweapon_beamlaser", "module_ablative_armor" }, }, - decorations = {"skin_support_zebra", "banner_overhead"}, - images = {overhead = "184"} + decorations = { "skin_support_zebra", "banner_overhead" }, + images = { overhead = "184" } }, dynfancy_support2 = { name = "Engineer Trainer", chassis = "support", modules = { - {"commweapon_beamlaser", "module_ablative_armor"}, + { "commweapon_beamlaser", "module_ablative_armor" }, }, - decorations = {"skin_support_hotrod"}, + decorations = { "skin_support_hotrod" }, }, dynfancy_support3 = { name = "Engineer Trainer", chassis = "support", modules = { - {"commweapon_beamlaser", "module_ablative_armor"}, + { "commweapon_beamlaser", "module_ablative_armor" }, }, - decorations = {"skin_support_green"}, + decorations = { "skin_support_green" }, }, dynfancy_support4 = { name = "Engineer Trainer", chassis = "support", modules = { - {"commweapon_beamlaser", "module_ablative_armor"}, + { "commweapon_beamlaser", "module_ablative_armor" }, }, - decorations = {"skin_support_dark", "banner_overhead"}, - images = {overhead = "175"} + decorations = { "skin_support_dark", "banner_overhead" }, + images = { overhead = "175" } }, dynfancy_guardian = { name = "Guardian Trainer", chassis = "assault", modules = { - {"commweapon_beamlaser", "module_ablative_armor"}, + { "commweapon_beamlaser", "module_ablative_armor" }, }, - decorations = {"skin_assault_steel"}, + decorations = { "skin_assault_steel" }, }, dynfancy_strike = { name = "Strike Trainer", chassis = "strike", modules = { - {"commweapon_beamlaser", "module_ablative_armor"}, - {"module_high_power_servos", "commweapon_personal_shield"}, - {"commweapon_clusterbomb", "module_dmg_booster", "module_ablative_armor"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, + { "commweapon_beamlaser", "module_ablative_armor" }, + { "module_high_power_servos", "commweapon_personal_shield" }, + { "commweapon_clusterbomb", "module_dmg_booster", "module_ablative_armor" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, }, - decorations = {"banner_overhead","skin_strike_renegade"}, - images = {overhead = "184"} + decorations = { "banner_overhead", "skin_strike_renegade" }, + images = { overhead = "184" } }, dynfancy_strike_lobster = { name = "Strike Trainer", chassis = "strike", modules = { - {"commweapon_beamlaser", "module_ablative_armor"}, - {"module_high_power_servos", "commweapon_personal_shield"}, - {"commweapon_clusterbomb", "module_dmg_booster", "module_ablative_armor"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, - {"module_high_power_servos", "module_ablative_armor", "module_dmg_booster"}, + { "commweapon_beamlaser", "module_ablative_armor" }, + { "module_high_power_servos", "commweapon_personal_shield" }, + { "commweapon_clusterbomb", "module_dmg_booster", "module_ablative_armor" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, + { "module_high_power_servos", "module_ablative_armor", "module_dmg_booster" }, }, - decorations = {"banner_overhead","skin_strike_chitin"}, - images = {overhead = "184"} + decorations = { "banner_overhead", "skin_strike_chitin" }, + images = { overhead = "184" } }, } -local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") +local chassisAllDefs = VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") for i = 1, #chassisAllDefs do local chassisDef = chassisAllDefs[i].dyncomms_predefined for key, value in pairs(chassisDef) do if not value.notSelectable then - ret[key]=value + ret[key] = value end end end diff --git a/gamedata/modularcomms/moduledefs.lua b/gamedata/modularcomms/moduledefs.lua index db07d19b44..89aba3c6c9 100644 --- a/gamedata/modularcomms/moduledefs.lua +++ b/gamedata/modularcomms/moduledefs.lua @@ -18,7 +18,7 @@ weapons = {} upgrades = { -- weapons -- note that context menu CRASHES if you don't put them here! - + commweapon_peashooter = { name = "Peashooter", description = "Basic self-defence weapon", @@ -100,7 +100,7 @@ upgrades = { name = "Torpedo", description = "Fires a torpedo effective against waterborne targets", }, - + -- dguns commweapon_concussion = { name = "Concussion Shot", @@ -134,558 +134,560 @@ upgrades = { name = "Sunburst Cannon", description = "Ruins a single target's day with a medium-range high-energy burst", }, - + -- conversion kits conversion_disruptor = { name = "Disruptor Beam", description = "Slow Beam: +33% reload time, +250 real damage", func = function(unitDef) - ReplaceWeapon(unitDef, "commweapon_slowbeam", "commweapon_disruptor") - end, + ReplaceWeapon(unitDef, "commweapon_slowbeam", "commweapon_disruptor") + end, }, conversion_shockrifle = { name = "Shock Rifle", description = "Light Particle Beam: Convert to a long-range sniper rifle", func = function(unitDef) - ReplaceWeapon(unitDef, "commweapon_lparticlebeam", "commweapon_shockrifle") - end, + ReplaceWeapon(unitDef, "commweapon_lparticlebeam", "commweapon_shockrifle") + end, }, conversion_partillery = { name = "Plasma Artillery", description = "Assault Cannon: Convert to a light artillery gun", func = function(unitDef) - ReplaceWeapon(unitDef, "commweapon_assaultcannon", "commweapon_partillery") - --unitDef.hightrajectory = 1 - end, + ReplaceWeapon(unitDef, "commweapon_assaultcannon", "commweapon_partillery") + --unitDef.hightrajectory = 1 + end, }, conversion_hparticlebeam = { name = "Heavy Particle Beam", description = "Light Particle Beam: Convert to an extended range rifle weapon", func = function(unitDef) - ReplaceWeapon(unitDef, "commweapon_lparticlebeam", "commweapon_hparticlebeam") - end, + ReplaceWeapon(unitDef, "commweapon_lparticlebeam", "commweapon_hparticlebeam") + end, }, - + -- weapon mods weaponmod_antiair = { name = "Anti-Air Kit", description = "Beam Laser/Riot Cannon/Missile Launcher: Convert to anti-air weapons", func = function(unitDef) - for i,v in pairs(weapons) do - local id = v.customparams.idstring - if (id == "commweapon_riotcannon") then - ReplaceWeapon(unitDef, "commweapon_riotcannon", "commweapon_flakcannon") - ReplaceWeapon(unitDef, "commweapon_riotcannon", "commweapon_flakcannon") - elseif (id == "commweapon_beamlaser") then - ReplaceWeapon(unitDef, "commweapon_beamlaser", "commweapon_aalaser") - ReplaceWeapon(unitDef, "commweapon_beamlaser", "commweapon_aalaser") - elseif (id == "commweapon_missilelauncher") then - ReplaceWeapon(unitDef, "commweapon_missilelauncher", "commweapon_aamissile") - ReplaceWeapon(unitDef, "commweapon_missilelauncher", "commweapon_aamissile") - end + for i, v in pairs(weapons) do + local id = v.customparams.idstring + if (id == "commweapon_riotcannon") then + ReplaceWeapon(unitDef, "commweapon_riotcannon", "commweapon_flakcannon") + ReplaceWeapon(unitDef, "commweapon_riotcannon", "commweapon_flakcannon") + elseif (id == "commweapon_beamlaser") then + ReplaceWeapon(unitDef, "commweapon_beamlaser", "commweapon_aalaser") + ReplaceWeapon(unitDef, "commweapon_beamlaser", "commweapon_aalaser") + elseif (id == "commweapon_missilelauncher") then + ReplaceWeapon(unitDef, "commweapon_missilelauncher", "commweapon_aamissile") + ReplaceWeapon(unitDef, "commweapon_missilelauncher", "commweapon_aamissile") end end + end }, weaponmod_autoflechette = { name = "Autoflechette", description = "Shotgun: -25% projectiles, -40% reload time", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - if v.customparams.idstring == "commweapon_shotgun" then - v.customparams.misceffect = nil - v.projectiles = v.projectiles * 0.75 - v.reloadtime = v.reloadtime * 0.6 - --break - end + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + if v.customparams.idstring == "commweapon_shotgun" then + v.customparams.misceffect = nil + v.projectiles = v.projectiles * 0.75 + v.reloadtime = v.reloadtime * 0.6 + --break end - end, + end + end, }, weaponmod_disruptor_ammo = { name = "Disruptor Ammo", description = "Shotgun/Heavy Machine Gun/Shock Rifle: +40% slow damage", func = function(unitDef) - local permitted = { - commweapon_shotgun = true, - commweapon_gaussrifle = true, - commweapon_heavymachinegun = true, - commweapon_shockrifle = true, - } - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - local wcp = v.customparams - local id = wcp.idstring - if permitted[id] then - wcp.timeslow_damagefactor = "0.4" - v.rgbcolor = [[0.9 0.1 0.9]] - if id == "commweapon_shotgun" or id == "commweapon_heavymachinegun" then - v.explosiongenerator = [[custom:BEAMWEAPON_HIT_PURPLE]] - elseif id == "commweapon_gaussrifle" then - v.explosiongenerator = [[custom:GAUSS_HIT_M_PURPLE]] - end -- no visual effect on shock rifle - if i == "commweapon_shotgun_green" or i == "commweapon_heavymachinegun_lime" then - v.rgbcolor = "0 1 0.7" - v.explosiongenerator = [[custom:BEAMWEAPON_HIT_TURQUOISE]] - end + local permitted = { + commweapon_shotgun = true, + commweapon_gaussrifle = true, + commweapon_heavymachinegun = true, + commweapon_shockrifle = true, + } + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + local wcp = v.customparams + local id = wcp.idstring + if permitted[id] then + wcp.timeslow_damagefactor = "0.4" + v.rgbcolor = [[0.9 0.1 0.9]] + if id == "commweapon_shotgun" or id == "commweapon_heavymachinegun" then + v.explosiongenerator = [[custom:BEAMWEAPON_HIT_PURPLE]] + elseif id == "commweapon_gaussrifle" then + v.explosiongenerator = [[custom:GAUSS_HIT_M_PURPLE]] + end -- no visual effect on shock rifle + if i == "commweapon_shotgun_green" or i == "commweapon_heavymachinegun_lime" then + v.rgbcolor = "0 1 0.7" + v.explosiongenerator = [[custom:BEAMWEAPON_HIT_TURQUOISE]] end end - end, + end + end, }, weaponmod_high_frequency_beam = { name = "High Frequency Beam", - description = " +15% damage and range to Beam Laser/Slow Beam/Disruptor Beam/Light Particle Beam/Heavy Particle Beam", - func = function(unitDef) - local weapons = unitDef.weapondefs or {} - local permitted = { - commweapon_beamlaser = true, - commweapon_slowbeam = true, - commweapon_disruptor = true, - commweapon_lparticlebeam = true, - commweapon_hparticlebeam = true, - } - for i,v in pairs(weapons) do - if permitted[v.customparams.idstring] then - v.range = v.range * 1.15 - for armorname, dmg in pairs(v.damage) do - v.damage[armorname] = dmg * 1.15 - end + description = + " +15% damage and range to Beam Laser/Slow Beam/Disruptor Beam/Light Particle Beam/Heavy Particle Beam", + func = function(unitDef) + local weapons = unitDef.weapondefs or {} + local permitted = { + commweapon_beamlaser = true, + commweapon_slowbeam = true, + commweapon_disruptor = true, + commweapon_lparticlebeam = true, + commweapon_hparticlebeam = true, + } + for i, v in pairs(weapons) do + if permitted[v.customparams.idstring] then + v.range = v.range * 1.15 + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 1.15 end end - end, + end + end, }, weaponmod_railaccel = { name = "Rail Accelerator", description = "Gauss Rifle: +10% damage, +20% range", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - local id = v.customparams.idstring - if id == "commweapon_gaussrifle" or id == "commweapon_massdriver" then - v.range = v.range * 1.2 - for armorname, dmg in pairs(v.damage) do - v.damage[armorname] = dmg * 1.1 - end + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + local id = v.customparams.idstring + if id == "commweapon_gaussrifle" or id == "commweapon_massdriver" then + v.range = v.range * 1.2 + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 1.1 end end - end, + end + end, }, weaponmod_high_caliber_barrel = { name = "High Caliber Barrel", description = "Shotgun/Riot Cannon/Assault Cannon/Plasma Artillery: +150% damage, +100% reload time", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - local permitted = { - commweapon_assaultcannon = true, - commweapon_shotgun = true, - commweapon_gaussrifle = true, - commweapon_partillery = true, - commweapon_partillery_napalm = true, - commweapon_riotcannon = true, - } - for i,v in pairs(weapons) do - local id = v.customparams.idstring - if permitted[id] then - if not (id == "commweapon_partillery" or id == "commweapon_partillery_napalm") then - v.reloadtime = v.reloadtime * 2 - v.customparams.highcaliber = true - for armorname, dmg in pairs(v.damage) do - v.damage[armorname] = dmg * 2.5 - end - else - ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_hpartillery") - ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_hpartillery") - ReplaceWeapon(unitDef, "commweapon_partillery_napalm", "commweapon_hpartillery_napalm") - ReplaceWeapon(unitDef, "commweapon_partillery_napalm", "commweapon_hpartillery_napalm") + local weapons = unitDef.weapondefs or {} + local permitted = { + commweapon_assaultcannon = true, + commweapon_shotgun = true, + commweapon_gaussrifle = true, + commweapon_partillery = true, + commweapon_partillery_napalm = true, + commweapon_riotcannon = true, + } + for i, v in pairs(weapons) do + local id = v.customparams.idstring + if permitted[id] then + if not (id == "commweapon_partillery" or id == "commweapon_partillery_napalm") then + v.reloadtime = v.reloadtime * 2 + v.customparams.highcaliber = true + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 2.5 end + else + ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_hpartillery") + ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_hpartillery") + ReplaceWeapon(unitDef, "commweapon_partillery_napalm", "commweapon_hpartillery_napalm") + ReplaceWeapon(unitDef, "commweapon_partillery_napalm", "commweapon_hpartillery_napalm") end end - end, + end + end, }, weaponmod_standoff_rocket = { name = "Standoff Rocket", description = "Rocket/Missile Launcher: +50% range, +25% damage, +50% reload time", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - local id = v.customparams.idstring - if id == "commweapon_rocketlauncher" then - v.range = v.range * 1.5 - v.reloadtime = v.reloadtime * 1.5 - for armorname, dmg in pairs(v.damage) do - v.damage[armorname] = dmg * 1.25 - end - v.model = [[wep_m_dragonsfang.s3o]] - v.soundhitvolume = 8 - v.soundstart = [[weapon/missile/missile2_fire_bass]] - v.soundstartvolume = 7 - --break - elseif id == "commweapon_missilelauncher" then - v.range = v.range * 1.5 - v.reloadtime = v.reloadtime * 1.5 - for armorname, dmg in pairs(v.damage) do - v.damage[armorname] = dmg * 1.25 - end - v.model = [[wep_m_phoenix.s3o]] - v.soundhitvolume = 5 - v.soundstart = [[weapon/missile/missile_fire7]] - v.soundstartvolume = 3 + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + local id = v.customparams.idstring + if id == "commweapon_rocketlauncher" then + v.range = v.range * 1.5 + v.reloadtime = v.reloadtime * 1.5 + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 1.25 + end + v.model = [[wep_m_dragonsfang.s3o]] + v.soundhitvolume = 8 + v.soundstart = [[weapon/missile/missile2_fire_bass]] + v.soundstartvolume = 7 + --break + elseif id == "commweapon_missilelauncher" then + v.range = v.range * 1.5 + v.reloadtime = v.reloadtime * 1.5 + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 1.25 end + v.model = [[wep_m_phoenix.s3o]] + v.soundhitvolume = 5 + v.soundstart = [[weapon/missile/missile_fire7]] + v.soundstartvolume = 3 end - end, + end + end, }, weaponmod_stun_booster = { name = "Flux Amplifier", description = "Lightning Gun: +25% paralyze damage, +2s paralyzetime", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - if v.customparams.idstring == "commweapon_lightninggun" then - v.customparams.extra_damage = v.customparams.extra_damage * 1.25 - v.paralyzetime = v.paralyzetime + 2 - end + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + if v.customparams.idstring == "commweapon_lightninggun" then + v.customparams.extra_damage = v.customparams.extra_damage * 1.25 + v.paralyzetime = v.paralyzetime + 2 end - end, + end + end, }, weaponmod_napalm_warhead = { name = "Napalm Warhead", description = "Riot Cannon/Plasma Artillery/Rocket Launcher: Reduced direct damage, sets target on fire", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - local permitted = { - commweapon_partillery = true, - commweapon_hpartillery = true, - commweapon_rocketlauncher = true, - commweapon_riotcannon = true, - } - for i,v in pairs(weapons) do - local id = v.customparams.idstring - if permitted[id] then - if (id == "commweapon_riotcannon") then -- -20% damage - for armorname, dmg in pairs(v.damage) do - v.damage[armorname] = dmg * 0.8 - end - v.customparams.burntime = "420" - v.rgbcolor = [[1 0.3 0.1]] - elseif (id == "commweapon_hpartillery") then -- -90% damage, 256 AoE, firewalker effect - ReplaceWeapon(unitDef, "commweapon_hpartillery", "commweapon_hpartillery_napalm") - ReplaceWeapon(unitDef, "commweapon_hpartillery", "commweapon_hpartillery_napalm") - elseif (id == "commweapon_partillery") then -- -25% damage, 128 AoE - ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_partillery_napalm") - ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_partillery_napalm") - else -- -25% damage, 128 AoE - for armorname, dmg in pairs(v.damage) do - v.damage[armorname] = dmg * 0.75 - end - v.customparams.burntime = "450" - v.areaofeffect = 128 + local weapons = unitDef.weapondefs or {} + local permitted = { + commweapon_partillery = true, + commweapon_hpartillery = true, + commweapon_rocketlauncher = true, + commweapon_riotcannon = true, + } + for i, v in pairs(weapons) do + local id = v.customparams.idstring + if permitted[id] then + if (id == "commweapon_riotcannon") then -- -20% damage + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 0.8 end - - if (id == "commweapon_riotcannon") or (id == "commweapon_rocketlauncher") then - v.explosiongenerator = [[custom:napalm_koda]] - v.customparams.burnchance = "1" - v.soundhit = [[weapon/burn_mixed]] + v.customparams.burntime = "420" + v.rgbcolor = [[1 0.3 0.1]] + elseif (id == "commweapon_hpartillery") then -- -90% damage, 256 AoE, firewalker effect + ReplaceWeapon(unitDef, "commweapon_hpartillery", "commweapon_hpartillery_napalm") + ReplaceWeapon(unitDef, "commweapon_hpartillery", "commweapon_hpartillery_napalm") + elseif (id == "commweapon_partillery") then -- -25% damage, 128 AoE + ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_partillery_napalm") + ReplaceWeapon(unitDef, "commweapon_partillery", "commweapon_partillery_napalm") + else -- -25% damage, 128 AoE + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg * 0.75 end - v.customparams.setunitsonfire = "1" + v.customparams.burntime = "450" + v.areaofeffect = 128 end + + if (id == "commweapon_riotcannon") or (id == "commweapon_rocketlauncher") then + v.explosiongenerator = [[custom:napalm_koda]] + v.customparams.burnchance = "1" + v.soundhit = [[weapon/burn_mixed]] + end + v.customparams.setunitsonfire = "1" end - end, + end + end, }, weaponmod_flame_enhancer = { name = "Long-Burn Napalm", description = "Flamethrower/Napalm Warhead: +40% on-fire time", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - if v.customparams.burntime then - v.customparams.burntime = v.customparams.burntime * 1.4 - end - if v.customparams.idstring == "commweapon_hpartillery_napalm" then - v.customparams.area_damage_duration = v.customparams.area_damage_duration * 1.4 - v.explosiongenerator = "custom:napalm_firewalker_long" - end + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + if v.customparams.burntime then + v.customparams.burntime = v.customparams.burntime * 1.4 + end + if v.customparams.idstring == "commweapon_hpartillery_napalm" then + v.customparams.area_damage_duration = v.customparams.area_damage_duration * 1.4 + v.explosiongenerator = "custom:napalm_firewalker_long" end - end, + end + end, order = 3.1, }, weaponmod_plasma_containment = { name = "Plasma Containment Field", description = "Heat Ray/Riot Cannon: +30% range", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - local id = v.customparams.idstring - if id == "commweapon_heatray" then - v.range = v.range * 1.3 - elseif id == "commweapon_riotcannon" then - v.range = v.range * 1.3 - end + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + local id = v.customparams.idstring + if id == "commweapon_heatray" then + v.range = v.range * 1.3 + elseif id == "commweapon_riotcannon" then + v.range = v.range * 1.3 end - end, + end + end, }, - + -- modules module_ablative_armor = { name = "Ablative Armor Plates", description = "Adds 600 HP", func = function(unitDef) - unitDef.health = unitDef.health + 600 - end, + unitDef.health = unitDef.health + 600 + end, }, module_adv_targeting = { name = "Advanced Targeting System", description = "Extends range of all weapons by 10%", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - v.customparams.rangemod = v.customparams.rangemod + 0.1 - end - end, + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + v.customparams.rangemod = v.customparams.rangemod + 0.1 + end + end, }, module_adv_nano = { name = "CarRepairer's Nanolathe", description = "Adds +5 metal/s build speed", func = function(unitDef) - if unitDef.workertime then unitDef.workertime = unitDef.workertime + 5 end - --if unitDef.builddistance then unitDef.builddistance = unitDef.builddistance + 60 end - end, + if unitDef.workertime then unitDef.workertime = unitDef.workertime + 5 end + --if unitDef.builddistance then unitDef.builddistance = unitDef.builddistance + 60 end + end, }, module_autorepair = { name = "Autorepair System", description = "Self-repairs 10 HP/s", func = function(unitDef) - unitDef.autoheal = (unitDef.autoheal or 0) + 10 - end, + unitDef.autoheal = (unitDef.autoheal or 0) + 10 + end, }, module_companion_drone = { name = "Companion Drone", description = "Spawns a pair of attack drones", func = function(unitDef) - unitDef.customparams.drones = unitDef.customparams.drones or {} - unitDef.customparams.drones[#unitDef.customparams.drones+1] = "module_companion_drone" - end, + unitDef.customparams.drones = unitDef.customparams.drones or {} + unitDef.customparams.drones[#unitDef.customparams.drones + 1] = "module_companion_drone" + end, }, module_battle_drone = { name = "Battle Drone", description = "Spawns an advanced combat drone", func = function(unitDef) - unitDef.customparams.drones = unitDef.customparams.drones or {} - unitDef.customparams.drones[#unitDef.customparams.drones+1] = "module_battle_drone" - end, + unitDef.customparams.drones = unitDef.customparams.drones or {} + unitDef.customparams.drones[#unitDef.customparams.drones + 1] = "module_battle_drone" + end, }, module_dmg_booster = { name = "Damage Booster", description = "Increases damage of all weapons by 10%", func = function(unitDef) - if unitDef.customparams.dynamic_comm then - -- Weapondefs are static - unitDef.customparams.damagemod = (unitDef.customparams.damagemod or 0) + 1 - else - -- Weapondefs stored in unitdef - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - v.customparams.damagemod = (v.customparams.damagemod or 0) + 0.1 - end + if unitDef.customparams.dynamic_comm then + -- Weapondefs are static + unitDef.customparams.damagemod = (unitDef.customparams.damagemod or 0) + 1 + else + -- Weapondefs stored in unitdef + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + v.customparams.damagemod = (v.customparams.damagemod or 0) + 0.1 end - end, + end + end, }, module_burst_loader = { name = "Burst Loader", description = "+1 burst, +70% reload time", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - local id = v.customparams.idstring - -- linear rather than exponential increase with stacking - v.reloadtime = v.reloadtime or 1 - local previousCount = v.customparams.burstloaders or 0 - local baseReload = v.reloadtime / (1 + 0.7*previousCount) - if id == "commweapon_beamlaser" or id == "commweapon_disruptor" or id == "commweapon_slowbeam" then - -- v.beamtime = v.beamtime + 10 -- beamlaser has 0.1, it's in seconds - v.corethickness = v.corethickness + v.corethickness/(previousCount + 1) - for armorname, dmg in pairs(v.damage) do - v.damage[armorname] = dmg + dmg/(previousCount + 1) - end - elseif id == "commweapon_shotgun" then - v.burst = (v.burst or 1) + 3 - v.sprayangle = (v.sprayangle or 0) + 256 - v.reloadtime = v.reloadtime + baseReload * 0.7 - else - v.burstrate = (v.burstrate or 0.1 ) - v.reloadtime = v.reloadtime + baseReload * 0.7 - v.burst = (v.burst or 1) + 1 - v.sprayangle = (v.sprayangle or 0) + 256 + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + local id = v.customparams.idstring + -- linear rather than exponential increase with stacking + v.reloadtime = v.reloadtime or 1 + local previousCount = v.customparams.burstloaders or 0 + local baseReload = v.reloadtime / (1 + 0.7 * previousCount) + if id == "commweapon_beamlaser" or id == "commweapon_disruptor" or id == "commweapon_slowbeam" then + -- v.beamtime = v.beamtime + 10 -- beamlaser has 0.1, it's in seconds + v.corethickness = v.corethickness + v.corethickness / (previousCount + 1) + for armorname, dmg in pairs(v.damage) do + v.damage[armorname] = dmg + dmg / (previousCount + 1) end - v.customparams.burstloaders = previousCount + 1 + elseif id == "commweapon_shotgun" then + v.burst = (v.burst or 1) + 3 + v.sprayangle = (v.sprayangle or 0) + 256 + v.reloadtime = v.reloadtime + baseReload * 0.7 + else + v.burstrate = (v.burstrate or 0.1) + v.reloadtime = v.reloadtime + baseReload * 0.7 + v.burst = (v.burst or 1) + 1 + v.sprayangle = (v.sprayangle or 0) + 256 end - end, + v.customparams.burstloaders = previousCount + 1 + end + end, }, module_energy_cell = { name = "Energy Cell", description = "Compact fuel cells that produce +6 energy", func = function(unitDef) - unitDef.energymake = (unitDef.energymake or 0) + 6 - end, + unitDef.energymake = (unitDef.energymake or 0) + 6 + end, }, module_fieldradar = { name = "Field Radar Module", description = "Basic radar system with 1800 range", func = function(unitDef) - unitDef.radardistance = (unitDef.radardistance or 0) - if unitDef.radardistance < 1800 then - unitDef.radardistance = 1800 - end - if (not unitDef.radaremitheight) or unitDef.radaremitheight < 100 then - unitDef.radaremitheight = 24 - end - end, + unitDef.radardistance = (unitDef.radardistance or 0) + if unitDef.radardistance < 1800 then + unitDef.radardistance = 1800 + end + if (not unitDef.radaremitheight) or unitDef.radaremitheight < 100 then + unitDef.radaremitheight = 24 + end + end, }, module_heavy_armor = { name = "High Density Plating", description = "Adds 1600 HP, slows comm by +10%", func = function(unitDef, attributeMods) - unitDef.health = unitDef.health + 1600 - attributeMods.speed = attributeMods.speed - 0.1 - end, + unitDef.health = unitDef.health + 1600 + attributeMods.speed = attributeMods.speed - 0.1 + end, }, module_high_power_servos = { name = "High Power Servos", description = "More powerful leg actuators increase speed by 10% of base", func = function(unitDef, attributeMods) - attributeMods.speed = attributeMods.speed + 0.1 - end, + attributeMods.speed = attributeMods.speed + 0.1 + end, }, module_personal_cloak = { name = "Personal Cloak", description = "Cloaks the commander", func = function(unitDef) - unitDef.cancloak = true - unitDef.cloakcost = unitDef.cloakcost or 5 - unitDef.mincloakdistance = math.max(150, unitDef.mincloakdistance or 0) - if unitDef.cloakcost > 5 then - unitDef.cloakcost = 5 - end - unitDef.cloakcostmoving = unitDef.cloakcostmoving or 10 - if unitDef.cloakcostmoving > 10 then - unitDef.cloakcostmoving = 10 - end - end, + unitDef.cancloak = true + unitDef.cloakcost = unitDef.cloakcost or 5 + unitDef.mincloakdistance = math.max(150, unitDef.mincloakdistance or 0) + if unitDef.cloakcost > 5 then + unitDef.cloakcost = 5 + end + unitDef.cloakcostmoving = unitDef.cloakcostmoving or 10 + if unitDef.cloakcostmoving > 10 then + unitDef.cloakcostmoving = 10 + end + end, }, module_personal_shield = { name = "Personal Shield", order = 5, description = "Generates a small bubble shield", func = function(unitDef) - if unitDef.customparams.dynamic_comm then - DynamicApplyWeapon(unitDef, "commweapon_personal_shield", #unitDef.weapons + 1) - else - ApplyWeapon(unitDef, "commweapon_personal_shield", 4) - end - end, + if unitDef.customparams.dynamic_comm then + DynamicApplyWeapon(unitDef, "commweapon_personal_shield", #unitDef.weapons + 1) + else + ApplyWeapon(unitDef, "commweapon_personal_shield", 4) + end + end, }, - + module_resurrect = { name = "Lazarus Device", description = "Enables resurrection of wrecks", func = function(unitDef) - unitDef.canresurrect = true - end, + unitDef.canresurrect = true + end, }, - + module_jumpjet = { name = "Jumpjet", description = "Allows the commander to jump", func = function(unitDef) - unitDef.customparams.canjump = 1 - unitDef.customparams.jump_range = 400 - unitDef.customparams.jump_speed = 6 - unitDef.customparams.jump_reload = 20 - unitDef.customparams.jump_from_midair = 1 - end, + unitDef.customparams.canjump = 1 + unitDef.customparams.jump_range = 400 + unitDef.customparams.jump_speed = 6 + unitDef.customparams.jump_reload = 20 + unitDef.customparams.jump_from_midair = 1 + end, }, - + module_areashield = { name = "Area Shield", order = 6, description = "A bubble shield that protects surrounding units within 350 m", func = function(unitDef) - --ApplyWeapon(unitDef, "commweapon_areashield", 2) - - if unitDef.customparams.dynamic_comm then - DynamicApplyWeapon(unitDef, "commweapon_areashield", #unitDef.weapons) -- not +1 so as to replace personal - else - ReplaceWeapon(unitDef, "commweapon_personal_shield", "commweapon_areashield") - end + --ApplyWeapon(unitDef, "commweapon_areashield", 2) + + if unitDef.customparams.dynamic_comm then + DynamicApplyWeapon(unitDef, "commweapon_areashield", #unitDef.weapons) -- not +1 so as to replace personal + else + ReplaceWeapon(unitDef, "commweapon_personal_shield", "commweapon_areashield") + end - unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} - table.insert(unitDef.customparams.lups_unit_fxs, "commAreaShield") - end, + unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} + table.insert(unitDef.customparams.lups_unit_fxs, "commAreaShield") + end, }, module_cloak_field = { name = "Cloaking Field", description = "Cloaks all friendly units within 350 m", func = function(unitDef) - unitDef.mincloakdistance = math.max(150, unitDef.mincloakdistance or 0) - unitDef.onoffable = true - unitDef.radarDistanceJam = (unitDef.radarDistanceJam and unitDef.radarDistanceJam > 350 and unitDef.radarDistanceJam) or 350 - unitDef.customparams.area_cloak = "1" - unitDef.customparams.area_cloak_upkeep = "15" - unitDef.customparams.area_cloak_radius = "350" - unitDef.customparams.area_cloak_decloak_distance = "75" - end, + unitDef.mincloakdistance = math.max(150, unitDef.mincloakdistance or 0) + unitDef.onoffable = true + unitDef.radarDistanceJam = (unitDef.radarDistanceJam and unitDef.radarDistanceJam > 350 and unitDef.radarDistanceJam) or + 350 + unitDef.customparams.area_cloak = "1" + unitDef.customparams.area_cloak_upkeep = "15" + unitDef.customparams.area_cloak_radius = "350" + unitDef.customparams.area_cloak_decloak_distance = "75" + end, }, module_jammer = { name = "Radar Jammer", description = "Masks radar signals of all units within 500 m", func = function(unitDef) - unitDef.radardistancejam = 500 - unitDef.activatewhenbuilt = true - unitDef.onoffable = true - end, + unitDef.radardistancejam = 500 + unitDef.activatewhenbuilt = true + unitDef.onoffable = true + end, }, - + module_jump_booster = { name = "Dragonfly Booster", description = "Increases jump range and height", func = function(unitDef) - unitDef.customparams.jumpclass = "commrecon2" - end, + unitDef.customparams.jumpclass = "commrecon2" + end, }, - + module_radarnet = { name = "Integrated Radar Network", description = "Reduces radar wobble for all units", func = function(unitDef) - unitDef.isTargetingUpgrade = true - unitDef.activatewhenbuilt = true + unitDef.isTargetingUpgrade = true + unitDef.activatewhenbuilt = true end, }, - + module_ultralight_hull = { name = "Ultralight Hull", description = "-1200 HP, +25% speed", func = function(unitDef, attributeMods) - unitDef.health = unitDef.health - 1200 - attributeMods.speed = attributeMods.speed + 0.25 - end, + unitDef.health = unitDef.health - 1200 + attributeMods.speed = attributeMods.speed + 0.25 + end, }, module_weapon_hicharge = { name = "Weapon Hi-Charger", description = "-1000 HP, +40% damage", func = function(unitDef, attributeMods) - unitDef.health = unitDef.health - 1000 - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - v.customparams.damagemod = v.customparams.damagemod + 0.4 - end - end, + unitDef.health = unitDef.health - 1000 + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + v.customparams.damagemod = v.customparams.damagemod + 0.4 + end + end, }, -- modules that use a weapon slot module_guardian_armor = { name = "Guardian Defence System", description = "Adds 100% HP (including other modules); self-repairs 20 HP/s", func = function(unitDef, attributeMods) - attributeMods.health = attributeMods.health + 1 - unitDef.autoheal = (unitDef.autoheal or 0) + 20 + attributeMods.health = attributeMods.health + 1 + unitDef.autoheal = (unitDef.autoheal or 0) + 20 end, useWeaponSlot = true, }, @@ -694,76 +696,76 @@ upgrades = { name = "Marathon Motion Control", description = "Increases speed by 50% of base", func = function(unitDef, attributeMods) - attributeMods.speed = attributeMods.speed + 0.5 + attributeMods.speed = attributeMods.speed + 0.5 end, useWeaponSlot = true, }, - + module_longshot = { name = "Longshot Fire Control", description = "Extends range of all weapons by 40%", func = function(unitDef) - local weapons = unitDef.weapondefs or {} - for i,v in pairs(weapons) do - v.customparams.rangemod = v.customparams.rangemod + 0.4 - end - end, + local weapons = unitDef.weapondefs or {} + for i, v in pairs(weapons) do + v.customparams.rangemod = v.customparams.rangemod + 0.4 + end + end, useWeaponSlot = true, }, - + module_super_nano = { name = "Engineer's Revenge", description = "Adds 20 metal/s build speed and 200 build range", func = function(unitDef) - if unitDef.workertime then unitDef.workertime = unitDef.workertime + 20 end - if unitDef.builddistance then unitDef.builddistance = unitDef.builddistance + 200 end + if unitDef.workertime then unitDef.workertime = unitDef.workertime + 20 end + if unitDef.builddistance then unitDef.builddistance = unitDef.builddistance + 200 end end, useWeaponSlot = true, }, - + -- deprecated module_improved_optics = { name = "Improved Optics", description = "Increases sight distance by 100 m", func = function(unitDef) - unitDef.sightdistance = unitDef.sightdistance + 100 - end, + unitDef.sightdistance = unitDef.sightdistance + 100 + end, }, module_repair_field = { name = "Repair Field", description = "Passively repairs all friendly units within 450 m", func = function(unitDef) - unitDef.customparams.repairaura_preset = "module_repairfield" - end, + unitDef.customparams.repairaura_preset = "module_repairfield" + end, }, - + -- secret stuff! module_econ = { name = "Economy Package", description = "Produces +2 energy and metal", func = function(unitDef) - unitDef.energymake = (unitDef.energymake or 0) + 2 - unitDef.metalmake = (unitDef.metalmake or 0) + 2 - end, + unitDef.energymake = (unitDef.energymake or 0) + 2 + unitDef.metalmake = (unitDef.metalmake or 0) + 2 + end, }, - + conversion_lazor = { name = "Uberlazor", description = "LOLOLOL", func = function(unitDef) - ReplaceWeapon(unitDef, "commweapon_beamlaser", "commweapon_hparticlebeam") - end, + ReplaceWeapon(unitDef, "commweapon_beamlaser", "commweapon_hparticlebeam") + end, } } include = include or VFS.Include -local modulesdefs=include("gamedata/modularcomms/modules_all_defs.lua") +local modulesdefs = include("gamedata/modularcomms/modules_all_defs.lua") for i = 1, #modulesdefs do local moduleDefs = modulesdefs[i].moduledef for key, value in pairs(moduleDefs) do - upgrades[key]=value + upgrades[key] = value end end @@ -780,80 +782,80 @@ end decorations = { skin_recon_dark = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/commrecon1dark.dds]] - unitDef.customparams.altskin2 = [[unittextures/commrecon2alt.dds]] - unitDef.buildpic = "skin_recon_dark.png" - end, + unitDef.customparams.altskin = [[unittextures/commrecon1dark.dds]] + unitDef.customparams.altskin2 = [[unittextures/commrecon2alt.dds]] + unitDef.buildpic = "skin_recon_dark.png" + end, }, skin_recon_red = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/commrecon1red.dds]] - unitDef.customparams.altskin2 = [[unittextures/commrecon2alt.dds]] - unitDef.buildpic = "skin_recon_red.png" - end, + unitDef.customparams.altskin = [[unittextures/commrecon1red.dds]] + unitDef.customparams.altskin2 = [[unittextures/commrecon2alt.dds]] + unitDef.buildpic = "skin_recon_red.png" + end, }, skin_recon_leopard = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/commrecon1leopard.dds]] - unitDef.customparams.altskin2 = [[unittextures/commrecon2alt.dds]] - unitDef.buildpic = "skin_recon_leopard.png" - end, + unitDef.customparams.altskin = [[unittextures/commrecon1leopard.dds]] + unitDef.customparams.altskin2 = [[unittextures/commrecon2alt.dds]] + unitDef.buildpic = "skin_recon_leopard.png" + end, }, skin_battle_blue = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/core_commander_1blue.dds]] - end, + unitDef.customparams.altskin = [[unittextures/core_commander_1blue.dds]] + end, }, skin_battle_camo = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/core_commander_1camo.dds]] - unitDef.buildpic = "skin_battle_camo.png" - end, + unitDef.customparams.altskin = [[unittextures/core_commander_1camo.dds]] + unitDef.buildpic = "skin_battle_camo.png" + end, }, skin_battle_tiger = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/core_commander_1tiger.dds]] - unitDef.buildpic = "skin_battle_tiger.png" - end, + unitDef.customparams.altskin = [[unittextures/core_commander_1tiger.dds]] + unitDef.buildpic = "skin_battle_tiger.png" + end, }, skin_support_dark = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/commsupport1dark.dds]] - unitDef.buildpic = "skin_support_dark.png" - end, + unitDef.customparams.altskin = [[unittextures/commsupport1dark.dds]] + unitDef.buildpic = "skin_support_dark.png" + end, }, skin_support_green = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/commsupport1green.dds]] - unitDef.buildpic = "skin_support_green.png" - end, + unitDef.customparams.altskin = [[unittextures/commsupport1green.dds]] + unitDef.buildpic = "skin_support_green.png" + end, }, skin_support_hotrod = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/commsupport1hotrod.dds]] - unitDef.buildpic = "skin_support_hotrod.png" - end, + unitDef.customparams.altskin = [[unittextures/commsupport1hotrod.dds]] + unitDef.buildpic = "skin_support_hotrod.png" + end, }, skin_support_zebra = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/commsupport1zebra.dds]] - unitDef.buildpic = "skin_support_zebra.png" - end, + unitDef.customparams.altskin = [[unittextures/commsupport1zebra.dds]] + unitDef.buildpic = "skin_support_zebra.png" + end, }, skin_assault_steel = { func = function(unitDef) - unitDef.customparams.altskin = [[unittextures/benzcom_1_steel.dds]] - unitDef.buildpic = "skin_assault_steel.png" - end, + unitDef.customparams.altskin = [[unittextures/benzcom_1_steel.dds]] + unitDef.buildpic = "skin_assault_steel.png" + end, }, - skin_strike_renegade={ + skin_strike_renegade = { func = function(unitDef) unitDef.customparams.altskin = [[unittextures/strikecom_renegade.dds]] unitDef.customparams.altskin2 = [[unittextures/strikecom_renegade_2.dds]] unitDef.buildpic = "skin_strike_renegade.png" end }, - skin_strike_chitin={ + skin_strike_chitin = { func = function(unitDef) unitDef.customparams.altskin = [[unittextures/strikecom_chitin.dds]] unitDef.customparams.altskin2 = [[unittextures/strikecom_chitin_2.dds]] @@ -862,73 +864,73 @@ decorations = { }, shield_red = { func = function(unitDef) - unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} - table.insert(unitDef.customparams.lups_unit_fxs, "commandShieldRed") - end, + unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} + table.insert(unitDef.customparams.lups_unit_fxs, "commandShieldRed") + end, }, shield_green = { func = function(unitDef) - unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} - table.insert(unitDef.customparams.lups_unit_fxs, "commandShieldGreen") - end, + unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} + table.insert(unitDef.customparams.lups_unit_fxs, "commandShieldGreen") + end, }, shield_blue = { func = function(unitDef) - unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} - table.insert(unitDef.customparams.lups_unit_fxs, "commandShieldBlue") - end, + unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} + table.insert(unitDef.customparams.lups_unit_fxs, "commandShieldBlue") + end, }, shield_orange = { func = function(unitDef) - unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} - table.insert(unitDef.customparams.lups_unit_fxs, "commandShieldOrange") - end, + unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} + table.insert(unitDef.customparams.lups_unit_fxs, "commandShieldOrange") + end, }, shield_violet = { func = function(unitDef) - unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} - table.insert(unitDef.customparams.lups_unit_fxs, "commandShieldViolet") - end, + unitDef.customparams.lups_unit_fxs = unitDef.customparams.lups_unit_fxs or {} + table.insert(unitDef.customparams.lups_unit_fxs, "commandShieldViolet") + end, }, - + icon_shoulders = { func = function(unitDef, config) - if config.decorations and config.decorations.icon_shoulders then - unitDef.customparams.decorationicons = unitDef.customparams.decorationicons or {} - unitDef.customparams.decorationicons.shoulders = config.decorations.icon_shoulders.image - end - end, + if config.decorations and config.decorations.icon_shoulders then + unitDef.customparams.decorationicons = unitDef.customparams.decorationicons or {} + unitDef.customparams.decorationicons.shoulders = config.decorations.icon_shoulders.image + end + end, }, - + icon_chest = { func = function(unitDef, config) - if config.decorations and config.decorations.icon_chest then - unitDef.customparams.decorationicons = unitDef.customparams.decorationicons or {} - unitDef.customparams.decorationicons.chest = config.decorations.icon_chest.image - end - end, + if config.decorations and config.decorations.icon_chest then + unitDef.customparams.decorationicons = unitDef.customparams.decorationicons or {} + unitDef.customparams.decorationicons.chest = config.decorations.icon_chest.image + end + end, }, - + icon_back = { func = function(unitDef, config) - if config.decorations and config.decorations.icon_back then - unitDef.customparams.decorationicons = unitDef.customparams.decorationicons or {} - unitDef.customparams.decorationicons.back = config.decorations.icon_back.image - end - end, + if config.decorations and config.decorations.icon_back then + unitDef.customparams.decorationicons = unitDef.customparams.decorationicons or {} + unitDef.customparams.decorationicons.back = config.decorations.icon_back.image + end + end, }, - + icon_overhead = { func = function(unitDef, config) - if config.decorations and config.decorations.icon_overhead then - unitDef.customparams.decorationicons = unitDef.customparams.decorationicons or {} - unitDef.customparams.decorationicons.overhead = config.decorations.icon_overhead.image - end - end, + if config.decorations and config.decorations.icon_overhead then + unitDef.customparams.decorationicons = unitDef.customparams.decorationicons or {} + unitDef.customparams.decorationicons.overhead = config.decorations.icon_overhead.image + end + end, }, } -for name,data in pairs(upgrades) do +for name, data in pairs(upgrades) do local order = data.order if not order then if name:find("commweapon_") then @@ -945,19 +947,19 @@ for name,data in pairs(upgrades) do end local weaponsList = VFS.DirList("gamedata/modularcomms/weapons", "*.lua") or {} -for i=1,#weaponsList do +for i = 1, #weaponsList do local name, array = VFS.Include(weaponsList[i]) weapons[name] = lowerkeys(array) - + local weapon = weapons[name] weapon.customparams = weapon.customparams or {} if name ~= "FAKELASER" then weapon.customparams.idstring = name end - + if weapon.customparams.altforms then for form, mods in pairs(weapon.customparams.altforms) do - local newName = name.."_"..form + local newName = name .. "_" .. form weapons[newName] = CopyTable(weapon, true) upgrades[newName] = CopyTable(upgrades[name], true) weapons[newName] = MergeTable(mods, weapons[newName], true) diff --git a/gamedata/modularcomms/modules/chickenbioarmor.lua b/gamedata/modularcomms/modules/chickenbioarmor.lua deleted file mode 100644 index efeb12df28..0000000000 --- a/gamedata/modularcomms/modules/chickenbioarmor.lua +++ /dev/null @@ -1,38 +0,0 @@ -local hp=500 -local rep=5 -local humanName="Bio Armor" -local description= "Bio Armor - Give " .. hp .. " hp and " .. rep .. " hp/s repair. Limit: 10" -return { - moduledef={ - module_chickenbioarmor={ - name=humanName, - description=description, - func = function(unitDef) - unitDef.health = unitDef.health + hp - unitDef.autoheal = (unitDef.autoheal or 0) + rep - end, - }, - - }, - dynamic_comm_def=function (shared) - shared=ModularCommDefsShared or shared -- for luals - local moduleImagePath=shared.moduleImagePath - local COST_MULT=shared.COST_MULT - local HP_MULT=shared.HP_MULT - return {{ - name = "module_chickenbioarmor", - humanName = humanName, - description = description, - image = moduleImagePath .. "module_repair_field.png", - limit = 10, - cost = 150 * COST_MULT, - requireLevel = 1, - requireChassis = {"chicken","assault"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + rep*HP_MULT - sharedData.healthBonus = (sharedData.healthBonus or 0) + hp*HP_MULT - end - }} - end -} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenbioarmorheavy.lua b/gamedata/modularcomms/modules/chickenbioarmorheavy.lua deleted file mode 100644 index a12fda970e..0000000000 --- a/gamedata/modularcomms/modules/chickenbioarmorheavy.lua +++ /dev/null @@ -1,42 +0,0 @@ -local hp=1500 -local rep=10 -local speed=-0.04 -local humanName="Heavy Bio Armor" -local description= "Heavy Bio Armor - Give " .. hp .. " hp and " .. rep .. " hp/s repair and ".. speed*100 .. "% speed. Limit: 5" - -return { - moduledef={ - module_chickenbioarmor={ - name=humanName, - description=description, - func = function(unitDef,attributeMods) - unitDef.health = unitDef.health + hp - unitDef.autoheal = (unitDef.autoheal or 0) + rep - attributeMods.speed = attributeMods.speed + speed - end, - }, - - }, - dynamic_comm_def=function (shared) - shared=ModularCommDefsShared or shared -- for luals - local moduleImagePath=shared.moduleImagePath - local COST_MULT=shared.COST_MULT - local HP_MULT=shared.HP_MULT - return {{ - name = "module_chickenbioarmor", - humanName = humanName, - description = description, - image = moduleImagePath .. "module_repair_field.png", - limit = 10, - cost = 150 * COST_MULT, - requireLevel = 2, - requireChassis = {"chicken","assault"}, - slotType = "module", - applicationFunction = function (modules, sharedData) - sharedData.autorepairRate = (sharedData.autorepairRate or 0) + rep*HP_MULT - sharedData.healthBonus = (sharedData.healthBonus or 0) + hp*HP_MULT - sharedData.speedMultPost = (sharedData.speedMultPost or 1) + speed - end - }} - end -} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenclaw.lua b/gamedata/modularcomms/modules/chickenclaw.lua deleted file mode 100644 index 18632da4a7..0000000000 --- a/gamedata/modularcomms/modules/chickenclaw.lua +++ /dev/null @@ -1,35 +0,0 @@ - -local humanName="Chicken Claw" -local description= "Chicken Claw: CLUCK" - -return { - moduledef={ - commweapon_chickenclaw={ - name=humanName, - description=description, - } - }, - dynamic_comm_def=function (shared) - shared=ModularCommDefsShared or shared - local moduleImagePath=shared.moduleImagePath - local COST_MULT=shared.COST_MULT - local HP_MULT=shared.HP_MULT - - local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon - return {{ - name = "commweapon_chickenclaw", - humanName = humanName, - description = description, - image = moduleImagePath .. "chickena.png", - limit = 2, - cost = 0, - requireChassis = {"chicken"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = applicationFunctionApplyWeapon(function () - return "commweapon_chickenclaw" - end), - isBasicWeapon=true, - }} - end -} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenflamethrower.lua b/gamedata/modularcomms/modules/chickenflamethrower.lua deleted file mode 100644 index ff2ceabc75..0000000000 --- a/gamedata/modularcomms/modules/chickenflamethrower.lua +++ /dev/null @@ -1,34 +0,0 @@ - -local humanName="Flame Thrower" -local description= "Flame Thrower" -return { - moduledef={ - commweapon_chickenflamethrower={ - name=humanName, - description=description, - } - }, - dynamic_comm_def=function (shared) - shared=ModularCommDefsShared or shared - local moduleImagePath=shared.moduleImagePath - local COST_MULT=shared.COST_MULT - local HP_MULT=shared.HP_MULT - - local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon - return {{ - name = "commweapon_chickenflamethrower", - humanName = humanName, - description = description, - image = moduleImagePath .. "commweapon_flamethrower.png", - limit = 2, - cost = 0, - requireChassis = {},-- bugged - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = applicationFunctionApplyWeapon(function () - return "commweapon_chickenflamethrower" - end), - isBasicWeapon=true, - }} - end -} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickengoo.lua b/gamedata/modularcomms/modules/chickengoo.lua deleted file mode 100644 index 5a4a6ab7fb..0000000000 --- a/gamedata/modularcomms/modules/chickengoo.lua +++ /dev/null @@ -1,45 +0,0 @@ - -local humanName="Chicken Blob" -local description= humanName .. " - Blob, can only shot at front, replace other weapons" - -return { - moduledef={ - commweapon_chickengoo={ - name=humanName, - description=description, - } - }, - dynamic_comm_def=function (shared) - shared=ModularCommDefsShared or shared - local moduleImagePath=shared.moduleImagePath - local COST_MULT=shared.COST_MULT - local HP_MULT=shared.HP_MULT - local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon - - return {{ - name = "commweapon_chickengoo", - humanName = humanName, - description = description, - image = moduleImagePath .. "commweapon_clusterbomb.png", - limit = 1, - cost = 0, - requireChassis = {"chicken"}, - requireLevel = 3, - slotType = "adv_weapon", - applicationFunction = applicationFunctionApplyWeapon(function () - return "commweapon_chickengoo" - end), - --[=[ - function (modules, sharedData) - if sharedData.noMoreWeapons then - return - end - local weaponName = "commweapon_chickengoo" - sharedData.weapon1 = weaponName - sharedData.weapon2 = nil - sharedData.noMoreWeapons = true - end,]=] - --isBasicWeapon=true, - }} - end -} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenshield.lua b/gamedata/modularcomms/modules/chickenshield.lua deleted file mode 100644 index a85114f8ab..0000000000 --- a/gamedata/modularcomms/modules/chickenshield.lua +++ /dev/null @@ -1,46 +0,0 @@ - -local humanName="Chicken Shield" -local description= humanName.." - Generates a weak but high regen shield" - -return { - moduledef={ - module_chickenshield={ - name=humanName, - description=description,order = 5, - func = function(unitDef) - if unitDef.customparams.dynamic_comm then ----@diagnostic disable-next-line: undefined-global - DynamicApplyWeapon(unitDef, "commweapon_chickenshield", #unitDef.weapons + 1) - else ----@diagnostic disable-next-line: undefined-global - ApplyWeapon(unitDef, "commweapon_chickenshield", 4) - end - end, - } - }, - dynamic_comm_def=function (shared) - shared=ModularCommDefsShared or shared - --local shared=ModularCommDefsShared - local moduleImagePath=shared.moduleImagePath - local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon - local COST_MULT=shared.COST_MULT - return {{ - name = "commweapon_chickenshield", - humanName = humanName, - description = description, - image = moduleImagePath .. "module_personal_shield.png", - limit = 1, - cost = 300 * COST_MULT, - prohibitingModules = {"module_personal_cloak"}, - requireOneOf = {"commweapon_personal_shield"}, - requireChassis = {"chicken"}, - requireLevel = 3, - slotType = "module", - - applicationFunction = function (modules, sharedData) - -- Do not override area shield - sharedData.shield = "commweapon_chickenshield" - end - }} - end -} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenspike.lua b/gamedata/modularcomms/modules/chickenspike.lua deleted file mode 100644 index d4bba52954..0000000000 --- a/gamedata/modularcomms/modules/chickenspike.lua +++ /dev/null @@ -1,35 +0,0 @@ - -local humanName="Chicken Spike" -local description= "Chicken Spike: Mid range skirmish weapon, can onlt shot at front" - -return { - moduledef={ - commweapon_chickenspike={ - name=humanName, - description=description, - } - }, - dynamic_comm_def=function (shared) - shared=ModularCommDefsShared or shared - local moduleImagePath=shared.moduleImagePath - local COST_MULT=shared.COST_MULT - local HP_MULT=shared.HP_MULT - - local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon - return {{ - name = "commweapon_chickenspike", - humanName = humanName, - description = description, - image = moduleImagePath .. "chickens.png", - limit = 2, - cost = 0, - requireChassis = {"chicken"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = applicationFunctionApplyWeapon(function () - return "commweapon_chickenspike" - end), - isBasicWeapon=true, - }} - end -} \ No newline at end of file diff --git a/gamedata/modularcomms/modules/chickenspores.lua b/gamedata/modularcomms/modules/chickenspores.lua deleted file mode 100644 index 71c67d0382..0000000000 --- a/gamedata/modularcomms/modules/chickenspores.lua +++ /dev/null @@ -1,34 +0,0 @@ - -local humanName="Chicken Spores" -local description= "Chicken Spores: Chasing Projectile, x0.5 damage vs ground" -return { - moduledef={ - commweapon_chickenspores={ - name=humanName, - description=description, - } - }, - dynamic_comm_def=function (shared) - shared=ModularCommDefsShared or shared - local moduleImagePath=shared.moduleImagePath - local COST_MULT=shared.COST_MULT - local HP_MULT=shared.HP_MULT - - local applicationFunctionApplyWeapon=shared.applicationFunctionApplyWeapon - return {{ - name = "commweapon_chickenspores", - humanName = humanName, - description = description, - image = moduleImagePath .. "chickend.png", - limit = 2, - cost = 0, - requireChassis = {"chicken"}, - requireLevel = 1, - slotType = "basic_weapon", - applicationFunction = applicationFunctionApplyWeapon(function () - return "commweapon_chickenspores" - end), - isBasicWeapon=true, - }} - end -} \ No newline at end of file diff --git a/gamedata/modularcomms/modules_all_defs.lua b/gamedata/modularcomms/modules_all_defs.lua index b7481edc07..4014884aa6 100644 --- a/gamedata/modularcomms/modules_all_defs.lua +++ b/gamedata/modularcomms/modules_all_defs.lua @@ -1,14 +1,13 @@ - if not Spring.ModularCommAPI then - Spring.ModularCommAPI={} + Spring.ModularCommAPI = {} end if not Spring.ModularCommAPI.Modules then - local Modules={} - Spring.ModularCommAPI.Modules=Modules - local moduleFiles=VFS.DirList("gamedata/modularcomms/modules", "*.lua") or {} - for i = 1, #moduleFiles do - local moduleDef = VFS.Include(moduleFiles[i]) - Modules[#Modules+1]=moduleDef - end + local Modules = {} + Spring.ModularCommAPI.Modules = Modules + local moduleFiles = VFS.DirList("gamedata/modularcomms/modules", "*.lua") or {} + for i = 1, #moduleFiles do + local moduleDef = VFS.Include(moduleFiles[i]) + Modules[#Modules + 1] = moduleDef + end end -return Spring.ModularCommAPI.Modules \ No newline at end of file +return Spring.ModularCommAPI.Modules diff --git a/gamedata/modularcomms/staticcomms.lua b/gamedata/modularcomms/staticcomms.lua index 6ca8a4a2a0..a0e5fc5b56 100644 --- a/gamedata/modularcomms/staticcomms.lua +++ b/gamedata/modularcomms/staticcomms.lua @@ -1,191 +1,191 @@ local commsCampaign = { - -- singleplayer - comm_mission_tutorial1 = { - chassis = "cremcom3", - name = "Tutorial Commander", - modules = { "commweapon_beamlaser", "module_autorepair", "module_autorepair"}, - }, + -- singleplayer + comm_mission_tutorial1 = { + chassis = "cremcom3", + name = "Tutorial Commander", + modules = { "commweapon_beamlaser", "module_autorepair", "module_autorepair" }, + }, - comm_campaign_ada = { - chassis = "cremcom2", - name = "Ada's Commander", - -- comm module list should be empty/nil to avoid funny stuff when merging with misson's module table - --modules = { "commweapon_beamlaser", "module_ablative_armor", "module_autorepair", "module_high_power_servos"}, - }, - - comm_campaign_promethean = { - chassis = "commrecon2", - name = "The Promethean", - --modules = { "commweapon_heatray", "module_ablative_armor", "module_ablative_armor", "weaponmod_plasma_containment", "module_autorepair" }, - decorations = {"skin_recon_red"}, - }, - - comm_campaign_freemachine = { - chassis = "commstrike2", - name = "Libertas Machina", - --modules = { "commweapon_riotcannon", "module_ablative_armor", "module_ablative_armor", "module_adv_targeting", "module_autorepair" }, - }, - - comm_campaign_odin = { - chassis = "commrecon2", - name = "Odin", - --modules = { "commweapon_lparticlebeam", "module_ablative_armor", "module_ablative_armor", "module_high_power_servos", "module_autorepair", "module_companion_drone"}, - }, + comm_campaign_ada = { + chassis = "cremcom2", + name = "Ada's Commander", + -- comm module list should be empty/nil to avoid funny stuff when merging with misson's module table + --modules = { "commweapon_beamlaser", "module_ablative_armor", "module_autorepair", "module_high_power_servos"}, + }, - comm_campaign_biovizier = { - chassis = "commsupport2", - name = "The Biovizier", - --modules = { "commweapon_gaussrifle", "module_ablative_armor", "weaponmod_railaccel", "module_autorepair", "module_autorepair" }, - decorations = { "skin_support_green" }, - }, - - comm_campaign_isonade = { - chassis = "commstrike2", -- TODO get a properly organic model - name = "Lord Isonade", - modules = { "commweapon_gaussrifle", "commweapon_gaussrifle", "module_heavy_armor", "module_dmg_booster", "module_autorepair", "module_autorepair" }, - decorations = { "skin_strike_chitin" }, - }, + comm_campaign_promethean = { + chassis = "commrecon2", + name = "The Promethean", + --modules = { "commweapon_heatray", "module_ablative_armor", "module_ablative_armor", "weaponmod_plasma_containment", "module_autorepair" }, + decorations = { "skin_recon_red" }, + }, - comm_campaign_legion = { - chassis = "commstrike2", - name = "Legate Fidus", - decorations = { "skin_strike_renegade" }, + comm_campaign_freemachine = { + chassis = "commstrike2", + name = "Libertas Machina", + --modules = { "commweapon_riotcannon", "module_ablative_armor", "module_ablative_armor", "module_adv_targeting", "module_autorepair" }, + }, - --modules = { "commweapon_shotgun", "module_heavy_armor", "weaponmod_autoflechette", "module_adv_targeting", "module_autorepair"}, - --decorations = { "skin_battle_tiger" }, - }, - - comm_campaign_praetorian = { - chassis = "benzcom2", - name = "Scipio Astra", - --modules = { "commweapon_assaultcannon", "module_heavy_armor", "weaponmod_high_caliber_barrel", "module_adv_targeting", "module_autorepair"}, - }, + comm_campaign_odin = { + chassis = "commrecon2", + name = "Odin", + --modules = { "commweapon_lparticlebeam", "module_ablative_armor", "module_ablative_armor", "module_high_power_servos", "module_autorepair", "module_companion_drone"}, + }, + + comm_campaign_biovizier = { + chassis = "commsupport2", + name = "The Biovizier", + --modules = { "commweapon_gaussrifle", "module_ablative_armor", "weaponmod_railaccel", "module_autorepair", "module_autorepair" }, + decorations = { "skin_support_green" }, + }, + + comm_campaign_isonade = { + chassis = "commstrike2", -- TODO get a properly organic model + name = "Lord Isonade", + modules = { "commweapon_gaussrifle", "commweapon_gaussrifle", "module_heavy_armor", "module_dmg_booster", "module_autorepair", "module_autorepair" }, + decorations = { "skin_strike_chitin" }, + }, + + comm_campaign_legion = { + chassis = "commstrike2", + name = "Legate Fidus", + decorations = { "skin_strike_renegade" }, + + --modules = { "commweapon_shotgun", "module_heavy_armor", "weaponmod_autoflechette", "module_adv_targeting", "module_autorepair"}, + --decorations = { "skin_battle_tiger" }, + }, + + comm_campaign_praetorian = { + chassis = "benzcom2", + name = "Scipio Astra", + --modules = { "commweapon_assaultcannon", "module_heavy_armor", "weaponmod_high_caliber_barrel", "module_adv_targeting", "module_autorepair"}, + }, } - + local comms = { - -- Not Hax - comm_riot_cai = { - chassis = "corcom1", - name = "Crowd Controller", - modules = { "commweapon_riotcannon", "module_adv_targeting",}, - cost = 250, - }, - comm_econ_cai = { - chassis = "commsupport1", - name = "Base Builder", - modules = { "commweapon_beamlaser", "module_econ",}, - cost = 275, - }, - comm_marksman_cai = { - chassis = "commsupport1", - name = "The Marksman", - modules = { "commweapon_gaussrifle", "module_adv_targeting",}, - cost = 225, - }, - comm_stun_cai = { - chassis = "armcom1", - name = "Exotic Assault", - modules = { "commweapon_lightninggun", "module_high_power_servos",}, - cost = 250, - }, - - -- Hax - comm_strike_pea = { - chassis = "armcom1", - name = "Peashooter Commander", - modules = { "commweapon_peashooter"}, - }, - comm_strike_hmg = { - chassis = "armcom1", - name = "Heavy Machine Gun Commander", - modules = { "commweapon_heavymachinegun"}, - }, - comm_strike_lpb = { - chassis = "armcom1", - name = "Light Particle Beam Commander", - modules = { "commweapon_lparticlebeam"}, - }, - comm_battle_pea = { - chassis = "corcom1", - name = "Peashooter Commander", - modules = { "commweapon_peashooter"}, - }, - comm_support_pea = { - chassis = "commsupport1", - name = "Peashooter Commander", - modules = { "commweapon_peashooter"}, - }, - comm_recon_pea = { - chassis = "commrecon1", - name = "Peashooter Commander", - modules = { "commweapon_peashooter"}, - }, - - comm_guardian = { - chassis = "armcom2", - name = "Star Guardian", - modules = { "commweapon_beamlaser", "module_ablative_armor", "module_high_power_servos", "weaponmod_high_frequency_beam"}, - }, - comm_thunder = { - chassis = "armcom2", - name = "Thunder Wizard", - modules = { "commweapon_lightninggun", "module_ablative_armor", "module_high_power_servos", "weaponmod_stun_booster", "module_energy_cell"}, - }, - comm_riot = { - chassis = "corcom2", - name = "Crowd Controller", - modules = { "commweapon_riotcannon", "commweapon_heatray"}, - }, - comm_flamer = { - chassis = "corcom2", - name = "The Fury", - modules = { "commweapon_flamethrower", "module_dmg_booster", "module_ablative_armor", "module_ablative_armor", "module_high_power_servos"}, - }, - comm_recon = { - chassis = "commrecon2", - name = "Ghost Recon", - modules = { "commweapon_lparticlebeam", "module_ablative_armor", "module_high_power_servos", "module_high_power_servos", "module_jammer" , "module_autorepair"}, - }, - comm_marine = { - chassis = "commrecon2", - name = "Space Marine", - modules = { "commweapon_heavymachinegun", "module_heavy_armor", "module_high_power_servos", "module_dmg_booster", "module_adv_targeting"}, - }, - comm_marksman = { - chassis = "commsupport2", - name = "The Marksman", - modules = { "commweapon_massdriver", "module_dmg_booster", "module_adv_targeting", "module_ablative_armor" , "module_high_power_servos"}, - }, - comm_hunter = { - chassis = "commsupport2", - name = "Bear Hunter", - modules = { "commweapon_shotgun", "module_dmg_booster", "module_adv_targeting", "module_high_power_servos", "module_fieldradar"}, - }, - comm_rocketeer = { - chassis = "benzcom2", - name = "Rocket Surgeon", - modules = { "commweapon_rocketlauncher", "module_dmg_booster", "module_adv_targeting", "module_ablative_armor"}, - }, - comm_hammer = { - chassis = "benzcom2", - name = "Hammer Slammer", - modules = { "commweapon_assaultcannon", "module_dmg_booster", "conversion_partillery"}, - }, + -- Not Hax + comm_riot_cai = { + chassis = "corcom1", + name = "Crowd Controller", + modules = { "commweapon_riotcannon", "module_adv_targeting", }, + cost = 250, + }, + comm_econ_cai = { + chassis = "commsupport1", + name = "Base Builder", + modules = { "commweapon_beamlaser", "module_econ", }, + cost = 275, + }, + comm_marksman_cai = { + chassis = "commsupport1", + name = "The Marksman", + modules = { "commweapon_gaussrifle", "module_adv_targeting", }, + cost = 225, + }, + comm_stun_cai = { + chassis = "armcom1", + name = "Exotic Assault", + modules = { "commweapon_lightninggun", "module_high_power_servos", }, + cost = 250, + }, + + -- Hax + comm_strike_pea = { + chassis = "armcom1", + name = "Peashooter Commander", + modules = { "commweapon_peashooter" }, + }, + comm_strike_hmg = { + chassis = "armcom1", + name = "Heavy Machine Gun Commander", + modules = { "commweapon_heavymachinegun" }, + }, + comm_strike_lpb = { + chassis = "armcom1", + name = "Light Particle Beam Commander", + modules = { "commweapon_lparticlebeam" }, + }, + comm_battle_pea = { + chassis = "corcom1", + name = "Peashooter Commander", + modules = { "commweapon_peashooter" }, + }, + comm_support_pea = { + chassis = "commsupport1", + name = "Peashooter Commander", + modules = { "commweapon_peashooter" }, + }, + comm_recon_pea = { + chassis = "commrecon1", + name = "Peashooter Commander", + modules = { "commweapon_peashooter" }, + }, + + comm_guardian = { + chassis = "armcom2", + name = "Star Guardian", + modules = { "commweapon_beamlaser", "module_ablative_armor", "module_high_power_servos", "weaponmod_high_frequency_beam" }, + }, + comm_thunder = { + chassis = "armcom2", + name = "Thunder Wizard", + modules = { "commweapon_lightninggun", "module_ablative_armor", "module_high_power_servos", "weaponmod_stun_booster", "module_energy_cell" }, + }, + comm_riot = { + chassis = "corcom2", + name = "Crowd Controller", + modules = { "commweapon_riotcannon", "commweapon_heatray" }, + }, + comm_flamer = { + chassis = "corcom2", + name = "The Fury", + modules = { "commweapon_flamethrower", "module_dmg_booster", "module_ablative_armor", "module_ablative_armor", "module_high_power_servos" }, + }, + comm_recon = { + chassis = "commrecon2", + name = "Ghost Recon", + modules = { "commweapon_lparticlebeam", "module_ablative_armor", "module_high_power_servos", "module_high_power_servos", "module_jammer", "module_autorepair" }, + }, + comm_marine = { + chassis = "commrecon2", + name = "Space Marine", + modules = { "commweapon_heavymachinegun", "module_heavy_armor", "module_high_power_servos", "module_dmg_booster", "module_adv_targeting" }, + }, + comm_marksman = { + chassis = "commsupport2", + name = "The Marksman", + modules = { "commweapon_massdriver", "module_dmg_booster", "module_adv_targeting", "module_ablative_armor", "module_high_power_servos" }, + }, + comm_hunter = { + chassis = "commsupport2", + name = "Bear Hunter", + modules = { "commweapon_shotgun", "module_dmg_booster", "module_adv_targeting", "module_high_power_servos", "module_fieldradar" }, + }, + comm_rocketeer = { + chassis = "benzcom2", + name = "Rocket Surgeon", + modules = { "commweapon_rocketlauncher", "module_dmg_booster", "module_adv_targeting", "module_ablative_armor" }, + }, + comm_hammer = { + chassis = "benzcom2", + name = "Hammer Slammer", + modules = { "commweapon_assaultcannon", "module_dmg_booster", "conversion_partillery" }, + }, } for name, data in pairs(commsCampaign) do - data.miscDefs = data.miscDefs or {} - data.miscDefs.customparams = data.miscDefs.customparams or {} - data.miscDefs.customparams.statsname = name; - data.miscDefs.reclaimable = false - data.miscDefs.canSelfDestruct = false - comms[name] = data + data.miscDefs = data.miscDefs or {} + data.miscDefs.customparams = data.miscDefs.customparams or {} + data.miscDefs.customparams.statsname = name; + data.miscDefs.reclaimable = false + data.miscDefs.canSelfDestruct = false + comms[name] = data end -------------------------------------------------------------------------------------- -- Dynamic Commander Clone Generation -------------------------------------------------------------------------------------- -local powerAtLevel = {2000, 3000, 4000, 5000, 6000} +local powerAtLevel = { 2000, 3000, 4000, 5000, 6000 } local function MakeClones(levelLimits, moduleNames, fullChassisName, unitName, power, modules, moduleType) if moduleType > #levelLimits then @@ -197,7 +197,7 @@ local function MakeClones(levelLimits, moduleNames, fullChassisName, unitName, p } return end - + for copies = 0, levelLimits[moduleType] do local newModules = Spring.Utilities.CopyTable(modules) for m = 1, copies do @@ -211,7 +211,8 @@ local function MakeCommanderChassisClones(chassis, levelLimits, moduleNames) for level = 1, #levelLimits do local fullChassisName = chassis .. level local modules = {} - MakeClones(levelLimits[level], moduleNames, fullChassisName, fullChassisName .. "_", powerAtLevel[level], modules, 1) + MakeClones(levelLimits[level], moduleNames, fullChassisName, fullChassisName .. "_", powerAtLevel[level], modules, + 1) end end @@ -219,12 +220,12 @@ end -- Must match dynamic_comm_defs.lua around line 800 (top of the chassis defs) -------------------------------------------------------------------------------------- -local chassisAllDefs=VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") +local chassisAllDefs = VFS.Include("gamedata/modularcomms/chassises_all_defs.lua") for i = 1, #chassisAllDefs do - local staticcommsDef=chassisAllDefs[i].staticcomms - local name,levelLimits,modules = staticcommsDef[1],staticcommsDef[2],staticcommsDef[3] - MakeCommanderChassisClones(name,levelLimits,modules) + local staticcommsDef = chassisAllDefs[i].staticcomms + local name, levelLimits, modules = staticcommsDef[1], staticcommsDef[2], staticcommsDef[3] + MakeCommanderChassisClones(name, levelLimits, modules) end --[[ @@ -233,32 +234,32 @@ for name,stats in pairs(comms) do end --]] -local costAtLevel = {[0] = 0, 0,200,600,300,400} +local costAtLevel = { [0] = 0, 0, 200, 600, 300, 400 } local morphableCommDefs = VFS.Include("gamedata/modularcomms/staticcomms_morphable.lua") for templateName, data in pairs(morphableCommDefs) do - local modules = {} - local cost = 0 - for i=0,#data.levels do - local levelInfo = data.levels[i] or {} - for moduleNum=1,#levelInfo do - modules[#modules+1] = levelInfo[moduleNum] - end - cost = cost + (levelInfo.cost or 0) + costAtLevel[i] - - local name = templateName .. "_" .. i - local humanName = data.name .. " level " .. i - comms[name] = { - chassis = data.chassis .. i, - name = humanName, - cost = cost, - modules = Spring.Utilities.CopyTable(modules), - } - if i<5 then - comms[name].morphto = templateName .. "_" .. (i+1) - end - end + local modules = {} + local cost = 0 + for i = 0, #data.levels do + local levelInfo = data.levels[i] or {} + for moduleNum = 1, #levelInfo do + modules[#modules + 1] = levelInfo[moduleNum] + end + cost = cost + (levelInfo.cost or 0) + costAtLevel[i] + + local name = templateName .. "_" .. i + local humanName = data.name .. " level " .. i + comms[name] = { + chassis = data.chassis .. i, + name = humanName, + cost = cost, + modules = Spring.Utilities.CopyTable(modules), + } + if i < 5 then + comms[name].morphto = templateName .. "_" .. (i + 1) + end + end end return comms diff --git a/gamedata/modularcomms/unitdefgen.lua b/gamedata/modularcomms/unitdefgen.lua index c494f5d080..770f4c4bc6 100644 --- a/gamedata/modularcomms/unitdefgen.lua +++ b/gamedata/modularcomms/unitdefgen.lua @@ -51,18 +51,18 @@ local function DecodeBase64CommData(toDecode, useLegacyTranslator) local commDataTable local commDataFunc local err, success - + if not (toDecode and type(toDecode) == 'string') then return {} end - + toDecode = string.gsub(toDecode, '_', '=') toDecode = Spring.Utilities.Base64Decode(toDecode) --Spring.Echo(toDecode) - commDataFunc, err = loadstring("return "..toDecode) + commDataFunc, err = loadstring("return " .. toDecode) if commDataFunc then success, commDataTable = pcall(commDataFunc) - if not success then -- execute Borat + if not success then -- execute Borat err = commDataTable commDataTable = {} elseif useLegacyTranslator then @@ -92,15 +92,16 @@ local legacyToDyncommChassisMap = legacyTranslators.legacyToDyncommChassisMap local function GenerateLevel0DyncommsAndWrecks() for commProfileID, commProfile in pairs(commData) do - Spring.Log("gamedata/modularcomms/unitdefgen.lua", "debug", "\tModularComms: Generating base dyncomm for " .. commProfile.name) + Spring.Log("gamedata/modularcomms/unitdefgen.lua", "debug", + "\tModularComms: Generating base dyncomm for " .. commProfile.name) local unitName = commProfile.baseUnitName - + local chassis = commProfile.chassis - local mappedChassis = legacyToDyncommChassisMap[chassis]-- or "assault" + local mappedChassis = legacyToDyncommChassisMap[chassis] -- or "assault" if mappedChassis then chassis = mappedChassis end - + UnitDefs[unitName] = CopyTable(UnitDefs["dyn" .. chassis .. "1"], true) local ud = UnitDefs[unitName] ud.name = commProfile.name @@ -108,9 +109,9 @@ local function GenerateLevel0DyncommsAndWrecks() ud.customparams = ud.customparams or {} ud.customparams.not_starter = 1 end - + local features = ud.featuredefs or {} - for featureName,array in pairs(features) do + for featureName, array in pairs(features) do local mult = 0.4 local typeName = "Wreckage" if featureName == "heap" then @@ -137,11 +138,11 @@ local function MergeModuleTables(moduleTable, previous) MergeModuleTables(moduleTable, data.prev) end local modules = data.modules or {} - for i=1,#modules do - moduleTable[#moduleTable+1] = modules[i] + for i = 1, #modules do + moduleTable[#moduleTable + 1] = modules[i] end end - + return moduleTable end @@ -157,7 +158,7 @@ local function ProcessComm(name, config) commDefs[name] = CopyTable(UnitDefs[config.chassis], true) commDefs[name].customparams = commDefs[name].customparams or {} local cp = commDefs[name].customparams - + -- set name commDefs[name].unitname = name if config.name then @@ -166,11 +167,11 @@ local function ProcessComm(name, config) if config.description then commDefs[name].description = config.description end - + -- store base values cp.basespeed = tostring(commDefs[name].speed) cp.basehp = tostring(commDefs[name].health) - for i,v in pairs(commDefs[name].weapondefs or {}) do + for i, v in pairs(commDefs[name].weapondefs or {}) do v.customparams = v.customparams or {} v.customparams.rangemod = 0 v.customparams.reloadmod = 0 @@ -182,7 +183,7 @@ local function ProcessComm(name, config) speed = 0, reload = 0, } - + -- process modules if config.modules then local modules = CopyTable(config.modules) @@ -193,21 +194,21 @@ local function ProcessComm(name, config) -- sort: weapons first, weapon mods next, regular modules last -- individual modules can have different order values as defined in moduledefs.lua table.sort(modules, - function(a,b) + function(a, b) local order_a = (upgrades[a] and upgrades[a].order) or 4 local order_b = (upgrades[b] and upgrades[b].order) or 4 return order_a < order_b - end ) + end) -- process all modules (including weapons) - for _,moduleName in ipairs(modules) do - if moduleName:find("commweapon_",1,true) then + for _, moduleName in ipairs(modules) do + if moduleName:find("commweapon_", 1, true) then if weapons[moduleName] then --Spring.Echo("\tApplying weapon: "..moduleName) ApplyWeapon(commDefs[name], moduleName) numWeapons = numWeapons + 1 else - Spring.Echo("\tERROR: Weapon "..moduleName.." not found") + Spring.Echo("\tERROR: Weapon " .. moduleName .. " not found") end end if upgrades[moduleName] then @@ -219,61 +220,64 @@ local function ProcessComm(name, config) numWeapons = numWeapons + 1 end else - Spring.Log("gamedata/modularcomms/unitdefgen.lua", "error", "\tERROR: Upgrade "..moduleName.." not found") + Spring.Log("gamedata/modularcomms/unitdefgen.lua", "error", + "\tERROR: Upgrade " .. moduleName .. " not found") end end - + cp.modules = config.modules end - + -- apply attributemods if attributeMods.speed > 0 then - commDefs[name].speed = commDefs[name].speed*(1+attributeMods.speed) + commDefs[name].speed = commDefs[name].speed * (1 + attributeMods.speed) else - commDefs[name].speed = commDefs[name].speed*(1+attributeMods.speed) + commDefs[name].speed = commDefs[name].speed * (1 + attributeMods.speed) --commDefs[name].speed = commDefs[name].speed/(1-attributeMods.speed) end - commDefs[name].health = commDefs[name].health*(1+attributeMods.health) - + commDefs[name].health = commDefs[name].health * (1 + attributeMods.health) + -- set costs - config.cost = config.cost or 0 + config.cost = config.cost or 0 -- a bit less of a hack - local commDefsCost = math.max(commDefs[name].metalcost or 0, commDefs[name].energycost or 0, commDefs[name].buildtime or 0) --one of these should be set in actual unitdef file + local commDefsCost = math.max(commDefs[name].metalcost or 0, commDefs[name].energycost or 0, + commDefs[name].buildtime or 0) --one of these should be set in actual unitdef file commDefs[name].metalcost = commDefsCost + config.cost commDefs[name].energycost = commDefsCost + config.cost commDefs[name].buildtime = commDefsCost + config.cost - cp.cost = config.cost - + cp.cost = config.cost + if config.power then commDefs[name].power = config.power end - + -- morph if config.morphto then cp.morphto = config.morphto cp.combatmorph = 1 end - + -- apply decorations if config.decorations then - for key,dec in pairs(config.decorations) do + for key, dec in pairs(config.decorations) do local decName = dec if type(dec) == "table" then decName = dec.name or key elseif type(dec) == "bool" then decName = key end - + if decorations[decName] then if decorations[decName].func then --apply upgrade function decorations[decName].func(commDefs[name], config) end else - Spring.Log("gamedata/modularcomms/unitdefgen.lua", "warning", "\tDecoration "..decName.." not found") + Spring.Log("gamedata/modularcomms/unitdefgen.lua", "warning", "\tDecoration " .. + decName .. " not found") end end end - + -- apply misc. defs if config.miscDefs then commDefs[name] = MergeTable(config.miscDefs, commDefs[name], true) @@ -291,14 +295,14 @@ local stressTemplate = { modules = {}, } for name in pairs(upgrades) do - stressTemplate.modules[#stressTemplate.modules+1] = name + stressTemplate.modules[#stressTemplate.modules + 1] = name end -for index,name in ipairs(stressChassis) do +for index, name in ipairs(stressChassis) do local def = CopyTable(stressTemplate, true) def.chassis = name - def.name = def.name..name - ProcessComm("stresstest"..index, def) - stressDefs["stresstest"..index] = true + def.name = def.name .. name + ProcessComm("stresstest" .. index, def) + stressDefs["stresstest" .. index] = true end -- for easy testing; creates test commanders with specific loadouts @@ -315,7 +319,7 @@ local staticComms3 = DecodeBase64CommData(modOptions.campaign_commanders) local staticCommsMerged = MergeTable(staticComms2, staticComms, true) staticCommsMerged = MergeTable(staticCommsMerged, staticComms3, true) -for name,data in pairs(staticCommsMerged) do +for name, data in pairs(staticCommsMerged) do ProcessComm(name, data) end @@ -331,19 +335,20 @@ end for name, data in pairs(commDefs) do --Spring.Echo("\tPostprocessing commtype: ".. name) - + -- apply intrinsic bonuses local damBonus = data.customparams.damagebonus or 0 ModifyWeaponDamage(data, damBonus, true) - - local rangeBonus = data.customparams.rangebonus or 0 + + local rangeBonus = data.customparams.rangebonus or 0 ModifyWeaponRange(data, rangeBonus, true) if data.customparams.speedbonus then commDefs[name].customparams.basespeed = commDefs[name].customparams.basespeed or commDefs[name].speed - commDefs[name].speed = commDefs[name].speed + (commDefs[name].customparams.basespeed*data.customparams.speedbonus) + commDefs[name].speed = commDefs[name].speed + + (commDefs[name].customparams.basespeed * data.customparams.speedbonus) end - + -- set weapon1 range - may need exception list in future depending on what weapons we add if data.weapondefs and not data.customparams.dynamic_comm then local maxRange = 0 @@ -376,9 +381,9 @@ for name, data in pairs(commDefs) do end data.sightdistance = math.max(math.min(maxRange * 1.1, 600), data.sightdistance) end - + -- set wreck values - for featureName,array in pairs(data.featuredefs or {}) do + for featureName, array in pairs(data.featuredefs or {}) do local mult = 0.4 local typeName = "Wreckage" if featureName == "heap" then @@ -392,32 +397,35 @@ for name, data in pairs(commDefs) do array.customparams = {} array.customparams.unit = data.unitname end - + -- rez speed if data.canresurrect then - data.resurrectspeed = data.workertime*0.5 + data.resurrectspeed = data.workertime * 0.5 end - + -- make sure weapons can hit their max range if data.weapondefs then for weaponName, weaponData in pairs(data.weapondefs) do if weaponData.weapontype == "MissileLauncher" then - weaponData.flighttime = math.max(weaponData.flighttime or 3, 1.2 * weaponData.range/weaponData.weaponvelocity) + weaponData.flighttime = math.max(weaponData.flighttime or 3, + 1.2 * weaponData.range / weaponData.weaponvelocity) elseif weaponData.weapontype == "Cannon" then - weaponData.weaponvelocity = math.max(weaponData.weaponvelocity, math.sqrt(weaponData.range * (weaponData.mygravity or 0.14)*1000)) + weaponData.weaponvelocity = math.max(weaponData.weaponvelocity, + math.sqrt(weaponData.range * (weaponData.mygravity or 0.14) * 1000)) end end end -- set morph time if data.customparams.morphto then - local morph_time = (commDefs[data.customparams.morphto].buildtime - data.buildtime) / (5 * (data.customparams.level + 2)) + local morph_time = (commDefs[data.customparams.morphto].buildtime - data.buildtime) / + (5 * (data.customparams.level + 2)) data.customparams.morphtime = tostring(math.floor(morph_time)) end end -- remove stress test defs -for key,_ in pairs(stressDefs) do +for key, _ in pairs(stressDefs) do commDefs[key] = nil end diff --git a/gamedata/modularcomms/weapons/chickenclaw.lua b/gamedata/modularcomms/weapons/chickenclaw.lua deleted file mode 100644 index 50e2722a9f..0000000000 --- a/gamedata/modularcomms/weapons/chickenclaw.lua +++ /dev/null @@ -1,31 +0,0 @@ -return "commweapon_chickenclaw",{ - name = [[Chicken Claws]], - areaOfEffect = 28, - craterBoost = 1, - craterMult = 0, - - customParams={ - - is_unit_weapon = 1, - }, - - damage = { - default = 600, - }, - - explosionGenerator = [[custom:NONE]], - impulseBoost = 0, - impulseFactor = 1, - interceptedByShieldType = 0, - noSelfDamage = true, - range = 140, - reloadtime = 1, - size = 0, - soundStart = [[chickens/bigchickenbreath]], - targetborder = 1, - tolerance = 8000, - --turret = true, - waterWeapon = true, - weaponType = [[Cannon]], - weaponVelocity = 600, - } \ No newline at end of file diff --git a/gamedata/modularcomms/weapons/chickenflamethrower.lua b/gamedata/modularcomms/weapons/chickenflamethrower.lua deleted file mode 100644 index 37b3e0bb76..0000000000 --- a/gamedata/modularcomms/weapons/chickenflamethrower.lua +++ /dev/null @@ -1,56 +0,0 @@ -local name = "commweapon_chickenflamethrower" -local weaponDef = { - name = [[Flame Thrower]], - areaOfEffect = 64, - avoidGround = false, - avoidFeature = false, - cegTag = [[flamer]], - collideFeature = false, - collideGround = false, - craterBoost = 0, - craterMult = 0, - - customParams = { - is_unit_weapon = 1, - --muzzleEffectFire = [[custom:RAIDMUZZLE]], - flamethrower = [[1]], - setunitsonfire = "1", - burnchance = "0.4", -- Per-impact - burntime = [[450]], - - light_camera_height = 2800, - light_color = [[0.6 0.39 0.18]], - light_radius = 260, - light_fade_time = 10, - light_beam_mult_frames = 5, - light_beam_mult = 5, - reaim_time = 1, - }, - - damage = { - default = 12.5, - }, - - explosionGenerator = [[custom:SMOKE]], - fallOffRate = 1, - fireStarter = 100, - heightMod = 1, - impulseBoost = 0, - impulseFactor = 0, - interceptedByShieldType = 1, - noExplode = true, - noSelfDamage = true, - range = 270, - reloadtime = 5/30, - rgbColor = [[1 1 1]], - soundStart = [[weapon/flamethrower]], - soundTrigger = true, - texture1 = [[flame]], - thickness = 0, - tolerance = 8000, - turret = false, - weaponType = [[LaserCannon]], - weaponVelocity = 800, -} - -return name, weaponDef diff --git a/gamedata/modularcomms/weapons/chickengoo.lua b/gamedata/modularcomms/weapons/chickengoo.lua deleted file mode 100644 index 22811e6eb4..0000000000 --- a/gamedata/modularcomms/weapons/chickengoo.lua +++ /dev/null @@ -1,43 +0,0 @@ -return "commweapon_chickengoo",{ - name = [[Blob]], - areaOfEffect = 200, - burst = 8, - burstrate = 0.033, - cegTag = [[queen_trail]], - craterBoost = 0, - craterMult = 0, - highTrajectory = 2, - - customParams = { - is_unit_weapon = 1, - light_radius = 0, - slot=3, - manualfire = 1, - reaim_time = 1, - }, - - damage = { - default = 600, - }, - - explosionGenerator = [[custom:large_green_goo]], - impulseBoost = 0, - impulseFactor = 0.4, - intensity = 0.7, - interceptedByShieldType = 1, - noSelfDamage = true, - proximityPriority = -4, - range = 550, - reloadtime = 15, - rgbColor = [[0.2 0.6 0]], - size = 8, - sizeDecay = 0, - soundStart = [[chickens/bigchickenroar]], - sprayAngle = 6100, - tolerance = 5000, - turret = false, - weaponType = [[Cannon]], - waterWeapon = true, - weaponVelocity = 600, - commandFire = true, - } \ No newline at end of file diff --git a/gamedata/modularcomms/weapons/chickenshield.lua b/gamedata/modularcomms/weapons/chickenshield.lua deleted file mode 100644 index b0ed916ced..0000000000 --- a/gamedata/modularcomms/weapons/chickenshield.lua +++ /dev/null @@ -1,32 +0,0 @@ -return "commweapon_chickenshield",{ - name = [[Shield]], - customParams={ - slot="2", - shield_rate=180, - }, - - damage = { - default = 10, - }, - - exteriorShield = true, - impulseFactor = 0, - interceptedByShieldType = 1, - shieldAlpha = 0.15, - shieldBadColor = [[1.0 1 0.1 1]], - shieldGoodColor = [[0.1 1.0 0.1 1]], - shieldInterceptType = 3, - shieldPower = 2500, - shieldPowerRegen = 180, - shieldPowerRegenEnergy = 0, - shieldRadius = 300, - shieldRepulser = false, - smartShield = true, - visibleShield = false, - visibleShieldRepulse = false, - --texture1 = [[wakelarge]], - --visibleShield = true, - --visibleShieldHitFrames = 30, - --visibleShieldRepulse = false, - weaponType = [[Shield]], - } \ No newline at end of file diff --git a/gamedata/modularcomms/weapons/chickenspike.lua b/gamedata/modularcomms/weapons/chickenspike.lua deleted file mode 100644 index e674125ad8..0000000000 --- a/gamedata/modularcomms/weapons/chickenspike.lua +++ /dev/null @@ -1,41 +0,0 @@ -return "commweapon_chickenspike",{ - name = [[Spike]], - areaOfEffect = 16, - avoidFeature = true, - avoidFriendly = true, - burnblow = true, - cegTag = [[small_green_goo]], - collideFeature = true, - collideFriendly = true, - craterBoost = 0, - craterMult = 0, - - customParams = { - is_unit_weapon = 1, - light_radius = 0, - }, - - damage = { - default = 225, - planes = 225, - }, - - explosionGenerator = [[custom:EMG_HIT]], - impactOnly = true, - impulseBoost = 0, - impulseFactor = 0.4, - interceptedByShieldType = 2, - model = [[spike.s3o]], - range = 460, - reloadtime = 1, - soundHit = [[chickens/spike_hit]], - soundStart = [[chickens/spike_fire]], - startVelocity = 320, - subMissile = 1, - turret = false, - waterWeapon = true, - weaponAcceleration = 100, - weaponType = [[Cannon]], - weaponVelocity = 280, - tolerance=8000, - } \ No newline at end of file diff --git a/gamedata/modularcomms/weapons/chickenspores.lua b/gamedata/modularcomms/weapons/chickenspores.lua deleted file mode 100644 index e3b4a294ba..0000000000 --- a/gamedata/modularcomms/weapons/chickenspores.lua +++ /dev/null @@ -1,48 +0,0 @@ -return "commweapon_chickenspores",{ - name = [[Spores]], - areaOfEffect = 24, - avoidFriendly = false, - burst = 8, - burstrate = 0.1, - collideFriendly = false, - craterBoost = 0, - craterMult = 0, - - customParams = { - is_unit_weapon = 1, - light_radius = 0, - }, - - damage = { - default = 85, - planes = 85*2, - }, - - dance = 60, - explosionGenerator = [[custom:NONE]], - fireStarter = 0, - flightTime = 5, - groundbounce = 1, - heightmod = 0.5, - impactOnly = true, - impulseBoost = 0, - impulseFactor = 0.4, - interceptedByShieldType = 2, - model = [[chickeneggpink.s3o]], - noSelfDamage = true, - range = 300, - reloadtime = 4, - smokeTrail = true, - startVelocity = 100, - texture1 = [[]], - texture2 = [[sporetrail]], - tolerance = 10000, - tracks = true, - turnRate = 24000, - turret = true, - waterweapon = true, - weaponAcceleration = 100, - weaponType = [[MissileLauncher]], - weaponVelocity = 500, - wobble = 32000, - } \ No newline at end of file diff --git a/modularCommAPI/api_modularcomms.lua b/modularCommAPI/api_modularcomms.lua index 167741a98e..35e2291995 100644 --- a/modularCommAPI/api_modularcomms.lua +++ b/modularCommAPI/api_modularcomms.lua @@ -3,20 +3,20 @@ local function GetInfo() return { - name = "Modular Comm Info", - desc = "Helper widget/gadget that provides info on modular comms.", - author = "KingRaptor", - date = "2011", - license = "GNU GPL, v2 or later", - layer = 0, - api = true, - enabled = true, + name = "Modular Comm Info", + desc = "Helper widget/gadget that provides info on modular comms.", + author = "KingRaptor", + date = "2011", + license = "GNU GPL, v2 or later", + layer = 0, + api = true, + enabled = true, alwaysStart = true, } end -local XG = (widget and WG) or (GG) -local VFSMODE = (widget and VFS.RAW_FIRST) or (VFS.ZIP_ONLY) +local XG = (widget and WG) or (GG) +local VFSMODE = (widget and VFS.RAW_FIRST) or (VFS.ZIP_ONLY) Spring.Utilities = Spring.Utilities or {} VFS.Include("LuaRules/Utilities/base64.lua", nil, VFSMODE) @@ -33,7 +33,7 @@ local legacyToDyncommChassisMap = legacyTranslators.legacyToDyncommChassisMap VFS.Include("gamedata/modularcomms/moduledefs.lua", nil, VFSMODE) -local commData = {} -- { players = {[playerID1] = {profiles...}, [playerID2] = {profiles...}}, static = {[staticProfileID1] = {}} } +local commData = {} -- { players = {[playerID1] = {profiles...}, [playerID2] = {profiles...}}, static = {[staticProfileID1] = {}} } local commProfilesByProfileID = {} local commProfileIDsByPlayerID = {} local profileIDByBaseDefID = {} @@ -61,10 +61,10 @@ local function LoadCommData() end commDataRaw = Spring.Utilities.Base64Decode(commDataRaw) --Spring.Echo(commDataRaw) - commDataFunc, err = loadstring("return "..commDataRaw) + commDataFunc, err = loadstring("return " .. commDataRaw) if commDataFunc then success, newCommProfilesByProfileID = pcall(commDataFunc) - if not success then -- execute Borat + if not success then -- execute Borat err = newCommProfilesByProfileID newCommProfilesByProfileID = {} end @@ -73,18 +73,19 @@ local function LoadCommData() if err then Spring.Log(GetInfo().name, "warning", 'Modular Comms API warning: ' .. err) end - + newCommProfilesByProfileID = legacyTranslators.FixOverheadIcon(newCommProfilesByProfileID) - + -- comm player entries - local commProfilesForPlayers = {} -- {[playerID1] = {}, [playerID2] = {}} + local commProfilesForPlayers = {} -- {[playerID1] = {}, [playerID2] = {}} local players = Spring.GetPlayerList() for i = 1, #players do local playerID = players[i] - local playerName, active, spectator, teamID, allyTeamID, _, _, country, rank, customKeys = Spring.GetPlayerInfo(playerID) - + local playerName, active, spectator, teamID, allyTeamID, _, _, country, rank, customKeys = Spring.GetPlayerInfo( + playerID) + if (not spectator) then - local playerCommProfileIDs -- [playerID] = {[commProfileID1] = {}, [commProfileID2] = {}, ...} + local playerCommProfileIDs -- [playerID] = {[commProfileID1] = {}, [commProfileID2] = {}, ...} local playerCommProfileIDsRaw = customKeys and customKeys.commanders if not (playerCommProfileIDsRaw and type(playerCommProfileIDsRaw) == 'string') then err = "Comm data entry for player " .. playerName .. " is empty or in invalid format" @@ -93,7 +94,7 @@ local function LoadCommData() playerCommProfileIDsRaw = string.gsub(playerCommProfileIDsRaw, '_', '=') playerCommProfileIDsRaw = Spring.Utilities.Base64Decode(playerCommProfileIDsRaw) local playerCommProfileIDsFunc - playerCommProfileIDsFunc, err = loadstring("return "..playerCommProfileIDsRaw) + playerCommProfileIDsFunc, err = loadstring("return " .. playerCommProfileIDsRaw) if playerCommProfileIDsFunc then success, playerCommProfileIDs = pcall(playerCommProfileIDsFunc) if not success then @@ -105,7 +106,7 @@ local function LoadCommData() if err then Spring.Log(GetInfo().name, "warning", 'Modular Comms API warning: ' .. err) end - + newCommProfileIDsByPlayerID[playerID] = playerCommProfileIDs local playerCommProfiles = {} for i = 1, #playerCommProfileIDs do @@ -115,7 +116,7 @@ local function LoadCommData() commProfilesForPlayers[playerID] = playerCommProfiles end end - + -- morphable static comms (e.g. trainers) local morphableStaticComms = {} for commProfileID, commDef in pairs(predefinedDynamicComms) do @@ -129,7 +130,7 @@ local function LoadCommData() end newCommData.players = commProfilesForPlayers newCommData.static = morphableStaticComms - + for profileID, profile in pairs(newCommProfilesByProfileID) do -- MAKE SURE THIS MATCHES WHAT UNITDEFGEN SETS profile.baseUnitDefID = UnitDefNames[profileID .. "_base"].id @@ -137,24 +138,24 @@ local function LoadCommData() profile.baseHeapID = FeatureDefNames[profileID .. "_base_heap"].id newProfileIDByBaseDefID[profile.baseUnitDefID] = profileID end - + -- Convert chassis to correct names. for profileID, profile in pairs(newCommProfilesByProfileID) do profile.chassis = legacyToDyncommChassisMap[profile.chassis] or profile.chassis end - + for i = 1, #UnitDefs do if UnitDefs[i].customParams.modules then local modulesRaw = {} local modulesHuman = {} - local modulesInternalFunc = loadstring("return ".. UnitDefs[i].customParams.modules) + local modulesInternalFunc = loadstring("return " .. UnitDefs[i].customParams.modules) local modulesInternal = modulesInternalFunc() - for i=1, #modulesInternal do + for i = 1, #modulesInternal do local modulename = modulesInternal[i] modulesRaw[i] = modulename modulesHuman[i] = upgrades[modulename].name end - legacyModulesByUnitDefName[UnitDefs[i].name] = {raw = modulesRaw, human = modulesHuman} + legacyModulesByUnitDefName[UnitDefs[i].name] = { raw = modulesRaw, human = modulesHuman } end end @@ -164,7 +165,6 @@ end -------------------------------------------------------------------------------- local function GetCommProfileInfo(commProfileID) - return commProfilesByProfileID[commProfileID] end @@ -225,7 +225,7 @@ local function Shutdown() XG.ModularCommAPI = nil end -local this = widget or gadget +local this = widget or gadget this.GetInfo = GetInfo this.Initialize = Initialize