Files
FoC-GameManager/Data/Scripts/Miscellaneous/GameManager/GalacticGameClass.lua
2026-03-20 09:49:44 -05:00

323 lines
9.7 KiB
Lua

require("PGBase")
require("GameManager/PlayerClass")
require("GameManager/UnitClass")
---@class GalacticGameClass
---@field StartTime integer The start time.
---@field Players PlayerClass[] The combatant players in this game.
---@field BuildStatsTable table The engine-owned GalacticBuildStatsTable reference, set from GameScoring.lua.
---@field KillStatsTable table The engine-owned GalacticKillStatsTable reference, set from GameScoring.lua.
---@field NeutralizedStatsTable table The engine-owned GalacticNeutralizedTable reference, set from GameScoring.lua.
---@field GalacticConquestTable table The engine-owned GalacticConquestTable reference, set from GameScoring.lua.
GalacticGameClass = {}
GalacticGameClass.__index = GalacticGameClass
---Creates a new Galactic Game context.
---@return GalacticGameClass
function GalacticGameClass:New()
ScriptMessage("Initializing Galactic game...")
local self = setmetatable({}, GalacticGameClass)
self.StartTime = GetCurrentTime()
self.Players = self:_FindPlayers()
ScriptMessage("Galactic Game initialized!")
return self
end
---Services the Galactic Game.
function GalacticGameClass:Service()
ScriptMessage("Servicing Galactic game...")
-- Service Players
for _, player in pairs(self.Players) do
player:Service()
end
end
-- ==================================================
-- Player event handlers
-- ==================================================
---Gets the Player by ID.
---@param id integer Player ID
---@return PlayerClass|nil
function GalacticGameClass: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 GalacticGameClass:PlayerQuit(id)
for playerId, player in pairs(self.Players) do
if playerId == id then
player:Quit()
end
end
end
-- ==================================================
-- Unit event handlers
-- ==================================================
---Adds a built unit to the Unit table.
---@param objectType GameObjectType The game object type that was built.
---@param player PlayerObject The player that owns the new game object.
---@param planet PlanetObject The planet the game object type was built at.
function GalacticGameClass:UnitBuilt(objectType, player, planet)
local playerId = player.Get_ID()
local playerEntry = self.Players[playerId]
if playerEntry then
local unit = playerEntry:AddUnit(objectType)
self:UpdateGalacticBuildStatsTable(unit, planet)
end
end
---Sets a unit as killed.
---@param gameObject GameObject The game object that was killed.
---@param killer PlayerObject The player that killed the game object.
function GalacticGameClass: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:UpdateGalacticKillStatsTable(killedUnit, killer)
end
end
function GalacticGameClass:UnitNeutralized(objectType, killer)
self:UpdateGalacticNeutralizedTable(objectType, killer)
end
-- ==================================================
-- Planet event handlers
-- ==================================================
---Sets a planet as changed faction.
---@param planet PlanetObject
---@param newOwner PlayerObject
---@param oldOwner PlayerObject
function GalacticGameClass:PlanetFactionChange(planet, newOwner, oldOwner)
end
-- ==================================================
-- Stat tables
-- ==================================================
---Updates the Galactic Build Stats Table with the build object type.
---@param unit UnitClass The game object type that was built.
---@param planet PlanetObject|nil The planet where the game object was built.
function GalacticGameClass:UpdateGalacticBuildStatsTable(unit, planet)
---@type GameObjectType|integer
local planetType = 1
if planet then
planetType = planet.Get_Type()
end
local playerEntry = self.BuildStatsTable[unit.OwnerId]
if not playerEntry then
playerEntry = {}
self.BuildStatsTable[unit.OwnerId] = playerEntry
end
local planetEntry = playerEntry[planetType]
if not planetEntry then
planetEntry = {}
playerEntry[planetType] = planetEntry
end
local typeEntry = planetEntry[unit.Name]
if not typeEntry then
typeEntry = {
build_count = 1,
combat_power = unit.CombatRating,
build_cost = unit.BuildCost,
score_value = unit.ScoreValue
}
planetEntry[unit.Name] = typeEntry
else
typeEntry.build_count = typeEntry.build_count + 1
typeEntry.combat_power = typeEntry.combat_power + unit.CombatRating
typeEntry.build_cost = typeEntry.build_cost + unit.BuildCost
typeEntry.score_value = typeEntry.score_value + unit.ScoreValue
end
end
---Updates the Galactic Kill Stats Table with the killed object.
---@param unit UnitClass The unit that was killed.
---@param killer PlayerObject The player that killed the unit.
function GalacticGameClass:UpdateGalacticKillStatsTable(unit, killer)
if not TestValid(killer) then
return
end
-- Update Frags
local fragEntry = self.KillStatsTable[FragIndex]
if not fragEntry then
fragEntry = {}
self.KillStatsTable[FragIndex] = fragEntry
end
local killerId = killer.Get_ID()
local killerEntry = fragEntry[killerId]
if not killerEntry then
killerEntry = {}
fragEntry[killerId] = killerEntry
end
local killerObjEntry = killerEntry[unit.GameObjectType]
if not killerObjEntry then
killerObjEntry = {
kills = 1,
combat_power = unit.CombatRating,
build_cost = unit.BuildCost,
score_value = unit.ScoreValue
}
killerEntry[unit.GameObjectType] = killerObjEntry
else
killerObjEntry.kills = killerObjEntry.kills + 1
killerObjEntry.combat_power = killerObjEntry.combat_power + unit.CombatRating
killerObjEntry.build_cost = killerObjEntry.build_cost + unit.BuildCost
killerObjEntry.score_value = killerObjEntry.score_value + unit.ScoreValue
end
-- Update Deaths
local deathEntry = self.KillStatsTable[DeathIndex]
if not deathEntry then
deathEntry = {}
self.KillStatsTable[DeathIndex] = deathEntry
end
local ownerEntry = deathEntry[unit.OwnerId]
if not ownerEntry then
ownerEntry = {}
deathEntry[unit.OwnerId] = ownerEntry
end
local ownerObjEntry = ownerEntry[unit.GameObjectType]
if not ownerObjEntry then
ownerObjEntry = {
kills = 1,
combat_power = unit.CombatRating,
build_cost = unit.BuildCost,
score_value = unit.ScoreValue
}
ownerEntry[unit.GameObjectType] = ownerObjEntry
else
ownerObjEntry.kills = ownerObjEntry.kills + 1
ownerObjEntry.combat_power = ownerObjEntry.combat_power + unit.CombatRating
ownerObjEntry.build_cost = ownerObjEntry.build_cost + unit.BuildCost
ownerObjEntry.score_value = ownerObjEntry.score_value + unit.ScoreValue
end
end
---Updates the Galactic Neutralized Table with the neutralized hero.
---@param objectType GameObjectType The hero type that was neutralized.
---@param killer GameObject The hero that killed this hero.
function GalacticGameClass:UpdateGalacticNeutralizedTable(objectType, killer)
local killerId = killer.Get_Owner().Get_ID()
local killerEntry = self.NeutralizedStatsTable[killerId]
if not killerEntry then
killerEntry = {}
self.NeutralizedStatsTable[killerId] = killerEntry
end
local neutralizedEntry = killerEntry[objectType]
if not neutralizedEntry then
neutralizedEntry = {
neutralized = 1
}
killerEntry[objectType] = neutralizedEntry
else
neutralizedEntry.neutralized = neutralizedEntry.neutralized + 1
end
end
-- ==================================================
-- Private functions
-- ==================================================
---@private
---Finds all players of defined Factions via FoCAPI.
---@return PlayerClass[]
function GalacticGameClass:_FindPlayers()
local isSuccess, result = pcall(Get_All_Players)
if isSuccess then
local players = {}
for _, playerWrapper in pairs(result) do
local factionName = playerWrapper.Get_Faction_Name()
for _, faction in pairs(Factions) do
if faction.Name == factionName then
local player = PlayerClass:New(playerWrapper)
players[player.Id] = player
end
end
end
return players
end
return self:_FindPlayersFallback()
end
---@private
---Finds all players of defined Factions via planets.
---@return PlayerClass[]
function GalacticGameClass:_FindPlayersFallback()
---@type PlayerClass[]
local players = {}
for _, planet in pairs(FindPlanet.Get_All_Planets()) do
local owner = planet.Get_Owner()
local factionName = owner.Get_Faction_Name()
for _, faction in pairs(Factions) do
if faction.Name == factionName then
local player = PlayerClass:New(owner)
players[player.Id] = player
end
end
end
return players
end