Compare commits

...

3 Commits

Author SHA1 Message Date
1be066c6ed Major refactor to include tactical combat feed 2026-03-10 23:05:20 -05:00
16b70204a1 Amend 2026-03-10 19:14:24 -05:00
487a5259fb Add Tutorial Text API 2026-03-10 19:12:38 -05:00
15 changed files with 788 additions and 369 deletions

View File

@@ -921,7 +921,7 @@ function PlayerObject.Release_Credits_For_Tactical(amount) end
---@param level number ---@param level number
function PlayerObject.Set_Tech_Level(level) end function PlayerObject.Set_Tech_Level(level) end
---@class PlanetObject ---@class PlanetObject : GameObject
local PlanetObject = {} local PlanetObject = {}
---@public ---@public
---@return boolean ---@return boolean

View File

@@ -24,6 +24,8 @@ function Get_All_Players() end
---@public ---@public
---Adds the specified text to the tutorial text box. ---Adds the specified text to the tutorial text box.
---A new text key will be appended as a new line.
---An existing text key will be overwritten.
---@param key string The key to use. ---@param key string The key to use.
---@param text string The text to add. ---@param text string The text to add.
---@param duration number The duration to keep text on screen, defaults to -1 (infinite). ---@param duration number The duration to keep text on screen, defaults to -1 (infinite).

View File

@@ -1,4 +1,22 @@
require("GameManager/FactionStruct") require("GameManager/FactionStruct")
require("GameManager/GUIManager")
require("GameManager/TutorialTextManager")
-- ==================================================
-- Define Manager constants
-- ==================================================
---The singleton GUI Manager.
---@type GUIManager
GUIManager = GUIManager:New()
---The singleton Tutorial Text Manager.
---@type TutorialTextManager
TextManager = TutorialTextManager:New()
---The local player.
---@type PlayerObject|nil
LocalPlayer = nil
-- ================================================== -- ==================================================
-- Define Faction constants -- Define Faction constants

View File

@@ -1,10 +1,7 @@
require("PGBase") require("PGBase")
require("GameManager/Constants") require("GameManager/Utilities")
---@class GUIManager ---@class GUIManager
---@field TacticalGame TacticalGameClass|nil The local Tactical Game state.
---@field SkirmishGame SkirmishGameClass|nil The local Skirmish Game state.
---@field ShowTeamId integer The Team ID units to display.
GUIManager = {} GUIManager = {}
GUIManager.__index = GUIManager GUIManager.__index = GUIManager
@@ -13,22 +10,15 @@ GUIManager.__index = GUIManager
function GUIManager:New() function GUIManager:New()
local self = setmetatable({}, GUIManager) local self = setmetatable({}, GUIManager)
self.TacticalGame = nil
self.SkirmishGame = nil
self.ShowTeamId = 0
return self return self
end end
---Initializes the GUI Manager for Skirmish mode. ---Initializes the GUI Manager for Skirmish mode.
---@param game SkirmishGameClass The Skirmish Game state. ---@param isSpectator boolean Whether to initialize in spectator mode.
function GUIManager:InitSkirmish(game) function GUIManager:InitSkirmish(isSpectator)
self.SkirmishGame = game self:InitTactical()
self.TacticalGame = game.TacticalGame
GUI_Component_Visibility(UI_GameTime, true) if isSpectator then
if self.SkirmishGame.IsLocalSpectator then
GUI_Component_Visibility(UI_CreditsT1, true) GUI_Component_Visibility(UI_CreditsT1, true)
GUI_Component_Visibility(UI_IconT1, true) GUI_Component_Visibility(UI_IconT1, true)
@@ -41,18 +31,12 @@ function GUIManager:InitSkirmish(game)
end end
---Initializes the GUI Manager for Tactical mode. ---Initializes the GUI Manager for Tactical mode.
---@param game TacticalGameClass The Tactical Game state. function GUIManager:InitTactical()
function GUIManager:InitTactical(game)
self.TacticalGame = game
GUI_Component_Visibility(UI_GameTime, true) GUI_Component_Visibility(UI_GameTime, true)
end end
---Resets the GUI Manager. ---Resets the GUI Manager.
function GUIManager:Reset() function GUIManager:Reset()
self.SkirmishGame = nil
self.TacticalGame = nil
GUI_Component_Text(UI_GameTime, "") GUI_Component_Text(UI_GameTime, "")
GUI_Text_Color(UI_GameTime, 1, 1, 1, 1) GUI_Text_Color(UI_GameTime, 1, 1, 1, 1)
GUI_Component_Visibility(UI_GameTime, false) GUI_Component_Visibility(UI_GameTime, false)
@@ -75,129 +59,43 @@ function GUIManager:Reset()
GUI_Component_Visibility(UI_CreditsTactical, true) GUI_Component_Visibility(UI_CreditsTactical, true)
end end
---Services the GUI Manager.
function GUIManager:Service()
if not self.TacticalGame then
-- Nothing to service
return
end
ScriptMessage("Servicing GUI Updates...")
ServiceGameTime(self.TacticalGame)
ServiceTeamCredits(self.SkirmishGame)
--ServiceUnitDisplay(self.SkirmishGame, self.ShowTeamId)
ServiceScreenText(self.SkirmishGame)
end
---Services Game Time display. ---Services Game Time display.
---@param tacticalGame TacticalGameClass The current Tactical Game state ---@param gameTime number The current game time.
function ServiceGameTime(tacticalGame) function GUIManager:DisplayGameTime(gameTime)
if not tacticalGame then local timeText = FormatTime(gameTime)
return local text = string.format("Time: %s", timeText)
end
local gameTime = Dirty_Floor(GetCurrentTime()) - tacticalGame.StartTime
local minutes = Dirty_Floor(gameTime / 60)
local minutesText = tostring(minutes)
if tonumber(minutes) < 10 then
minutesText = "0" .. minutesText
end
local seconds = gameTime - (minutes * 60)
local secondsText = tostring(seconds)
if tonumber(seconds) < 10 then
secondsText = "0" .. secondsText
end
local text = string.format("Time: %s:%s", minutesText, secondsText)
GUI_Component_Text(UI_GameTime, text) GUI_Component_Text(UI_GameTime, text)
end end
---Services Team Credits display. ---Displays credits for the specified team
---@param skirmishGame SkirmishGameClass The current Skirmish Game state. ---@param team TeamStruct The team.
function ServiceTeamCredits(skirmishGame) ---@param credits number The team credits.
if not skirmishGame then ---@param income number The team income.
function GUIManager:DisplayTeamCredits(team, credits, income)
local uiText, uiIcon = "", ""
if team.Number == 1 then
uiText = UI_CreditsT1
uiIcon = UI_IconT1
elseif team.Number == 2 then
uiText = UI_CreditsT2
uiIcon = UI_IconT2
else
return return
end end
if not skirmishGame.IsLocalSpectator then
return
end
---Displays credits for the specified team
---@param team TeamStruct The team to service.
---@param uiText string The name of the UI Component to display Team credits in.
---@param uiIcon string The name of the UI Component to display the Faction icon in.
local function DisplayTeamCredits(team, uiText, uiIcon)
local teamCredits = skirmishGame:CalculateTeamTotalCredits(team.Id)
local teamIncome = skirmishGame:CalculateTeamTotalIncome(team.Id)
local positiveText = "+" local positiveText = "+"
if teamIncome < 0 then if income < 0 then
positiveText = "" positiveText = ""
end end
local text = string.format("Team %d: $%d (%s%d)", team.Number, teamCredits, positiveText, teamIncome) local text = string.format("Team %d: $%d (%s%d)", team.Number, credits, positiveText, income)
local icon = team.Faction.Icon local icon = team.Faction.Icon
local color = team.Faction.Color local color = team.Faction.Color
GUI_Button_Icon(uiIcon, icon, color.R, color.G, color.B, 1) GUI_Button_Icon(uiIcon, icon, color.R, color.G, color.B, 1)
GUI_Component_Text(uiText, text) GUI_Component_Text(uiText, text)
GUI_Text_Color(uiText, color.R, color.G, color.B, 1) GUI_Text_Color(uiText, color.R, color.G, color.B, 1)
end
for _, team in pairs(skirmishGame.Teams) do
if team.Number == 1 then
DisplayTeamCredits(team, UI_CreditsT1, UI_IconT1)
elseif team.Number == 2 then
DisplayTeamCredits(team, UI_CreditsT2, UI_IconT2)
end
end
end
---Services Team Units display.
---@param skirmishGame SkirmishGameClass The current Skirmish Game state.
---@param teamId integer The Team ID's units to display.
function ServiceUnitDisplay(skirmishGame, teamId)
if not skirmishGame then
return
end
if not skirmishGame.IsLocalSpectator then
return
end
local localPlayer = Find_Player("local")
if not localPlayer then
return
end
local function DisplayTeamUnit(unit, uiComponent)
end
local players = skirmishGame:GetPlayersOnTeam(teamId)
---@type table<string, integer> Units Table by name with alive count.
local units = {}
for _, player in pairs(players) do
local playerUnits = player:GetAliveUnits()
for _, playerUnit in pairs(playerUnits) do
localPlayer.Select_Object(playerUnit.GameObjectWrapper)
if not units[playerUnit.Name] then
units[playerUnit.Name] = 1
else
units[playerUnit.Name] = units[playerUnit.Name] + 1
end
end
end
end
function ServiceScreenText(skirmishGame)
end end

