diff --git a/mods/squads/mods/Intercept Group/img/achievements/peak.png b/mods/squads/mods/Intercept Group/img/achievements/peak.png new file mode 100644 index 0000000..1e3be21 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/achievements/peak.png differ diff --git a/mods/squads/mods/Intercept Group/img/achievements/secret.png b/mods/squads/mods/Intercept Group/img/achievements/secret.png new file mode 100644 index 0000000..7068104 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/achievements/secret.png differ diff --git a/mods/squads/mods/Intercept Group/img/achievements/throttle.png b/mods/squads/mods/Intercept Group/img/achievements/throttle.png new file mode 100644 index 0000000..b1f6c0c Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/achievements/throttle.png differ diff --git a/mods/squads/mods/Intercept Group/img/achievements/wide.png b/mods/squads/mods/Intercept Group/img/achievements/wide.png new file mode 100644 index 0000000..5db0721 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/achievements/wide.png differ diff --git a/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_R.png b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_R.png new file mode 100644 index 0000000..6fc5223 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_R.png differ diff --git a/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_R1.png b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_R1.png new file mode 100644 index 0000000..b184b60 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_R1.png differ diff --git a/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_R2.png b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_R2.png new file mode 100644 index 0000000..9b6d5cf Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_R2.png differ diff --git a/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_U.png b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_U.png new file mode 100644 index 0000000..be9491a Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_U.png differ diff --git a/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_U1.png b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_U1.png new file mode 100644 index 0000000..b89c6e4 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_U1.png differ diff --git a/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_U2.png b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_U2.png new file mode 100644 index 0000000..b23b404 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_U2.png differ diff --git a/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_hit.png b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_hit.png new file mode 100644 index 0000000..41dbc02 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_hit.png differ diff --git a/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_start.png b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_start.png new file mode 100644 index 0000000..1af7ae4 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/effects/tosx_heatlaser_start.png differ diff --git a/mods/squads/mods/Intercept Group/img/effects/tosx_shotup_seeker.png b/mods/squads/mods/Intercept Group/img/effects/tosx_shotup_seeker.png new file mode 100644 index 0000000..565b636 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/effects/tosx_shotup_seeker.png differ diff --git a/mods/squads/mods/Intercept Group/img/icons/mod_icon.png b/mods/squads/mods/Intercept Group/img/icons/mod_icon.png new file mode 100644 index 0000000..2a7b742 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/icons/mod_icon.png differ diff --git a/mods/squads/mods/Intercept Group/img/icons/squad_icon.png b/mods/squads/mods/Intercept Group/img/icons/squad_icon.png new file mode 100644 index 0000000..5584ffb Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/icons/squad_icon.png differ diff --git a/mods/squads/mods/Intercept Group/img/structures/garage_broken.png b/mods/squads/mods/Intercept Group/img/structures/garage_broken.png new file mode 100644 index 0000000..1973da2 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/structures/garage_broken.png differ diff --git a/mods/squads/mods/Intercept Group/img/structures/garage_on.png b/mods/squads/mods/Intercept Group/img/structures/garage_on.png new file mode 100644 index 0000000..bd61eca Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/structures/garage_on.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1.png new file mode 100644 index 0000000..ed70295 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_a.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_a.png new file mode 100644 index 0000000..18209be Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_a.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_broken.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_broken.png new file mode 100644 index 0000000..130e4d3 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_broken.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_h.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_h.png new file mode 100644 index 0000000..3adcee6 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_h.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_ns.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_ns.png new file mode 100644 index 0000000..b1f6906 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_ns.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_w.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_w.png new file mode 100644 index 0000000..7524204 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_w.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_w_broken.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_w_broken.png new file mode 100644 index 0000000..17d0d4d Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn1_w_broken.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2.png new file mode 100644 index 0000000..e4931c3 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_a.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_a.png new file mode 100644 index 0000000..59cda5f Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_a.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_broken.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_broken.png new file mode 100644 index 0000000..b6f9d70 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_broken.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_h.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_h.png new file mode 100644 index 0000000..b54ce18 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_h.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_ns.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_ns.png new file mode 100644 index 0000000..83e6568 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_ns.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_w.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_w.png new file mode 100644 index 0000000..4193744 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_w.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_w_broken.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_w_broken.png new file mode 100644 index 0000000..bcd63cc Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn2_w_broken.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3.png new file mode 100644 index 0000000..2d345c4 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_a.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_a.png new file mode 100644 index 0000000..0dc0e34 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_a.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_broken.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_broken.png new file mode 100644 index 0000000..6cc1a91 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_broken.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_h.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_h.png new file mode 100644 index 0000000..0011301 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_h.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_ns.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_ns.png new file mode 100644 index 0000000..21c07a8 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_ns.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_w.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_w.png new file mode 100644 index 0000000..7f16856 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_w.png differ diff --git a/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_w_broken.png b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_w_broken.png new file mode 100644 index 0000000..146f4ac Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/units/player/tosx_mech_burn3_w_broken.png differ diff --git a/mods/squads/mods/Intercept Group/img/weapons/tosx_weapon_concussion.png b/mods/squads/mods/Intercept Group/img/weapons/tosx_weapon_concussion.png new file mode 100644 index 0000000..c82f9df Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/weapons/tosx_weapon_concussion.png differ diff --git a/mods/squads/mods/Intercept Group/img/weapons/tosx_weapon_focusbeam.png b/mods/squads/mods/Intercept Group/img/weapons/tosx_weapon_focusbeam.png new file mode 100644 index 0000000..2a45c4f Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/weapons/tosx_weapon_focusbeam.png differ diff --git a/mods/squads/mods/Intercept Group/img/weapons/tosx_weapon_shockwave.png b/mods/squads/mods/Intercept Group/img/weapons/tosx_weapon_shockwave.png new file mode 100644 index 0000000..4abc956 Binary files /dev/null and b/mods/squads/mods/Intercept Group/img/weapons/tosx_weapon_shockwave.png differ diff --git a/mods/squads/mods/Intercept Group/scripts/achievementTriggers.lua b/mods/squads/mods/Intercept Group/scripts/achievementTriggers.lua new file mode 100644 index 0000000..52f518f --- /dev/null +++ b/mods/squads/mods/Intercept Group/scripts/achievementTriggers.lua @@ -0,0 +1,38 @@ + +local path = mod_loader.mods[modApi.currentMod].scriptPath + +local this = {} + +function this:load() + modApi:addPreEnvironmentHook(function(mission) + local edgecount = 0 + + local edge = {0,0,0,0} --x0,x7,y0,y7 + local mechs = extract_table(Board:GetPawns(TEAM_PLAYER)) + for i,id in pairs(mechs) do + local p = Board:GetPawn(id):GetSpace() + if Board:IsValid(p) and p.x == 0 or p.x == 7 or p.y == 0 or p.y == 7 then + if (p.x == 0 or p.x == 7) and (p.y == 0 or p.y == 7) then --corner; skip + elseif p.x == 0 then + edge[1]=1 + elseif p.x == 7 then + edge[2]=1 + elseif p.y == 0 then + edge[3]=1 + elseif p.y == 7 then + edge[4]=1 + end + end + end + + for i,v in pairs(edge) do + edgecount = edgecount + v + end + + if edgecount >= 3 then + tosx_interceptsquad_Chievo("tosx_intercept_wide") + end + end) +end + +return this \ No newline at end of file diff --git a/mods/squads/mods/Intercept Group/scripts/achievements.lua b/mods/squads/mods/Intercept Group/scripts/achievements.lua new file mode 100644 index 0000000..9e8435f --- /dev/null +++ b/mods/squads/mods/Intercept Group/scripts/achievements.lua @@ -0,0 +1,94 @@ + +local this = {} + +local path = mod_loader.mods[modApi.currentMod].resourcePath +local modid = "tosx_InterceptGroup" -- Also the squad id + +function tosx_interceptsquad_Chievo(id) + -- exit if not our squad + if GAME.additionalSquadData.squad ~= modid then return end + if IsTestMechScenario() then return end + -- exit if current one is unlocked + if modApi.achievements:getProgress(modid,id) then return end + modApi.achievements:trigger(modid,id) + if id == "tosx_intercept_peak" then + modApi.achievements:trigger(modid,"tosx_intercept_secret", {aa = true}) + elseif id == "tosx_intercept_throttle" then + modApi.achievements:trigger(modid,"tosx_intercept_secret", {bb = true}) + elseif id == "tosx_intercept_wide" then + modApi.achievements:trigger(modid,"tosx_intercept_secret", {cc = true}) + end + if modApi.achievements:isProgress(modid,"tosx_intercept_secret", {reward = true }) then return end + if modApi.achievements:isProgress(modid,"tosx_intercept_secret", {aa = true, bb = true, cc = true,}) then + -- Suppress the toast for the secret achievement + local oldtoastadd = modApi.toasts.add + modApi.toasts.add = function() end + modApi.achievements:trigger(modid,"tosx_intercept_secret", {reward = true }) + modApi.toasts.add = oldtoastadd + + modApi.toasts:add(tosx_interceptUnlock()) + end +end + +local imgs = { + "peak", + "throttle", + "wide", + "secret", +} + +local achname = "tosx_intercept_" +for _, img in ipairs(imgs) do + modApi:appendAsset("img/achievements/".. achname..img ..".png", path .."img/achievements/".. img ..".png") +end + +modApi.achievements:add{ + id = "tosx_intercept_peak", + name = "Peak Efficiency", + tip = "Shoot the Focused Beam 4 times in a single battle at exactly range 3", + img = "img/achievements/tosx_intercept_peak.png", + squad = "tosx_InterceptGroup", +} + +modApi.achievements:add{ + id = "tosx_intercept_throttle", + name = "Full Throttle", + tip = "Kill 2 enemies with a single use of the Shockwave Engines after traveling 6 tiles", + img = "img/achievements/tosx_intercept_throttle.png", + squad = "tosx_InterceptGroup", +} + +modApi.achievements:add{ + id = "tosx_intercept_wide", + name = "Far and Wide", + tip = "End a turn with Mechs on 3 different edges of the map (excluding corners)", + img = "img/achievements/tosx_intercept_wide.png", + squad = "tosx_InterceptGroup", +} + +modApi.achievements:add{ + id = "tosx_intercept_secret", + name = "Intercept Group Secret Reward", + tip = "Complete all 3 Intercept Group achievements\n\nPeak Efficiency: $aa\nFull Throttle: $bb\nFar and Wide: $cc\n\nReward: $reward", + img = "img/achievements/tosx_intercept_secret.png", + squad = "tosx_InterceptGroup", + global = "Secret Rewards", + secret = true, + objective = { + aa = true, + bb = true, + cc = true, + reward = "?|Secret Structure" + } +} + +function tosx_interceptUnlock() + return { + unlockTitle = 'Structure Unlocked!', + name = 'Garage', + tip = 'Garage. This structure can now appear in future missions on R.S.T.', + img = 'img/achievements/'..achname..'secret.png', + } +end + +return this \ No newline at end of file diff --git a/mods/squads/mods/Intercept Group/scripts/animations.lua b/mods/squads/mods/Intercept Group/scripts/animations.lua new file mode 100644 index 0000000..a35f163 --- /dev/null +++ b/mods/squads/mods/Intercept Group/scripts/animations.lua @@ -0,0 +1,29 @@ +-- ANIMS.tosx_liquidmetal = Animation:new{ + -- Image = "effects/tosx_liquidmetal.png", + -- NumFrames = 10, + -- Time = 0.05, + -- PosX = -33, + -- PosY = -14, + -- Loop = false, +-- } + +ANIMS.tosx_firepush_0 = ANIMS.airpush_0:new{ + Image = "effects/tosx_firepush_U.png", +} + +ANIMS.tosx_firepush_1 = ANIMS.airpush_1:new{ + Image = "effects/tosx_firepush_R.png", +} + +ANIMS.tosx_firepush_2 = ANIMS.airpush_2:new{ + Image = "effects/tosx_firepush_D.png", +} + +ANIMS.tosx_firepush_3 = ANIMS.airpush_3:new{ + Image = "effects/tosx_firepush_L.png", +} + + +ANIMS.tosx_ExploRepulse3 = ANIMS.ExploRepulse3:new{ + Frames = {7,6,5,4,3,2,1,0}, +} \ No newline at end of file diff --git a/mods/squads/mods/Intercept Group/scripts/init.lua b/mods/squads/mods/Intercept Group/scripts/init.lua new file mode 100644 index 0000000..ad3927c --- /dev/null +++ b/mods/squads/mods/Intercept Group/scripts/init.lua @@ -0,0 +1,108 @@ +local descriptiontext = "These industrial Mechs use targeted shockwaves to disrupt Vek formations." + +local mod = { + id = "tosx_InterceptGroup", + name = "Intercept Group", + version = "0.01", + modApiVersion = "2.8.2", + icon = "img/icons/mod_icon.png", + description = descriptiontext, +} + +-- Helper function to load mod scripts +function mod:loadScript(path) + return require(self.scriptPath..path) +end + +function mod:init() + local sprites = self:loadScript("libs/sprites") + sprites.addMechs( + { + Name = "tosx_mech_burn1", + Default = { PosX = -23, PosY = 0 }, + Animated = { PosX = -23, PosY = 0, NumFrames = 4},--[ -37, -18 ] + Broken = { PosX = -24, PosY = -2 }, + Submerged = { PosX = -18, PosY = 12 }, + SubmergedBroken = { PosX = -18, PosY = 11 }, + Icon = {}, + }, + { + Name = "tosx_mech_burn2", + Default = { PosX = -19, PosY = 7 }, + Animated = { PosX = -19, PosY = 7, NumFrames = 4}, + Broken = { PosX = -16, PosY = 11 }, + Submerged = { PosX = -13, PosY = 16 }, + SubmergedBroken = { PosX = -16, PosY = 16 }, + Icon = {}, + }, + { + Name = "tosx_mech_burn3", + Default = { PosX = -24, PosY = -4 }, + Animated = { PosX = -24, PosY = -4, NumFrames = 4}, + Broken = { PosX = -21, PosY = 1 }, + Submerged = { PosX = -19, PosY = 7 }, + SubmergedBroken = { PosX = -20, PosY = 10 }, + Icon = {}, + } + ) + + local palette = { + id = self.id, + name = "Intercept Red", + image = "img/units/player/tosx_mech_burn1.png", + colorMap = { + + lights = { 250, 192, 17 }, + main_highlight = { 211, 77, 70 }, + main_light = { 111, 29, 32 }, + main_mid = { 55, 20, 26 }, + main_dark = { 26, 12, 14 }, + metal_light = { 110, 101, 118 }, + metal_mid = { 54, 46, 61 }, + metal_dark = { 32, 25, 38 }, + }, + } + modApi:addPalette(palette) + + modApi:appendAsset("img/weapons/tosx_weapon_focusbeam.png",self.resourcePath.."img/weapons/tosx_weapon_focusbeam.png") + modApi:appendAsset("img/weapons/tosx_weapon_concussion.png",self.resourcePath.."img/weapons/tosx_weapon_concussion.png") + modApi:appendAsset("img/weapons/tosx_weapon_shockwave.png",self.resourcePath.."img/weapons/tosx_weapon_shockwave.png") + + modApi:appendAsset("img/effects/tosx_shotup_seeker.png",self.resourcePath.."img/effects/tosx_shotup_seeker.png") + + modApi:appendAsset("img/effects/tosx_heatlaser_start.png",self.resourcePath.."img/effects/tosx_heatlaser_start.png") + modApi:appendAsset("img/effects/tosx_heatlaser_U.png",self.resourcePath.."img/effects/tosx_heatlaser_U.png") + modApi:appendAsset("img/effects/tosx_heatlaser_U1.png",self.resourcePath.."img/effects/tosx_heatlaser_U1.png") + modApi:appendAsset("img/effects/tosx_heatlaser_U2.png",self.resourcePath.."img/effects/tosx_heatlaser_U2.png") + modApi:appendAsset("img/effects/tosx_heatlaser_R.png",self.resourcePath.."img/effects/tosx_heatlaser_R.png") + modApi:appendAsset("img/effects/tosx_heatlaser_R1.png",self.resourcePath.."img/effects/tosx_heatlaser_R1.png") + modApi:appendAsset("img/effects/tosx_heatlaser_R2.png",self.resourcePath.."img/effects/tosx_heatlaser_R2.png") + modApi:appendAsset("img/effects/tosx_heatlaser_hit.png",self.resourcePath.."img/effects/tosx_heatlaser_hit.png") + local laser_loc = Point(-12,3) + Location["effects/tosx_heatlaser_start.png"] = laser_loc + Location["effects/tosx_heatlaser_U.png"] = laser_loc + Location["effects/tosx_heatlaser_U1.png"] = laser_loc + Location["effects/tosx_heatlaser_U2.png"] = laser_loc + Location["effects/tosx_heatlaser_R.png"] = laser_loc + Location["effects/tosx_heatlaser_R1.png"] = laser_loc + Location["effects/tosx_heatlaser_R2.png"] = laser_loc + Location["effects/tosx_heatlaser_hit.png"] = laser_loc + + require(self.scriptPath.."pawns") + require(self.scriptPath.."weapons") + require(self.scriptPath.."animations") + + require(self.scriptPath .."achievements") + if modApi.achievements:getProgress(self.id,"tosx_intercept_secret") and --without this check, will error if no profile + modApi.achievements:getProgress(self.id,"tosx_intercept_secret").reward then + require(self.scriptPath .."side_objectives") + end +end + +function mod:load(options, version) + modApi:addSquad({"Intercept Group","tosx_Burn1Mech", "tosx_Burn2Mech", "tosx_Burn3Mech", id = "tosx_InterceptGroup",}, "Intercept Group", descriptiontext, self.resourcePath .. "img/icons/squad_icon.png") + + require(self.scriptPath .."achievementTriggers"):load() +end + +return mod \ No newline at end of file diff --git a/mods/squads/mods/Intercept Group/scripts/libs/sprites.lua b/mods/squads/mods/Intercept Group/scripts/libs/sprites.lua new file mode 100644 index 0000000..21289d1 --- /dev/null +++ b/mods/squads/mods/Intercept Group/scripts/libs/sprites.lua @@ -0,0 +1,193 @@ +------------------------------------------------------------------------------ +-- Sprite Loader Library +-- v1.0 +-- https://github.com/KnightMiner/ITB-KnightUtils/blob/master/libs/sprites.lua +------------------------------------------------------------------------------ +-- Contains helpers to load sprites and create animations +------------------------------------------------------------------------------ +local sprites = {} +local mod = mod_loader.mods[modApi.currentMod] + +--[[-- + Adds a sprite to the game + + @param path Base sprite path + @param filename File to add +]] +function sprites.addSprite(path, filename) + modApi:appendAsset( + string.format("img/%s/%s.png", path, filename), + string.format("%simg/%s/%s.png", mod.resourcePath, path, filename) + ) +end + +--[[-- + Adds sprites for an achievement, adding both unlocked and greyed out + + @param name Achievement base filename + @param objectives Optional list of objectives images to load, for use with GetImg +]] +function sprites.addAchievement(name, objectives) + sprites.addSprite("achievements", name) + sprites.addSprite("achievements", name .. "_gray") + -- add any extra objective images requested + if objectives then + for _, objective in pairs(objectives) do + sprites.addSprite("achievements", name .. "_" .. objective) + end + end +end + +--[[-- + Converts a name into a path to a mech sprite + + @param name Mech sprite name + @return Sprite path +]] +local function spritePath(path, name) + return string.format("%s/%s.png", path, name) +end + +--[[-- + Adds a sprite animations + + @param path Base sprite path + @param name Animation name and filename + @param settings Animation settings, such as positions and frametime +]] +function sprites.addAnimation(path, name, settings) + sprites.addSprite(path, name) + settings = settings or {} + settings.Image = spritePath(path, name) + + -- base animation is passed in settings + local base = settings.Base or "Animation" + settings.Base = nil + + -- create the animation + ANIMS[name] = ANIMS[base]:new(settings) +end + +--[[ + Adds the specific animation for a unit + + @param path Base folder for the unit + @param base Base animation object + @param name Mech name + @param key Key in object containing animation data + @param suffix Suffix for this animation type + @param fileSuffix Suffix used in the filepath. If unset, defaults to suffix +]] +local function addUnitAnim(path, base, name, object, suffix, fileSuffix) + if object then + -- default fileSuffix to the animation suffix + fileSuffix = fileSuffix or suffix + + -- add the sprite to the resource list + local filename = name .. fileSuffix + sprites.addSprite(path, filename) + + -- add the mech animation to the animation list + object.Image = spritePath(path, filename) + ANIMS[name..suffix] = ANIMS[base]:new(object); + end +end + +--- Resource paths for each unit type +local PATHS = { + mech = "units/player", + mission = "units/mission", + enemy = "units/aliens", + bot = "units/snowbots" +} + +--- Base animation for each unit type +local BASES = { + mech = "MechUnit", + mission = "BaseUnit", + enemy = "EnemyUnit", + bot = "BaseUnit" +} + +--- Bases for UI icons for each unit type +local ICON_BASES = { + mech = "MechIcon", + mission = "SingleImage" +} + +--[[-- + Adds a list of resources to the game + + @param group varargs parameter of all mechs to add + @param objects Animation datas to add +]] +local function addUnitAnims(group, objects) + local path = PATHS[group] + local base = BASES[group] + local iconBase = ICON_BASES[group] + + -- loop through all passed parameters + for _, object in pairs(objects) do + local name = object.Name + + -- these types are pretty uniform + addUnitAnim(path, base, name, object.Default, "" ) + addUnitAnim(path, base, name, object.Animated, "a", "_a" ) + addUnitAnim(path, base, name, object.Broken, "_broken" ) + addUnitAnim(path, base, name, object.Death, "d", "_death" ) + addUnitAnim(path, base, name, object.Submerged, "w", "_w" ) + addUnitAnim(path, base, name, object.SubmergedBroken, "w_broken", "_w_broken") + addUnitAnim(path, base, name, object.Disabled, "off", "_off" ) + + -- emerge has a different base + addUnitAnim(path, "BaseEmerge", name, object.Emerge, "e", "_emerge" ) + + -- if we have a base icon, try icon + if iconBase ~= nil then + addUnitAnim(path, iconBase, name, object.Icon, "_ns") + end + + -- mechs have the extra hanger sprite + if group == "mech" and not object.NoHanger then + sprites.addSprite(path, name .. "_h") + end + end +end + +--[[-- + Adds a list of mech sprites and animations to the game + + @param sprites varargs parameter of all mechs to add +]] +function sprites.addMechs(...) + addUnitAnims("mech", {...}) +end + +--[[-- + Adds a list of mission unit sprites and animations to the game + + @param sprites varargs parameter of all mission units to add +]] +function sprites.addMissionUnits(...) + addUnitAnims("mission", {...}) +end + +--[[-- + Adds a list of enemy unit sprites and animations to the game + + @param sprites varargs parameter of all enemies to add +]] +function sprites.addEnemyUnits(...) + addUnitAnims("enemy", {...}) +end + +--[[-- + Adds a list of bot unit sprites and animations to the game + + @param sprites varargs parameter of all bots to add +]] +function sprites.addBotUnits(...) + addUnitAnims("bot", {...}) +end + +return sprites diff --git a/mods/squads/mods/Intercept Group/scripts/libs/worldConstants.lua b/mods/squads/mods/Intercept Group/scripts/libs/worldConstants.lua new file mode 100644 index 0000000..9e87ba4 --- /dev/null +++ b/mods/squads/mods/Intercept Group/scripts/libs/worldConstants.lua @@ -0,0 +1,161 @@ + +-------------------------------------------- +-- World Constants v.1.1 - code library +-------------------------------------------- +-- provides functions for setting/resetting +-- projectile/charge speed, +-- artillery/leap height, +-- gravity (strange results) +-------------------------------------------- +-------------------------------------------- +-- NOTE: +-- changing any constant, will affect every +-- weapon in the game. +-- to play nice with other mods, it is +-- important to reset them after each use. +-- +-- to apply a new value to your weapon, +-- follow this simple checklist: +-- +--------------------------------- +-- 1. set the constant +-- 2. AddProjectile(.. NO_DELAY) +-- 3. reset constant +--------------------------------- +-- +-- always use NO_DELAY between setting and +-- resetting to ensure it all happens in a +-- single cycle. +-- +-------------------------------------------- +-------------------------------------------- + +------------------- +-- initialization: +------------------- + +-- local worldConstants = require(self.scriptPath ..'worldConstants') + + +------------------ +-- function list: +------------------ + +----------------------------------------------- +-- worldConstants.SetSpeed(effect, value) +----------------------------------------------- +-- sets projectile/charge speed to 'value' +----------------------------------------------- + +-------------------------------------- +-- worldConstants.ResetSpeed(effect) +-------------------------------------- +-- resets projectile/charge speed +-------------------------------------- + +------------------------------------------- +-- worldConstants.SetHeight(effect, value) +------------------------------------------- +-- sets artillery/leap height to 'value' +------------------------------------------- + +-------------------------------------- +-- worldConstants.ResetHeight(effect) +-------------------------------------- +-- resets artillery/leap height +-------------------------------------- + +-------------------------------------------- +-- worldConstants.SetGravity(effect, value) +-------------------------------------------- +-- sets gravity to 'value' +-------------------------------------------- + +--------------------------------------- +-- worldConstants.ResetGravity(effect) +--------------------------------------- +-- resets gravity +--------------------------------------- + +-------------------------------------- +-- worldConstants.GetDefaultGravity() +-------------------------------------- +-- returns the default gravity. +-------------------------------------- + +-------------------------------------- +-- worldConstants.GetDefaultSpeed() +-------------------------------------- +-- returns the default +-- projectile/charge speed. +-------------------------------------- + +-------------------------------------- +-- worldConstants.GetDefaultHeight() +-------------------------------------- +-- returns the default +-- artillery/leap height. +-------------------------------------- + +---------------------------------------------------------------- +---------------------------------------------------------------- + +local default_gravity = Values["gravity"] +local default_x_velocity = Values["x_velocity"] +local default_y_velocity = Values["y_velocity"] + +local this = { + GetDefaultGravity = function() return default_gravity end, + GetDefaultSpeed = function() return default_x_velocity end, + GetDefaultHeight = function() return default_y_velocity end +} + +local orig_world_constants = {} + +function this.SetConstant(effect, name, value) + assert(type(effect) == 'userdata') + assert(type(name) == 'string') + assert(type(value) == 'number') + assert( + not orig_world_constants[name], + "Attempted to change constant ".. name .." multiple times without resetting it inbetween.") + + orig_world_constants[name] = Values[name] + effect:AddScript("Values['".. name .."'] = ".. value) +end + +function this.ResetConstant(effect, name) + assert(type(effect) == 'userdata') + assert( + orig_world_constants[name], + "Attempted to reset constant ".. name .." without setting it first.") + + effect:AddScript("Values['".. name .."'] = ".. orig_world_constants[name]) + orig_world_constants[name] = nil +end + +function this.SetSpeed(effect, value) + this.SetConstant(effect, 'x_velocity', value) +end + +function this.ResetSpeed(effect) + this.ResetConstant(effect, 'x_velocity') +end + +function this.SetHeight(effect, value) + this.SetConstant(effect, 'y_velocity', value) +end + +function this.ResetHeight(effect) + this.ResetConstant(effect, 'y_velocity') +end + +function this.SetGravity(effect, value) + this.SetConstant(effect, 'gravity', value) +end + +function this.ResetGravity(effect) + this.ResetConstant(effect, 'gravity') +end + +return this \ No newline at end of file diff --git a/mods/squads/mods/Intercept Group/scripts/pawns.lua b/mods/squads/mods/Intercept Group/scripts/pawns.lua new file mode 100644 index 0000000..61d3088 --- /dev/null +++ b/mods/squads/mods/Intercept Group/scripts/pawns.lua @@ -0,0 +1,43 @@ +local mod = modApi:getCurrentMod() +local imageOffset = modApi:getPaletteImageOffset(mod.id) + +tosx_Burn1Mech = Pawn:new{ + Name = "Beam Mech", + Class = "Prime", + Health = 3, + MoveSpeed = 3, + Image = "tosx_mech_burn1", + ImageOffset = imageOffset, + SkillList = {"tosx_Prime_ThermalLance"}, + SoundLocation = "/mech/prime/inferno_mech/", + SoundLocation = "/mech/brute/doubletank_mech/", + DefaultTeam = TEAM_PLAYER, + ImpactMaterial = IMPACT_METAL, + Massive = true, +} +tosx_Burn2Mech = Pawn:new{ + Name = "Cycle Mech", + Class = "Brute", + Health = 2, + MoveSpeed = 4, + Image = "tosx_mech_burn2", + ImageOffset = imageOffset, + SkillList = {"tosx_Brute_Shockwave"}, + SoundLocation = "/mech/brute/bulk_mech/", + DefaultTeam = TEAM_PLAYER, + ImpactMaterial = IMPACT_METAL, + Massive = true, +} +tosx_Burn3Mech = Pawn:new{ + Name = "Bunker Mech", + Class = "Ranged", + Health = 3, + MoveSpeed = 3, + Image = "tosx_mech_burn3", + ImageOffset = imageOffset, + SkillList = {"tosx_Ranged_Concussion"}, + SoundLocation = "/mech/science/exchange_mech/", + DefaultTeam = TEAM_PLAYER, + ImpactMaterial = IMPACT_METAL, + Massive = true, +} \ No newline at end of file diff --git a/mods/squads/mods/Intercept Group/scripts/side_objectives.lua b/mods/squads/mods/Intercept Group/scripts/side_objectives.lua new file mode 100644 index 0000000..40f454c --- /dev/null +++ b/mods/squads/mods/Intercept Group/scripts/side_objectives.lua @@ -0,0 +1,23 @@ +--[[ +easyEdit corp lists: + "archive" + "rst" + "pinnacle" + "detritus" +Reward types (defined constants): + REWARD_REP + REWARD_POWER + REWARD_TECH +]] + +CreateStructure{ + Id = "tosx_garage", + Name = "Garage", + Path = "img/structures/", + Image = "garage",--!!! + ImageOffset = Point(-20,-2), + Reward = REWARD_REP +} + +local corpStructureList = easyEdit.structureList:get("rst") +corpStructureList:addAssets("tosx_garage") \ No newline at end of file diff --git a/mods/squads/mods/Intercept Group/scripts/weapons.lua b/mods/squads/mods/Intercept Group/scripts/weapons.lua new file mode 100644 index 0000000..6f42bd7 --- /dev/null +++ b/mods/squads/mods/Intercept Group/scripts/weapons.lua @@ -0,0 +1,337 @@ +local mod = mod_loader.mods[modApi.currentMod] +local worldConstants = require(mod.scriptPath.."libs/worldConstants") + +local wt2 = { + tosx_Prime_ThermalLance_Upgrade1 = "+1 Max Damage", + tosx_Prime_ThermalLance_Upgrade2 = "+1 Max Damage", + + tosx_Brute_Shockwave_Upgrade1 = "+1 Phasing", + tosx_Brute_Shockwave_Upgrade2 = "+1 Phasing", + + tosx_Ranged_Concussion_Upgrade1 = "Ignite", + tosx_Ranged_Concussion_Upgrade2 = "+1 Damage", +} +for k,v in pairs(wt2) do Weapon_Texts[k] = v end + + + +tosx_Prime_ThermalLance = Skill:new{ + Name = "Focused Beam", + Description = "Fire a controlled beam that decreases in damage the more tiles it hits.", + Icon = "weapons/tosx_weapon_focusbeam.png", + Class = "Prime", + Rarity = 2, + MinDamage = 1, + Damage = 3, + PowerCost = 0, + Grid = false, + LaserArt = "effects/tosx_heatlaser", + LaunchSound = "/weapons/fire_beam", + Upgrades = 2, + UpgradeCost = {2, 3}, + TipImage = { + Unit = Point(2,3), + Building = Point(2,1), + Enemy = Point(2,2), + Target = Point(2,0), + Second_Origin = Point(2,3), + Second_Target = Point(2,2), + } +} +modApi:addWeaponDrop("tosx_Prime_ThermalLance") + +local function fireCheck(p) + return Board:IsFire(p) or (Board:IsPawnSpace(p) and Board:GetPawn(p):IsFire()) +end + +local function fireUnitCheck(p) + return Board:IsPawnSpace(p) and (Board:IsFire(p) or Board:GetPawn(p):IsFire()) +end + +function tosx_Prime_ThermalLance:GetTargetArea(p1) + local ret = PointList() + + for i = DIR_START, DIR_END do + for k = 1, self.Damage do + local curr = p1 + DIR_VECTORS[i]*k + if Board:IsValid(curr) then + ret:push_back(curr) + else + break + end + end + end + + return ret +end + +function tosx_Prime_ThermalLance:GetSkillEffect(p1, p2) + local ret = SkillEffect() + local dir = GetDirection(p2 - p1) + local distance = p1:Manhattan(p2) + local amount = self.Damage + 1 - distance + + for k = 1, distance do + local curr = p1 + DIR_VECTORS[dir]*k + local damage = SpaceDamage(curr, amount) + if Board:IsBuilding(curr) and self.Grid then + damage.iDamage = DAMAGE_ZERO + end + if k == distance then + ret:AddProjectile(damage,self.LaserArt) + else + ret:AddDamage(damage) + end + end + + if not Board:IsTipImage() and distance == 3 then + ret:AddScript([[ + local mission = GetCurrentMission() + if mission then + if not mission.tosx_intercept_peak then mission.tosx_intercept_peak = 0 end + mission.tosx_intercept_peak = mission.tosx_intercept_peak + 1 + if mission.tosx_intercept_peak >= 4 then + tosx_interceptsquad_Chievo("tosx_intercept_peak") + end + end + ]]) + end + + return ret +end + +tosx_Prime_ThermalLance_A = tosx_Prime_ThermalLance:new{ + UpgradeDescription = "Increases max damage by 1.", + Damage = 4, +} + +tosx_Prime_ThermalLance_B = tosx_Prime_ThermalLance:new{ + UpgradeDescription = "Increases max damage by 1.", + Damage = 4, +} + +tosx_Prime_ThermalLance_AB = tosx_Prime_ThermalLance:new{ + Damage = 5, +} + + +tosx_Brute_Shockwave = Skill:new{ + Name = "Shockwave Engine", + Description = "Dash in a line, pushing 3 tiles on either side when you stop.", + Icon = "weapons/tosx_weapon_shockwave.png", + Class = "Brute", + ShockSound = "/weapons/modified_cannons", + LaunchSound = "/weapons/charge", + Upgrades = 2, + Obstacles = 0, + Damage = 0, + UpgradeCost = {1, 2}, + TipImage = { + Unit = Point(2,3), + Enemy = Point(3,1), + Enemy2 = Point(1,1), + Target = Point(2,1), + }, +} +modApi:addWeaponDrop("tosx_Brute_Shockwave") + +function tosx_Brute_Shockwave:GetTargetArea(p1) + local ret = PointList() + for dir = DIR_START, DIR_END do + local max_i = 0 + local obstacles = 0 + for i = 1,7 do + local point = p1 + DIR_VECTORS[dir]*i + if not Board:IsBlocked(point, Pawn:GetPathProf()) then + max_i = i + end + if Board:IsBlocked(point, PATH_PROJECTILE) then + obstacles = obstacles + 1 + if obstacles > self.Obstacles then + break + end + elseif Board:IsBlocked(point, Pawn:GetPathProf()) then + break + end + end + for i = 1,max_i do + local point = p1 + DIR_VECTORS[dir]*i + ret:push_back(point) + end + end + return ret +end + +function tosx_Brute_Shockwave:GetSkillEffect(p1, p2) + local ret = SkillEffect() + local dir = GetDirection(p2 - p1) + local dir2 = GetDirection(p1 - p2) + local width = 3 + local behind = p1 + DIR_VECTORS[dir2] + local target = p2 + + if Board:IsBlocked(target, PATH_PROJECTILE) then + -- p2 must be on an obstacle we're passing; march forward + for i = 1, self.Obstacles do + target = target + DIR_VECTORS[dir] + if not Board:IsBlocked(target, PATH_PROJECTILE) then + break + end + end + end + + -- melee to emphasize speed. + local damage0 = SpaceDamage(behind) + damage0.bHide = true + ret:AddMelee(p1, damage0, FULL_DELAY) + + -- Charge really fast + local superspeed = 5 + worldConstants.SetSpeed(ret, superspeed) + ret:AddCharge(Board:GetPath(p1, target, PATH_FLYER), NO_DELAY) + worldConstants.ResetSpeed(ret) + + ret:AddSound(self.ShockSound) + ret:AddBoardShake(1) + + for i = 0, width*2 do + local p = target + DIR_VECTORS[(dir+1)%4]*(width - i) + if Board:IsValid(p) and p ~= target then + local damage = SpaceDamage(p, 0, dir) + damage.sAnimation = "airpush_"..dir + ret:AddDamage(damage) + ret:AddBounce(p, 3) + end + end + + if not Board:IsTipImage() and p1:Manhattan(target) >= 6 then + local count = Board:GetEnemyCount() + ret:AddScript(string.format([[ + local fx = SkillEffect(); + fx:AddScript("if %s - Board:GetEnemyCount() >= 2 then tosx_interceptsquad_Chievo('tosx_intercept_throttle') end") + Board:AddEffect(fx); + ]], count)) + end + + return ret +end + +tosx_Brute_Shockwave_A = tosx_Brute_Shockwave:new{ + UpgradeDescription = "Mech can phase through 1 additional obstacle when charging.", + Obstacles = 1, + TipImage = { + Unit = Point(2,3), + Enemy = Point(3,1), + Enemy2 = Point(1,1), + Building = Point(2,2), + Target = Point(2,1), + }, +} + +tosx_Brute_Shockwave_B = tosx_Brute_Shockwave:new{ + UpgradeDescription = "Mech can phase through 1 additional obstacle when charging.", + Obstacles = 1, + TipImage = { + Unit = Point(2,3), + Enemy = Point(3,1), + Enemy2 = Point(1,1), + Building = Point(2,2), + Target = Point(2,1), + }, +} + +tosx_Brute_Shockwave_AB = tosx_Brute_Shockwave:new{ + Obstacles = 2, + TipImage = { + Unit = Point(2,4), + Enemy = Point(3,1), + Enemy2 = Point(1,1), + Building = Point(2,2), + Building2 = Point(2,3), + Target = Point(2,1), + }, +} + + +tosx_Ranged_Concussion = Skill:new{ + Name = "Concussion Artillery", + Description = "Damage a tile and push 2 tiles on either side.", + Icon = "weapons/tosx_weapon_concussion.png", + Damage = 1, + Class = "Ranged", + ArtillerySize = 8, + LaunchSound = "/weapons/heavy_rocket", + ImpactSound = "/weapons/mercury_fist", + UpShot = "effects/tosx_shotup_seeker.png", + Explo = "ExploArt1", + Upgrades = 2, + Fire = false, + UpgradeCost = {2, 2}, + TipImage = { + Unit = Point(2,3), + Enemy = Point(2,1), + Enemy2 = Point(1,1), + Target = Point(2,1), + }, +} +modApi:addWeaponDrop("tosx_Ranged_Concussion") + +function tosx_Ranged_Concussion:GetTargetArea(p1) + local ret = PointList() + for dir = DIR_START, DIR_END do + for i = 2, self.ArtillerySize do + local curr = p1 + DIR_VECTORS[dir] * i + if not Board:IsValid(curr) then + break + end + ret:push_back(curr) + end + end + return ret +end + +function tosx_Ranged_Concussion:GetSkillEffect(p1, p2) + local ret = SkillEffect() + local direction = GetDirection(p2 - p1) + + local damage = SpaceDamage(p2,self.Damage) + damage.sAnimation = self.Explo + + if self.Fire then + damage.iFire = EFFECT_CREATE + end + + ret:AddBounce(p1, 3) + ret:AddArtillery(damage, self.UpShot) + ret:AddBounce(p2, 3) + for j = 2,1,-1 do + for i = 1,3,2 do + local d = (direction+i)%4 + local p = p2 + DIR_VECTORS[d]*j + local damage2 = SpaceDamage(p,0,d) + damage2.sAnimation = "airpush_"..d + + ret:AddDamage(damage2) + end + ret:AddDelay(0.1) + end + + return ret +end + +tosx_Ranged_Concussion_A = tosx_Ranged_Concussion:new{ + UpgradeDescription = "Lights target tile on Fire.", + Fire = true, + Explo = "ExploArt2", +} + +tosx_Ranged_Concussion_B = tosx_Ranged_Concussion:new{ + UpgradeDescription = "Increases damage by 1.", + Damage = 2, +} + +tosx_Ranged_Concussion_AB = tosx_Ranged_Concussion:new{ + Fire = true, + Damage = 2, + Explo = "ExploArt2", +} \ No newline at end of file diff --git a/scripts/init.lua b/scripts/init.lua index 30d45b3..15ba9bb 100644 --- a/scripts/init.lua +++ b/scripts/init.lua @@ -5,7 +5,7 @@ return { description = "Mods by tosx.", icon = "scripts/icon.png", submodFolders = {"mods/"}, - version = "1.23", + version = "1.24", init = function() end, load = function() end }