diff --git a/changelog/snippets/other.6596.md b/changelog/snippets/other.6596.md new file mode 100644 index 0000000000..5c442427d6 --- /dev/null +++ b/changelog/snippets/other.6596.md @@ -0,0 +1 @@ +- (#6596) Annotate files related to scripted tasks like the Scry ability of the Eye of Rhianne or unit Enhancements. diff --git a/engine/Core/Blueprints/UnitBlueprint.lua b/engine/Core/Blueprints/UnitBlueprint.lua index 8a60a413ca..0c8bdb1ce9 100644 --- a/engine/Core/Blueprints/UnitBlueprint.lua +++ b/engine/Core/Blueprints/UnitBlueprint.lua @@ -36,6 +36,9 @@ -- read more here: https://wiki.faforever.com/en/Blueprints ---@class UnitBlueprint: EntityBlueprint +--- Table keyed with a `ScriptTask`'s `TaskName` that determines the properties of the order button for that ability. +--- The `OrderInfo.behavior` is overwritten in `orders.lua`. +---@field Abilities table --- the number of build bots a Cybran builder has ---@field BuildBotTotal? number --- set to an integer that describes the unit's position in the list of build icons diff --git a/engine/Library.lua b/engine/Library.lua index 23e5689018..e7b519a03f 100644 --- a/engine/Library.lua +++ b/engine/Library.lua @@ -73,6 +73,7 @@ end function debug.allocatedsize(obj) end +--- Returns a cached table of all table allocations tracked between calls of `debug.trackallocations(true)` and `debug.trackallocations(false)`. ---@return table function debug.allocinfo() end diff --git a/engine/Sim/CUnitScriptTask.lua b/engine/Sim/CUnitScriptTask.lua index c8b9796fc9..b56e80856e 100644 --- a/engine/Sim/CUnitScriptTask.lua +++ b/engine/Sim/CUnitScriptTask.lua @@ -3,13 +3,15 @@ ---@class moho.ScriptTask_Methods local CUnitScriptTask = {} ---- --- Set the AI result, success or fail -function CUnitScriptTask:SetAIResult() +--- Set the AI result, success (1) or fail (2) +---@param result +---| 1 # Success: Successfully carried out the order. +---| 2 # Fail: Failed to carry out the order. +function CUnitScriptTask:SetAIResult(result) end ---- --- +--- Get the unit this task was ordered to. +---@return Unit function CUnitScriptTask:GetUnit() end diff --git a/engine/User.lua b/engine/User.lua index ef83854aaf..cf421068fa 100644 --- a/engine/User.lua +++ b/engine/User.lua @@ -602,10 +602,37 @@ end function GetUnitCommandDataOfUnit(unit) end ---- Givens a `RULEUCC` type command, return the equivalent `UNITCOMMAND` command. ---- See `/lua/ui/game/commandgraphparams.lua#CommandGraphParams`. ----@param rule CommandCap ----@return string +--- Given a `RULEUCC` type command, return the equivalent `UNITCOMMAND` command or "None" otherwise. +--- See `/lua/ui/game/commandgraphparams.lua#CommandGraphParams` or `UserUnitCommand`. +--[[``` + RULEUCC_Move = Move + RULEUCC_Stop = Stop + RULEUCC_Attack = Attack + RULEUCC_Guard = Guard + RULEUCC_Patrol = Patrol + RULEUCC_RetaliateToggle = None + RULEUCC_Repair = Repair + RULEUCC_Capture = Capture + RULEUCC_Transport = TransportUnloadUnits + RULEUCC_CallTransport = TransportLoadUnits + RULEUCC_Nuke = Nuke + RULEUCC_Tactical = Tactical + RULEUCC_Teleport = Teleport + RULEUCC_Ferry = Ferry +RULEUCC_SiloBuildTactical = BuildSiloTactical + RULEUCC_SiloBuildNuke = BuildSiloNuke + RULEUCC_Sacrifice = Sacrifice + RULEUCC_Pause = Pause + RULEUCC_Overcharge = OverCharge + RULEUCC_Dive = Dive + RULEUCC_Reclaim = Reclaim + RULEUCC_SpecialAction = SpecialAction + RULEUCC_Dock = None + RULEUCC_Script = None + RULEUCC_Invalid = None +```]] +---@param rule EngineCommandCap +---@return string | "None" function GetUnitCommandFromCommandCap(rule) end @@ -810,11 +837,11 @@ end function IssueBlueprintCommandToUnit(unit, command, blueprintid, count, clear) end ---- ----@param command any ----@param string any? +--- Issue a command to the current selection. +---@param command UserUnitCommand # Will crash the game if not a valid command. +---@param luaParams? table | string | number | boolean # Will crash the game if the table contains non-serializable types. ---@param clear boolean? -function IssueCommand(command, string, clear) +function IssueCommand(command, luaParams, clear) end --- @@ -822,12 +849,12 @@ end function IssueDockCommand(clear) end ---- +--- Issue a command to the given units. ---@param unitList UserUnit[] ----@param command string ----@param string? string +---@param command UserUnitCommand # Will crash the game if not a valid command. +---@param luaParams? table | string | number | boolean # Will crash the game if the table contains non-serializable types. ---@param clear? boolean -function IssueUnitCommand(unitList, command, string, clear) +function IssueUnitCommand(unitList, command, luaParams, clear) end --- Given a MS Windows char code, returns the Maui char code diff --git a/engine/User/UserUnit.lua b/engine/User/UserUnit.lua index 4f7d4c8e17..e310abd174 100644 --- a/engine/User/UserUnit.lua +++ b/engine/User/UserUnit.lua @@ -6,49 +6,71 @@ local UserUnit = {} ---@alias UserUnitCommand ---- | 'UNITCOMMAND_BuildFactory' ---- | 'UNITCOMMAND_BuildSilo' ---- | 'UNITCOMMAND_DestroySelf' ---- | 'UNITCOMMAND_KillSelf' ---- | 'UNITCOMMAND_AssistCommander' ---- | 'UNITCOMMAND_Upgrade' ---- | 'UNITCOMMAND_Land' ---- | 'UNITCOMMAND_Stop' ---- | 'UNITCOMMAND_Dive' ---- | 'UNITCOMMAND_OverCharge' ---- | 'UNITCOMMAND_Sacrifice' ---- | 'UNITCOMMAND_Capture' ---- | 'UNITCOMMAND_Dock' ---- | 'UNITCOMMAND_Repair' ---- | 'UNITCOMMAND_Reclaim' ---- | 'UNITCOMMAND_Guard' ---- | 'UNITCOMMAND_BuildMobile' ---- | 'UNITCOMMAND_BuildAssist' ---- | 'UNITCOMMAND_Teleport' ---- | 'UNITCOMMAND_Ferry' ---- | 'UNITCOMMAND_AssistMove' ---- | 'UNITCOMMAND_DetachFromTransport' ---- | 'UNITCOMMAND_TransportUnloadSpecificUnits' ---- | 'UNITCOMMAND_TransportUnloadUnits' ---- | 'UNITCOMMAND_TransportReverseLoadUnits' ---- | 'UNITCOMMAND_TransportLoadUnits' ---- | 'UNITCOMMAND_FormPatrol' ---- | 'UNITCOMMAND_Patrol' ---- | 'UNITCOMMAND_CoordinatedMove' ---- | 'UNITCOMMAND_FormMove' ---- | 'UNITCOMMAND_Move' ---- | 'UNITCOMMAND_Nuke' ---- | 'UNITCOMMAND_FormAggressiveMove' ---- | 'UNITCOMMAND_AggressiveMove' ---- | 'UNITCOMMAND_Script' ---- | 'UNITCOMMAND_Tactical' ---- | 'UNITCOMMAND_FormAttack' ---- | 'UNITCOMMAND_Retaliate' ---- | 'UNITCOMMAND_Attack' +---| "UNITCOMMAND_BuildFactory" +---| "UNITCOMMAND_BuildSilo" +---| "UNITCOMMAND_DestroySelf" +---| "UNITCOMMAND_KillSelf" +---| "UNITCOMMAND_AssistCommander" +---| "UNITCOMMAND_Upgrade" +---| "UNITCOMMAND_Land" +---| "UNITCOMMAND_Stop" +---| "UNITCOMMAND_Dive" +---| "UNITCOMMAND_OverCharge" +---| "UNITCOMMAND_Sacrifice" +---| "UNITCOMMAND_Capture" +---| "UNITCOMMAND_Dock" +---| "UNITCOMMAND_Repair" +---| "UNITCOMMAND_Reclaim" +---| "UNITCOMMAND_Guard" +---| "UNITCOMMAND_BuildMobile" +---| "UNITCOMMAND_BuildAssist" +---| "UNITCOMMAND_Teleport" +---| "UNITCOMMAND_Ferry" +---| "UNITCOMMAND_AssistMove" +---| "UNITCOMMAND_DetachFromTransport" # Does nothing? +---| "UNITCOMMAND_TransportUnloadSpecificUnits" +---| "UNITCOMMAND_TransportUnloadUnits" +---| "UNITCOMMAND_TransportReverseLoadUnits" +---| "UNITCOMMAND_TransportLoadUnits" +---| "UNITCOMMAND_FormPatrol" +---| "UNITCOMMAND_Patrol" +---| "UNITCOMMAND_CoordinatedMove" +---| "UNITCOMMAND_FormMove" +---| "UNITCOMMAND_Move" +---| "UNITCOMMAND_Nuke" +---| "UNITCOMMAND_FormAggressiveMove" +---| "UNITCOMMAND_AggressiveMove" +---| "UNITCOMMAND_Script" +---| "UNITCOMMAND_Tactical" +---| "UNITCOMMAND_FormAttack" +---| "UNITCOMMAND_Retaliate" +---| "UNITCOMMAND_Attack" +---| "Move" +---| "Stop" +---| "Attack" +---| "Guard" +---| "Patrol" +---| "Repair" +---| "Capture" +---| "TransportUnloadUnits" +---| "TransportLoadUnits" +---| "Nuke" +---| "Tactical" +---| "Teleport" +---| "Ferry" +---| "BuildSiloTactical" +---| "BuildSiloNuke" +---| "Sacrifice" +---| "Pause" +---| "OverCharge" +---| "Dive" +---| "Reclaim" +---| "SpecialAction" +---| "None" ---@alias UserUnitBlueprintCommand ---- | 'UNITCOMMAND_Upgrade' ---- | 'UNITCOMMAND_BuildFactory' +---| "UNITCOMMAND_Upgrade" +---| "UNITCOMMAND_BuildFactory" ---@class UICommandInfo ---@field type 'Teleport' | 'Move' | string diff --git a/lua/RemoteViewing.lua b/lua/RemoteViewing.lua index 4cdceb093a..73929fd487 100644 --- a/lua/RemoteViewing.lua +++ b/lua/RemoteViewing.lua @@ -7,11 +7,29 @@ --** --** Copyright © 2007 Gas Powered Games, Inc. All rights reserved. --**************************************************************************** + local VizMarker = import("/lua/sim/vizmarker.lua").VizMarker -- TODO: make sure each new instance is using a previous metatable + +-- TODO: Fix the RemoteViewingUnit class annotation always taking definitions from the Unit class instead of the base class. + +---@class RemoteViewingData +---@field RemoteViewingFunctions table +---@field DisableCounter number +---@field IntelButton boolean +---@field Satellite VizMarker +---@field PendingVisibleLocation Vector +---@field VisibleLocation Vector + +---@generic T: Unit +---@param SuperClass T | Unit +---@return T | RemoteViewingUnit function RemoteViewing(SuperClass) + ---@class RemoteViewingUnit: Unit + ---@field RemoteViewingData RemoteViewingData return Class(SuperClass) { + ---@param self RemoteViewingUnit OnCreate = function(self) SuperClass.OnCreate(self) self.RemoteViewingData = {} @@ -20,12 +38,19 @@ function RemoteViewing(SuperClass) self.RemoteViewingData.IntelButton = true end, - OnStopBeingBuilt = function(self,builder,layer) + ---@param self RemoteViewingUnit + ---@param builder Unit + ---@param layer Layer + OnStopBeingBuilt = function(self, builder, layer) self.Sync.Abilities = self:GetBlueprint().Abilities self:SetMaintenanceConsumptionInactive() - SuperClass.OnStopBeingBuilt(self,builder,layer) + SuperClass.OnStopBeingBuilt(self, builder, layer) end, + ---@param self RemoteViewingUnit + ---@param instigator Unit + ---@param type DamageType + ---@param overkillRatio number OnKilled = function(self, instigator, type, overkillRatio) SuperClass.OnKilled(self, instigator, type, overkillRatio) if self.RemoteViewingData.Satellite then @@ -34,18 +59,21 @@ function RemoteViewing(SuperClass) self:SetMaintenanceConsumptionInactive() end, + ---@param self RemoteViewingUnit DisableRemoteViewingButtons = function(self) self.Sync.Abilities = self:GetBlueprint().Abilities self.Sync.Abilities.TargetLocation.Active = false self:RemoveToggleCap('RULEUTC_IntelToggle') end, + ---@param self RemoteViewingUnit EnableRemoteViewingButtons = function(self) self.Sync.Abilities = self:GetBlueprint().Abilities self.Sync.Abilities.TargetLocation.Active = true self:AddToggleCap('RULEUTC_IntelToggle') end, + ---@param self RemoteViewingUnit TargetLocationThread = function(self) local Cost = CreateEconomyEvent(self, self:GetBlueprint().Economy.InitialRemoteViewingEnergyDrain * (self.EnergyMaintAdjMod or 1), 0, 1, self.SetWorkProgress) WaitFor(Cost) @@ -57,6 +85,8 @@ function RemoteViewing(SuperClass) self:CreateVisibleEntity() end, + ---@param self RemoteViewingUnit + ---@param location Vector OnTargetLocation = function(self, location) if self.RemoteViewingData.PendingVisibleLocation then self.RemoteViewingData.PendingVisibleLocation = location @@ -65,7 +95,8 @@ function RemoteViewing(SuperClass) self:ForkThread(self.TargetLocationThread) end end, - + + ---@param self RemoteViewingUnit CreateVisibleEntity = function(self) -- Only give a visible area if we have a location and intel button enabled if not self.RemoteViewingData.VisibleLocation then @@ -94,7 +125,7 @@ function RemoteViewing(SuperClass) else -- Move and reactivate old visible area if not self.RemoteViewingData.Satellite:BeenDestroyed() then - Warp( self.RemoteViewingData.Satellite, self.RemoteViewingData.VisibleLocation ) + Warp(self.RemoteViewingData.Satellite, self.RemoteViewingData.VisibleLocation) self.RemoteViewingData.Satellite:EnableIntel('Omni') self.RemoteViewingData.Satellite:EnableIntel('Radar') self.RemoteViewingData.Satellite:EnableIntel('Vision') @@ -109,6 +140,7 @@ function RemoteViewing(SuperClass) end end, + ---@param self RemoteViewingUnit DisableVisibleEntity = function(self) -- visible entity already off if self.RemoteViewingData.DisableCounter > 1 then return end @@ -121,6 +153,8 @@ function RemoteViewing(SuperClass) end end, + ---@param self RemoteViewingUnit + ---@param intel IntelType OnIntelEnabled = function(self, intel) -- Make sure the button is only calculated once rather than once per possible intel type if not self.RemoteViewingData.IntelButton then @@ -131,6 +165,8 @@ function RemoteViewing(SuperClass) SuperClass.OnIntelEnabled(self, intel) end, + ---@param self RemoteViewingUnit + ---@param intel IntelType OnIntelDisabled = function(self, intel) -- make sure button is only calculated once rather than once per possible intel type if self.RemoteViewingData.IntelButton then @@ -141,6 +177,7 @@ function RemoteViewing(SuperClass) SuperClass.OnIntelDisabled(self, intel) end, + ---@param self RemoteViewingUnit DisableResourceMonitor = function(self) WaitSeconds(0.5) local fraction = self:GetResourceConsumed() @@ -155,6 +192,7 @@ function RemoteViewing(SuperClass) end end, + ---@param self RemoteViewingUnit EnableResourceMonitor = function(self) local recharge = self:GetBlueprint().Intel.ReactivateTime or 10 WaitSeconds(recharge) diff --git a/lua/abilitydefinition.lua b/lua/abilitydefinition.lua index 3eab0271ba..459ea33c34 100644 --- a/lua/abilitydefinition.lua +++ b/lua/abilitydefinition.lua @@ -2,6 +2,10 @@ -- Ability Definitions -- +--- Defines the default behavior of ability buttons in `orders.lua` for each `ScriptTask`'s `TaskName`. +--- The `OrderInfo` here has the `OrderInfo` of `UnitBlueprint.Abilities` merged onto it. +--- The `OrderInfo.behavior` is overwritten in `orders.lua`. +---@type table abilities = { ['TargetLocation'] = { preferredSlot = 8, diff --git a/lua/sim/ScriptTask.lua b/lua/sim/ScriptTask.lua index 55b3075d4c..56f2bec7d2 100644 --- a/lua/sim/ScriptTask.lua +++ b/lua/sim/ScriptTask.lua @@ -4,70 +4,83 @@ --* Copyright © 2008 Gas Powered Games, Inc. All rights reserved. --***************************************************************************** --- Task status values returned from TaskTick(). Note that an integer cast to --- ETaskStatus means to wait that many ticks before returning. TASKSTATUS_Repeat --- is equivalent to waiting 0 ticks. Do not modify this as this is a reflection of --- the internal task codes used by the engine. +-- Task status values returned from TaskTick(). Do not modify this as this is a reflection of the internal task codes used by the engine. +---@alias ScriptTaskStatus +---| -1 # Done: The task is destroyed and then the unit proceeds to the next command. +---| -2 # Suspend: the thread is suspended but there is no way implemented to resume it? +---| -3 # Abort: "kill all tasks on this thread". Not implemented, usage will cause the unit to be stuck on the command. +---| -4 # Delay: move task to end of this tick's task queue. There is no way to have multiple tasks per tick? +---| 0 # Repeat execution immediately. +---| 1+ # 1+: The task waits the given number of ticks. For example, the value `3` means the task waits for three ticks. +---| number + +--- Task status values returned from TaskTick(). Do not modify this as this is a reflection of the internal task codes used by the engine. TASKSTATUS = { - -- Task has completed and can be removed from the task stack; it will be - -- popped and deleted automatically. Execution will immediately continue - -- with the task's parent. - -- You can also use TASKSTATUS_Done to do a tail call, by first pushing - -- the task to switch to and then returning TASKSTATUS_Done. + ---"Task has completed and can be removed from the task stack; it will be + --- popped and deleted automatically. Execution will immediately continue + --- with the task's parent. + --- You can also use TASKSTATUS_Done to do a tail call, by first pushing + --- the task to switch to and then returning TASKSTATUS_Done." - Seems unimplemented. + + ---The task counts as completed and is destroyed by the engine. Then the unit proceeds to the next command in the command queue. Done = -1, - -- move task's thread onto >ed list; some external event will - -- reactivate it. + --- The task's thread suspends, but there is no implementation to resume it? + --- The unit waits forever on the command but the command can be cleared manually to resume the unit. Suspend = -2, - -- kill all tasks on this thread + --- The task aborts: "kill all tasks on this thread". + --- Not implemented, usage will cause the unit to be stuck on the command. Abort = -3, - -- reschedule the ticking of this task until the rest of the tasks have been - -- ticked (puts it at the end of the list) + --- The task delays: It is moved to the end of the this tick's task queue and is executed after all other tasks. + --- There is no way to have multiple tasks in 1 tick? Delay = -4, - -- task needs to repeat execution immediately, usually caused by a change - -- in the task stack + --- The task repeats and executes immediately again. + --- You can use this right after changing the state of a task. Repeat = 0, - -- Task is done with its execution for this tick, but should be called back - -- on the next tick. + --- The task waits the given number of ticks. For example, the value `3` means the task waits for three ticks. Wait = 1, - - -- Returning a number greater than TASKSTATUS_Wait incdicates an additional - -- number of ticks to wait. For example: - -- return TASKSTATUS_Wait + 3 - -- This indicates a wait of 4 ticks. } +---@alias ScriptTaskAIResult +---| 0 # Unknown: The unit is performing the task. +---| 1 # Success: The unit succesfully completed the task. +---| 2 # Fail: The unit failed to carry out the order. +---| 3 # Ignored: The unit is unable to carry out the order. + +--- Task results for ScriptTask:SetAIResult(). Do not modify this as this is a reflection of +--- the internal task codes used by the engine. AIRESULT = { - -- Command in progress; result has not been set yet - Unknown=0, + -- The unit is performing the task. + Unknown = 0, - -- Successfully carried out the order. - Success=1, + -- The unit succesfully completed the task. + Success = 1, - -- Failed to carry out the order. - Fail=2, + -- The unit failed to carry out the order. + Fail = 2, - -- The order made no sense for this type of unit, and was ignored. - Ignored=3, + -- The unit is unable to carry out the order. + Ignored = 3, } ---@class ScriptTask : moho.ScriptTask_Methods +---@field CommandData { TaskName: string } | table # LuaParams table from the user side. This table is shared by all units ordered the task from one command. ScriptTask = Class(moho.ScriptTask_Methods) { - -- Called immediately when task is created + --- Called immediately when task is created ---@param self ScriptTask - ---@param commandData any - OnCreate = function(self,commandData) + ---@param commandData { TaskName: string } | table # LuaParams table from the user side. This table is shared by all units ordered the task from one command. + OnCreate = function(self, commandData) self.CommandData = commandData end, - -- Called by the engine every tick. Function must return a value in TaskStatus + --- Called by the engine at an interval determined by the returned TaskStatus value ---@param self ScriptTask - ---@return integer + ---@return ScriptTaskStatus TaskTick = function(self) LOG('tick') self:SetAIResult(AIRESULT.Fail) @@ -75,8 +88,8 @@ ScriptTask = Class(moho.ScriptTask_Methods) { return TASKSTATUS.Done end, - -- Called by the engine when the task is destroyed. This could be it naturally going away after completion or because it was cancelled by another task. + --- Called by the engine when the task is destroyed. This could be it naturally going away after completion or because it was cancelled by another task. ---@param self ScriptTask OnDestroy = function(self) end, -} \ No newline at end of file +} diff --git a/lua/sim/Unit.lua b/lua/sim/Unit.lua index 2537e59a22..94503d4e40 100644 --- a/lua/sim/Unit.lua +++ b/lua/sim/Unit.lua @@ -147,6 +147,7 @@ local cUnitGetBuildRate = cUnit.GetBuildRate ---@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 +---@field Sync { id: string, army: Army } # Sync table replicated to the global sync table as to be copied to the user layer at sync time. Unit = ClassUnit(moho.unit_methods, IntelComponent, VeterancyComponent, DebugUnitComponent) { IsUnit = true, diff --git a/lua/sim/tasks/AttackMove.lua b/lua/sim/tasks/AttackMove.lua index 0181e21ccc..bfab9f6211 100644 --- a/lua/sim/tasks/AttackMove.lua +++ b/lua/sim/tasks/AttackMove.lua @@ -3,17 +3,20 @@ --* --* Dummy task for the Attack Move button --***************************************************************************** + local ScriptTask = import("/lua/sim/scripttask.lua").ScriptTask local TASKSTATUS = import("/lua/sim/scripttask.lua").TASKSTATUS local AIRESULT = import("/lua/sim/scripttask.lua").AIRESULT ----@class AttackMove : ScriptTask +---@class AttackMoveTask : ScriptTask +---@field CommandData { TaskName: "AttackMove" } # LuaParams table from the user side. This table is shared by all units ordered the task from one command. AttackMove = Class(ScriptTask) { - ---@param self AttackMove - ---@return integer + -- Called by the engine every tick. Function must return a value in TaskStatus + ---@param self AttackMoveTask + ---@return ScriptTaskStatus TaskTick = function(self) self:SetAIResult(AIRESULT.Success) return TASKSTATUS.Done end, -} \ No newline at end of file +} diff --git a/lua/sim/tasks/EnhanceTask.lua b/lua/sim/tasks/EnhanceTask.lua index f6bf4be8fa..ae2a86bf2d 100644 --- a/lua/sim/tasks/EnhanceTask.lua +++ b/lua/sim/tasks/EnhanceTask.lua @@ -3,28 +3,31 @@ --* --* Copyright Š 2008 Gas Powered Games, Inc. All rights reserved. --***************************************************************************** + local ScriptTask = import("/lua/sim/scripttask.lua").ScriptTask local TASKSTATUS = import("/lua/sim/scripttask.lua").TASKSTATUS local AIRESULT = import("/lua/sim/scripttask.lua").AIRESULT ---@class EnhanceTask : ScriptTask +---@field CommandData { TaskName: "EnhanceTask", Enhancement: Enhancement } # LuaParams table from the user side. This table is shared by all units ordered the task from one command. +---@field Success? boolean # Whether or not the upgrade finished building EnhanceTask = Class(ScriptTask) { ---@param self EnhanceTask - ---@param commandData any - OnCreate = function(self,commandData) - ScriptTask.OnCreate(self,commandData) + ---@param commandData { TaskName: "EnhanceTask", Enhancement: Enhancement } # LuaParams table from the user side. This table is shared by all units ordered the task from one command. + OnCreate = function(self, commandData) + ScriptTask.OnCreate(self, commandData) self:GetUnit():SetWorkProgress(0.0) - self:GetUnit():SetUnitState('Enhancing',true) - self:GetUnit():SetUnitState('Upgrading',true) + self:GetUnit():SetUnitState('Enhancing', true) + self:GetUnit():SetUnitState('Upgrading', true) self.LastProgress = 0 ChangeState(self, self.Stopping) end, ---@param self EnhanceTask OnDestroy = function(self) - self:GetUnit():SetUnitState('Enhancing',false) - self:GetUnit():SetUnitState('Upgrading',false) + self:GetUnit():SetUnitState('Enhancing', false) + self:GetUnit():SetUnitState('Upgrading', false) self:GetUnit():SetWorkProgress(0.0) if self.Success then self:SetAIResult(AIRESULT.Success) @@ -35,6 +38,9 @@ EnhanceTask = Class(ScriptTask) { end, Stopping = State { + --- Called by the engine at an interval determined by the returned TaskStatus value + ---@param self EnhanceTask + ---@return ScriptTaskStatus TaskTick = function(self) local unit = self:GetUnit() @@ -45,7 +51,7 @@ EnhanceTask = Class(ScriptTask) { -- check if enhancement was started (not restricted and met prerequisite) local workStarted = unit:OnWorkBegin(self.CommandData.Enhancement) if not workStarted then - self.Success = false -- required for AI notification + self.Success = false -- required for AI notification return TASKSTATUS.Done -- not using Abort because it will freeze the unit else ChangeState(self, self.Enhancing) @@ -56,6 +62,9 @@ EnhanceTask = Class(ScriptTask) { }, Enhancing = State { + --- Called by the engine at an interval determined by the returned TaskStatus value + ---@param self EnhanceTask + ---@return ScriptTaskStatus TaskTick = function(self) local unit = self:GetUnit() local current = unit.WorkProgress @@ -69,16 +78,16 @@ EnhanceTask = Class(ScriptTask) { end end - if((self.LastProgress < 0.25 and current >= 0.25) or + if ((self.LastProgress < 0.25 and current >= 0.25) or (self.LastProgress < 0.50 and current >= 0.50) or (self.LastProgress < 0.75 and current >= 0.75)) then - unit:OnBuildProgress(self.LastProgress,current) + unit:OnBuildProgress(self.LastProgress, current) end self.LastProgress = current unit:SetWorkProgress(current) - if(current < 1.0) then + if (current < 1.0) then return TASKSTATUS.Wait end @@ -93,4 +102,4 @@ EnhanceTask = Class(ScriptTask) { return TASKSTATUS.Done end, }, -} \ No newline at end of file +} diff --git a/lua/sim/tasks/GiveTask.lua b/lua/sim/tasks/GiveTask.lua index 6ada40b489..20950f1e37 100644 --- a/lua/sim/tasks/GiveTask.lua +++ b/lua/sim/tasks/GiveTask.lua @@ -3,12 +3,17 @@ local TASKSTATUS = import("/lua/sim/scripttask.lua").TASKSTATUS local GiveUnitsToPlayer = import("/lua/simutils.lua").GiveUnitsToPlayer local SpawnPing = import("/lua/simping.lua").SpawnPing -local transferList = {} +local transferList = {} + ---@class GiveTask : ScriptTask +---@field CommandData { TaskName: "GiveTask", To: Army } # LuaParams table from the user side. This table is shared by all units ordered the task from one command. +---@field Army Army +---@field first boolean GiveTask = Class(ScriptTask) { + --- Called immediately when task is created ---@param self GiveTask - ---@param commandData any + ---@param commandData { TaskName: "GiveTask", To: Army } # LuaParams table from the user side. This table is shared by all units ordered the task from one command. OnCreate = function(self, commandData) ScriptTask.OnCreate(self, commandData) @@ -25,8 +30,9 @@ GiveTask = Class(ScriptTask) { self.first = true end, + --- Called by the engine at an interval determined by the returned TaskStatus value ---@param self GiveTask - ---@return integer + ---@return ScriptTaskStatus TaskTick = function(self) if self.first then -- Wait a tick to let all GiveTask commands execute @@ -43,20 +49,20 @@ GiveTask = Class(ScriptTask) { end if units[1] then - GiveUnitsToPlayer({To=to}, units) + GiveUnitsToPlayer({ To = to }, units) local data = { - Type='alert', - Location=units[1]:GetPosition(), - Lifetime=10, - Owner=self.Army, - To=to, - Ring='/game/marker/ring_yellow02-blur.dds', - Sound='UEF_Select_Radar', - Mesh='alert_marker', - ArrowColor='yellow', + Type = 'alert', + Location = units[1]:GetPosition(), + Lifetime = 10, + Owner = self.Army, + To = to, + Ring = '/game/marker/ring_yellow02-blur.dds', + Sound = 'UEF_Select_Radar', + Mesh = 'alert_marker', + ArrowColor = 'yellow', } SpawnPing(data) - end + end end transferList[self.Army] = {} @@ -65,4 +71,4 @@ GiveTask = Class(ScriptTask) { } -- imports kept for backwards compatibility with mods -local AIRESULT = import("/lua/sim/scripttask.lua").AIRESULT \ No newline at end of file +local AIRESULT = import("/lua/sim/scripttask.lua").AIRESULT diff --git a/lua/sim/tasks/TargetLocation.lua b/lua/sim/tasks/TargetLocation.lua index a8f62517f3..141888fb8b 100644 --- a/lua/sim/tasks/TargetLocation.lua +++ b/lua/sim/tasks/TargetLocation.lua @@ -3,30 +3,35 @@ --* --* Copyright © 2008 Gas Powered Games, Inc. All rights reserved. --***************************************************************************** + local ScriptTask = import("/lua/sim/scripttask.lua").ScriptTask local TASKSTATUS = import("/lua/sim/scripttask.lua").TASKSTATUS local AIRESULT = import("/lua/sim/scripttask.lua").AIRESULT ----@class TargetLocation : ScriptTask +---@class TargetLocationTask : ScriptTask +---@field CommandData { TaskName: "TargetLocation", UserValidated: boolean, Location: Vector } # LuaParams table from `UserScriptCommand`. This table is shared by all units ordered the task from one command. +---@field GetUnit fun(self: TargetLocationTask): RemoteViewingUnit TargetLocation = Class(ScriptTask) { - ---@param self TargetLocation - ---@param commandData table - OnCreate = function(self,commandData) - ScriptTask.OnCreate(self,commandData) - local unit = self:GetUnit():OnTargetLocation(commandData.Location) + --- Called immediately when task is created + ---@param self TargetLocationTask + ---@param commandData { TaskName: "TargetLocation", UserValidated: boolean, Location: Vector } # LuaParams table from `UserScriptCommand`. This table is shared by all units ordered the task from one command. + OnCreate = function(self, commandData) + ScriptTask.OnCreate(self, commandData) + self:GetUnit():OnTargetLocation(commandData.Location) end, - ---@param self TargetLocation - ---@return number + --- Called by the engine at an interval determined by the returned TaskStatus value + ---@param self TargetLocationTask + ---@return ScriptTaskStatus TaskTick = function(self) self:SetAIResult(AIRESULT.Success) return TASKSTATUS.Done end, - ---@param self TargetLocation - ---@return boolean + ---@param self TargetLocationTask + ---@return true IsInRange = function(self) return true end, -} \ No newline at end of file +} diff --git a/lua/system/utils.lua b/lua/system/utils.lua index 4b108ed8ed..aeeafd7006 100644 --- a/lua/system/utils.lua +++ b/lua/system/utils.lua @@ -176,13 +176,18 @@ function table.deepcopy(t,backrefs) end end ---- table.merged(t1,t2) returns a table in which fields from t2 overwrite ---- fields from t1. Neither t1 nor t2 is modified. The returned table may ---- share structure with either t1 or t2, so it is not safe to modify. --- e.g. t1 = { x=1, y=2, sub1={z=3}, sub2={w=4} } --- t2 = { y=5, sub1={a=6}, sub2="Fred" } --- merged(t1,t2) -> { x=1, y=5, sub1={a=6,z=3}, sub2="Fred" } --- merged(t2,t1) -> { x=1, y=2, sub1={a=6,z=3}, sub2={w=4} } +--- Overwrites fields in t1 with fields from t2, and returns t1. +--- The returned table may share structure with t2, so it is not safe to modify. +--- For example: +--- ```lua +--- t1 = { x=1, y=2, sub1={z=3}, sub2={w=4} } +--- t2 = { y=5, sub1={a=6}, sub2="Fred" } +--- merged(t2,t1) -> t1: { x=1, y=2, sub1={a=6,z=3}, sub2={w=4} } +--- merged(t1,t2) -> t1: { x=1, y=5, sub1={a=6,z=3}, sub2="Fred" } +--- ``` +---@param t1 table +---@param t2 table # Overwrites t1 +---@return table function table.merged(t1, t2) if t1==t2 then diff --git a/lua/ui/game/commandmode.lua b/lua/ui/game/commandmode.lua index f893caf6ad..c59db097eb 100644 --- a/lua/ui/game/commandmode.lua +++ b/lua/ui/game/commandmode.lua @@ -6,6 +6,7 @@ --* --* Copyright © 2005 Gas Powered Games, Inc. All rights reserved. --***************************************************************************** + local commandMeshResources = import("/lua/ui/game/commandmeshes.lua").commandMeshResources local Prefs = import("/lua/user/prefs.lua") @@ -96,7 +97,7 @@ local MathAtan = math.atan ---@class CommandModeDataBase ---@field cursor? CommandCap # Similar to the field 'name' ----@field altCursor string # Allows for an alternative cursor +---@field altCursor? string # Allows for an alternative cursor ---@class CommandModeDataOrder : CommandModeDataBase ---@field name CommandCap @@ -107,7 +108,10 @@ local MathAtan = math.atan ---@class CommandModeDataBuildAnchored : CommandModeDataBase ----@alias CommandModeData CommandModeDataOrder | CommandModeDataBuild | CommandModeDataBuildAnchored | false +---@class CommandModeDataOrderScript : CommandModeDataOrder +---@field TaskName string + +---@alias CommandModeData CommandModeDataOrder | CommandModeDataOrderScript | CommandModeDataBuild | CommandModeDataBuildAnchored | false ---@type CommandMode local cachedCommandMode = false diff --git a/lua/user/UserScriptCommand.lua b/lua/user/UserScriptCommand.lua index d3024ec6a4..820cd9d5fe 100644 --- a/lua/user/UserScriptCommand.lua +++ b/lua/user/UserScriptCommand.lua @@ -4,6 +4,7 @@ --* --* Copyright © 2008 Gas Powered Games, Inc. All rights reserved. --***************************************************************************** + local CM = import("/lua/ui/game/commandmode.lua") -- The user wants to issue an ability order in the current command mode. This @@ -18,25 +19,30 @@ local CM = import("/lua/ui/game/commandmode.lua") -- bool UserValidated - Whether or not this request has been validated -- table AuthorizedUnits - List of units to issue the command to -- } + +--- Called by the engine whenever a `RULEUCC_Script` order is issued with a target through command mode. +--- The return value overwrites the lua params table passed to the ScriptTask script sim-side, except for the field `AuthorizedUnits`, which is interpreted by the engine instead of being passed. +---@param data UserCommand +---@return { TaskName: string, UserValidated: boolean, Location: Vector, AuthorizedUnits: UserUnit[] } result function VerifyScriptCommand(data) local mode = CM.GetCommandMode() - + local result = { TaskName = mode[2].TaskName, UserValidated = false, Location = data.Target.Position } - + if mode[1] != "order" then WARN('VerifyScriptCommand() called when command mode is not "order"') return result end - + if mode[2].name != "RULEUCC_Script" then WARN('VerifyScriptCommand() called when command name is not "Script"') return result end - + --LOG('verify script: ',mode[2].UserVerifyScript) if mode[2].UserVerifyScript then import(mode[2].UserVerifyScript).VerifyScriptCommand(data,result) @@ -44,6 +50,6 @@ function VerifyScriptCommand(data) result.AuthorizedUnits = data.Units result.UserValidated = true end - + return result end diff --git a/units/XAB3301/XAB3301_script.lua b/units/XAB3301/XAB3301_script.lua index f64a26bf34..9a1cac7231 100644 --- a/units/XAB3301/XAB3301_script.lua +++ b/units/XAB3301/XAB3301_script.lua @@ -7,16 +7,26 @@ --** --** Copyright © 2007 Gas Powered Games, Inc. All rights reserved. --**************************************************************************** + local AStructureUnit = import("/lua/aeonunits.lua").AStructureUnit local AQuantumGateAmbient = import("/lua/effecttemplates.lua").AQuantumGateAmbient -- Setup as RemoteViewing child of AStructureUnit local RemoteViewing = import("/lua/remoteviewing.lua").RemoteViewing -AStructureUnit = RemoteViewing( AStructureUnit ) - -XAB3301 = ClassUnit( AStructureUnit ) { - +---@diagnostic disable-next-line: cast-local-type +AStructureUnit = RemoteViewing(AStructureUnit) + +---@class XAB3301: AStructureUnit, RemoteViewingUnit +---@field Animator moho.AnimationManipulator +---@field RotatorBot moho.RotateManipulator +---@field RotatorTop moho.RotateManipulator +---@field TrashAmbientEffects TrashBag +---@field ScryEnabled boolean +XAB3301 = ClassUnit(AStructureUnit) { + ---@param self XAB3301 + ---@param builder Unit + ---@param layer Layer OnStopBeingBuilt = function(self, builder, layer) AStructureUnit.OnStopBeingBuilt(self, builder, layer) @@ -35,20 +45,21 @@ XAB3301 = ClassUnit( AStructureUnit ) { self.TrashAmbientEffects = TrashBag() end, + ---@param self XAB3301 CreateVisibleEntity = function(self) AStructureUnit.CreateVisibleEntity(self) if self.RemoteViewingData.VisibleLocation and self.RemoteViewingData.DisableCounter == 0 and self.RemoteViewingData.IntelButton then - if self.ScryEnabled then + if self.ScryEnabled then CreateLightParticle(self, "spin02", self.Army, 1, 20, 'glow_02', 'ramp_blue_16') - else + else CreateLightParticle(self, "spin02", self.Army, 10, 20, 'glow_02', 'ramp_blue_22') end if not self.ScryEnabled then - self.ScryEnabled = true - + self.ScryEnabled = true + self.Animator:SetRate(1) self.RotatorBot:SetTargetSpeed(12) self.RotatorTop:SetTargetSpeed(-8) @@ -61,6 +72,7 @@ XAB3301 = ClassUnit( AStructureUnit ) { end, + ---@param self XAB3301 DisableVisibleEntity = function(self) AStructureUnit.DisableVisibleEntity(self) @@ -69,8 +81,8 @@ XAB3301 = ClassUnit( AStructureUnit ) { self.RotatorTop:SetTargetSpeed(-4) self.TrashAmbientEffects:Destroy() - self.ScryEnabled = false + self.ScryEnabled = false end, } -TypeClass = XAB3301 \ No newline at end of file +TypeClass = XAB3301