View File

@@ -65,9 +65,9 @@ end
---@param player table The FoC PlayerWrapper object that owns the new Unit. ---@param player table The FoC PlayerWrapper object that owns the new Unit.
function GalacticGameClass:UnitBuilt(objectType, player) function GalacticGameClass:UnitBuilt(objectType, player)
local playerId = player.Get_ID() local playerId = player.Get_ID()
local player = self.Players[playerId] local playerEntry = self.Players[playerId]
if player then if playerEntry then
player:AddUnit(objectType) playerEntry:AddUnit(objectType)
end end
end end

View File

@@ -45,10 +45,10 @@ function PlayerClass:Service()
-- Pass 1: Collect assigned game object wrappers from alive units -- Pass 1: Collect assigned game object wrappers from alive units
for _, unit in pairs(self:GetAliveUnits()) do for _, unit in pairs(self:GetAliveUnits()) do
if TestValid(unit.GameObjectWrapper) then if TestValid(unit.GameObject) then
assignedUnits[unit.GameObjectWrapper] = true assignedUnits[unit.GameObject] = true
else else
unit:SetDead() unit:SetDead(-1)
end end
end end
@@ -81,11 +81,14 @@ end
---Adds a Unit type to the Player's reinforcement list. ---Adds a Unit type to the Player's reinforcement list.
---@param objectType table FoC GameObjectTypeWrapper object that was built. ---@param objectType table FoC GameObjectTypeWrapper object that was built.
---@return UnitClass
function PlayerClass:AddUnit(objectType) function PlayerClass:AddUnit(objectType)
local unit = UnitClass:New(objectType, self.Id) local unit = UnitClass:New(objectType, self.Id)
table.insert(self.Units, unit) table.insert(self.Units, unit)
ScriptMessage("Unit Added: %s", unit:Debug()) ScriptMessage("Unit Added: %s", unit:Debug())
return unit
end end
---Gets all Reinforcement Units for this Player. ---Gets all Reinforcement Units for this Player.

View File

@@ -20,7 +20,6 @@ end
---@param credits number ---@param credits number
function ResourceClass:SetCredits(credits) function ResourceClass:SetCredits(credits)
self.LastCredits = self.Credits self.LastCredits = self.Credits
self.Credits = credits
if credits < 0 then if credits < 0 then
self.Credits = 0 self.Credits = 0

View File

