From 74a5b7d8367f11ec79169982f7863e8ad86b9ec5 Mon Sep 17 00:00:00 2001 From: "(Jip) Willem Wijnia" Date: Tue, 10 Dec 2024 01:33:44 +0100 Subject: [PATCH 1/4] Expose player ratings and divisions to the session (#6569) --- changelog/snippets/fix.6569.md | 1 + engine/User/CLobby.lua | 2 + .../lobby/autolobby/AutolobbyController.lua | 87 ++++++++++-- .../components/AutolobbyArguments.lua | 127 ++++++++++++++++++ scripts/LaunchFAInstances.ps1 | 5 +- 5 files changed, 208 insertions(+), 14 deletions(-) create mode 100644 changelog/snippets/fix.6569.md create mode 100644 lua/ui/lobby/autolobby/components/AutolobbyArguments.lua diff --git a/changelog/snippets/fix.6569.md b/changelog/snippets/fix.6569.md new file mode 100644 index 0000000000..6d32706c6b --- /dev/null +++ b/changelog/snippets/fix.6569.md @@ -0,0 +1 @@ +- (#6569) Fix the matchmaker lobby not passing ratings, divisions and clan tags to the session diff --git a/engine/User/CLobby.lua b/engine/User/CLobby.lua index eb132bd52e..a5c0099bdd 100644 --- a/engine/User/CLobby.lua +++ b/engine/User/CLobby.lua @@ -43,6 +43,8 @@ local CLobby = {} ---@field Timeouts any # Read by the engine to determine the behavior of time outs. ---@field CivilianAlliance any # Read by the engine to determine the alliance towards civilians. ---@field GameSpeed any # Read by the engine to determine the behavior of game speed (adjustments). +---@field Ratings table +---@field Divisions table ---@class UILobbyLaunchGameModsConfiguration ---@field name string # Read by the engine, TODO diff --git a/lua/ui/lobby/autolobby/AutolobbyController.lua b/lua/ui/lobby/autolobby/AutolobbyController.lua index 364fc8df4a..180d2b652f 100644 --- a/lua/ui/lobby/autolobby/AutolobbyController.lua +++ b/lua/ui/lobby/autolobby/AutolobbyController.lua @@ -29,6 +29,8 @@ local DebugComponent = import("/lua/shared/components/DebugComponent.lua").Debug local AutolobbyServerCommunicationsComponent = import("/lua/ui/lobby/autolobby/components/AutolobbyServerCommunicationsComponent.lua") .AutolobbyServerCommunicationsComponent +local AutolobbyArgumentsComponent = import("/lua/ui/lobby/autolobby/components/AutolobbyArguments.lua").AutolobbyArgumentsComponent + local AutolobbyMessages = import("/lua/ui/lobby/autolobby/AutolobbyMessages.lua").AutolobbyMessages local AutolobbyEngineStrings = { @@ -62,6 +64,7 @@ local AutolobbyEngineStrings = { ---@field DIV string # Related to rating/divisions ---@field SUBDIV string # Related to rating/divisions ---@field PL number # Related to rating/divisions +---@field PlayerClan string ---@alias UIAutolobbyConnections boolean[][] ---@alias UIAutolobbyStatus UIPeerLaunchStatus[] @@ -86,7 +89,7 @@ local AutolobbyEngineStrings = { ---@field DesiredPeerId UILobbyPeerId --- Responsible for the behavior of the automated lobby. ----@class UIAutolobbyCommunications : moho.lobby_methods, DebugComponent, UIAutolobbyServerCommunicationsComponent +---@class UIAutolobbyCommunications : moho.lobby_methods, DebugComponent, UIAutolobbyServerCommunicationsComponent, UIAutolobbyArgumentsComponent ---@field Trash TrashBag ---@field LocalPeerId UILobbyPeerId # a number that is stringified ---@field LocalPlayerName string # nickname @@ -100,7 +103,7 @@ local AutolobbyEngineStrings = { ---@field LobbyParameters? UIAutolobbyParameters # Used for rejoining functionality ---@field HostParameters? UIAutolobbyHostParameters # Used for rejoining functionality ---@field JoinParameters? UIAutolobbyJoinParameters # Used for rejoining functionality -AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsComponent, DebugComponent) { +AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsComponent, AutolobbyArgumentsComponent, DebugComponent) { ---@param self UIAutolobbyCommunications __init = function(self) @@ -108,7 +111,7 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC self.LocalPeerId = "-2" self.LocalPlayerName = "Charlie" - self.PlayerCount = tonumber(GetCommandLineArg("/players", 1)[1]) or 2 + self.PlayerCount = self:GetCommandLineArgumentNumber("/players", 2) self.HostID = "-2" self.GameMods = {} @@ -147,20 +150,21 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC end -- retrieve team and start spot - info.Team = tonumber(GetCommandLineArg("/team", 1)[1]) - info.StartSpot = tonumber(GetCommandLineArg("/startspot", 1)[1]) or -1 -- TODO + info.Team = self:GetCommandLineArgumentNumber("/team", -1) + info.StartSpot = self:GetCommandLineArgumentNumber("/startspot", -1) -- determine army color based on start location info.PlayerColor = GameColors.MapToWarmCold(info.StartSpot) info.ArmyColor = GameColors.MapToWarmCold(info.StartSpot) -- retrieve rating - info.DEV = tonumber(GetCommandLineArg("/deviation", 1)[1]) or 500 - info.MEAN = tonumber(GetCommandLineArg("/mean", 1)[1]) or 1500 - info.NG = tonumber(GetCommandLineArg("/numgames", 1)[1]) or 0 - info.DIV = (GetCommandLineArg("/division", 1)[1]) or "" - info.SUBDIV = (GetCommandLineArg("/subdivision", 1)[1]) or "" + info.DEV = self:GetCommandLineArgumentNumber("/deviation", 500) + info.MEAN = self:GetCommandLineArgumentNumber("/mean", 1500) + info.NG = self:GetCommandLineArgumentNumber("/numgames", 0) + info.DIV = self:GetCommandLineArgumentString("/division", "") + info.SUBDIV = self:GetCommandLineArgumentString("/subdivision", "") info.PL = math.floor(info.MEAN - 3 * info.DEV) + info.PlayerClan = self:GetCommandLineArgumentString("/clan", "") return info end, @@ -193,7 +197,7 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC } -- process game options from the command line - for name, value in Utils.GetCommandLineArgTable("/gameoptions") do + for name, value in self:GetCommandLineArgumentArray("/gameoptions") do if name and value then options[name] = value else @@ -294,6 +298,59 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC return 'Ready' end, + ---@param self UIAutolobbyCommunications + ---@param playerOptions UIAutolobbyPlayer[] + ---@return table + CreateRatingsTable = function(self, playerOptions) + ---@type table + local allRatings = {} + + for slot, options in pairs(playerOptions) do + if options.Human and options.PL then + allRatings[options.PlayerName] = options.PL + end + end + + return allRatings + end, + + ---@param self UIAutolobbyCommunications + ---@param playerOptions UIAutolobbyPlayer[] + ---@return table + CreateDivisionsTable = function(self, playerOptions) + ---@type table + local allDivisions = {} + + for slot, options in pairs(playerOptions) do + if options.Human and options.PL then + if options.DIV ~= "unlisted" then + local division = options.DIV + if options.SUBDIV and options.SUBDIV ~= "" then + division = division .. ' ' .. options.SUBDIV + end + allDivisions[options.PlayerName] = division + end + end + end + + return allDivisions + end, + + ---@param self UIAutolobbyCommunications + ---@param playerOptions UIAutolobbyPlayer[] + ---@return table + CreateClanTagsTable = function(self, playerOptions) + local allClanTags = {} + + for slot, options in pairs(playerOptions) do + if options.PlayerClan then + allClanTags[options.PlayerName] = options.PlayerClan + end + end + + return allClanTags + end, + --- Verifies whether we can launch the game. ---@param self UIAutolobbyCommunications ---@param peerStatus UIAutolobbyStatus @@ -488,6 +545,12 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC self:SendPlayerOptionToServer(ownerId, 'Faction', playerOptions.Faction) end + -- tuck them into the game options. By all means a hack, but + -- this way they are available in both the sim and the UI + self.GameOptions.Ratings = self:CreateRatingsTable(self.PlayerOptions) + self.GameOptions.Divisions = self:CreateDivisionsTable(self.PlayerOptions) + self.GameOptions.ClanTags = self:CreateClanTagsTable(self.PlayerOptions) + -- create game configuration local gameConfiguration = { GameMods = self.GameMods, @@ -496,7 +559,7 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC Observers = {}, } - -- send it to all players and tell them to launch + -- send it to all players and tell them to launch with the configuration self:BroadcastData({ Type = "Launch", GameConfig = gameConfiguration }) self:LaunchGame(gameConfiguration) end diff --git a/lua/ui/lobby/autolobby/components/AutolobbyArguments.lua b/lua/ui/lobby/autolobby/components/AutolobbyArguments.lua new file mode 100644 index 0000000000..c17f4fa4bd --- /dev/null +++ b/lua/ui/lobby/autolobby/components/AutolobbyArguments.lua @@ -0,0 +1,127 @@ +--****************************************************************************************************** +--** Copyright (c) 2024 Willem 'Jip' Wijnia +--** +--** Permission is hereby granted, free of charge, to any person obtaining a copy +--** of this software and associated documentation files (the "Software"), to deal +--** in the Software without restriction, including without limitation the rights +--** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +--** copies of the Software, and to permit persons to whom the Software is +--** furnished to do so, subject to the following conditions: +--** +--** The above copyright notice and this permission notice shall be included in all +--** copies or substantial portions of the Software. +--** +--** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +--** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +--** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +--** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +--** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +--** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +--** SOFTWARE. +--****************************************************************************************************** + +--- A component that represent all the supported lobby <-> server communications. +---@class UIAutolobbyArgumentsComponent +AutolobbyArgumentsComponent = ClassSimple { + + --- Represent all valid command line arguments for the lobby + ArgumentKeys = { + ["/init"] = true, + ["/joincustom"] = true, + ["/gpgnet"] = true, + + -- related to player info + ["/clan"] = true, + ["/country"] = true, + ["/numgames"] = true, + + -- related to player settings + ["/team"] = true, + ["/uef"] = true, + ["/cybran"] = true, + ["/aeon"] = true, + ["/seraphim"] = true, + ["/startspot"] = true, + + -- related to rating + ["/deviation"] = true, + ["/mean"] = true, + + -- related to divisions + ["division"] = true, + ["/subdivision"] = true, + + -- related to game settings + ["/gameoptions"] = true, + ["/players"] = true, + }, + + --- Verifies that it is an expected command line argument + ---@param self UIAutolobbyArgumentsComponent | UIAutolobbyCommunications + ---@param option string + ---@return boolean + ValidCommandLineKey = function(self, option) + if not self.ArgumentKeys[option] then + self:DebugWarn("Unknown command line argument: ", option) + return false + end + + return true + end, + + --- Attempts to retrieve a string-like command line argument + ---@param self UIAutolobbyArgumentsComponent | UIAutolobbyCommunications + ---@param option string + ---@param default string + ---@return string + GetCommandLineArgumentString = function(self, option, default) + if not self:ValidCommandLineKey(option) then + return default + end + + -- try to get the first argument + local arguments = GetCommandLineArg(option, 1) + if arguments and (not option[ arguments[1] ]) then + return arguments[1] + end + + return default + end, + + --- Attempts to retrieve a number-like command line argument + ---@param self UIAutolobbyArgumentsComponent | UIAutolobbyCommunications + ---@param option string + ---@param default number + ---@return number + GetCommandLineArgumentNumber = function(self, option, default) + if not self:ValidCommandLineKey(option) then + return default + end + + -- try to get the first argument and parse it as a number + local arguments = GetCommandLineArg(option, 1) + if arguments and (not option[ arguments[1] ]) then + local parsed = tonumber(arguments[1]) + if parsed then + return parsed + else + self:DebugWarn("Failed to parse as a number: ", arguments[1], " for key ", option) + return default + end + end + + return default + end, + + --- Attempts to retrieve a table-like command line argument + ---@param self UIAutolobbyArgumentsComponent | UIAutolobbyCommunications + ---@param option string + ---@return table + GetCommandLineArgumentArray = function(self, option) + if not self:ValidCommandLineKey(option) then + return {} + end + + return import("/lua/system/utils.lua").GetCommandLineArgTable(option) + end, +} diff --git a/scripts/LaunchFAInstances.ps1 b/scripts/LaunchFAInstances.ps1 index 8a22fca4a6..123faab0e1 100644 --- a/scripts/LaunchFAInstances.ps1 +++ b/scripts/LaunchFAInstances.ps1 @@ -34,6 +34,7 @@ $gameName = "MyGame" # Array of factions to choose from $factions = @("UEF", "Seraphim", "Cybran", "Aeon") +$clans = @("Yps", "Nom", "Cly", "Mad", "Gol", "Kur", "Row", "Jip", "Bal", "She") # Get the screen resolution (for placing and resizing the windows) Add-Type -AssemblyName System.Windows.Forms @@ -91,7 +92,7 @@ if ($players -eq 1) { $hostLogFile = "host_dev_1.log" $hostFaction = $factions | Get-Random $hostTeamArgument = Get-TeamArgument -instanceNumber 0 - $hostArguments = "/log $hostLogFile /showlog /hostgame $hostProtocol $port $hostPlayerName $gameName $map /startspot 1 /players $players /$hostFaction $hostTeamArgument $baseArguments" + $hostArguments = "/log $hostLogFile /showlog /hostgame $hostProtocol $port $hostPlayerName $gameName $map /startspot 1 /players $players /$hostFaction $hostTeamArgument $baseArguments /division HostDivision /subdivision 1 /clan $($clans | Get-Random)" # Launch host game instance Launch-GameInstance -instanceNumber 1 -xPos 0 -yPos 0 -arguments $hostArguments @@ -107,7 +108,7 @@ if ($players -eq 1) { $clientPlayerName = "ClientPlayer_$($i + 1)" $clientFaction = $factions | Get-Random $clientTeamArgument = Get-TeamArgument -instanceNumber $i - $clientArguments = "/log $clientLogFile /joingame $hostProtocol localhost:$port $clientPlayerName /startspot $($i + 1) /players $players /$clientFaction $clientTeamArgument $baseArguments" + $clientArguments = "/log $clientLogFile /joingame $hostProtocol localhost:$port $clientPlayerName /startspot $($i + 1) /players $players /$clientFaction $clientTeamArgument $baseArguments /division Diamond /subdivision $($i + 1) /clan $($clans | Get-Random)" Launch-GameInstance -instanceNumber ($i + 1) -xPos $xPos -yPos $yPos -arguments $clientArguments } From 73ed88ea7755a36c1293f08700fe67c810c464f1 Mon Sep 17 00:00:00 2001 From: BlackYps <52536103+BlackYps@users.noreply.github.com> Date: Tue, 10 Dec 2024 20:57:30 +0100 Subject: [PATCH 2/4] Changelog for 3816 (#6579) --- changelog/snippets/balance.6568.md | 3 --- changelog/snippets/fix.6546.md | 1 - changelog/snippets/fix.6569.md | 1 - docs/_posts/2024-12-10-3816.md | 35 ++++++++++++++++++++++++++++++ lua/ui/lobby/changelogData.lua | 17 ++++++++++++++- lua/version.lua | 6 ++--- mod_info.lua | 2 +- 7 files changed, 55 insertions(+), 10 deletions(-) delete mode 100644 changelog/snippets/balance.6568.md delete mode 100644 changelog/snippets/fix.6546.md delete mode 100644 changelog/snippets/fix.6569.md create mode 100644 docs/_posts/2024-12-10-3816.md diff --git a/changelog/snippets/balance.6568.md b/changelog/snippets/balance.6568.md deleted file mode 100644 index ee192345e2..0000000000 --- a/changelog/snippets/balance.6568.md +++ /dev/null @@ -1,3 +0,0 @@ -- (#6568) Vulthoo have been underperforming after their rework. Their biggest weak point was the excessive amount of build time required which made it impractical to make them in the earlier stages of tech 2 especially. - - Vulthoo: - - BuildTime: 3300 --> 2700 \ No newline at end of file diff --git a/changelog/snippets/fix.6546.md b/changelog/snippets/fix.6546.md deleted file mode 100644 index 52c07bf551..0000000000 --- a/changelog/snippets/fix.6546.md +++ /dev/null @@ -1 +0,0 @@ -- (#6546) Fix an exploit that allows being notified of enemy Billy nuke launches. diff --git a/changelog/snippets/fix.6569.md b/changelog/snippets/fix.6569.md deleted file mode 100644 index 6d32706c6b..0000000000 --- a/changelog/snippets/fix.6569.md +++ /dev/null @@ -1 +0,0 @@ -- (#6569) Fix the matchmaker lobby not passing ratings, divisions and clan tags to the session diff --git a/docs/_posts/2024-12-10-3816.md b/docs/_posts/2024-12-10-3816.md new file mode 100644 index 0000000000..d03c7a4511 --- /dev/null +++ b/docs/_posts/2024-12-10-3816.md @@ -0,0 +1,35 @@ +--- +layout: post +title: Game version 3816 +permalink: changelog/3816 +--- + +# Game version 3816 (10th of December, 2024) + +This hotfix primarily fixes the bug that rating and divisions were not displayed in matchmaker games. + +With kind regards, + +BlackYps + +## Balance + +- (#6568) Vulthoo have been underperforming after their rework. Their biggest weak point was the excessive amount of build time required which made it impractical to make them in the earlier stages of tech 2 especially. + - Vulthoo: + - BuildTime: 3300 --> 2700 + +## Bug fixes + +- (#6546) Fix an exploit that allows being notified of enemy Billy nuke launches. + +- (#6569) Fix the matchmaker lobby not passing ratings, divisions and clan tags to the session, making them not visible in the scoreboard. + + +## Contributors + +With thanks to the following people who contributed through coding and testing: + +- Jip +- Nomander +- ETFreeman +- Clyf diff --git a/lua/ui/lobby/changelogData.lua b/lua/ui/lobby/changelogData.lua index d0357f7af4..179a569f3e 100644 --- a/lua/ui/lobby/changelogData.lua +++ b/lua/ui/lobby/changelogData.lua @@ -1,8 +1,23 @@ ---@type number -last_version = 3815 +last_version = 3816 ---@type PatchNotes[] gamePatches = { + { + version = 3816, + name = "Hotfix", + hasPrettyGithubRelease = true, + hasPrettyPatchnotes = false, + description = { + "# Game version 3816 (10th of December, 2024)", + "", + "This hotfix primarily fixes the bug that ratings and divisions were not displayed in matchmaker games.", + "", + "With kind regards,", + "", + "BlackYps", + }, + }, { version = 3815, name = "Hotfix", diff --git a/lua/version.lua b/lua/version.lua index 3631c223aa..d55e91f97e 100644 --- a/lua/version.lua +++ b/lua/version.lua @@ -34,9 +34,9 @@ local Commit = 'unknown' -- The use of `'` instead of `"` is **intentional** --#endregion -local Version = "3815" ----@alias PATCH "3815" ----@alias VERSION "1.5.3815" +local Version = "3816" +---@alias PATCH "3816" +---@alias VERSION "1.5.3816" ---@return PATCH # Game release function GetVersion() LOG(string.format('Supreme Commander: Forged Alliance Lua version %s at %s (%s)', Version, GameType, Commit)) diff --git a/mod_info.lua b/mod_info.lua index b0f3331b2b..33c29502c3 100644 --- a/mod_info.lua +++ b/mod_info.lua @@ -27,7 +27,7 @@ -- - https://github.com/FAForever/fa/blob/deploy/fafdevelop/lua/MODS.LUA name = "Forged Alliance Forever" -version = 3815 -- needs to be an integer as it is parsed as a short (16 bit integer) +version = 3816 -- needs to be an integer as it is parsed as a short (16 bit integer) _faf_modname='faf' copyright = "Forged Alliance Forever Community" description = "Forged Alliance Forever extends Forged Alliance, bringing new patches, game modes, units, ladder, and much more!" From 8f68350c211a3344b01bc127937211937b662cb2 Mon Sep 17 00:00:00 2001 From: lL1l1 <82986251+lL1l1@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:25:24 -0800 Subject: [PATCH 3/4] Make assisters start repairing shields immediately (#6464) Assist orders take 7-11 ticks to react to the shield being damaged, but by issuing a repair order when the shield gets damaged this shortens to 1 tick --- changelog/snippets/balance.6464.md | 1 + lua/shield.lua | 41 +++++++++++++++++++++++++++--- lua/sim/Unit.lua | 1 + 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 changelog/snippets/balance.6464.md diff --git a/changelog/snippets/balance.6464.md b/changelog/snippets/balance.6464.md new file mode 100644 index 0000000000..a9abc12adb --- /dev/null +++ b/changelog/snippets/balance.6464.md @@ -0,0 +1 @@ +- (#6464) Make engineers assisting a shield start repairing the shield in 0.1 seconds instead of 0.7 to 1.1 seconds. diff --git a/lua/shield.lua b/lua/shield.lua index 8a6d344f4f..fb0dcd0d53 100644 --- a/lua/shield.lua +++ b/lua/shield.lua @@ -42,6 +42,8 @@ local MathSqrt = math.sqrt local MathMin = math.min local TableAssimilate = table.assimilate +local TableGetn = table.getn +local TableEmpty = table.empty -- cache globals local Warp = Warp @@ -59,6 +61,9 @@ local ArmyGetHandicap = ArmyGetHandicap local CoroutineYield = coroutine.yield local CreateEmitterAtBone = CreateEmitterAtBone local _c_CreateShield = _c_CreateShield +local IssueClearCommands = IssueClearCommands +local IssueRepair = IssueRepair +local IssueGuard = IssueGuard -- cache cfunctions local EntityGetHealth = _G.moho.entity_methods.GetHealth @@ -87,6 +92,8 @@ local EntitySetParentOffset = _G.moho.entity_methods.SetParentOffset local UnitSetScriptBit = _G.moho.unit_methods.SetScriptBit local UnitIsUnitState = _G.moho.unit_methods.IsUnitState local UnitRevertCollisionShape = _G.moho.unit_methods.RevertCollisionShape +local UnitGetGuards = _G.moho.unit_methods.GetGuards +local UnitGetCommandQueue = _G.moho.unit_methods.GetCommandQueue local IEffectOffsetEmitter = _G.moho.IEffect.OffsetEmitter @@ -356,7 +363,7 @@ Shield = ClassShield(moho.shield_methods, Entity) { --- Retrieves allied shields that overlap with this shield, caches the results per tick -- @param self A shield that we're computing the overlapping shields for - -- @param tick Optional parameter, represents the game tick. Used to determine if we need to refresh the cash + -- @param tick Optional parameter, represents the game tick. Used to determine if we need to refresh the cache GetOverlappingShields = function(self, tick) -- allow the game tick to be send to us, saves cycles @@ -509,6 +516,12 @@ Shield = ClassShield(moho.shield_methods, Entity) { self:ApplyDamage(instigator, amount, vector, damageType, true) end, + ---@param self Shield + ---@param instigator Unit + ---@param amount number + ---@param vector Vector + ---@param dmgType DamageType + ---@param doOverspill boolean ApplyDamage = function(self, instigator, amount, vector, dmgType, doOverspill) -- cache information used throughout the function @@ -565,12 +578,32 @@ Shield = ClassShield(moho.shield_methods, Entity) { -- do damage logic for shield - if self.Owner ~= instigator then + local owner = self.Owner + if owner ~= instigator then local absorbed = self:OnGetDamageAbsorption(instigator, amount, dmgType) -- take some damage EntityAdjustHealth(self, instigator, -absorbed) + -- force guards to start repairing in 1 tick instead of waiting for them to react 7-11 ticks + if tick > owner.tickIssuedShieldRepair then + owner.tickIssuedShieldRepair = tick + local guards = UnitGetGuards(owner) + if not TableEmpty(guards) then + -- filter out guards with something queued after the shield assist order, as to not delete clear their queue + for i, guard in guards do + if TableGetn(UnitGetCommandQueue(guard)) >= 2 then + guards[i] = nil + end + end + + -- For the filtered guards, clear their assist order, order repair, then re-add the assist order after + IssueClearCommands(guards) + IssueRepair(guards, owner) + IssueGuard(guards, owner) + end + end + -- check to spawn impact effect local r = Random(1, self.Size) if dmgType ~= "ShieldSpill" @@ -684,8 +717,8 @@ Shield = ClassShield(moho.shield_methods, Entity) { end, --- Called when a shield collides with a projectile to check if the collision is valid - -- @param self The shield we're checking the collision for - -- @param other The projectile we're checking the collision with + ---@param self Shield The shield we're checking the collision for + ---@param other Projectile The projectile we're checking the collision with OnCollisionCheck = function(self, other) -- special logic when it is a projectile to simulate air crashes diff --git a/lua/sim/Unit.lua b/lua/sim/Unit.lua index bbe6a3ab48..2537e59a22 100644 --- a/lua/sim/Unit.lua +++ b/lua/sim/Unit.lua @@ -146,6 +146,7 @@ local cUnitGetBuildRate = cUnit.GetBuildRate ---@field ReclaimTimeMultiplier? number ---@field CaptureTimeMultiplier? number ---@field PlatoonHandle? Platoon +---@field tickIssuedShieldRepair number? # Used by shields to keep track of when this unit's guards were ordered to start shield repair instantly Unit = ClassUnit(moho.unit_methods, IntelComponent, VeterancyComponent, DebugUnitComponent) { IsUnit = true, From 508885dfcedf97b7fd5e36d7c42f21ce3f522b7e Mon Sep 17 00:00:00 2001 From: lL1l1 <82986251+lL1l1@users.noreply.github.com> Date: Thu, 12 Dec 2024 01:07:39 -0800 Subject: [PATCH 4/4] Annotate `AddBlinkyBox` (#6577) --- changelog/snippets/other.6577.md | 1 + engine/User.lua | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelog/snippets/other.6577.md diff --git a/changelog/snippets/other.6577.md b/changelog/snippets/other.6577.md new file mode 100644 index 0000000000..1a53a6e6b3 --- /dev/null +++ b/changelog/snippets/other.6577.md @@ -0,0 +1 @@ +- (#6577) Annotate `AddBlinkyBox`. This UI-side global engine function makes a unit's selection box blink for some time. diff --git a/engine/User.lua b/engine/User.lua index e80673bc60..ef83854aaf 100644 --- a/engine/User.lua +++ b/engine/User.lua @@ -124,8 +124,8 @@ --- | 'NUMPAD_DECIMAL' --- | 'NUMPAD_DIVIDE' ---- No clue what this does ----@param entityId number +--- Repeatedly the selection box of the unit to the hovered-over state to create a blinking effect +---@param entityId EntityId ---@param onTime number ---@param offTime number ---@param totalTime number