require("PGBase") require("GameManager/Constants") require("GameManager/GalacticGameClass") require("GameManager/TacticalGameClass") require("GameManager/SkirmishGameClass") -- ================================================== -- Script Locals -- ================================================== ---Debug Counter. When this equals ServiceDebugRate, the script will print debug stats. local DebugCounter = 0 ---Debugging service rate. local ServiceDebugRate = 10 ---The Galactic Game manager. ---@type GalacticGameClass|nil local GalacticGame = nil ---The Tactical Game manager. ---@type TacticalGameClass|SkirmishGameClass|nil local TacticalGame = nil -- ================================================== -- Script Globals -- ================================================== ScriptPoolCount = 0 ServiceRate = 1 ScriptShouldCRC = false ---GameSpy Game Stats table ---@deprecated GameSpy_Game_Stats = {} ---GameSpy Player Stats table ---@deprecated GameSpy_Player_Stats = {} ---Tactical Frag/Death Stat Table for post-game. ---[frag|death][playerid][object_type][build_count, credits_spent, combat_power] TacticalKillStatsTable = { [FragIndex] = {}, [DeathIndex] = {} } -- ================================================== -- Script State Functions -- ================================================== ---Sets up the base variables for this script. function Base_Definitions() DebugMessage("%s -- In Base_Definitions.", tostring(Script)) DebugCounter = 0 end ---Main script function. Does event pumps and servicing. ---@diagnostic disable-next-line function main() DebugMessage("%s -- In main.", tostring(Script)) if GameService then while 1 do GameService() PumpEvents() end end ScriptExit() end ---Script servicing function. function GameService() DebugCounter = DebugCounter + 1 if DebugCounter == ServiceDebugRate then ServiceDebug() DebugCounter = 0 end if GalacticGame then GalacticGame:Service() end if TacticalGame then TacticalGame:Service() end end ---Script debug servicing. function ServiceDebug() DebugMessage("%s -- TacticalKillStatsTable dump:", tostring(Script)) local fragEntry = TacticalKillStatsTable[FragIndex] if fragEntry then for playerId, unitTypes in pairs(fragEntry) do for objType, data in pairs(unitTypes) do DebugMessage(" FRAG player=%d type=%s kills=%d cp=%d cost=%d score=%d", playerId, tostring(objType), data.kills, data.combat_power, data.build_cost, data.score_value) end end else DebugMessage(" FRAG (empty)") end local deathEntry = TacticalKillStatsTable[DeathIndex] if deathEntry then for playerId, unitTypes in pairs(deathEntry) do for objType, data in pairs(unitTypes) do DebugMessage(" DEATH player=%d type=%s kills=%d cp=%d cost=%d score=%d", playerId, tostring(objType), data.kills, data.combat_power, data.build_cost, data.score_value) end end else DebugMessage(" DEATH (empty)") end end -- ================================================== -- Reset State -- ================================================== ---Reset the Tactical mode game stats. function Reset_Tactical_Stats() DebugMessage("%s -- In Reset_Tactical_Stats", tostring(Script)) TacticalKillStatsTable = { [FragIndex] = {}, [DeathIndex] = {} } TacticalTeamKillStatsTable = { [FragIndex] = {}, [DeathIndex] = {} } ResetTacticalRegistry() end ---Reset all the stats and player lists. function Reset_Stats() DebugMessage("%s -- In Reset_Stats", tostring(Script)) Reset_Tactical_Stats() end ---A dirty hack to reset tactical script registry values function ResetTacticalRegistry() DebugMessage("Resetting Allow_AI_Controlled_Fog_Reveal to 1 (allowed)") GlobalValue.Set("Allow_AI_Controlled_Fog_Reveal", 1) end --- ================================================== --- Event Handlers --- ================================================== ---This event is triggered on a game mode start. ---@param mode string Name of the new mode (i.e. Galactic, Land, Space) ---@param map string Name of the map. function Game_Mode_Starting_Event(mode, map) DebugMessage("%s -- Game Mode %s (%s) now starting.", tostring(Script), mode, map) LocalPlayer = Find_Player("local") if StringCompare(mode, "Galactic") then -- Galactic Campaign Init_Galactic() elseif GalacticGame then -- Galactic mode transition to Tactical Init_Tactical(mode) else -- Skirmish tactical Init_Skirmish(mode) end end ---This event is triggered on a game mode end. ---@param oldMode string Name of the old mode (i.e. Galactic, Land, Space) function Game_Mode_Ending_Event(oldMode) DebugMessage("%s -- Game Mode %s now ending.", tostring(Script), oldMode) if StringCompare(oldMode, "Galactic") then -- Galactic mode ending Reset_Galactic() elseif GalacticGame then -- Tactical mode transition to Galactic Reset_Tactical() else -- Skirmish mode ending Reset_Skirmish() end LocalPlayer = nil end ---This event is triggered when a player quits the game. ---@param player PlayerObject FoC PlayerWrapper object that just quit. function Player_Quit_Event(player) DebugMessage("%s -- Player %s (%d) has quit.", tostring(Script), player.Get_Name(), player.Get_ID()) if TacticalGame then TacticalGame:PlayerQuit(player.Get_ID()) end end ---This event is triggered when production has finished in a tactical mode ---@param objectType GameObjectType FoC GameObjectTypeWrapper object that was just built. ---@param player PlayerObject FoC PlayerWrapper object that built the object. ---@param location PlanetObject|nil FoC GameObjectWrapper of the planet. function Tactical_Production_End_Event(objectType, player, location) if location then DebugMessage("%s -- Tactical production of unit %s by %s ended at %s.", tostring(Script), objectType.Get_Name(), player.Get_Name(), location.Get_Type().Get_Name()) else DebugMessage("%s -- Tactical production of unit %s by %s ended.", tostring(Script), objectType.Get_Name(), player.Get_Name()) end if TacticalGame then TacticalGame:UnitBuilt(objectType, player) end end ---This event is triggered when a unit is destroyed in tactical mode. ---@param object GameObject FoC GameObjectWrapper object that was just killed. ---@param killer PlayerObject FoC PlayerWrapper object that killed the object. function Tactical_Unit_Destroyed_Event(object, killer) DebugMessage("%s -- Tactical unit %s destroyed by %s.", tostring(Script), object.Get_Type().Get_Name(), killer.Get_Name()) if TacticalGame then TacticalGame:UnitKilled(object, killer) end end ---This event is triggered when production has begun on an item at a given planet. ---@param planet PlanetObject FoC GameObjectWrapper object of the planet. ---@param objectType GameObjectType FoC GameObjectTypeWrapper object that was just queued. function Galactic_Production_Begin_Event(planet, objectType) DebugMessage("%s -- Galactic production of %s started at %s.", tostring(Script), objectType.Get_Name(), planet.Get_Type().Get_Name()) end ---This event is triggered when production has been prematurely canceled ---on an item at a given planet. ---@param planet PlanetObject FoC GameObjectWrapper object of the planet. ---@param objectType GameObjectType FoC GameObjectTypeWrapper object that was just canceled.. function Galactic_Production_Canceled_Event(planet, objectType) DebugMessage("%s -- Galactic production of %s canceled at %s.", tostring(Script), objectType.Get_Name(), planet.Get_Type().Get_Name()) end ---This event is triggered when production has finished on an item at a given planet. ---@param planet PlanetObject FoC GameObjectWrapper or of the planet. ---@param object GameObject|GameObjectType FoC GameObjectWrapper or GameObjectTypeWrapper of the object that was just created. function Galactic_Production_End_Event(planet, object) local typeName = "" if object.Get_Type == nil then -- object must be a GameObjectTypeWrapper not a GameObjectWrapper if it doesn't -- have a Get_Type function. typeName = object.Get_Name() else -- object points to the GameObjectWrapper that was just created. typeName = object.Get_Type().Get_Name() end DebugMessage("%s -- Galactic production of %s ended at %s.", tostring(Script), typeName, planet.Get_Type().Get_Name()) end ---This event is triggered when a unit is destroyed in galactic mode. ---@param object GameObject FoC GameObjectWrapper object that was just killed. ---@param killer PlayerObject FoC PlayerWrapper object that killed the object. function Galactic_Unit_Destroyed_Event(object, killer) DebugMessage("%s -- Object %s killed by %s.", tostring(Script), object.Get_Type().Get_Name(), killer.Get_Name()) end ---This event is triggered when the level of a starbase changes. ---@param planet PlanetObject FoC GameObjectWrapper object of the planet. ---@param oldType GameObjectType FoC GameObjectTypeWrapper object of the old starbase type. ---@param newType GameObjectType FoC GameObjectTypeWrapper object of the new starbase type. function Galactic_Starbase_Level_Change(planet, oldType, newType) DebugMessage("%s -- %s Starbase changed from %s to %s.", tostring(Script), planet.Get_Type().Get_Name(), tostring(oldType), tostring(newType)) if oldType == nil then return end if newType ~= nil then return end local fake_object_type = oldType local fake_object_player = planet.Get_Owner() local fake_object = {} fake_object.Get_Owner = function() return fake_object_player end fake_object.Get_Type = function() return fake_object_type end fake_object.Get_Game_Scoring_Type = function() return fake_object_type end fake_object.Is_Valid = function() return true end Galactic_Unit_Destroyed_Event(fake_object, planet.Get_Final_Blow_Player()) end ---This event is called when a planet changes faction in galactic mode. ---@param planet PlanetObject FoC GameObjectWrapper object of the planet. ---@param newOwner PlayerObject FoC PlayerWrapper of the new owner. ---@param oldOwner PlayerObject FoC PlayerWrapper of the old owner. function Galactic_Planet_Faction_Change(planet, newOwner, oldOwner) local planetName = planet.Get_Type().Get_Name() DebugMessage("%s -- %s changed control from %s to %s.", tostring(Script), planetName, oldOwner.Get_Name(), newOwner.Get_Name()) end ---This event is called when a hero is neutralized by another hero in galactic mode. ---@param heroType GameObjectType FoC GameObjectTypeWrapper object for the neutralized hero type. ---@param killer GameObject FoC GameObjectWrapper object that killed the hero. function Galactic_Neutralized_Event(heroType, killer) DebugMessage("%s -- Hero %s killed by %s.", tostring(Script), heroType.Get_Name(), killer.Get_Owner().Get_Name()) end --- ================================================== --- Engine Callbacks --- ================================================== ---Returns the number of frags by player for the given object type. ---@param objectType GameObjectType FoC GameObjectTypeWrapper object to query. ---@param player PlayerObject FoC PlayerWrapper object to query. ---@return integer function Get_Frag_Count_For_Type(objectType, player) return 0 end ---Returns the number of heroes neutralized by player for the given object type. ---@param objectType GameObjectType FoC GameObjectTypeWrapper object to query. ---@param player PlayerObject FoC PlayerWrapper object to query. ---@return integer function Get_Neutralized_Count_For_Type(objectType, player) return 0 end ---Returns a game stat for the provided control ID. ---@param player PlayerObject FoC PlayerWrapper object to query. ---@param controlId string The Control ID. ---@param isTactical boolean Whether the game mode was a tactical mode. ---@return number|string function Get_Game_Stat_For_Control_ID(player, controlId, isTactical) DebugMessage("%s -- In Get_Game_Stat_For_Control_ID for %s, Control %s, %s", tostring(Script), player.Get_Name(), controlId, isTactical and "Tactical" or "Galactic") if StringCompare(controlId, "IDC_MILITARY_EFFICIENCY_STATIC") then elseif StringCompare(controlId, "IDC_CONQUEST_EFFICIENCY_STATIC") then elseif StringCompare(controlId, "IDC_KILL_EFFICIENCY_STATIC") then elseif StringCompare(controlId, "IDC_YOUR_LOSS_VAL_STATIC") then elseif StringCompare(controlId, "IDC_ENEMY_LOSS_VAL_STATIC") then elseif StringCompare(controlId, "IDC_TITLE_STATIC") then else DebugMessage("%s -- Unknown Control ID: %s", tostring(Script), controlId) end return 0 end ---Returns the current Player ID winner by score. ---@return integer Player ID function Get_Current_Winner_By_Score() return 0 end --- ================================================== --- Engine Callbacks for GameSpy [deprecated] --- ================================================== ---Updates the GameSpy game stats table. ---@deprecated function Update_GameSpy_Game_Stats() GameSpy_Game_Stats = {} end ---Updates the GameSpy player stats table ---@param player PlayerObject FoC PlayerWrapper object. ---@deprecated function Update_GameSpy_Player_Stats(player) GameSpy_Player_Stats = {} end --- ================================================== --- Galactic Functions --- ================================================== ---Initializes Galactic mode. function Init_Galactic() DebugMessage("%s -- Initializing Galactic rules.", tostring(Script)) Reset_Stats() GalacticGame = GalacticGameClass:New() end ---Resets Galactic mode. function Reset_Galactic() DebugMessage("%s -- Resetting Galactic rules.", tostring(Script)) Reset_Stats() GalacticGame = nil end --- ================================================== --- Tactical Functions --- ================================================== ---Initializes Tactical mode. ---@param gameMode string The tactical game mode. function Init_Tactical(gameMode) DebugMessage("%s -- Initializing Tactical %s rules.", tostring(Script), gameMode) Reset_Tactical_Stats() TacticalGame = TacticalGameClass:New(gameMode) TacticalGame.KillStatsTable = TacticalKillStatsTable GUIManager:InitTactical() TextManager:RegisterView(TacticalGame.CombatFeed) TextManager:SetCurrentView("combat_feed") end ---Resets Tactical mode. function Reset_Tactical() DebugMessage("%s -- Resetting Tactical rules.", tostring(Script)) Reset_Tactical_Stats() TacticalGame = nil GUIManager:Reset() TextManager:Reset() end --- ================================================== --- Skirmish Functions --- ================================================== ---Initializes Skirmish mode. ---@param gameMode string The tactical game mode. function Init_Skirmish(gameMode) DebugMessage("%s -- Initializing Skirmish Tactical %s rules.", tostring(Script), gameMode) Reset_Stats() TacticalGame = SkirmishGameClass:New(gameMode) TacticalGame.KillStatsTable = TacticalKillStatsTable GUIManager:InitSkirmish(TacticalGame.IsLocalSpectator) TextManager:RegisterView(TacticalGame.CombatFeed) TextManager:SetCurrentView("combat_feed") end ---Resets Skirmish mode. function Reset_Skirmish() DebugMessage("%s -- Resetting Skirmish Tactical rules.", tostring(Script)) Reset_Stats() TacticalGame = nil GUIManager:Reset() TextManager:Reset() end