@@ -1,110 +1,26 @@
require("PGBase")
require("GameManager/Constants")
require("GameManager/TacticalGameClass") require("GameManager/TacticalGameClass")
require("GameManager/SpectatorStruct") require("GameManager/SpectatorStruct")
require("GameManager/TeamStruct") require("GameManager/TeamStruct")
---@class SkirmishGameClass ---@class SkirmishGameClass : TacticalGameClass
---@field TacticalGame TacticalGameClass The underlying Tactical Game context.
---@field Spectators SpectatorStruct[] The spectator players in this game. ---@field Spectators SpectatorStruct[] The spectator players in this game.
---@field IsLocalSpectator boolean Whether the local player is a spectator. ---@field IsLocalSpectator boolean Whether the local player is a spectator.
---@field Teams TeamStruct[] The teams in this game. ---@field Teams TeamStruct[] The teams in this game.
SkirmishGameClass = {} SkirmishGameClass = {}
SkirmishGameClass.__index = SkirmishGameClass SkirmishGameClass.__index = SkirmishGameClass
setmetatable(SkirmishGameClass, { __index = TacticalGameClass })
---Creates a new Skirmish Game context. ---Creates a new Skirmish Game context.
---@param gameMode string The game mode. ---@param gameMode string The game mode.
---@return SkirmishGameClass ---@return SkirmishGameClass
function SkirmishGameClass:New(gameMode) function SkirmishGameClass:New(gameMode)
ScriptMessage("Initializing Skirmish game...") ScriptMessage("Initializing Skirmish game...")
local self = setmetatable({}, SkirmishGameClass) local self = setmetatable(TacticalGameClass:New(gameMode), SkirmishGameClass)
---Finds all spectators in the game. ---@cast self SkirmishGameClass
---@return SpectatorStruct[] self:_FindSpectators()
local function FindSpectators() self.IsLocalSpectator = self:_GetLocalSpectator()
---@type SpectatorStruct[] self:_BuildTeams()
local spectators = {}
---@type string
local spectatorMarker = nil
if StringCompare(gameMode, "Space") then
spectatorMarker = Spectator_Marker_Space
elseif StringCompare(gameMode, "Land") then
spectatorMarker = Spectator_Marker_Land
end
if spectatorMarker then
for k, marker in pairs(Find_All_Objects_Of_Type(spectatorMarker)) do
local playerWrapper = marker.Get_Owner()
local playerId = playerWrapper.Get_ID()
if not spectators[playerId] then
local spectator = SpectatorStruct:New(playerWrapper)
spectators[playerId] = spectator
ScriptMessage("Found Spectator: %s", spectator:Debug())
end
end
end
return spectators
end
self.TacticalGame = TacticalGameClass:New(gameMode)
self.Spectators = FindSpectators()
---Gets whether the local player is a spectator.
---@returns boolean
local function GetLocalSpectator()
local localPlayer = Find_Player("local")
if not localPlayer then
return false
end
return self:GetSpectator(localPlayer.Get_ID()) ~= nil
end
self.IsLocalSpectator = GetLocalSpectator()
---Builds all teams in the game.
---@return TeamStruct[]
local function BuildTeams()
---@type TeamStruct[]
local teams = {}
-- Build combatant player teams
for playerId, player in pairs(self.TacticalGame.Players) do
local teamId = player.TeamId
if teamId >= 0 then
if teams[teamId] == nil then
teams[teamId] = TeamStruct:New(teamId, player.Faction, false)
end
end
end
-- Build spectator player teams
for playerId, spectator in pairs(self.Spectators) do
local teamId = spectator.TeamId
if teamId >= 0 then
local team = teams[teamId]
if team == nil then
team = TeamStruct:New(teamId, spectator.Faction, true)
teams[teamId] = team
ScriptMessage("Found Team: %s", team:Debug())
else
team.IsSpectator = true
end
end
end
return teams
end
self.Teams = BuildTeams()
ScriptMessage("Skirmish Game initialized!") ScriptMessage("Skirmish Game initialized!")
return self return self
@@ -112,31 +28,116 @@ end
---Services the Skirmish Game. ---Services the Skirmish Game.
function SkirmishGameClass:Service() function SkirmishGameClass:Service()
ScriptMessage("Servicing Skirmish Game...")
-- Service TacticalGame -- Service TacticalGame
self.TacticalGame:Service() TacticalGameClass.Service(self)
ScriptMessage("Servicing Skirmish Game...")
for _, team in pairs(self.Teams) do
local credits = self:CalculateTeamTotalCredits(team.Id)
local income = self:CalculateTeamTotalIncome(team.Id)
GUIManager:DisplayTeamCredits(team, credits, income)
end
end end
-- ==================================================
-- Unit event handlers
-- ==================================================
---Displays unit built combat text.
---@param unit UnitClass The built unit.
function SkirmishGameClass:CombatTextUnitBuilt(unit)
local owner = self.Players[unit.OwnerId]
if not owner then
return
end
local team = self.Teams[owner.TeamId]
if not team then
return
end
local timeText = FormatTime(unit.BuildTime)
local text = string.format("%s\t<T%d> [%s]: BUILT %s ($%d)", timeText, team.Number, owner.Name, unit.Name,
unit.BuildCost)
local faction = Factions[owner.Faction]
---@type ColorStruct
local color
if faction then
color = faction.Color
else
color = ColorStruct:New(1, 1, 1, 1)
end
self.CombatFeed:Append(text, -1, color)
TextManager:SetCurrentView("combat_feed")
end
---Displays killed unit combat text.
---@param unit UnitClass The killed unit.
function SkirmishGameClass:CombatTextUnitKilled(unit)
local owner = self.Players[unit.OwnerId]
if not owner then
return
end
local killer = self.Players[unit.KillerId]
local timeText = FormatTime(unit.DeathTime)
if not killer then
local team = self.Teams[owner.TeamId]
if not team then
return
end
local text = string.format("%s\t<T%d> [%s]: MISTAKES WERE MADE %s", timeText, team.Number, owner.Name, unit.Name)
local color = ColorStruct:New(0.8, 0.8, 0.8, 1)
self.CombatFeed:Append(text, -1, color)
else
local team = self.Teams[killer.TeamId]
if not team then
return
end
local text = string.format("%s\t<T%d> [%s]: KILLED %s (%s)", timeText, team.Number, killer.Name, unit.Name,
owner.Name)
local faction = Factions[killer.Faction]
---@type ColorStruct
local color = nil
if faction then
color = faction.Color
else
color = ColorStruct:New(1, 1, 1, 1)
end
self.CombatFeed:Append(text, -1, color)
end
end
-- ==================================================
-- Player functions
-- ==================================================
---Gets the Spectator by Player ID. ---Gets the Spectator by Player ID.
---@param id integer Player ID ---@param id integer Player ID
---@return SpectatorStruct|nil ---@return SpectatorStruct|nil
function SkirmishGameClass:GetSpectator(id) function SkirmishGameClass:GetSpectator(id)
for playerId, spectator in pairs(self.Spectators) do return self.Spectators[id]
if playerId == id then
return spectator
end
end
end end
---Gets the Team by ID. ---Gets the Team by ID.
---@param id integer Team ID ---@param id integer Team ID
---@return TeamStruct|nil ---@return TeamStruct|nil
function SkirmishGameClass:GetTeam(id) function SkirmishGameClass:GetTeam(id)
for teamId, team in pairs(self.Teams) do return self.Teams[id]
if teamId == id then
return team
end
end
end end
---Gets the Players for the Team ID. ---Gets the Players for the Team ID.
@@ -146,7 +147,7 @@ function SkirmishGameClass:GetPlayersOnTeam(id)
---@type PlayerClass[] ---@type PlayerClass[]
local players = {} local players = {}
for playerId, player in pairs(self.TacticalGame.Players) do for playerId, player in pairs(self.Players) do
if player.TeamId == id then if player.TeamId == id then
players[playerId] = player players[playerId] = player
end end
@@ -155,6 +156,10 @@ function SkirmishGameClass:GetPlayersOnTeam(id)
return players return players
end end
-- ==================================================
-- Team functions
-- ==================================================
---Calculates the Team ID's current total credits. ---Calculates the Team ID's current total credits.
---@param id integer Team ID. ---@param id integer Team ID.
---@return integer ---@return integer
@@ -182,3 +187,86 @@ function SkirmishGameClass:CalculateTeamTotalIncome(id)
return totalIncome return totalIncome
end end
-- ==================================================
-- Private functions
-- ==================================================
---@private
---Finds all spectators in the game.
function SkirmishGameClass:_FindSpectators()
---@type SpectatorStruct[]
local spectators = {}
---@type string
local spectatorMarker = nil
if StringCompare(self.GameMode, "Space") then
spectatorMarker = Spectator_Marker_Space
elseif StringCompare(self.GameMode, "Land") then
spectatorMarker = Spectator_Marker_Land
end
if spectatorMarker then
for k, marker in pairs(Find_All_Objects_Of_Type(spectatorMarker)) do
local playerWrapper = marker.Get_Owner()
local playerId = playerWrapper.Get_ID()
if not spectators[playerId] then
local spectator = SpectatorStruct:New(playerWrapper)
spectators[playerId] = spectator
ScriptMessage("Found Spectator: %s", spectator:Debug())
end
end
end
self.Spectators = spectators
end
---@private
---Gets whether the local player is a spectator.
---@returns boolean
function SkirmishGameClass:_GetLocalSpectator()
if not LocalPlayer then
return false
end
return self:GetSpectator(LocalPlayer.Get_ID()) ~= nil
end
---@private
---Builds all teams in the game.
function SkirmishGameClass:_BuildTeams()
---@type TeamStruct[]
local teams = {}
-- Build combatant player teams
for playerId, player in pairs(self.Players) do
local teamId = player.TeamId
if teamId >= 0 then
if teams[teamId] == nil then
teams[teamId] = TeamStruct:New(teamId, player.Faction, false)
end
end
end
-- Build spectator player teams
for playerId, spectator in pairs(self.Spectators) do
local teamId = spectator.TeamId
if teamId >= 0 then
local team = teams[teamId]
if team == nil then
team = TeamStruct:New(teamId, spectator.Faction, true)
teams[teamId] = team
ScriptMessage("Found Team: %s", team:Debug())
else
team.IsSpectator = true
end
end
end
self.Teams = teams
end

