Initial commit
This commit is contained in:
152
.luadefs/foc_engine.lua
Normal file
152
.luadefs/foc_engine.lua
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
---@meta
|
||||||
|
---@diagnostic disable: missing-fields
|
||||||
|
-- Empire at War / Forces of Corruption engine API stubs.
|
||||||
|
-- This file is never executed — the Lua Language Server reads it as definitions only.
|
||||||
|
|
||||||
|
-- ==================================================
|
||||||
|
-- Engine Object Types
|
||||||
|
-- ==================================================
|
||||||
|
|
||||||
|
---A player in the game (C++ PlayerWrapper userdata).
|
||||||
|
---@class PlayerWrapper
|
||||||
|
---@field Get_Name fun(): string
|
||||||
|
---@field Get_ID fun(): integer
|
||||||
|
---@field Get_Faction fun(): string
|
||||||
|
---@field Get_Credits fun(): number
|
||||||
|
---@field Is_Valid fun(): boolean
|
||||||
|
---@field Is_Human fun(): boolean
|
||||||
|
---@field Is_Ally fun(other: PlayerWrapper): boolean
|
||||||
|
---@field Is_Enemy fun(other: PlayerWrapper): boolean
|
||||||
|
---@field Select_Object fun(other: GameObjectWrapper)
|
||||||
|
|
||||||
|
---A game object instance (C++ GameObjectWrapper userdata).
|
||||||
|
---@class GameObjectWrapper
|
||||||
|
---@field Get_Type fun(): GameObjectTypeWrapper
|
||||||
|
---@field Get_Owner fun(): PlayerWrapper
|
||||||
|
---@field Get_Final_Blow_Player fun(): PlayerWrapper
|
||||||
|
---@field Get_Game_Scoring_Type fun(): GameObjectTypeWrapper
|
||||||
|
---@field Is_Valid fun(): boolean
|
||||||
|
---@field Is_Pool_Safe fun(): boolean
|
||||||
|
---@field Service_Wrapper fun()
|
||||||
|
|
||||||
|
---A game object type definition (C++ GameObjectTypeWrapper userdata).
|
||||||
|
---@class GameObjectTypeWrapper
|
||||||
|
---@field Get_Name fun(): string
|
||||||
|
---@field Is_Valid fun(): boolean
|
||||||
|
|
||||||
|
-- ==================================================
|
||||||
|
-- Script Object
|
||||||
|
-- ==================================================
|
||||||
|
|
||||||
|
---The engine-injected script context object.
|
||||||
|
---@class ScriptObject
|
||||||
|
---@field Debug_Should_Issue_Event_Alert fun(): boolean
|
||||||
|
|
||||||
|
---Engine-injected script context. Set by the engine before the script runs.
|
||||||
|
---@type ScriptObject
|
||||||
|
Script = {}
|
||||||
|
|
||||||
|
---Engine-injected object context. Set by the engine before the script runs.
|
||||||
|
---@type GameObjectWrapper
|
||||||
|
Object = {}
|
||||||
|
|
||||||
|
-- ==================================================
|
||||||
|
-- GlobalValue / ThreadValue
|
||||||
|
-- (callable table: GlobalValue("key") to get, GlobalValue.Set("key", val) to set)
|
||||||
|
-- ==================================================
|
||||||
|
|
||||||
|
---@class ValueStore
|
||||||
|
---@field Set fun(key: string, value: any)
|
||||||
|
---@operator call(string): any
|
||||||
|
|
||||||
|
---Persistent global value store shared across scripts.
|
||||||
|
---@type ValueStore
|
||||||
|
GlobalValue = {}
|
||||||
|
|
||||||
|
---Per-thread value store.
|
||||||
|
---@type ValueStore
|
||||||
|
ThreadValue = {}
|
||||||
|
|
||||||
|
-- ==================================================
|
||||||
|
-- Engine Global Functions
|
||||||
|
-- ==================================================
|
||||||
|
|
||||||
|
---Pumps services for the script.
|
||||||
|
function Pump_Service() end
|
||||||
|
|
||||||
|
---Compares two strings for equality (case-insensitive in FoC).
|
||||||
|
---@param a string
|
||||||
|
---@param b string
|
||||||
|
---@return boolean
|
||||||
|
function StringCompare(a, b) end
|
||||||
|
|
||||||
|
---Finds a player by name (e.g. "local", "empire", "rebel").
|
||||||
|
---@param name string
|
||||||
|
---@return PlayerWrapper
|
||||||
|
function Find_Player(name) end
|
||||||
|
|
||||||
|
---Returns the current game time in seconds.
|
||||||
|
---@return number
|
||||||
|
function GetCurrentTime() end
|
||||||
|
|
||||||
|
---Returns the ID of the current thread, or -1 if not in a thread.
|
||||||
|
---@return integer
|
||||||
|
function GetThreadID() end
|
||||||
|
|
||||||
|
---Returns the next pending event function, or nil if the queue is empty.
|
||||||
|
---@return (fun(...): any) | nil
|
||||||
|
function GetEvent() end
|
||||||
|
|
||||||
|
---Exits the current script.
|
||||||
|
function _ScriptExit() end
|
||||||
|
|
||||||
|
---Pops up a message box (internal engine call).
|
||||||
|
---@param message string
|
||||||
|
function _MessagePopup(message) end
|
||||||
|
|
||||||
|
---Sends a message to the script log (internal engine call).
|
||||||
|
---@param message string
|
||||||
|
function _ScriptMessage(message) end
|
||||||
|
|
||||||
|
---Sends a message to the debug output (internal engine call — note: typo in original source).
|
||||||
|
---@param message string
|
||||||
|
function _OuputDebug(message) end
|
||||||
|
|
||||||
|
---Dumps the current Lua call stack as a string.
|
||||||
|
---@return string
|
||||||
|
function DumpCallStack() end
|
||||||
|
|
||||||
|
---Sets the visibility of the named component.
|
||||||
|
---@param component string
|
||||||
|
---@param isVisible boolean
|
||||||
|
function GUI_Component_Visibility(component, isVisible) end
|
||||||
|
|
||||||
|
---Sets the text for the named component.
|
||||||
|
---@param component string
|
||||||
|
---@param text string
|
||||||
|
function GUI_Component_Text(component, text) end
|
||||||
|
|
||||||
|
---Sets the text color for the named component.
|
||||||
|
---@param component string
|
||||||
|
---@param r number
|
||||||
|
---@param g number
|
||||||
|
---@param b number
|
||||||
|
---@param a number
|
||||||
|
function GUI_Text_Color(component, r, g, b, a) end
|
||||||
|
|
||||||
|
---Sets the icon for the named component.
|
||||||
|
---@param component string
|
||||||
|
---@param icon string
|
||||||
|
---@param r number
|
||||||
|
---@param g number
|
||||||
|
---@param b number
|
||||||
|
---@param a number
|
||||||
|
function GUI_Button_Icon(component, icon, r, g, b, a) end
|
||||||
|
|
||||||
|
---Finds all objects matching the criteria.
|
||||||
|
---@param a any
|
||||||
|
---@param b any
|
||||||
|
---@param c any
|
||||||
|
---@param d any
|
||||||
|
---@return GameObjectWrapper[]
|
||||||
|
function Find_All_Objects_Of_Type(a, b, c, d) end
|
||||||
12
.vscode/settings.json
vendored
Normal file
12
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"Lua.workspace.library": [
|
||||||
|
"${workspaceFolder}/.luadefs"
|
||||||
|
],
|
||||||
|
"Lua.workspace.checkThirdParty": false,
|
||||||
|
"Lua.runtime.version": "Lua 5.1",
|
||||||
|
"Lua.diagnostics.globals": [
|
||||||
|
"Script",
|
||||||
|
"GlobalValue",
|
||||||
|
"ThreadValue"
|
||||||
|
]
|
||||||
|
}
|
||||||
287
Data/Scripts/Library/PGBase.lua
Normal file
287
Data/Scripts/Library/PGBase.lua
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGBase.lua#2 $
|
||||||
|
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
--
|
||||||
|
-- (C) Petroglyph Games, Inc.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- ***** ** * *
|
||||||
|
-- * ** * * *
|
||||||
|
-- * * * * *
|
||||||
|
-- * * * * * * * *
|
||||||
|
-- * * *** ****** * ** **** *** * * * ***** * ***
|
||||||
|
-- * ** * * * ** * ** ** * * * * ** ** ** *
|
||||||
|
-- *** ***** * * * * * * * * ** * * * *
|
||||||
|
-- * * * * * * * * * * * * * * *
|
||||||
|
-- * * * * * * * * * * ** * * * *
|
||||||
|
-- * ** * * ** * ** * * ** * * * *
|
||||||
|
-- ** **** ** * **** ***** * ** *** * *
|
||||||
|
-- * * *
|
||||||
|
-- * * *
|
||||||
|
-- * * *
|
||||||
|
-- * * * *
|
||||||
|
-- **** * *
|
||||||
|
--
|
||||||
|
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
-- C O N F I D E N T I A L S O U R C E C O D E -- D O N O T D I S T R I B U T E
|
||||||
|
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
--
|
||||||
|
-- $File: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGBase.lua $
|
||||||
|
--
|
||||||
|
-- Original Author: Brian Hayes
|
||||||
|
--
|
||||||
|
-- $Author: James_Yarrow $
|
||||||
|
--
|
||||||
|
-- $Change: 45244 $
|
||||||
|
--
|
||||||
|
-- $DateTime: 2006/05/26 10:01:00 $
|
||||||
|
--
|
||||||
|
-- $Revision: #2 $
|
||||||
|
--
|
||||||
|
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
require("PGDebug")
|
||||||
|
|
||||||
|
YieldCount = 0;
|
||||||
|
|
||||||
|
function ScriptExit()
|
||||||
|
_ScriptExit() -- set a flag in 'C' to terminate the whole script on next yield
|
||||||
|
|
||||||
|
if GetThreadID() >= 0 then
|
||||||
|
coroutine.yield(false) -- return false to exit this thread
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Sleep(time)
|
||||||
|
|
||||||
|
--DebugMessage("Sleeping... SleepTime: %.3f, CurTime: %.3f\n", time, GetCurrentTime())
|
||||||
|
ThreadValue.Set("StartTime", GetCurrentTime())
|
||||||
|
while GetCurrentTime() - ThreadValue("StartTime") < time do
|
||||||
|
PumpEvents()
|
||||||
|
end
|
||||||
|
--DebugMessage("Done with Sleep. Continuing, CurTime: %.3f\n", GetCurrentTime())
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Service the block until optional max duration has expired or alternate break function returns true
|
||||||
|
-- Pass -1 max_duration to use optional alternate break function with no time limit
|
||||||
|
function BlockOnCommand(block, max_duration, alternate_break_func)
|
||||||
|
|
||||||
|
PumpEvents()
|
||||||
|
|
||||||
|
if not block then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
break_block = false
|
||||||
|
|
||||||
|
ThreadValue.Set("BlockStart", GetCurrentTime())
|
||||||
|
|
||||||
|
repeat
|
||||||
|
if break_block == true then
|
||||||
|
break_block = false
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
PumpEvents()
|
||||||
|
|
||||||
|
if ((max_duration ~= nil) and (max_duration ~= -1)
|
||||||
|
and (GetCurrentTime() - ThreadValue("BlockStart") > max_duration)) then
|
||||||
|
--MessageBox("%s -- Had a time limit and it expired", tostring(Script))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if ((alternate_break_func ~= nil) and alternate_break_func()) then
|
||||||
|
--MessageBox("%s-- had a break func and it returned true", tostring(Script))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
until (block.IsFinished() == true)
|
||||||
|
|
||||||
|
PumpEvents()
|
||||||
|
|
||||||
|
return block.Result()
|
||||||
|
end
|
||||||
|
|
||||||
|
function BreakBlock()
|
||||||
|
break_block = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestCommand(block)
|
||||||
|
if not block then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
PumpEvents()
|
||||||
|
|
||||||
|
return block.IsFinished()
|
||||||
|
end
|
||||||
|
|
||||||
|
function PumpEvents()
|
||||||
|
|
||||||
|
if Object and type(Object) == "userdata" then
|
||||||
|
Object.Service_Wrapper()
|
||||||
|
end
|
||||||
|
|
||||||
|
if Pump_Service and type(Pump_Service) == "function" then
|
||||||
|
Pump_Service()
|
||||||
|
end
|
||||||
|
|
||||||
|
if ThreadValue("InPumpEvents") then
|
||||||
|
ScriptError("%s -- Already in pump event!!", tostring(Script))
|
||||||
|
end
|
||||||
|
|
||||||
|
ThreadValue.Set("InPumpEvents", true)
|
||||||
|
|
||||||
|
--DebugMessage("%s -- Entering yield. Count: %d, Time: %.3f\n", tostring(Script), YieldCount, GetCurrentTime())
|
||||||
|
YieldCount = YieldCount + 1
|
||||||
|
coroutine.yield(true) -- yield here and return to 'C'
|
||||||
|
--DebugMessage("%s -- Return from yield. Count: %d, Time: %.3f\n", tostring(Script), YieldCount, GetCurrentTime())
|
||||||
|
|
||||||
|
CurrentEvent = GetEvent()
|
||||||
|
while CurrentEvent do
|
||||||
|
ScriptMessage("%s -- Pumping Event: %s.", tostring(Script), tostring(CurrentEvent))
|
||||||
|
EventParams = GetEvent.Params()
|
||||||
|
if EventParams then
|
||||||
|
CurrentEvent(unpack(EventParams))
|
||||||
|
else
|
||||||
|
CurrentEvent()
|
||||||
|
end
|
||||||
|
|
||||||
|
if Script.Debug_Should_Issue_Event_Alert() and DebugEventAlert then
|
||||||
|
DebugEventAlert(CurrentEvent, EventParams)
|
||||||
|
end
|
||||||
|
|
||||||
|
CurrentEvent = GetEvent()
|
||||||
|
end
|
||||||
|
ThreadValue.Set("InPumpEvents", false)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestValid(wrapper)
|
||||||
|
if wrapper == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if wrapper.Is_Valid == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return wrapper.Is_Valid()
|
||||||
|
end
|
||||||
|
|
||||||
|
function Clamp(value, min, max)
|
||||||
|
if value < min then
|
||||||
|
return min
|
||||||
|
elseif value > max then
|
||||||
|
return max
|
||||||
|
else
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Nasty hack of a floor function to be replaced if a math library floor funciton is exposed
|
||||||
|
function Dirty_Floor(val)
|
||||||
|
return string.format("%d", val) -- works on implicit string to int conversion
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Machine independent modulus function
|
||||||
|
function Simple_Mod(a,b)
|
||||||
|
--return a-b*math.floor(a/b)
|
||||||
|
return a-b*Dirty_Floor(a/b)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Returns if something happened, given a % chance
|
||||||
|
function Chance(seed, percent)
|
||||||
|
roll = Simple_Mod((seed + 1), 100)
|
||||||
|
is_allowed = roll < percent
|
||||||
|
DebugMessage("%s -- seed:%d percent:%d roll:%d is_allowed:%s", tostring(Script), seed, percent, roll, tostring(is_allowed))
|
||||||
|
return is_allowed
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GetCurrentMinute()
|
||||||
|
--return math.floor(GetCurrentTime()/60)
|
||||||
|
return Dirty_Floor(GetCurrentTime()/60)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Every X seconds, the AI will have a new opportunity to see if it's allowed to use an ability
|
||||||
|
function GetAbilityChanceSeed()
|
||||||
|
return GetCurrentTime()
|
||||||
|
end
|
||||||
|
|
||||||
|
function GetChanceAllowed(difficulty)
|
||||||
|
--Possibly change these back, but randomness makes things hard to test
|
||||||
|
chance = 100
|
||||||
|
if difficulty == "Easy" then
|
||||||
|
chance = 100
|
||||||
|
elseif difficulty == "Hard" then
|
||||||
|
chance = 100
|
||||||
|
end
|
||||||
|
return chance
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function PlayerSpecificName(player_object, var_name)
|
||||||
|
-- ret_value = tostring(player_object.Get_ID()) .. "_" .. var_name
|
||||||
|
-- DebugMessage("%s -- creating player specific string %s.", tostring(Script), ret_value)
|
||||||
|
-- return ret_value
|
||||||
|
return (tostring("PLAYER" .. player_object.Get_ID()) .. "_" .. var_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Flush_G()
|
||||||
|
|
||||||
|
entries_for_deletion = {}
|
||||||
|
|
||||||
|
--Define the set of tables that we had better keep around
|
||||||
|
very_important_tables = {
|
||||||
|
_LOADED,
|
||||||
|
coroutine,
|
||||||
|
string,
|
||||||
|
LuaWrapperMetaTable,
|
||||||
|
_G,
|
||||||
|
security,
|
||||||
|
table,
|
||||||
|
entries_for_deletion
|
||||||
|
}
|
||||||
|
|
||||||
|
--Silly thing is nil (we think) if we try to add it earlier
|
||||||
|
table.insert(very_important_tables, very_important_tables)
|
||||||
|
|
||||||
|
--Iterate all globals
|
||||||
|
for i,g_entry in pairs(_G) do
|
||||||
|
|
||||||
|
if type(g_entry) == "table" then
|
||||||
|
--Tables are inherently unsafe: who knows what might be in there?
|
||||||
|
--If they're not in the list of things we must keep then they go.
|
||||||
|
|
||||||
|
for j,important_entry in pairs(very_important_tables) do
|
||||||
|
if important_entry == g_entry then
|
||||||
|
keep_table = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not keep_table then
|
||||||
|
table.insert(entries_for_deletion, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
keep_table = nil
|
||||||
|
|
||||||
|
elseif type(g_entry) == "userdata" then
|
||||||
|
--Some User Data (e.g. our code functions) should be kept, but some is very, very dangerous.
|
||||||
|
--Query the object to see whether it's safe to persist.
|
||||||
|
|
||||||
|
if not g_entry.Is_Pool_Safe() then
|
||||||
|
table.insert(entries_for_deletion, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
for i,bad_entry in pairs(entries_for_deletion) do
|
||||||
|
_G[bad_entry] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
entries_for_deletion = nil
|
||||||
|
very_important_tables = nil
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
86
Data/Scripts/Library/PGDebug.lua
Normal file
86
Data/Scripts/Library/PGDebug.lua
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGDebug.lua#1 $
|
||||||
|
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
--
|
||||||
|
-- (C) Petroglyph Games, Inc.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- ***** ** * *
|
||||||
|
-- * ** * * *
|
||||||
|
-- * * * * *
|
||||||
|
-- * * * * * * * *
|
||||||
|
-- * * *** ****** * ** **** *** * * * ***** * ***
|
||||||
|
-- * ** * * * ** * ** ** * * * * ** ** ** *
|
||||||
|
-- *** ***** * * * * * * * * ** * * * *
|
||||||
|
-- * * * * * * * * * * * * * * *
|
||||||
|
-- * * * * * * * * * * ** * * * *
|
||||||
|
-- * ** * * ** * ** * * ** * * * *
|
||||||
|
-- ** **** ** * **** ***** * ** *** * *
|
||||||
|
-- * * *
|
||||||
|
-- * * *
|
||||||
|
-- * * *
|
||||||
|
-- * * * *
|
||||||
|
-- **** * *
|
||||||
|
--
|
||||||
|
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
-- C O N F I D E N T I A L S O U R C E C O D E -- D O N O T D I S T R I B U T E
|
||||||
|
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
--
|
||||||
|
-- $File: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGDebug.lua $
|
||||||
|
--
|
||||||
|
-- Original Author: Brian Hayes
|
||||||
|
--
|
||||||
|
-- $Author: Andre_Arsenault $
|
||||||
|
--
|
||||||
|
-- $Change: 37816 $
|
||||||
|
--
|
||||||
|
-- $DateTime: 2006/02/15 15:33:33 $
|
||||||
|
--
|
||||||
|
-- $Revision: #1 $
|
||||||
|
--
|
||||||
|
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
function DebugEventAlert(event, params)
|
||||||
|
message = tostring(Script) .. ": handled event " .. tostring(event)
|
||||||
|
|
||||||
|
function AppendParameter(ival, parameter)
|
||||||
|
message = message .. "\nParameter " .. tostring(ival) .. ": " .. tostring(parameter)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.foreachi(params, AppendParameter)
|
||||||
|
|
||||||
|
MessageBox(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
function MessageBox(...)
|
||||||
|
_MessagePopup(string.format(unpack(arg)))
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScriptMessage(...)
|
||||||
|
_ScriptMessage(string.format(unpack(arg)))
|
||||||
|
end
|
||||||
|
|
||||||
|
function DebugMessage(...)
|
||||||
|
_ScriptMessage(string.format(unpack(arg)))
|
||||||
|
end
|
||||||
|
|
||||||
|
function OutputDebug(...)
|
||||||
|
_OuputDebug(string.format(unpack(arg)))
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScriptError(...)
|
||||||
|
outstr = string.format(unpack(arg))
|
||||||
|
_OuputDebug(outstr .. "\n")
|
||||||
|
_ScriptMessage(outstr)
|
||||||
|
outstr = DumpCallStack()
|
||||||
|
_OuputDebug(outstr .. "\n")
|
||||||
|
_ScriptMessage(outstr)
|
||||||
|
ScriptExit()
|
||||||
|
end
|
||||||
|
|
||||||
|
function DebugPrintTable(unit_table)
|
||||||
|
DebugMessage("%s -- unit table contents:", tostring(Script))
|
||||||
|
for key, obj in pairs(unit_table) do
|
||||||
|
DebugMessage("%s -- \t\t** unit:%s", tostring(Script), tostring(obj))
|
||||||
|
end
|
||||||
|
end
|
||||||
27
Data/Scripts/Miscellaneous/GameManager/ColorStruct.lua
Normal file
27
Data/Scripts/Miscellaneous/GameManager/ColorStruct.lua
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
require("PGBase")
|
||||||
|
|
||||||
|
---@class ColorStruct
|
||||||
|
---@field R number The red component.
|
||||||
|
---@field G number The green component.
|
||||||
|
---@field B number The blue component.
|
||||||
|
ColorStruct = {}
|
||||||
|
ColorStruct.__index = ColorStruct
|
||||||
|
|
||||||
|
---Creates a new Color object.
|
||||||
|
---@param r number The red component
|
||||||
|
---@param g number The green component
|
||||||
|
---@param b number The blue component
|
||||||
|
---@return ColorStruct
|
||||||
|
function ColorStruct:New(r, g, b)
|
||||||
|
local self = setmetatable({}, ColorStruct)
|
||||||
|
|
||||||
|
self.R = Clamp(r, 0, 1)
|
||||||
|
self.G = Clamp(g, 0, 1)
|
||||||
|
self.B = Clamp(b, 0, 1)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function ColorStruct:Debug()
|
||||||
|
return string.format("RGB (%d, %d, %d)", self.R, self.G, self.B)
|
||||||
|
end
|
||||||
105
Data/Scripts/Miscellaneous/GameManager/Constants.lua
Normal file
105
Data/Scripts/Miscellaneous/GameManager/Constants.lua
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
require("FactionStruct")
|
||||||
|
|
||||||
|
-- ==================================================
|
||||||
|
-- Define Faction constants
|
||||||
|
-- ==================================================
|
||||||
|
|
||||||
|
---Defines tactical factions.
|
||||||
|
---@return FactionStruct[]
|
||||||
|
function DefineFactions()
|
||||||
|
---@type FactionStruct[]
|
||||||
|
local factions = {}
|
||||||
|
|
||||||
|
---Rebel Faction
|
||||||
|
---@type FactionStruct
|
||||||
|
local RebelFaction = FactionStruct:New("REBEL")
|
||||||
|
|
||||||
|
RebelFaction.DisplayName = "Rebellion"
|
||||||
|
RebelFaction.Color = ColorStruct:New(1, 0, 0)
|
||||||
|
RebelFaction.Icon = "I_ICON_SPECTATOR_REBEL.TGA"
|
||||||
|
RebelFaction.LandStartUnitName = "Rebel_Infantry_Squad"
|
||||||
|
RebelFaction.SpaceStartUnitName = "Rebel_X-Wing_Squadron"
|
||||||
|
factions[RebelFaction.Name] = RebelFaction
|
||||||
|
|
||||||
|
---Empire Faction
|
||||||
|
---@type FactionStruct
|
||||||
|
local EmpireFaction = FactionStruct:New("EMPIRE")
|
||||||
|
|
||||||
|
EmpireFaction.DisplayName = "Empire"
|
||||||
|
EmpireFaction.Color = ColorStruct:New(0, 1, 1)
|
||||||
|
EmpireFaction.Icon = "I_ICON_SPECTATOR_EMPIRE.TGA"
|
||||||
|
EmpireFaction.LandStartUnitName = "Imperial_Stormtrooper_Squad"
|
||||||
|
EmpireFaction.SpaceStartUnitName = "TIE_Interceptor_Squadron_Container"
|
||||||
|
factions[EmpireFaction.Name] = EmpireFaction
|
||||||
|
|
||||||
|
---Underworld Faction
|
||||||
|
---@type FactionStruct
|
||||||
|
local UnderworldFaction = FactionStruct:New("UNDERWORLD")
|
||||||
|
|
||||||
|
UnderworldFaction.DisplayName = "Zann Consortium"
|
||||||
|
UnderworldFaction.Color = ColorStruct:New(1, 1, 0)
|
||||||
|
UnderworldFaction.Icon = "I_ICON_SPECTATOR_UNDERWORLD.TGA"
|
||||||
|
UnderworldFaction.LandStartUnitName = "Underworld_Merc_Squad"
|
||||||
|
UnderworldFaction.SpaceStartUnitName = "StarViper_Team"
|
||||||
|
factions[UnderworldFaction.Name] = UnderworldFaction
|
||||||
|
|
||||||
|
---Hutts Faction
|
||||||
|
local HuttFaction = FactionStruct:New("HUTTS")
|
||||||
|
|
||||||
|
HuttFaction.DisplayName = "Hutt Cartel"
|
||||||
|
HuttFaction.Color = ColorStruct:New(1, 0, 1)
|
||||||
|
HuttFaction.Icon = "I_ICON_SPECTATOR_HUTTS.TGA"
|
||||||
|
HuttFaction.LandStartUnitName = "Hutt_Soldier_Squad"
|
||||||
|
HuttFaction.SpaceStartUnitName = "V_Wing_Squadron_Container"
|
||||||
|
factions[HuttFaction.Name] = HuttFaction
|
||||||
|
|
||||||
|
---Pirates Faction
|
||||||
|
local PirateFaction = FactionStruct:New("PIRATES")
|
||||||
|
|
||||||
|
PirateFaction.DisplayName = "Pirates"
|
||||||
|
PirateFaction.Color = ColorStruct:New(0, 1, 0)
|
||||||
|
PirateFaction.Icon = "I_ICON_SPECTATOR_PIRATES.TGA"
|
||||||
|
PirateFaction.LandStartUnitName = "Pirate_Soldier_Squad"
|
||||||
|
PirateFaction.SpaceStartUnitName = "Pirate_Fighter_Squadron"
|
||||||
|
factions[PirateFaction.Name] = PirateFaction
|
||||||
|
|
||||||
|
return factions
|
||||||
|
end
|
||||||
|
|
||||||
|
---Constant Global of all Tactical Factions
|
||||||
|
---@type FactionStruct[]
|
||||||
|
Factions = DefineFactions()
|
||||||
|
|
||||||
|
-- ==================================================
|
||||||
|
-- Define UI Constants
|
||||||
|
-- ==================================================
|
||||||
|
|
||||||
|
---GUI Component to display game time.
|
||||||
|
UI_GameTime = "s_select_41"
|
||||||
|
|
||||||
|
---GUI Components to display Team 1 credits.
|
||||||
|
UI_IconT1 = "s_health_42"
|
||||||
|
UI_CreditsT1 = "s_health_41"
|
||||||
|
|
||||||
|
---GUI Component to display Team 2 credits.
|
||||||
|
UI_IconT2 = "s_shield_42"
|
||||||
|
UI_CreditsT2 = "s_shield_41"
|
||||||
|
|
||||||
|
---GUI Component to enable/disable population.
|
||||||
|
UI_PlanetaryPop = "text_planetary_pop"
|
||||||
|
|
||||||
|
---GUI Component to enable/disable tactical credits.
|
||||||
|
UI_CreditsTactical = "text_credits_tactical"
|
||||||
|
|
||||||
|
---Gets the specator marker for the game mode.
|
||||||
|
---@param gameMode string Game mode.
|
||||||
|
---@return string|nil
|
||||||
|
function GetSpectatorMarkerName(gameMode)
|
||||||
|
if StringCompare(gameMode, "Space") then
|
||||||
|
return "Spectator_Reveal_Marker"
|
||||||
|
elseif StringCompare(gameMode, "Land") then
|
||||||
|
return "Spectator_Reveal_Marker_Land"
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
31
Data/Scripts/Miscellaneous/GameManager/FactionStruct.lua
Normal file
31
Data/Scripts/Miscellaneous/GameManager/FactionStruct.lua
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
require("ColorStruct")
|
||||||
|
|
||||||
|
---@class FactionStruct
|
||||||
|
---@field Name string Faction name.
|
||||||
|
---@field DisplayName string Display name.
|
||||||
|
---@field Color ColorStruct Color.
|
||||||
|
---@field Icon string Icon name.
|
||||||
|
---@field LandStartUnitName string Land starting unit name.
|
||||||
|
---@field SpaceStartUnitName string Space starting unit name.
|
||||||
|
FactionStruct = {}
|
||||||
|
FactionStruct.__index = FactionStruct
|
||||||
|
|
||||||
|
---Creates a new Faction struct.
|
||||||
|
---@param name string The internal faction name.
|
||||||
|
---@return FactionStruct
|
||||||
|
function FactionStruct:New(name)
|
||||||
|
local self = setmetatable({}, FactionStruct)
|
||||||
|
|
||||||
|
self.Name = name
|
||||||
|
self.DisplayName = name
|
||||||
|
self.Color = ColorStruct:New(1, 1, 1)
|
||||||
|
self.Icon = ""
|
||||||
|
self.LandStartUnitName = ""
|
||||||
|
self.SpaceStartUnitName = ""
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function FactionStruct:Debug()
|
||||||
|
return string.format("Faction %s (%s)", self.DisplayName, self.Name)
|
||||||
|
end
|
||||||
194
Data/Scripts/Miscellaneous/GameManager/GUIManager.lua
Normal file
194
Data/Scripts/Miscellaneous/GameManager/GUIManager.lua
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
require("PGBase")
|
||||||
|
require("GameManager.Constants")
|
||||||
|
|
||||||
|
---@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.__index = GUIManager
|
||||||
|
|
||||||
|
---Creates a new GUI Manager.
|
||||||
|
---@return GUIManager
|
||||||
|
function GUIManager:New()
|
||||||
|
local self = setmetatable({}, GUIManager)
|
||||||
|
|
||||||
|
self.TacticalGame = nil
|
||||||
|
self.SkirmishGame = nil
|
||||||
|
self.ShowTeamId = 0
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---Initializes the GUI Manager for Skirmish mode.
|
||||||
|
---@param game SkirmishGameClass The Skirmish Game state.
|
||||||
|
function GUIManager:InitSkirmish(game)
|
||||||
|
self.SkirmishGame = game
|
||||||
|
self.TacticalGame = game.TacticalGame
|
||||||
|
|
||||||
|
GUI_Component_Visibility(UI_GameTime, true)
|
||||||
|
|
||||||
|
if self.SkirmishGame.IsLocalSpectator then
|
||||||
|
GUI_Component_Visibility(UI_CreditsT1, true)
|
||||||
|
GUI_Component_Visibility(UI_IconT1, true)
|
||||||
|
|
||||||
|
GUI_Component_Visibility(UI_CreditsT2, true)
|
||||||
|
GUI_Component_Visibility(UI_IconT2, true)
|
||||||
|
|
||||||
|
GUI_Component_Visibility(UI_PlanetaryPop, false)
|
||||||
|
GUI_Component_Visibility(UI_CreditsTactical, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---Initializes the GUI Manager for Tactical mode.
|
||||||
|
---@param game TacticalGameClass The Tactical Game state.
|
||||||
|
function GUIManager:InitTactical(game)
|
||||||
|
self.TacticalGame = game
|
||||||
|
|
||||||
|
GUI_Component_Visibility(UI_GameTime, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Resets the GUI Manager.
|
||||||
|
function GUIManager:Reset()
|
||||||
|
self.SkirmishGame = nil
|
||||||
|
self.TacticalGame = nil
|
||||||
|
|
||||||
|
GUI_Component_Text(UI_GameTime, "")
|
||||||
|
GUI_Text_Color(UI_GameTime, 1, 1, 1, 1)
|
||||||
|
GUI_Component_Visibility(UI_GameTime, false)
|
||||||
|
|
||||||
|
GUI_Component_Text(UI_CreditsT1, "")
|
||||||
|
GUI_Text_Color(UI_CreditsT1, 1, 1, 1, 1)
|
||||||
|
GUI_Component_Visibility(UI_CreditsT1, false)
|
||||||
|
|
||||||
|
GUI_Button_Icon(UI_IconT1, "", 1, 1, 1, 1)
|
||||||
|
GUI_Component_Visibility(UI_IconT1, false)
|
||||||
|
|
||||||
|
GUI_Component_Text(UI_CreditsT2, "")
|
||||||
|
GUI_Text_Color(UI_CreditsT2, 1, 1, 1, 1)
|
||||||
|
GUI_Component_Visibility(UI_CreditsT2, false)
|
||||||
|
|
||||||
|
GUI_Button_Icon(UI_IconT2, "", 1, 1, 1, 1)
|
||||||
|
GUI_Component_Visibility(UI_IconT2, false)
|
||||||
|
|
||||||
|
GUI_Component_Visibility(UI_PlanetaryPop, true)
|
||||||
|
GUI_Component_Visibility(UI_CreditsTactical, true)
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Services Game Time display.
|
||||||
|
---@param tacticalGame TacticalGameClass The current Tactical Game state
|
||||||
|
function ServiceGameTime(tacticalGame)
|
||||||
|
if not tacticalGame then
|
||||||
|
return
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Services Team Credits display.
|
||||||
|
---@param skirmishGame SkirmishGameClass The current Skirmish Game state.
|
||||||
|
function ServiceTeamCredits(skirmishGame)
|
||||||
|
if not skirmishGame then
|
||||||
|
return
|
||||||
|
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 = "+"
|
||||||
|
|
||||||
|
if teamIncome < 0 then
|
||||||
|
positiveText = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local text = string.format("Team %d: $%d (%s%d)", team.Number, teamCredits, positiveText, teamIncome)
|
||||||
|
local icon = team.Faction.Icon
|
||||||
|
local color = team.Faction.Color
|
||||||
|
|
||||||
|
GUI_Button_Icon(uiIcon, icon, color.R, color.G, color.B, 1)
|
||||||
|
GUI_Component_Text(uiText, text)
|
||||||
|
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 function DisplayTeamUnit(unit, uiComponent)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local localPlayer = Find_Player("local")
|
||||||
|
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
|
||||||
73
Data/Scripts/Miscellaneous/GameManager/GalacticGameClass.lua
Normal file
73
Data/Scripts/Miscellaneous/GameManager/GalacticGameClass.lua
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
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 Units UnitClass[] The units in this game.
|
||||||
|
GalacticGameClass = {}
|
||||||
|
GalacticGameClass.__index = GalacticGameClass
|
||||||
|
|
||||||
|
---Creates a new Galactic Game context.
|
||||||
|
---@return GalacticGameClass
|
||||||
|
function GalacticGameClass:New()
|
||||||
|
ScriptMessage("Initializing Galactic game...")
|
||||||
|
local self = setmetatable({}, GalacticGameClass)
|
||||||
|
|
||||||
|
---Finds all combatant players in the game.
|
||||||
|
---@return PlayerClass[]
|
||||||
|
local function FindPlayers()
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
self.StartTime = GetCurrentTime()
|
||||||
|
self.Players = FindPlayers()
|
||||||
|
self.Units = {}
|
||||||
|
ScriptMessage("Galactic Game initialized!")
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---Services the Galactic Game.
|
||||||
|
function GalacticGameClass:Service()
|
||||||
|
ScriptMessage("Servicing Galactic game...")
|
||||||
|
|
||||||
|
-- Service Players
|
||||||
|
for playerId, player in pairs(self.Players) do
|
||||||
|
player:Service()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---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
|
||||||
|
|
||||||
|
---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 GalacticGameClass:UnitBuilt(objectType, player)
|
||||||
|
local playerId = player.Get_ID()
|
||||||
|
local player = self.Players[playerId]
|
||||||
|
|
||||||
|
if player then
|
||||||
|
player:AddUnit(objectType)
|
||||||
|
end
|
||||||
|
end
|
||||||
123
Data/Scripts/Miscellaneous/GameManager/PlayerClass.lua
Normal file
123
Data/Scripts/Miscellaneous/GameManager/PlayerClass.lua
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
require("PGBase")
|
||||||
|
require("GameManager.ResourceClass")
|
||||||
|
require("GameManager.UnitClass")
|
||||||
|
|
||||||
|
---@class PlayerClass
|
||||||
|
---@field Id integer Player ID.
|
||||||
|
---@field TeamId integer Team ID.
|
||||||
|
---@field Name string Player name.
|
||||||
|
---@field Faction string Faction name.
|
||||||
|
---@field IsHuman boolean Whether this player is a human.
|
||||||
|
---@field QuitTime integer The game time this player quit, or -1 if they are still in the game.
|
||||||
|
---@field Resource ResourceClass The player's resources.
|
||||||
|
---@field PlayerWrapper table The FoC PlayerWrapper object.
|
||||||
|
---@field Units UnitClass[] The Units belonging to this player.
|
||||||
|
PlayerClass = {}
|
||||||
|
PlayerClass.__index = PlayerClass
|
||||||
|
|
||||||
|
---Constructs a new Player object.
|
||||||
|
---@param player table FoC PlayerWrapper object
|
||||||
|
---@return PlayerClass
|
||||||
|
function PlayerClass:New(player)
|
||||||
|
local self = setmetatable({}, PlayerClass)
|
||||||
|
|
||||||
|
self.Id = player.Get_ID()
|
||||||
|
self.TeamId = player.Get_Team()
|
||||||
|
self.Name = player.Get_Name()
|
||||||
|
self.Faction = player.Get_Faction_Name()
|
||||||
|
self.IsHuman = player.Is_Human()
|
||||||
|
self.QuitTime = -1
|
||||||
|
self.Resource = ResourceClass:New()
|
||||||
|
self.PlayerWrapper = player
|
||||||
|
self.Units = {}
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---Updates credits and income.
|
||||||
|
function PlayerClass:Service()
|
||||||
|
if not self:HasQuit() then
|
||||||
|
-- Update player resources
|
||||||
|
self.Resource:SetCredits(self.PlayerWrapper.Get_Credits())
|
||||||
|
|
||||||
|
-- Service Alive Units
|
||||||
|
local assignedUnits = {}
|
||||||
|
|
||||||
|
-- Pass 1: Collect assigned game object wrappers from alive units
|
||||||
|
for _, unit in pairs(self:GetAliveUnits()) do
|
||||||
|
if TestValid(unit.GameObjectWrapper) then
|
||||||
|
assignedUnits[unit.GameObjectWrapper] = true
|
||||||
|
else
|
||||||
|
unit:SetDead()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Pass 2: Assign unclaimed wrappers to reinforcement units
|
||||||
|
for k, unit in pairs(self:GetReinforcementUnits()) do
|
||||||
|
local matchingUnits = Find_All_Objects_Of_Type(unit.Name, self.PlayerWrapper)
|
||||||
|
|
||||||
|
for _, object in pairs(matchingUnits) do
|
||||||
|
if not assignedUnits[object] then
|
||||||
|
unit:SetAlive(object)
|
||||||
|
assignedUnits[object] = true
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---Sets that the player has quit.
|
||||||
|
function PlayerClass:Quit()
|
||||||
|
self.QuitTime = GetCurrentTime()
|
||||||
|
end
|
||||||
|
|
||||||
|
---Whether this player has quit the game.
|
||||||
|
---@return boolean
|
||||||
|
function PlayerClass:HasQuit()
|
||||||
|
return self.QuitTime >= 0
|
||||||
|
end
|
||||||
|
|
||||||
|
---Adds a Unit type to the Player's reinforcement list.
|
||||||
|
---@param objectType table FoC GameObjectTypeWrapper object that was built.
|
||||||
|
function PlayerClass:AddUnit(objectType)
|
||||||
|
local unit = UnitClass:New(objectType, self.Id)
|
||||||
|
|
||||||
|
table.insert(self.Units, unit)
|
||||||
|
ScriptMessage("Unit Added: %s", unit:Debug())
|
||||||
|
end
|
||||||
|
|
||||||
|
---Gets all Reinforcement Units for this Player.
|
||||||
|
---@return UnitClass[]
|
||||||
|
function PlayerClass:GetReinforcementUnits()
|
||||||
|
---@type UnitClass[]
|
||||||
|
local units = {}
|
||||||
|
|
||||||
|
for k, unit in pairs(self.Units) do
|
||||||
|
if unit:IsReinforcement() then
|
||||||
|
table.insert(units, unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return units
|
||||||
|
end
|
||||||
|
|
||||||
|
---Gets all Alive Units for this Player.
|
||||||
|
---@return UnitClass[]
|
||||||
|
function PlayerClass:GetAliveUnits()
|
||||||
|
---@type UnitClass[]
|
||||||
|
local units = {}
|
||||||
|
|
||||||
|
for k, unit in pairs(self.Units) do
|
||||||
|
if unit:IsAlive() then
|
||||||
|
table.insert(units, unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return units
|
||||||
|
end
|
||||||
|
|
||||||
|
function PlayerClass:Debug()
|
||||||
|
return string.format("Player %s (%d) on Faction %s, Team %d", self.Name, self.Id, self.Faction, self.TeamId)
|
||||||
|
end
|
||||||
36
Data/Scripts/Miscellaneous/GameManager/ResourceClass.lua
Normal file
36
Data/Scripts/Miscellaneous/GameManager/ResourceClass.lua
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---@class ResourceClass
|
||||||
|
---@field Credits number The current credits.
|
||||||
|
---@field LastCredits number The credits on the last frame.
|
||||||
|
---@field Income integer The current income.
|
||||||
|
ResourceClass = {}
|
||||||
|
ResourceClass.__index = ResourceClass
|
||||||
|
|
||||||
|
---Constructs a new Resource object.
|
||||||
|
function ResourceClass:New()
|
||||||
|
local self = setmetatable({}, ResourceClass)
|
||||||
|
|
||||||
|
self.Credits = 0
|
||||||
|
self.LastCredits = 0
|
||||||
|
self.Income = 0
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---Sets the current credits and updates income.
|
||||||
|
---@param credits number
|
||||||
|
function ResourceClass:SetCredits(credits)
|
||||||
|
self.LastCredits = self.Credits
|
||||||
|
self.Credits = credits
|
||||||
|
|
||||||
|
if credits < 0 then
|
||||||
|
self.Credits = 0
|
||||||
|
else
|
||||||
|
self.Credits = credits
|
||||||
|
end
|
||||||
|
|
||||||
|
self.Income = self.Credits - self.LastCredits
|
||||||
|
end
|
||||||
|
|
||||||
|
function ResourceClass:Debug()
|
||||||
|
return string.format("Credits: %d, Income: %d", self.Credits, self.Income)
|
||||||
|
end
|
||||||
173
Data/Scripts/Miscellaneous/GameManager/SkirmishGameClass.lua
Normal file
173
Data/Scripts/Miscellaneous/GameManager/SkirmishGameClass.lua
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
require("PGBase")
|
||||||
|
require("GameManager.Constants")
|
||||||
|
require("GameManager.TacticalGameClass")
|
||||||
|
require("GameManager.SpectatorStruct")
|
||||||
|
require("GameManager.TeamStruct")
|
||||||
|
|
||||||
|
---@class SkirmishGameClass
|
||||||
|
---@field TacticalGame TacticalGameClass The underlying Tactical Game context.
|
||||||
|
---@field Spectators SpectatorStruct[] The spectator players in this game.
|
||||||
|
---@field IsLocalSpectator boolean Whether the local player is a spectator.
|
||||||
|
---@field Teams TeamStruct[] The teams in this game.
|
||||||
|
SkirmishGameClass = {}
|
||||||
|
SkirmishGameClass.__index = SkirmishGameClass
|
||||||
|
|
||||||
|
---Creates a new Skirmish Game context.
|
||||||
|
---@param gameMode string The game mode.
|
||||||
|
---@return SkirmishGameClass
|
||||||
|
function SkirmishGameClass:New(gameMode)
|
||||||
|
ScriptMessage("Initializing Skirmish game...")
|
||||||
|
local self = setmetatable({}, SkirmishGameClass)
|
||||||
|
|
||||||
|
---Finds all spectators in the game.
|
||||||
|
---@return SpectatorStruct[]
|
||||||
|
local function FindSpectators()
|
||||||
|
---@type SpectatorStruct[]
|
||||||
|
local spectators = {}
|
||||||
|
local spectatorMarker = GetSpectatorMarkerName(gameMode)
|
||||||
|
|
||||||
|
if spectatorMarker ~= nil 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")
|
||||||
|
|
||||||
|
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!")
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---Services the Skirmish Game.
|
||||||
|
function SkirmishGameClass:Service()
|
||||||
|
ScriptMessage("Servicing Skirmish Game...")
|
||||||
|
-- Service TacticalGame
|
||||||
|
self.TacticalGame:Service()
|
||||||
|
end
|
||||||
|
|
||||||
|
---Gets the Spectator by Player ID.
|
||||||
|
---@param id integer Player ID
|
||||||
|
---@return SpectatorStruct|nil
|
||||||
|
function SkirmishGameClass:GetSpectator(id)
|
||||||
|
for playerId, spectator in pairs(self.Spectators) do
|
||||||
|
if playerId == id then
|
||||||
|
return spectator
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---Gets the Team by ID.
|
||||||
|
---@param id integer Team ID
|
||||||
|
---@return TeamStruct|nil
|
||||||
|
function SkirmishGameClass:GetTeam(id)
|
||||||
|
for teamId, team in pairs(self.Teams) do
|
||||||
|
if teamId == id then
|
||||||
|
return team
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---Gets the Players for the Team ID.
|
||||||
|
---@param id integer Team ID
|
||||||
|
---@return PlayerClass[]
|
||||||
|
function SkirmishGameClass:GetPlayersOnTeam(id)
|
||||||
|
---@type PlayerClass[]
|
||||||
|
local players = {}
|
||||||
|
|
||||||
|
for playerId, player in pairs(self.TacticalGame.Players) do
|
||||||
|
if player.TeamId == id then
|
||||||
|
players[playerId] = player
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return players
|
||||||
|
end
|
||||||
|
|
||||||
|
---Calculates the Team ID's current total credits.
|
||||||
|
---@param id integer Team ID.
|
||||||
|
---@return integer
|
||||||
|
function SkirmishGameClass:CalculateTeamTotalCredits(id)
|
||||||
|
local players = self:GetPlayersOnTeam(id)
|
||||||
|
local totalCredits = 0
|
||||||
|
|
||||||
|
for playerId, player in pairs(players) do
|
||||||
|
totalCredits = totalCredits + player.Resource.Credits
|
||||||
|
end
|
||||||
|
|
||||||
|
return totalCredits
|
||||||
|
end
|
||||||
|
|
||||||
|
---Calculates the Team ID's current total income.
|
||||||
|
---@param id integer Team ID.
|
||||||
|
---@return integer
|
||||||
|
function SkirmishGameClass:CalculateTeamTotalIncome(id)
|
||||||
|
local players = self:GetPlayersOnTeam(id)
|
||||||
|
local totalIncome = 0
|
||||||
|
|
||||||
|
for playerId, player in pairs(players) do
|
||||||
|
totalIncome = totalIncome + player.Resource.Income
|
||||||
|
end
|
||||||
|
|
||||||
|
return totalIncome
|
||||||
|
end
|
||||||
26
Data/Scripts/Miscellaneous/GameManager/SpectatorStruct.lua
Normal file
26
Data/Scripts/Miscellaneous/GameManager/SpectatorStruct.lua
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---@class SpectatorStruct
|
||||||
|
---@field Id integer Player ID.
|
||||||
|
---@field TeamId integer Team ID.
|
||||||
|
---@field Name string Player name.
|
||||||
|
---@field Faction string Faction name.
|
||||||
|
---@field PlayerWrapper table The FoC PlayerWrapper object.
|
||||||
|
SpectatorStruct = {}
|
||||||
|
SpectatorStruct.__index = SpectatorStruct
|
||||||
|
|
||||||
|
---Constructs a new Spectator object.
|
||||||
|
---@param wrapper table FoC PlayerWrapper
|
||||||
|
function SpectatorStruct:New(wrapper)
|
||||||
|
local self = setmetatable({}, SpectatorStruct)
|
||||||
|
|
||||||
|
self.Id = wrapper.Get_ID()
|
||||||
|
self.TeamId = wrapper.Get_Team()
|
||||||
|
self.Name = wrapper.Get_Name()
|
||||||
|
self.Faction = wrapper.Get_Faction_Name()
|
||||||
|
self.PlayerWrapper = wrapper
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function SpectatorStruct:Debug()
|
||||||
|
return string.format("Spectator %s (%d) on Faction %s, Team %d", self.Name, self.Id, self.Faction, self.TeamId)
|
||||||
|
end
|
||||||
120
Data/Scripts/Miscellaneous/GameManager/TacticalGameClass.lua
Normal file
120
Data/Scripts/Miscellaneous/GameManager/TacticalGameClass.lua
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
require("PGBase")
|
||||||
|
require("GameManager.PlayerClass")
|
||||||
|
|
||||||
|
---@class TacticalGameClass
|
||||||
|
---@field GameMode string The tactical game mode.
|
||||||
|
---@field StartTime integer The start time.
|
||||||
|
---@field Players PlayerClass[] The combatant players in this game.
|
||||||
|
---@field ReinforcementUnitCount table<string, integer> Key: Unit Type, Value: Count
|
||||||
|
---@field AliveUnitCount table<string, integer> Key: Unit Type, Value: Count
|
||||||
|
---@field DeadUnitCount table<string, integer> Key: Unit Type, Value: Count
|
||||||
|
TacticalGameClass = {}
|
||||||
|
TacticalGameClass.__index = TacticalGameClass
|
||||||
|
|
||||||
|
---Creates a new Tactical Game context.
|
||||||
|
---@param gameMode string The game mode.
|
||||||
|
---@return TacticalGameClass
|
||||||
|
function TacticalGameClass:New(gameMode)
|
||||||
|
ScriptMessage("Initializing Tactical game...")
|
||||||
|
local self = setmetatable({}, TacticalGameClass)
|
||||||
|
|
||||||
|
---Finds all combatant players in the game.
|
||||||
|
---@return PlayerClass[]
|
||||||
|
local function FindPlayers()
|
||||||
|
---@type PlayerClass[]
|
||||||
|
local players = {}
|
||||||
|
|
||||||
|
for k, faction in pairs(Factions) do
|
||||||
|
local startingUnit = nil
|
||||||
|
|
||||||
|
if StringCompare(gameMode, "Land") then
|
||||||
|
startingUnit = faction.LandStartUnitName
|
||||||
|
elseif StringCompare(gameMode, "Space") then
|
||||||
|
startingUnit = faction.SpaceStartUnitName
|
||||||
|
end
|
||||||
|
|
||||||
|
if startingUnit then
|
||||||
|
for i, unit in pairs(Find_All_Objects_Of_Type(startingUnit)) do
|
||||||
|
local playerWrapper = unit.Get_Owner()
|
||||||
|
local playerId = playerWrapper.Get_ID()
|
||||||
|
|
||||||
|
if players[playerId] == nil then
|
||||||
|
local player = PlayerClass:New(playerWrapper)
|
||||||
|
|
||||||
|
players[playerId] = player
|
||||||
|
ScriptMessage("Found Player: %s", player:Debug())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
28
Data/Scripts/Miscellaneous/GameManager/TeamStruct.lua
Executable file
28
Data/Scripts/Miscellaneous/GameManager/TeamStruct.lua
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
require("GameManager.Constants")
|
||||||
|
|
||||||
|
---@class TeamStruct
|
||||||
|
---@field Id integer Team ID.
|
||||||
|
---@field Number integer Team number.
|
||||||
|
---@field Faction FactionStruct Faction struct for this team.
|
||||||
|
---@field IsSpectator boolean Whether this team's players are spectators.
|
||||||
|
TeamStruct = {}
|
||||||
|
TeamStruct.__index = TeamStruct
|
||||||
|
|
||||||
|
---Constructs a new Team object.
|
||||||
|
---@param id integer Team ID
|
||||||
|
---@param faction string Faction name
|
||||||
|
---@param isSpectator boolean Is a Spectator team
|
||||||
|
function TeamStruct:New(id, faction, isSpectator)
|
||||||
|
local self = setmetatable({}, TeamStruct)
|
||||||
|
|
||||||
|
self.Id = id
|
||||||
|
self.Number = id + 1
|
||||||
|
self.Faction = Factions[faction]
|
||||||
|
self.IsSpectator = isSpectator
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function TeamStruct:Debug()
|
||||||
|
return string.format("Team %d: %s (%d)", self.Number, self.Faction.Name, self.Id)
|
||||||
|
end
|
||||||
89
Data/Scripts/Miscellaneous/GameManager/UnitClass.lua
Normal file
89
Data/Scripts/Miscellaneous/GameManager/UnitClass.lua
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
require("PGBase")
|
||||||
|
|
||||||
|
---@class UnitClass
|
||||||
|
---@field Name string Unit name.
|
||||||
|
---@field OwnerId integer Owner Player ID.
|
||||||
|
---@field BuildCost integer Tactical build cost.
|
||||||
|
---@field CombatRating integer AI combat power rating.
|
||||||
|
---@field BuildTime number Game time that this unit was built.
|
||||||
|
---@field AliveTime number Game time that this unit became "alive".
|
||||||
|
---@field DeathTime number Game time that this unit was killed.
|
||||||
|
---@field GameObjectWrapper table|nil The FoC GameObjectWrapper object.
|
||||||
|
---@field GameObjectTypeWrapper table The FoC GameObjectTypeWrapper object.
|
||||||
|
---@field Icon string Name of the icon for this object.
|
||||||
|
UnitClass = {}
|
||||||
|
UnitClass.__index = UnitClass
|
||||||
|
|
||||||
|
---Constructs a new Unit object.
|
||||||
|
---@param objectType table FoC GameObjectTypeWrapper object
|
||||||
|
---@param playerId integer The Owner Player ID
|
||||||
|
function UnitClass:New(objectType, playerId)
|
||||||
|
local self = setmetatable({}, UnitClass)
|
||||||
|
|
||||||
|
self.Name = objectType.Get_Name()
|
||||||
|
self.OwnerId = playerId
|
||||||
|
self.BuildCost = objectType.Get_Tactical_Build_Cost()
|
||||||
|
self.CombatRating = objectType.Get_Combat_Rating()
|
||||||
|
self.BuildTime = GetCurrentTime()
|
||||||
|
self.AliveTime = -1
|
||||||
|
self.DeathTime = -1
|
||||||
|
self.GameObjectWrapper = nil
|
||||||
|
self.GameObjectTypeWrapper = objectType
|
||||||
|
self.Icon = "I_BUTTON_COMMAND_BAR_PIRATE_SYMBOL.TGA"
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---Whether this Unit is a reinforcement.
|
||||||
|
---@return boolean
|
||||||
|
function UnitClass:IsReinforcement()
|
||||||
|
return self.AliveTime < 0 and self.DeathTime < 0
|
||||||
|
end
|
||||||
|
|
||||||
|
---Whether this Unit is currently alive.
|
||||||
|
---@return boolean
|
||||||
|
function UnitClass:IsAlive()
|
||||||
|
return self.AliveTime >= 0 and self.DeathTime < 0
|
||||||
|
end
|
||||||
|
|
||||||
|
---Whether this Unit is dead.
|
||||||
|
---@return boolean
|
||||||
|
function UnitClass:IsDead()
|
||||||
|
return self.DeathTime >= 0
|
||||||
|
end
|
||||||
|
|
||||||
|
---Sets the time this unit became "alive".
|
||||||
|
---@param object table FoC GameObjectWrapper object
|
||||||
|
function UnitClass:SetAlive(object)
|
||||||
|
if self.AliveTime >= 0 then
|
||||||
|
-- Do not override once set
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self.AliveTime = GetCurrentTime()
|
||||||
|
self.GameObjectWrapper = object
|
||||||
|
ScriptMessage("Unit Spawned: %s", self:Debug())
|
||||||
|
end
|
||||||
|
|
||||||
|
---Sets the unit as dead.
|
||||||
|
function UnitClass:SetDead()
|
||||||
|
if self.DeathTime >= 0 then
|
||||||
|
-- Do not override once set
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self.DeathTime = GetCurrentTime()
|
||||||
|
ScriptMessage("Unit Killed: %s", self:Debug())
|
||||||
|
end
|
||||||
|
|
||||||
|
function UnitClass:Debug()
|
||||||
|
if self:IsReinforcement() then
|
||||||
|
return string.format("Reinforcement Unit %s, Owned by %d, Built at: %d", self.Name, self.OwnerId, self.BuildTime)
|
||||||
|
elseif self:IsAlive() then
|
||||||
|
return string.format("Alive Unit %s, Owned by %d, Alive at: %d", self.Name, self.OwnerId, self.AliveTime)
|
||||||
|
elseif self:IsDead() then
|
||||||
|
return string.format("Dead Unit %s, Owned by %d, Death at: %d", self.Name, self.OwnerId, self.DeathTime)
|
||||||
|
else
|
||||||
|
return string.format("Unit %s, Owned by %d, Unknown state", self.Name, self.OwnerId)
|
||||||
|
end
|
||||||
|
end
|
||||||
443
Data/Scripts/Miscellaneous/GameScoring.lua
Executable file
443
Data/Scripts/Miscellaneous/GameScoring.lua
Executable file
@@ -0,0 +1,443 @@
|
|||||||
|
require("PGBase")
|
||||||
|
require("GameManager.Constants")
|
||||||
|
require("GameManager.GUIManager")
|
||||||
|
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 Local Player FoC PlayerWrapper object.
|
||||||
|
local LocalPlayer = nil
|
||||||
|
|
||||||
|
---The GUI Manager.
|
||||||
|
---@type GUIManager
|
||||||
|
local GUIManager = GUIManager:New()
|
||||||
|
|
||||||
|
---The Galactic Game manager.
|
||||||
|
---@type GalacticGameClass|nil
|
||||||
|
local GalacticGame = nil
|
||||||
|
|
||||||
|
---The Tactical Game manager.
|
||||||
|
---@type TacticalGameClass|nil
|
||||||
|
local TacticalGame = nil
|
||||||
|
|
||||||
|
---The Skirmish Game manager.
|
||||||
|
---@type SkirmishGameClass|nil
|
||||||
|
local SkirmishGame = 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 = {}
|
||||||
|
|
||||||
|
-- ==================================================
|
||||||
|
-- Script State Functions
|
||||||
|
-- ==================================================
|
||||||
|
|
||||||
|
---Sets up the base variables for this script.
|
||||||
|
function Base_Definitions()
|
||||||
|
DebugMessage("%s -- In Base_Definitions.", tostring(Script))
|
||||||
|
|
||||||
|
DebugCounter = 0
|
||||||
|
LocalPlayer = Find_Player("local")
|
||||||
|
end
|
||||||
|
|
||||||
|
---Main script function. Does event pumps and servicing.
|
||||||
|
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()
|
||||||
|
|
||||||
|
if TacticalGame then
|
||||||
|
TacticalGame:Service()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if SkirmishGame then
|
||||||
|
SkirmishGame:Service()
|
||||||
|
end
|
||||||
|
|
||||||
|
if GUIManager then
|
||||||
|
GUIManager:Service()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---Script debug servicing.
|
||||||
|
function ServiceDebug()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ==================================================
|
||||||
|
-- Reset State
|
||||||
|
-- ==================================================
|
||||||
|
|
||||||
|
---Reset the Tactical mode game stats.
|
||||||
|
function Reset_Tactical_Stats()
|
||||||
|
DebugMessage("%s -- In Reset_Tactical_Stats", tostring(Script))
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
---This event is triggered when a player quits the game.
|
||||||
|
---@param player table 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 table FoC GameObjectTypeWrapper object that was just built.
|
||||||
|
---@param player table FoC PlayerWrapper object that built the object.
|
||||||
|
---@param location table|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 table FoC GameObjectWrapper object that was just killed.
|
||||||
|
---@param killer table 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)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---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 objectType table 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 table FoC GameObjectWrapper object of the planet.
|
||||||
|
---@param objectType table 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 table FoC GameObjectWrapper or of the planet.
|
||||||
|
---@param object table 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 table FoC GameObjectWrapper object that was just killed.
|
||||||
|
---@param killer table 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 table FoC GameObjectWrapper object of the planet.
|
||||||
|
---@param oldType table FoC GameObjectTypeWrapper object of the old starbase type.
|
||||||
|
---@param newType table 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 table FoC GameObjectWrapper object of the planet.
|
||||||
|
---@param newOwner table FoC PlayerWrapper of the new owner.
|
||||||
|
---@param oldOwner table 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 table FoC GameObjectTypeWrapper object for the neutralized hero type.
|
||||||
|
---@param killer table 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 table FoC GameObjectTypeWrapper object to query.
|
||||||
|
---@param player table 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 table FoC GameObjectTypeWrapper object to query.
|
||||||
|
---@param player table 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 table 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 table FoC PlayerWrapper object.
|
||||||
|
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)
|
||||||
|
GUIManager:InitTactical(TacticalGame)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Resets Tactica mode.
|
||||||
|
function Reset_Tactical()
|
||||||
|
DebugMessage("%s -- Resetting Tactical rules.", tostring(Script))
|
||||||
|
Reset_Tactical_Stats()
|
||||||
|
TacticalGame = nil
|
||||||
|
GUIManager:Reset()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- ==================================================
|
||||||
|
--- Skirmish Functions
|
||||||
|
--- ==================================================
|
||||||
|
|
||||||
|
---Initializes Skirmish mode.
|
||||||
|
---@param gameMode string The tactical game mode.
|
||||||
|
function Init_Skirmish(gameMode)
|
||||||
|
DebugMessage("%s -- Initializing Skirmish Tacitcal %s rules.", tostring(Script), gameMode)
|
||||||
|
Reset_Stats()
|
||||||
|
SkirmishGame = SkirmishGameClass:New(gameMode)
|
||||||
|
TacticalGame = SkirmishGame.TacticalGame
|
||||||
|
GUIManager:InitSkirmish(SkirmishGame)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Reset_Skirmish()
|
||||||
|
DebugMessage("%s -- Resetting Skirmish Tactical rules.", tostring(Script))
|
||||||
|
Reset_Stats()
|
||||||
|
SkirmishGame = nil
|
||||||
|
TacticalGame = nil
|
||||||
|
GUIManager:Reset()
|
||||||
|
end
|
||||||
33
README.md
33
README.md
@@ -1,2 +1,33 @@
|
|||||||
# FoC-GameManager
|
# FoC GameManager
|
||||||
|
|
||||||
|
A Lua framework for Star Wars: Empire at War: Forces of Corruption that hijacks `GameScoring.lua` to create game manager states for each game mode type.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- In-game time display in tactical modes
|
||||||
|
- Skirmish spectating with team credits display
|
||||||
|
- *Coming soon* Spectator unit list display of per-team reinforcement pool, active units, and killed units
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
- Copy the `Data/Scripts/Miscellaneous` folder into your mod.
|
||||||
|
- That's it.
|
||||||
|
|
||||||
|
## Important Considerations
|
||||||
|
|
||||||
|
If your mod has made changes to `GameScoring.lua`, this framework will not work without some extra care.
|
||||||
|
I have essentially entirely re-written `GameScoring.lua` as most all of the scoring functions within it are deprecated post-GameSpy era.
|
||||||
|
If you had other stuff that you were doing in there, you may want to consider adding it to one of these files as serviced functions:
|
||||||
|
|
||||||
|
- `GalacticGameClass.lua`
|
||||||
|
- `TacticalGameClass.lua`
|
||||||
|
- `SkirmishGameClass.lua`
|
||||||
|
|
||||||
|
Alternatively, you can create your own game class using one of these as the template to service your own custom scripts.
|
||||||
|
Just make sure to add it into `GameScoring.lua` as a game manager when your particular game mode is initialized.
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
**Q:** `Data/Scripts/Library` is included in the repository. Do I need to include those files as well?
|
||||||
|
|
||||||
|
**A:** No. I included these files so that the Lua language server would identify issues in the framework code files. There are no changes to these files and they already exist in the core game, so there is no need to include them.
|
||||||
Reference in New Issue
Block a user