View File

@@ -1,13 +1,13 @@
require("PGBase") require("PGBase")
require("GameManager/Constants")
require("GameManager/PlayerClass") require("GameManager/PlayerClass")
require("GameManager/TutorialTextFeed")
---@class TacticalGameClass ---@class TacticalGameClass
---@field GameMode string The tactical game mode. ---@field GameMode string The tactical game mode.
---@field StartTime integer The start time. ---@field StartTime integer The start time.
---@field Players PlayerClass[] The combatant players in this game. ---@field Players PlayerClass[] The combatant players in this game.
---@field ReinforcementUnitCount table<string, integer> Key: Unit Type, Value: Count ---@field CombatFeed TutorialTextFeed Text feed for unit builds and kills.
---@field AliveUnitCount table<string, integer> Key: Unit Type, Value: Count
---@field DeadUnitCount table<string, integer> Key: Unit Type, Value: Count
TacticalGameClass = {} TacticalGameClass = {}
TacticalGameClass.__index = TacticalGameClass TacticalGameClass.__index = TacticalGameClass
@@ -18,9 +18,175 @@ function TacticalGameClass:New(gameMode)
ScriptMessage("Initializing Tactical game...") ScriptMessage("Initializing Tactical game...")
local self = setmetatable({}, TacticalGameClass) local self = setmetatable({}, TacticalGameClass)
---Finds all combatant players in the game. self.GameMode = gameMode
---@return PlayerClass[] self.StartTime = GetCurrentTime()
local function FindPlayers() self.Players = self:_FindPlayers(gameMode)
self.CombatFeed = TutorialTextFeed:New("combat_feed", 6)
ScriptMessage("Tactical Game initialized!")
return self
end
---Services the Tactical Game.
function TacticalGameClass:Service()
ScriptMessage("Servicing Tactical Game...")
-- Service Players
for _, player in pairs(self.Players) do
player:Service()
end
local gameTime = GetCurrentTime() - self.StartTime
GUIManager:DisplayGameTime(gameTime)
end
-- ==================================================
-- State functions
-- ==================================================
---Whether this Tactical game is in space mode.
---@return boolean
function TacticalGameClass:IsSpaceMode()
return StringCompare(self.GameMode, "Space")
end
---Whether this Tactical game is in land mode.
function TacticalGameClass:IsLandMode()
return StringCompare(self.GameMode, "Land")
end
-- ==================================================
-- Player functions
-- ==================================================
---Gets the Player by ID.
---@param id integer Player ID
---@return PlayerClass|nil
function TacticalGameClass:GetPlayer(id)
return self.Players[id]
end
---Records the Player ID as having quit at the current time.
---@param id integer Player ID.
function TacticalGameClass:PlayerQuit(id)
local player = self.Players[id]
if player then
player:Quit()
end
end
-- ==================================================
-- Unit event handlers
-- ==================================================
---Adds a built unit to the Unit table.
---@param objectType GameObjectType The FoC GameObjectTypeWrapper object type that was built.
---@param player PlayerObject The FoC PlayerWrapper object that owns the new Unit.
function TacticalGameClass:UnitBuilt(objectType, player)
local playerId = player.Get_ID()
local playerEntry = self.Players[playerId]
if playerEntry then
local unit = playerEntry:AddUnit(objectType)
self:CombatTextUnitBuilt(unit)
end
end
---Displays unit built combat text.
---@param unit UnitClass The built unit.
function TacticalGameClass:CombatTextUnitBuilt(unit)
local owner = self.Players[unit.OwnerId]
if not owner then
return
end
local timeText = FormatTime(unit.BuildTime)
local text = string.format("%s\t[%s]: BUILT %s ($%d)", timeText, owner.Name, unit.Name, unit.BuildCost)
local faction = Factions[owner.Faction]
---@type ColorStruct
local color
if faction then
color = faction.Color
else
color = ColorStruct:New(1, 1, 1, 1)
end
self.CombatFeed:Append(text, -1, color)
end
---Sets a unit as killed.
---@param gameObject GameObject The FoC GameObjectWrapper object that was killed.
---@param killer PlayerObject The FoC PlayerWrapper object that killed the Unit.
function TacticalGameClass:UnitKilled(gameObject, killer)
local ownerId = gameObject.Get_Owner().Get_ID()
local owner = self.Players[ownerId]
if not owner then
return
end
---@type UnitClass|nil
local killedUnit = nil
for _, unit in pairs(owner.Units) do
if unit.GameObject == gameObject then
killedUnit = unit
break
end
end
if killedUnit then
killedUnit:SetDead(killer.Get_ID())
self:CombatTextUnitKilled(killedUnit)
end
end
---Displays killed unit combat text.
---@param unit UnitClass The killed unit.
function TacticalGameClass:CombatTextUnitKilled(unit)
local owner = self.Players[unit.OwnerId]
if not owner then
return
end
local killer = self.Players[unit.KillerId]
local timeText = FormatTime(unit.DeathTime)
if not killer then
local text = string.format("%s\t[%s]: MISTAKES WERE MADE %s", timeText, owner.Name, unit.Name)
local color = ColorStruct:New(0.8, 0.8, 0.8, 1)
self.CombatFeed:Append(text, -1, color)
else
local text = string.format("%s\t[%s]: KILLED %s (%s)", timeText, killer.Name, unit.Name, owner.Name)
local faction = Factions[killer.Faction]
---@type ColorStruct
local color = nil
if faction then
color = faction.Color
else
color = ColorStruct:New(1, 1, 1, 1)
end
self.CombatFeed:Append(text, -1, color)
end
end
-- ==================================================
-- Private functions
-- ==================================================
---@private
---@param gameMode string The current game mode.
---@return PlayerClass[]
function TacticalGameClass:_FindPlayers(gameMode)
---@type PlayerClass[] ---@type PlayerClass[]
local players = {} local players = {}
@@ -49,72 +215,4 @@ function TacticalGameClass:New(gameMode)
end end
return players return players
end
self.GameMode = gameMode
self.StartTime = GetCurrentTime()
self.Players = FindPlayers()
ScriptMessage("Tactical Game initialized!")
return self
end
---Services the Tactical Game.
function TacticalGameClass:Service()
ScriptMessage("Servicing Tactical Game...")
-- Service Players
for _, player in pairs(self.Players) do
player:Service()
end
end
---Whether this Tactical game is in space mode.
---@return boolean
function TacticalGameClass:IsSpaceMode()
return StringCompare(self.GameMode, "Space")
end
---Whether this Tactical game is in land mode.
function TacticalGameClass:IsLandMode()
return StringCompare(self.GameMode, "Land")
end
---Gets the Player by ID.
---@param id integer Player ID
---@return PlayerClass|nil
function TacticalGameClass:GetPlayer(id)
for playerId, player in pairs(self.Players) do
if playerId == id then
return player
end
end
end
---Records the Player ID as having quit at the current time.
---@param id integer Player ID.
function TacticalGameClass:PlayerQuit(id)
for playerId, player in pairs(self.Players) do
if playerId == id then
player:Quit()
end
end
end
---Adds a built unit to the Unit table.
---@param objectType table The FoC GameObjectTypeWrapper object type that was built.
---@param player table The FoC PlayerWrapper object that owns the new Unit.
function TacticalGameClass:UnitBuilt(objectType, player)
local playerId = player.Get_ID()
local player = self.Players[playerId]
if player then
player:AddUnit(objectType)
end
end
---Sets a unit as killed.
---@param gameObject table The FoC GameObjectWrapper object that was killed.
function TacticalGameClass:UnitKilled(gameObject)
-- Find a way to set the unit as killed
end end

View File

@@ -0,0 +1,74 @@
require("GameManager/TutorialTextView")
---A fixed-capacity feed view. Appending a new line when at capacity evicts the
---oldest (top-most) entry first. Rendering is driven by the IsActive flag set
---by TutorialTextManager; no manager reference is needed.
---
---@class TutorialTextFeed : TutorialTextView
---@field MaxLines integer Maximum number of lines to display at once.
---@field _KeyOrder string[] Insertion-ordered list of active entry keys (oldest first).
---@field _NextId integer Counter used to generate unique entry keys.
TutorialTextFeed = setmetatable({}, { __index = TutorialTextView })
TutorialTextFeed.__index = TutorialTextFeed
---Creates a new Tutorial Text Feed.
---@param name string The view name.
---@param maxLines integer Maximum number of lines to display at once.
---@return TutorialTextFeed
function TutorialTextFeed:New(name, maxLines)
local self = setmetatable(TutorialTextView:New(name), TutorialTextFeed)
---@cast self TutorialTextFeed
self.MaxLines = maxLines
self._KeyOrder = {}
self._NextId = 0
return self
end
---Appends a new line to the bottom of the feed.
---If the feed is at capacity, the oldest line is removed first.
---Only renders to the screen when this view is active.
---@param text string The display text.
---@param duration number|nil Duration in seconds, defaults to -1 (infinite).
---@param color ColorStruct|nil The text color, defaults to white.
function TutorialTextFeed:Append(text, duration, color)
---@diagnostic disable-next-line
if table.getn(self._KeyOrder) >= self.MaxLines then
local oldestKey = table.remove(self._KeyOrder, 1)
self.Entries[oldestKey] = nil
if self.IsActive then
Remove_Tutorial_Text(oldestKey)
end
end
self._NextId = self._NextId + 1
local key = self.Name .. "_" .. self._NextId
self:SetEntry(key, text, duration, color)
table.insert(self._KeyOrder, key)
if self.IsActive then
local entry = self.Entries[key]
Add_Tutorial_Text(entry.Key, entry.Text, entry.Duration,
entry.Color.R, entry.Color.G, entry.Color.B, entry.Color.A)
end
end
---Removes all entries from the feed.
---Only clears the screen when this view is active.
function TutorialTextFeed:Clear()
if self.IsActive then
for _, key in ipairs(self._KeyOrder) do
Remove_Tutorial_Text(key)
end
end
self.Entries = {}
self._KeyOrder = {}
end
function TutorialTextFeed:Debug()
return string.format("TutorialTextFeed '%s' (%d/%d lines)",
---@diagnostic disable-next-line
self.Name, table.getn(self._KeyOrder), self.MaxLines)
end

View File

@@ -0,0 +1,169 @@
require("GameManager/TutorialTextView")
---Manages multiple named tutorial text views, rendering only the active view.
---
---Views hold their own state independently. Only the current view is rendered
---to the screen. Switching views clears the screen and renders the new view's
---current state.
---
---@class TutorialTextManager
---@field Views table<string, TutorialTextView> All registered views by name.
---@field CurrentViewName string|nil The name of the currently active view.
TutorialTextManager = {}
TutorialTextManager.__index = TutorialTextManager
---Creates a new Tutorial Text Manager.
---@return TutorialTextManager
function TutorialTextManager:New()
local self = setmetatable({}, TutorialTextManager)
self.Views = {}
self.CurrentViewName = nil
return self
end
---Registers a new view. If a view with the given name already exists it is returned as-is.
---@param name string The view name.
---@return TutorialTextView
function TutorialTextManager:AddView(name)
if not self.Views[name] then
self.Views[name] = TutorialTextView:New(name)
end
return self.Views[name]
end
---Registers an existing view instance (e.g. a TutorialTextFeed).
---If a view with the same name already exists it is returned as-is.
---@param view TutorialTextView The view to register.
---@return TutorialTextView
function TutorialTextManager:RegisterView(view)
if not self.Views[view.Name] then
self.Views[view.Name] = view
end
return self.Views[view.Name]
end
---Returns a registered view by name, or nil if it does not exist.
---@param name string The view name.
---@return TutorialTextView|nil
function TutorialTextManager:GetView(name)
return self.Views[name]
end
---Switches the active view. Clears the screen then renders the new view's current state.
---@param name string The view name to activate.
function TutorialTextManager:SetCurrentView(name)
if self.CurrentViewName == name then
return
end
local oldView = self.Views[self.CurrentViewName]
if oldView then
oldView.IsActive = false
end
self:_ClearScreen()
self.CurrentViewName = name
local newView = self.Views[name]
if newView then
newView.IsActive = true
self:_RenderView(newView)
end
end
---Sets or updates a text entry in a view.
---If the view is currently active the change is immediately rendered to the screen.
---@param viewName string The view to update.
---@param key string The unique key for this entry.
---@param text string The display text.
---@param duration number|nil Duration in seconds, defaults to -1 (infinite).
---@param color ColorStruct|nil The text color, defaults to white.
function TutorialTextManager:UpdateEntry(viewName, key, text, duration, color)
local view = self.Views[viewName]
if not view then
return
end
view:SetEntry(key, text, duration, color)
if self.CurrentViewName == viewName then
local entry = view.Entries[key]
Add_Tutorial_Text(entry.Key, entry.Text, entry.Duration,
entry.Color.R, entry.Color.G, entry.Color.B, entry.Color.A)
end
end
---Removes a text entry from a view.
---If the view is currently active the entry is immediately removed from the screen.
---@param viewName string The view to update.
---@param key string The key to remove.
function TutorialTextManager:RemoveEntry(viewName, key)
local view = self.Views[viewName]
if not view then
return
end
view:RemoveEntry(key)
if self.CurrentViewName == viewName then
Remove_Tutorial_Text(key)
end
end
---Clears all entries from a view.
---If the view is currently active all entries are immediately removed from the screen.
---@param viewName string The view to clear.
function TutorialTextManager:ClearView(viewName)
local view = self.Views[viewName]
if not view then
return
end
if self.CurrentViewName == viewName then
self:_ClearScreen()
end
view:Clear()
end
---Removes all views and clears the screen.
function TutorialTextManager:Reset()
self:_ClearScreen()
self.Views = {}
self.CurrentViewName = nil
end
---Renders all entries of a view to the screen.
---@param view TutorialTextView
function TutorialTextManager:_RenderView(view)
for _, entry in pairs(view.Entries) do
Add_Tutorial_Text(entry.Key, entry.Text, entry.Duration,
entry.Color.R, entry.Color.G, entry.Color.B, entry.Color.A)
end
end
---Removes all entries of the current view from the screen.
function TutorialTextManager:_ClearScreen()
if not self.CurrentViewName then
return
end
local view = self.Views[self.CurrentViewName]
if not view then
return
end
for key in pairs(view.Entries) do
Remove_Tutorial_Text(key)
end
end
function TutorialTextManager:Debug()
local count = 0
for _ in pairs(self.Views) do count = count + 1 end
return string.format("TutorialTextManager (views: %d, current: '%s')",
count, self.CurrentViewName or "none")
end

View File

@@ -0,0 +1,60 @@
require("GameManager/ColorStruct")
---Represents a single text entry in a tutorial text view.
---@class TutorialTextEntry
---@field Key string The unique key for this entry.
---@field Text string The display text.
---@field Duration number Duration in seconds, or -1 for infinite.
---@field Color ColorStruct The text color.
---Represents a named set of tutorial text entries.
---@class TutorialTextView
---@field Name string The view name.
---@field Entries table<string, TutorialTextEntry> Entries keyed by their text key.
---@field IsActive boolean Whether this view is currently being displayed.
TutorialTextView = {}
TutorialTextView.__index = TutorialTextView
---Creates a new Tutorial Text View.
---@param name string The view name.
---@return TutorialTextView
function TutorialTextView:New(name)
local self = setmetatable({}, TutorialTextView)
self.Name = name
self.Entries = {}
self.IsActive = false
return self
end
---Sets or updates a text entry in this view.
---@param key string The unique key for this entry.
---@param text string The display text.
---@param duration number|nil Duration in seconds, defaults to -1 (infinite).
---@param color ColorStruct|nil The text color, defaults to white.
function TutorialTextView:SetEntry(key, text, duration, color)
self.Entries[key] = {
Key = key,
Text = text,
Duration = duration or -1,
Color = color or ColorStruct:New(1, 1, 1, 1),
}
end
---Removes a text entry from this view.
---@param key string The key to remove.
function TutorialTextView:RemoveEntry(key)
self.Entries[key] = nil
end
---Removes all entries from this view.
function TutorialTextView:Clear()
self.Entries = {}
end
function TutorialTextView:Debug()
local count = 0
for _ in pairs(self.Entries) do count = count + 1 end
return string.format("TutorialTextView '%s' (%d entries)", self.Name, count)
end

View File

@@ -8,9 +8,9 @@ require("PGBase")
---@field BuildTime number Game time that this unit was built. ---@field BuildTime number Game time that this unit was built.
---@field AliveTime number Game time that this unit became "alive". ---@field AliveTime number Game time that this unit became "alive".
---@field DeathTime number Game time that this unit was killed. ---@field DeathTime number Game time that this unit was killed.
---@field GameObjectWrapper table|nil The FoC GameObjectWrapper object. ---@field KillerId integer|nil The Player ID that killed this unit.
---@field GameObjectTypeWrapper table The FoC GameObjectTypeWrapper object. ---@field GameObject GameObject|nil The FoC GameObjectWrapper object.
---@field Icon string Name of the icon for this object. ---@field GameObjectType GameObjectType The FoC GameObjectTypeWrapper object.
UnitClass = {} UnitClass = {}
UnitClass.__index = UnitClass UnitClass.__index = UnitClass
@@ -27,9 +27,9 @@ function UnitClass:New(objectType, playerId)
self.BuildTime = GetCurrentTime() self.BuildTime = GetCurrentTime()
self.AliveTime = -1 self.AliveTime = -1
self.DeathTime = -1 self.DeathTime = -1
self.GameObjectWrapper = nil self.KillerId = nil
self.GameObjectTypeWrapper = objectType self.GameObject = nil
self.Icon = "I_BUTTON_COMMAND_BAR_PIRATE_SYMBOL.TGA" self.GameObjectType = objectType
return self return self
end end
@@ -61,18 +61,20 @@ function UnitClass:SetAlive(object)
end end
self.AliveTime = GetCurrentTime() self.AliveTime = GetCurrentTime()
self.GameObjectWrapper = object self.GameObject = object
ScriptMessage("Unit Spawned: %s", self:Debug()) ScriptMessage("Unit Spawned: %s", self:Debug())
end end
---Sets the unit as dead. ---Sets the unit as dead.
function UnitClass:SetDead() ---@param killerId integer The Player ID that killed this unit.
function UnitClass:SetDead(killerId)
if self.DeathTime >= 0 then if self.DeathTime >= 0 then
-- Do not override once set -- Do not override once set
return return
end end
self.DeathTime = GetCurrentTime() self.DeathTime = GetCurrentTime()
self.KillerId = killerId
ScriptMessage("Unit Killed: %s", self:Debug()) ScriptMessage("Unit Killed: %s", self:Debug())
end end

View File

@@ -0,0 +1,20 @@
---Formats the game time in seconds to MM:SS.
---@param gameTime number The game time in seconds.
---@return string
function FormatTime(gameTime)
local minutes = Dirty_Floor(gameTime / 60)
local minutesText = tostring(minutes)
if tonumber(minutes) < 10 then
minutesText = "0" .. minutesText
end
local seconds = Dirty_Floor(gameTime - (minutes * 60))
local secondsText = tostring(seconds)
if tonumber(seconds) < 10 then
secondsText = "0" .. secondsText
end
return string.format("%s:%s", minutesText, secondsText)
end

View File

@@ -1,6 +1,5 @@
require("PGBase") require("PGBase")
require("GameManager/Constants") require("GameManager/Constants")
require("GameManager/GUIManager")
require("GameManager/GalacticGameClass") require("GameManager/GalacticGameClass")
require("GameManager/TacticalGameClass") require("GameManager/TacticalGameClass")
require("GameManager/SkirmishGameClass") require("GameManager/SkirmishGameClass")
@@ -15,25 +14,14 @@ local DebugCounter = 0
---Debugging service rate. ---Debugging service rate.
local ServiceDebugRate = 5 local ServiceDebugRate = 5
---The Local Player FoC PlayerWrapper object.
local LocalPlayer = nil
---The GUI Manager.
---@type GUIManager
local GUIManager = GUIManager:New()
---The Galactic Game manager. ---The Galactic Game manager.
---@type GalacticGameClass|nil ---@type GalacticGameClass|nil
local GalacticGame = nil local GalacticGame = nil
---The Tactical Game manager. ---The Tactical Game manager.
---@type TacticalGameClass|nil ---@type TacticalGameClass|SkirmishGameClass|nil
local TacticalGame = nil local TacticalGame = nil
---The Skirmish Game manager.
---@type SkirmishGameClass|nil
local SkirmishGame = nil
-- ================================================== -- ==================================================
-- Script Globals -- Script Globals
-- ================================================== -- ==================================================
@@ -59,7 +47,6 @@ function Base_Definitions()
DebugMessage("%s -- In Base_Definitions.", tostring(Script)) DebugMessage("%s -- In Base_Definitions.", tostring(Script))
DebugCounter = 0 DebugCounter = 0
LocalPlayer = Find_Player("local")
end end
---Main script function. Does event pumps and servicing. ---Main script function. Does event pumps and servicing.
@@ -88,19 +75,11 @@ function GameService()
if GalacticGame then if GalacticGame then
GalacticGame:Service() GalacticGame:Service()
end
if TacticalGame then if TacticalGame then
TacticalGame:Service() TacticalGame:Service()
end end
end
if SkirmishGame then
SkirmishGame:Service()
end
if GUIManager then
GUIManager:Service()
end
end end
---Script debug servicing. ---Script debug servicing.
@@ -142,6 +121,8 @@ end
function Game_Mode_Starting_Event(mode, map) function Game_Mode_Starting_Event(mode, map)
DebugMessage("%s -- Game Mode %s (%s) now starting.", tostring(Script), mode, map) DebugMessage("%s -- Game Mode %s (%s) now starting.", tostring(Script), mode, map)
LocalPlayer = Find_Player("local")
if StringCompare(mode, "Galactic") then if StringCompare(mode, "Galactic") then
-- Galactic Campaign -- Galactic Campaign
Init_Galactic() Init_Galactic()
@@ -169,10 +150,12 @@ function Game_Mode_Ending_Event(oldMode)
-- Skirmish mode ending -- Skirmish mode ending
Reset_Skirmish() Reset_Skirmish()
end end
LocalPlayer = nil
end end
---This event is triggered when a player quits the game. ---This event is triggered when a player quits the game.
---@param player table FoC PlayerWrapper object that just quit. ---@param player PlayerObject FoC PlayerWrapper object that just quit.
function Player_Quit_Event(player) function Player_Quit_Event(player)
DebugMessage("%s -- Player %s (%d) has quit.", tostring(Script), player.Get_Name(), player.Get_ID()) DebugMessage("%s -- Player %s (%d) has quit.", tostring(Script), player.Get_Name(), player.Get_ID())
@@ -182,9 +165,9 @@ function Player_Quit_Event(player)
end end
---This event is triggered when production has finished in a tactical mode ---This event is triggered when production has finished in a tactical mode
---@param objectType table FoC GameObjectTypeWrapper object that was just built. ---@param objectType GameObjectType FoC GameObjectTypeWrapper object that was just built.
---@param player table FoC PlayerWrapper object that built the object. ---@param player PlayerObject FoC PlayerWrapper object that built the object.
---@param location table|nil FoC GameObjectWrapper of the planet. ---@param location PlanetObject|nil FoC GameObjectWrapper of the planet.
function Tactical_Production_End_Event(objectType, player, location) function Tactical_Production_End_Event(objectType, player, location)
if location then if location then
DebugMessage("%s -- Tactical production of unit %s by %s ended at %s.", tostring(Script), objectType.Get_Name(), DebugMessage("%s -- Tactical production of unit %s by %s ended at %s.", tostring(Script), objectType.Get_Name(),
@@ -201,20 +184,20 @@ function Tactical_Production_End_Event(objectType, player, location)
end end
---This event is triggered when a unit is destroyed in tactical mode. ---This event is triggered when a unit is destroyed in tactical mode.
---@param object table FoC GameObjectWrapper object that was just killed. ---@param object GameObject FoC GameObjectWrapper object that was just killed.
---@param killer table FoC PlayerWrapper object that killed the object. ---@param killer PlayerObject FoC PlayerWrapper object that killed the object.
function Tactical_Unit_Destroyed_Event(object, killer) function Tactical_Unit_Destroyed_Event(object, killer)
DebugMessage("%s -- Tactical unit %s destroyed by %s.", tostring(Script), object.Get_Type().Get_Name(), DebugMessage("%s -- Tactical unit %s destroyed by %s.", tostring(Script), object.Get_Type().Get_Name(),
killer.Get_Name()) killer.Get_Name())
if TacticalGame then if TacticalGame then
TacticalGame:UnitKilled(object) TacticalGame:UnitKilled(object, killer)
end end
end end
---This event is triggered when production has begun on an item at a given planet. ---This event is triggered when production has begun on an item at a given planet.
---@param planet table FoC GameObjectWrapper object of the planet. ---@param planet PlanetObject FoC GameObjectWrapper object of the planet.
---@param objectType table FoC GameObjectTypeWrapper object that was just queued. ---@param objectType GameObjectType FoC GameObjectTypeWrapper object that was just queued.
function Galactic_Production_Begin_Event(planet, objectType) function Galactic_Production_Begin_Event(planet, objectType)
DebugMessage("%s -- Galactic production of %s started at %s.", tostring(Script), objectType.Get_Name(), DebugMessage("%s -- Galactic production of %s started at %s.", tostring(Script), objectType.Get_Name(),
planet.Get_Type().Get_Name()) planet.Get_Type().Get_Name())
@@ -222,16 +205,16 @@ end
---This event is triggered when production has been prematurely canceled ---This event is triggered when production has been prematurely canceled
---on an item at a given planet. ---on an item at a given planet.
---@param planet table FoC GameObjectWrapper object of the planet. ---@param planet PlanetObject FoC GameObjectWrapper object of the planet.
---@param objectType table FoC GameObjectTypeWrapper object that was just canceled.. ---@param objectType GameObjectType FoC GameObjectTypeWrapper object that was just canceled..
function Galactic_Production_Canceled_Event(planet, objectType) function Galactic_Production_Canceled_Event(planet, objectType)
DebugMessage("%s -- Galactic production of %s canceled at %s.", tostring(Script), objectType.Get_Name(), DebugMessage("%s -- Galactic production of %s canceled at %s.", tostring(Script), objectType.Get_Name(),
planet.Get_Type().Get_Name()) planet.Get_Type().Get_Name())
end end
---This event is triggered when production has finished on an item at a given planet. ---This event is triggered when production has finished on an item at a given planet.
---@param planet table FoC GameObjectWrapper or of the planet. ---@param planet PlanetObject FoC GameObjectWrapper or of the planet.
---@param object table FoC GameObjectWrapper or GameObjectTypeWrapper of the object that was just created. ---@param object GameObject|GameObjectType FoC GameObjectWrapper or GameObjectTypeWrapper of the object that was just created.
function Galactic_Production_End_Event(planet, object) function Galactic_Production_End_Event(planet, object)
local typeName = "" local typeName = ""
@@ -249,16 +232,16 @@ function Galactic_Production_End_Event(planet, object)
end end
---This event is triggered when a unit is destroyed in galactic mode. ---This event is triggered when a unit is destroyed in galactic mode.
---@param object table FoC GameObjectWrapper object that was just killed. ---@param object GameObject FoC GameObjectWrapper object that was just killed.
---@param killer table FoC PlayerWrapper object that killed the object. ---@param killer PlayerObject FoC PlayerWrapper object that killed the object.
function Galactic_Unit_Destroyed_Event(object, killer) function Galactic_Unit_Destroyed_Event(object, killer)
DebugMessage("%s -- Object %s killed by %s.", tostring(Script), object.Get_Type().Get_Name(), killer.Get_Name()) DebugMessage("%s -- Object %s killed by %s.", tostring(Script), object.Get_Type().Get_Name(), killer.Get_Name())
end end
---This event is triggered when the level of a starbase changes. ---This event is triggered when the level of a starbase changes.
---@param planet table FoC GameObjectWrapper object of the planet. ---@param planet PlanetObject FoC GameObjectWrapper object of the planet.
---@param oldType table FoC GameObjectTypeWrapper object of the old starbase type. ---@param oldType GameObjectType FoC GameObjectTypeWrapper object of the old starbase type.
---@param newType table FoC GameObjectTypeWrapper object of the new starbase type. ---@param newType GameObjectType FoC GameObjectTypeWrapper object of the new starbase type.
function Galactic_Starbase_Level_Change(planet, oldType, newType) function Galactic_Starbase_Level_Change(planet, oldType, newType)
DebugMessage("%s -- %s Starbase changed from %s to %s.", tostring(Script), planet.Get_Type().Get_Name(), DebugMessage("%s -- %s Starbase changed from %s to %s.", tostring(Script), planet.Get_Type().Get_Name(),
tostring(oldType), tostring(newType)) tostring(oldType), tostring(newType))
@@ -295,9 +278,9 @@ function Galactic_Starbase_Level_Change(planet, oldType, newType)
end end
---This event is called when a planet changes faction in galactic mode. ---This event is called when a planet changes faction in galactic mode.
---@param planet table FoC GameObjectWrapper object of the planet. ---@param planet PlanetObject FoC GameObjectWrapper object of the planet.
---@param newOwner table FoC PlayerWrapper of the new owner. ---@param newOwner PlayerObject FoC PlayerWrapper of the new owner.
---@param oldOwner table FoC PlayerWrapper of the old owner. ---@param oldOwner PlayerObject FoC PlayerWrapper of the old owner.
function Galactic_Planet_Faction_Change(planet, newOwner, oldOwner) function Galactic_Planet_Faction_Change(planet, newOwner, oldOwner)
local planetName = planet.Get_Type().Get_Name() local planetName = planet.Get_Type().Get_Name()
@@ -306,8 +289,8 @@ function Galactic_Planet_Faction_Change(planet, newOwner, oldOwner)
end end
---This event is called when a hero is neutralized by another hero in galactic mode. ---This event is called when a hero is neutralized by another hero in galactic mode.
---@param heroType table FoC GameObjectTypeWrapper object for the neutralized hero type. ---@param heroType GameObjectType FoC GameObjectTypeWrapper object for the neutralized hero type.
---@param killer table FoC GameObjectWrapper object that killed the hero. ---@param killer GameObject FoC GameObjectWrapper object that killed the hero.
function Galactic_Neutralized_Event(heroType, killer) function Galactic_Neutralized_Event(heroType, killer)
DebugMessage("%s -- Hero %s killed by %s.", tostring(Script), heroType.Get_Name(), killer.Get_Owner().Get_Name()) DebugMessage("%s -- Hero %s killed by %s.", tostring(Script), heroType.Get_Name(), killer.Get_Owner().Get_Name())
end end
@@ -317,23 +300,23 @@ end
--- ================================================== --- ==================================================
---Returns the number of frags by player for the given object type. ---Returns the number of frags by player for the given object type.
---@param objectType table FoC GameObjectTypeWrapper object to query. ---@param objectType GameObjectType FoC GameObjectTypeWrapper object to query.
---@param player table FoC PlayerWrapper object to query. ---@param player PlayerObject FoC PlayerWrapper object to query.
---@return integer ---@return integer
function Get_Frag_Count_For_Type(objectType, player) function Get_Frag_Count_For_Type(objectType, player)
return 0 return 0
end end
---Returns the number of heroes neutralized by player for the given object type. ---Returns the number of heroes neutralized by player for the given object type.
---@param objectType table FoC GameObjectTypeWrapper object to query. ---@param objectType GameObjectType FoC GameObjectTypeWrapper object to query.
---@param player table FoC PlayerWrapper object to query. ---@param player PlayerObject FoC PlayerWrapper object to query.
---@return integer ---@return integer
function Get_Neutralized_Count_For_Type(objectType, player) function Get_Neutralized_Count_For_Type(objectType, player)
return 0 return 0
end end
---Returns a game stat for the provided control ID. ---Returns a game stat for the provided control ID.
---@param player table FoC PlayerWrapper object to query. ---@param player PlayerObject FoC PlayerWrapper object to query.
---@param controlId string The Control ID. ---@param controlId string The Control ID.
---@param isTactical boolean Whether the game mode was a tactical mode. ---@param isTactical boolean Whether the game mode was a tactical mode.
---@return number|string ---@return number|string
@@ -377,7 +360,8 @@ function Update_GameSpy_Game_Stats()
end end
---Updates the GameSpy player stats table ---Updates the GameSpy player stats table
---@param player table FoC PlayerWrapper object. ---@param player PlayerObject FoC PlayerWrapper object.
---@deprecated
function Update_GameSpy_Player_Stats(player) function Update_GameSpy_Player_Stats(player)
GameSpy_Player_Stats = {} GameSpy_Player_Stats = {}
end end
@@ -410,7 +394,9 @@ function Init_Tactical(gameMode)
DebugMessage("%s -- Initializing Tactical %s rules.", tostring(Script), gameMode) DebugMessage("%s -- Initializing Tactical %s rules.", tostring(Script), gameMode)
Reset_Tactical_Stats() Reset_Tactical_Stats()
TacticalGame = TacticalGameClass:New(gameMode) TacticalGame = TacticalGameClass:New(gameMode)
GUIManager:InitTactical(TacticalGame) GUIManager:InitTactical()
TextManager:RegisterView(TacticalGame.CombatFeed)
TextManager:SetCurrentView("combat_feed")
end end
---Resets Tactical mode. ---Resets Tactical mode.
@@ -419,6 +405,7 @@ function Reset_Tactical()
Reset_Tactical_Stats() Reset_Tactical_Stats()
TacticalGame = nil TacticalGame = nil
GUIManager:Reset() GUIManager:Reset()
TextManager:Reset()
end end
--- ================================================== --- ==================================================
@@ -428,18 +415,19 @@ end
---Initializes Skirmish mode. ---Initializes Skirmish mode.
---@param gameMode string The tactical game mode. ---@param gameMode string The tactical game mode.
function Init_Skirmish(gameMode) function Init_Skirmish(gameMode)
DebugMessage("%s -- Initializing Skirmish Tacitcal %s rules.", tostring(Script), gameMode) DebugMessage("%s -- Initializing Skirmish Tactical %s rules.", tostring(Script), gameMode)
Reset_Stats() Reset_Stats()
SkirmishGame = SkirmishGameClass:New(gameMode) TacticalGame = SkirmishGameClass:New(gameMode)
TacticalGame = SkirmishGame.TacticalGame GUIManager:InitSkirmish(TacticalGame.IsLocalSpectator)
GUIManager:InitSkirmish(SkirmishGame) TextManager:RegisterView(TacticalGame.CombatFeed)
TextManager:SetCurrentView("combat_feed")
end end
---Resets Skirmish mode. ---Resets Skirmish mode.
function Reset_Skirmish() function Reset_Skirmish()
DebugMessage("%s -- Resetting Skirmish Tactical rules.", tostring(Script)) DebugMessage("%s -- Resetting Skirmish Tactical rules.", tostring(Script))
Reset_Stats() Reset_Stats()
SkirmishGame = nil
TacticalGame = nil TacticalGame = nil
GUIManager:Reset() GUIManager:Reset()
TextManager:Reset()
end end