Initial commit
This commit is contained in:
163
DATA/SCRIPTS/LIBRARY/PGAICOMMANDS.LUA
Normal file
163
DATA/SCRIPTS/LIBRARY/PGAICOMMANDS.LUA
Normal file
@@ -0,0 +1,163 @@
|
||||
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGAICommands.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/PGAICommands.lua $
|
||||
--
|
||||
-- Original Author: Brian Hayes
|
||||
--
|
||||
-- $Author: James_Yarrow $
|
||||
--
|
||||
-- $Change: 57990 $
|
||||
--
|
||||
-- $DateTime: 2006/11/13 17:33:10 $
|
||||
--
|
||||
-- $Revision: #2 $
|
||||
--
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require("PGCommands")
|
||||
|
||||
function Base_Definitions()
|
||||
-- DebugMessage("%s -- In Base_Definitions", tostring(Script))
|
||||
|
||||
InSpaceConflict = false
|
||||
MagicPlan = false
|
||||
|
||||
-- Scale all counter forces by this factor
|
||||
MinContrastScale = 1.0
|
||||
MaxContrastScale = 1.5
|
||||
PerFailureContrastAdjust = 0.1
|
||||
EnemyContrastTypes = {}
|
||||
FriendlyContrastTypes = {}
|
||||
ContrastTypeScale = {}
|
||||
|
||||
-- Track abilities that got cancelled (nebula or whatever) so we can turn them on later
|
||||
lib_cancelled_abilities = {}
|
||||
|
||||
Common_Base_Definitions()
|
||||
|
||||
-- nil out the global Taskforce variables.
|
||||
if TaskForce and type(TaskForce) == "table" then
|
||||
for idx,tfdef in pairs(TaskForce) do
|
||||
if type(tfdef) == "table" and type(tfdef[1]) == "string" then
|
||||
_G[tfdef[1]] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if PlanDefinitionLoad then
|
||||
Set_Contrast_Values()
|
||||
end
|
||||
|
||||
PlanDefinitionLoad = nil
|
||||
|
||||
if Definitions then
|
||||
Definitions()
|
||||
end
|
||||
end
|
||||
|
||||
function Set_Contrast_Values()
|
||||
_e_cnt = 1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "Fighter"
|
||||
FriendlyContrastTypeNames = {"AntiFighter", "Bomber", "Fighter", "Corvette", "Frigate", "Capital"}
|
||||
FriendlyContrastWeights = {4.0, 0.25, 1.0, 1.0, 1.0, 1.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "Bomber"
|
||||
FriendlyContrastTypeNames = {"AntiBomber", "Frigate", "Capital", "Fighter", "Bomber", "Corvette"}
|
||||
FriendlyContrastWeights = {4.0, 0.25, 0.25, 1.0, 1.0, 1.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "Transport"
|
||||
FriendlyContrastTypeNames = {"Fighter", "Bomber", "Corvette", "Frigate", "Capital", }
|
||||
FriendlyContrastWeights = {1.0, 1.0, 1.0, 1.0, 1.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "Corvette"
|
||||
FriendlyContrastTypeNames = {"AntiCorvette", "Fighter", "Bomber", "Corvette", "Frigate", "Capital"}
|
||||
FriendlyContrastWeights = {3.0, 0.25, 0.25, 1.0, 1.0, 1.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "Frigate"
|
||||
FriendlyContrastTypeNames = {"AntiFrigate", "Corvette", "Fighter", "Bomber", "Frigate", "Capital"}
|
||||
FriendlyContrastWeights = {3.0, 0.5, 1.0, 1.0, 1.0, 1.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "Capital"
|
||||
FriendlyContrastTypeNames = {"AntiCapital", "Corvette", "Frigate", "Fighter", "Bomber", "Capital"}
|
||||
FriendlyContrastWeights = {2.0, 0.33, 0.5, 0.75, 1.0, 1.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "Infantry"
|
||||
FriendlyContrastTypeNames = {"AntiInfantry", "Vehicle", "Infantry", "Air", "Structure", "LandHero"}
|
||||
FriendlyContrastWeights = {2.0, 0.5, 1.0, 1.0, 1.0, 2.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "Vehicle"
|
||||
FriendlyContrastTypeNames = {"AntiVehicle", "Infantry", "Vehicle", "Air", "Structure", "LandHero"}
|
||||
FriendlyContrastWeights = {2.0, 0.25, 1.0, 1.0, 1.0, 2.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "Air"
|
||||
FriendlyContrastTypeNames = {"AntiAir", "Infantry", "Vehicle", "Air", "Structure", "LandHero"}
|
||||
FriendlyContrastWeights = {2.0, 1.0, 1.0, 1.0, 1.0, 1.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "Structure"
|
||||
FriendlyContrastTypeNames = {"AntiStructure", "Infantry", "Vehicle", "Air", "Structure", "LandHero"}
|
||||
FriendlyContrastWeights = {2.0, 1.0, 1.0, 1.0, 1.0, 1.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
EnemyContrastTypes[_e_cnt] = "LandHero"
|
||||
FriendlyContrastTypeNames = {"Infantry", "Vehicle", "Air", "Structure", "LandHero"}
|
||||
FriendlyContrastWeights = {0.5, 0.5, 0.5, 0.25, 1.0}
|
||||
FriendlyContrastTypes[_e_cnt] = WeightedTypeList.Create()
|
||||
FriendlyContrastTypes[_e_cnt].Parse(FriendlyContrastTypeNames, FriendlyContrastWeights)
|
||||
_e_cnt = _e_cnt+1;
|
||||
|
||||
end
|
||||
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
|
||||
|
||||
134
DATA/SCRIPTS/LIBRARY/PGBASEDEFINITIONS.LUA
Normal file
134
DATA/SCRIPTS/LIBRARY/PGBASEDEFINITIONS.LUA
Normal file
@@ -0,0 +1,134 @@
|
||||
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGBaseDefinitions.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/PGBaseDefinitions.lua $
|
||||
--
|
||||
-- Original Author: Brian Hayes
|
||||
--
|
||||
-- $Author: Andre_Arsenault $
|
||||
--
|
||||
-- $Change: 37816 $
|
||||
--
|
||||
-- $DateTime: 2006/02/15 15:33:33 $
|
||||
--
|
||||
-- $Revision: #1 $
|
||||
--
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require("PGBase")
|
||||
|
||||
BAD_WEIGHT = -1000000000000000000.0
|
||||
BIG_FLOAT = 1000000000000000000.0
|
||||
|
||||
-- Set the garbage collection threshold to 256k
|
||||
collectgarbage(256)
|
||||
|
||||
function Common_Base_Definitions()
|
||||
-- Clear out the thread specific values.
|
||||
ThreadValue.Reset()
|
||||
|
||||
-- Clear out any thread events.
|
||||
GetEvent.Reset()
|
||||
|
||||
TimerTable = {}
|
||||
DeathTable = {}
|
||||
ProxTable = {}
|
||||
AttackedTable = {}
|
||||
CurrentEvent = nil
|
||||
EventParams = nil
|
||||
block = nil
|
||||
break_block = false
|
||||
YieldCount = 0
|
||||
AITarget = nil
|
||||
Object = nil
|
||||
Target = nil
|
||||
FreeStore = nil
|
||||
PlayerObject = nil
|
||||
LastService = nil
|
||||
Budget = nil
|
||||
enemy = nil
|
||||
taskforce = nil
|
||||
tfObj = nil
|
||||
stage = nil
|
||||
UnitType = nil
|
||||
invade_status = nil
|
||||
path = nil
|
||||
InvasionActive = false
|
||||
unit = nil
|
||||
|
||||
hide_target = nil
|
||||
healer = nil
|
||||
xfire_pos = nil
|
||||
kite_pos = nil
|
||||
friendly = nil
|
||||
|
||||
block_table = {}
|
||||
|
||||
lib_anti_idle_block = nil
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- base constructor
|
||||
function Base_Definitions()
|
||||
|
||||
Common_Base_Definitions()
|
||||
|
||||
if Definitions then
|
||||
Definitions()
|
||||
end
|
||||
end
|
||||
|
||||
function Evaluator_Clean_Up()
|
||||
Target = nil
|
||||
PlayerObject = nil
|
||||
|
||||
if Clean_Up then
|
||||
Clean_Up()
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns true if the entire list is not in some kind of obscuring field
|
||||
function UnitListIsObscured(unit_list)
|
||||
for i, unit in pairs(unit_list) do
|
||||
if not (unit.Is_In_Nebula() or unit.Is_In_Asteroid_Field() or unit.Is_In_Ion_Storm()) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-- Remove all invalid or dead units from a list and return it.
|
||||
function Cull_Unit_List(unit_list)
|
||||
for k, unit in pairs(unit_list) do
|
||||
if not TestValid(unit) then
|
||||
unit_list[k] = nil
|
||||
end
|
||||
end
|
||||
return unit_list
|
||||
end
|
||||
593
DATA/SCRIPTS/LIBRARY/PGCOMMANDS.LUA
Normal file
593
DATA/SCRIPTS/LIBRARY/PGCOMMANDS.LUA
Normal file
@@ -0,0 +1,593 @@
|
||||
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGCommands.lua#10 $
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
--
|
||||
-- (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/PGCommands.lua $
|
||||
--
|
||||
-- Original Author: Brian Hayes
|
||||
--
|
||||
-- $Author: James_Yarrow $
|
||||
--
|
||||
-- $Change: 53991 $
|
||||
--
|
||||
-- $DateTime: 2006/09/08 11:01:51 $
|
||||
--
|
||||
-- $Revision: #10 $
|
||||
--
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require("PGBaseDefinitions")
|
||||
|
||||
-- Deprecated...
|
||||
--
|
||||
-- function ProduceForce(taskforce)
|
||||
-- tfIndex = 0
|
||||
--
|
||||
-- DebugMessage("Beginning production on %s at %s.", tostring(taskforce),
|
||||
-- tostring(taskforce.Production_Facility()))
|
||||
--
|
||||
-- -- loop through all the unit types and produce each one.
|
||||
-- UnitType = taskforce.Get_Type_Of_Unit(tfIndex)
|
||||
-- while UnitType do
|
||||
--
|
||||
-- -- Build the object at the production facility.
|
||||
-- tfObj = WaitProduceObject(UnitType, taskforce.Production_Facility())
|
||||
-- DebugMessage("Object %s produced.", tostring(tfObj))
|
||||
--
|
||||
-- -- Add the object to the task force.
|
||||
-- taskforce.Add_Force(tfObj)
|
||||
--
|
||||
-- -- Remove our reference to the object, since a merge will destroy it.
|
||||
-- tfObj.Release()
|
||||
--
|
||||
-- -- Merge the new fleets together.
|
||||
-- BlockOnCommand(taskforce.Form_Units())
|
||||
--
|
||||
-- -- Look for another unit type.
|
||||
-- tfIndex = tfIndex + 1
|
||||
-- UnitType = taskforce.Get_Type_Of_Unit(tfIndex)
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- function ProduceObject(player, objecttype, where)
|
||||
-- return _ProduceObject(player, objecttype, where)
|
||||
-- end
|
||||
--
|
||||
-- function WaitProduceObject(objecttype, where)
|
||||
-- return BlockOnCommand(ProduceObject(PlayerObject, objecttype, where))
|
||||
-- end
|
||||
|
||||
function WaitForever()
|
||||
DebugMessage("%s -- Waiting forever...", tostring(Script))
|
||||
while true do
|
||||
PumpEvents()
|
||||
end
|
||||
-- BlockOnCommand(BlockForever())
|
||||
DebugMessage("%s -- Something interrupted the wait!.", tostring(Script))
|
||||
end
|
||||
|
||||
-- TimerTable[func] = {timeout = timeout, start_time = GetCurrentTime(), param = param }
|
||||
--function Debug_Timer_Table()
|
||||
-- OutputDebug("%s -- TimerTable Dump.\n", tostring(Script))
|
||||
-- for func,tabtab in pairs(TimerTable) do
|
||||
-- for idx,tab in pairs(tabtab) do
|
||||
-- OutputDebug("%s, %f, %f, %s\n", tostring(func), tab.timeout, tab.start_time, tostring(tab.param))
|
||||
-- end
|
||||
-- end
|
||||
--end
|
||||
|
||||
function Register_Timer(func, timeout, param)
|
||||
if TimerTable[func] == nil then
|
||||
TimerTable[func] = {}
|
||||
end
|
||||
|
||||
table.insert(TimerTable[func], {timeout = timeout, start_time = GetCurrentTime(), param = param})
|
||||
end
|
||||
|
||||
function Process_Timers()
|
||||
for func,tabtab in pairs(TimerTable) do
|
||||
found_entry = false
|
||||
for idx,tab in pairs(tabtab) do
|
||||
found_entry = true
|
||||
if tab.timeout + tab.start_time < GetCurrentTime() then
|
||||
tabtab[idx] = nil
|
||||
func(tab.param)
|
||||
Process_Timers()
|
||||
return
|
||||
end
|
||||
end
|
||||
if found_entry == false then
|
||||
TimerTable[func] = nil
|
||||
Process_Timers()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Cancels all occurences of this timer function
|
||||
function Cancel_Timer(func)
|
||||
if func ~= nil then
|
||||
TimerTable[func] = nil
|
||||
else
|
||||
MessageBox("%s -- cancelling nonexistant function, got:%s; aborting.", tostring(Script), type(func))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Setup a callback for the death or deletion of a given object.
|
||||
function Register_Death_Event(obj, func)
|
||||
if not TestValid(obj) then
|
||||
MessageBox("%s -- Error, object doesn't exist or has already died.", tostring(Script))
|
||||
return
|
||||
end
|
||||
|
||||
if DeathTable[obj] ~= nil then
|
||||
MessageBox("%s -- Error, object already registered for death event", tostring(Script))
|
||||
return
|
||||
end
|
||||
|
||||
DeathTable[obj] = func
|
||||
end
|
||||
|
||||
function Process_Death_Events()
|
||||
for obj, func in pairs(DeathTable) do
|
||||
if not TestValid(obj) then
|
||||
DeathTable[obj] = nil
|
||||
func()
|
||||
Process_Death_Events()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Setup a callback for a given object falling under attack.
|
||||
function Register_Attacked_Event(obj, func)
|
||||
if not TestValid(obj) then
|
||||
MessageBox("%s -- Error, object doesn't exist or has died.", tostring(Script))
|
||||
return
|
||||
end
|
||||
|
||||
if AttackedTable[obj] ~= nil then
|
||||
MessageBox("%s -- Error, object already registered for attacked event", tostring(Script))
|
||||
return
|
||||
end
|
||||
|
||||
-- Storing the callback and if the object currently has a "deadly enemy"
|
||||
AttackedTable[obj] = {func, false}
|
||||
end
|
||||
|
||||
|
||||
-- Executes the callback with (true, object) if first going under attack.
|
||||
-- Executes the callback with (false) if no longer under attack.
|
||||
function Process_Attacked_Events()
|
||||
for obj, table in pairs(AttackedTable) do
|
||||
if not TestValid(obj) then
|
||||
AttackedTable[obj] = nil
|
||||
else
|
||||
most_deadly_enemy = FindDeadlyEnemy(obj)
|
||||
if most_deadly_enemy then
|
||||
|
||||
-- If we have a deadly enemy and this just became true, run the callback.
|
||||
if not table[2] then
|
||||
table[2] = true
|
||||
table[1](true, most_deadly_enemy, obj)
|
||||
Process_Attacked_Events()
|
||||
return
|
||||
end
|
||||
|
||||
-- Update that we don't have a deadly enemy any longer.
|
||||
--else
|
||||
elseif table[2] then
|
||||
--MessageBox("obj:%s now has no deadly enemy", tostring(obj))
|
||||
table[2] = false
|
||||
table[1](false, nil, obj)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Cancel_Attacked_Event(obj)
|
||||
if obj ~= nil then
|
||||
AttackedTable[obj] = nil
|
||||
else
|
||||
MessageBox("received nil object")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Set up proximity triggers on arbitrary objects and have them serviced.
|
||||
function Register_Prox(obj, func, range, player_filter)
|
||||
|
||||
-- prevent this from doing anything in galactic mode
|
||||
if Get_Game_Mode() == "Galactic" then
|
||||
DebugMessage("%s -- Warning, proximity register disallowed in galactic mode; aborting.", tostring(Script))
|
||||
return
|
||||
end
|
||||
|
||||
if not TestValid(obj) then
|
||||
MessageBox("%s -- Error, prox object doesn't exist; aborting", tostring(Script))
|
||||
ScriptError("%s -- Error, prox object doesn't exist; aborting", tostring(Script))
|
||||
return
|
||||
end
|
||||
|
||||
-- Note the player_filter is optional. The user of this function must check
|
||||
-- for player validity at the source.
|
||||
if player_filter == nil then
|
||||
DebugMessage("%s -- Warning, passed a nil player, not filtering prox by player", tostring(Script))
|
||||
end
|
||||
|
||||
obj.Event_Object_In_Range(func, range, player_filter)
|
||||
ProxTable[obj] = 1
|
||||
end
|
||||
|
||||
function Process_Proximities()
|
||||
for obj, count in pairs(ProxTable) do
|
||||
if TestValid(obj) then
|
||||
obj.Service_Wrapper()
|
||||
else
|
||||
ProxTable[obj] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Pump_Service()
|
||||
Process_Timers()
|
||||
Process_Death_Events()
|
||||
Process_Proximities()
|
||||
Process_Attacked_Events()
|
||||
|
||||
-- Don't test if this is a function, so that we can catch accidental redefinitions when it's used as a function.
|
||||
if Process_Reinforcements then
|
||||
Process_Reinforcements()
|
||||
end
|
||||
|
||||
-- This is for behavior that we need evaluated every service without regard to story event state.
|
||||
if Story_Mode_Service then
|
||||
Story_Mode_Service()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Try an ability if the AI difficulty will allow a chance
|
||||
function Try_Ability(thing, ability_name, target)
|
||||
|
||||
owner = PlayerObject
|
||||
if not Is_A_Taskforce(thing) then
|
||||
owner = thing.Get_Owner()
|
||||
end
|
||||
if owner == nil then
|
||||
MessageBox("%s -- no owner for thing:%s", tostring(Script), tostring(thing))
|
||||
end
|
||||
|
||||
-- At a given difficulty, there is a chance that the ability use will be allowed.
|
||||
if not Chance(GetAbilityChanceSeed(), GetChanceAllowed(owner.Get_Difficulty())) then
|
||||
return false
|
||||
end
|
||||
|
||||
return Use_Ability_If_Able(thing, ability_name, target)
|
||||
end
|
||||
|
||||
|
||||
-- Activates the ability for a unit or a taskforce's units if able.
|
||||
-- Optionally uses ability on a target.
|
||||
-- Returns true if the ability was attempted
|
||||
function Use_Ability_If_Able(thing, ability_name, target)
|
||||
|
||||
-- Taskforces aren't able to check for the ability availablity or readiness, but check this for units
|
||||
if Is_A_Taskforce(thing) or (thing.Has_Ability(ability_name) and thing.Is_Ability_Ready(ability_name) and (not thing.Is_Ability_Active(ability_name))) then
|
||||
|
||||
if target == nil then
|
||||
thing.Activate_Ability(ability_name, true)
|
||||
elseif TestValid(target) then
|
||||
thing.Activate_Ability(ability_name, target)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function Is_A_Taskforce(thing)
|
||||
return thing and thing.Get_Unit_Table
|
||||
end
|
||||
|
||||
|
||||
-- This will consider diverting the passed object in order to use an area of effect ability centered on the unit.
|
||||
function ConsiderDivertAndAOE(object, ability_name, area_of_effect, recent_enemy_units, min_threat_to_use_ability)
|
||||
|
||||
-- At a given difficulty, there is a chance that the divert for ability use will be allowed.
|
||||
if (not aoe_pos) and (not Chance(GetCurrentMinute(), GetChanceAllowed(object.Get_Owner().Get_Difficulty()))) then
|
||||
return
|
||||
end
|
||||
|
||||
-- See if the ability is ready and there are enough enemies around to consider using it.
|
||||
if object.Is_Ability_Ready(ability_name) then
|
||||
|
||||
DebugMessage("%s -- %s is ready and trigger number met", tostring(Script), ability_name)
|
||||
|
||||
-- If we haven't found a good use for the ability
|
||||
if aoe_pos == nil then
|
||||
|
||||
-- Find a good place to use the ability and divert or throw the result away.
|
||||
aoe_pos, aoe_victim_threat = Find_Best_Local_Threat_Center(recent_enemy_units, area_of_effect)
|
||||
if aoe_pos == nil then
|
||||
DebugMessage("%s -- couldn't get a valid threat center", tostring(Script))
|
||||
DebugPrintTable(recent_enemy_units)
|
||||
return
|
||||
end
|
||||
|
||||
DebugMessage("%s -- Found ability pos with threat %d", tostring(Script), aoe_victim_threat)
|
||||
if (aoe_victim_threat > min_threat_to_use_ability) then
|
||||
|
||||
-- Check distance to prevent the unit from spinning in circles on repeated diversions
|
||||
if object.Get_Distance(aoe_pos) > 15 then
|
||||
DebugMessage("%s -- Met minimum threat; diverting.", tostring(Script))
|
||||
Use_Ability_If_Able(object, "SPRINT")
|
||||
object.Divert(aoe_pos)
|
||||
else
|
||||
DebugMessage("%s -- Met minimum threat; Already very close to ideal target so no divert necessary.", tostring(Script))
|
||||
end
|
||||
else
|
||||
DebugMessage("%s -- Resetting pos and threat.", tostring(Script))
|
||||
aoe_pos = nil
|
||||
aoe_victim_threat = nil
|
||||
end
|
||||
|
||||
-- We have found a good use for the ability
|
||||
else
|
||||
|
||||
-- Are we done chasing down the position to use the ability?
|
||||
if object.Is_On_Diversion() then
|
||||
|
||||
DebugMessage("%s -- In process of diverting to chase threat %d (no new orders issued)", tostring(Script), aoe_victim_threat)
|
||||
|
||||
else
|
||||
|
||||
-- We're done diverting. Perform a sanity check to make sure at least one enemy is now in range.
|
||||
--if OneOrMoreInRange(object, recent_enemy_units, area_of_effect) then
|
||||
-- We're done diverting so check to see if we're at least in range of the best location (even if not centered on it)
|
||||
aoe_pos, aoe_victim_threat = Find_Best_Local_Threat_Center(recent_enemy_units, area_of_effect)
|
||||
if aoe_pos and (object.Get_Distance(aoe_pos) < area_of_effect) then
|
||||
|
||||
-- Use the ability
|
||||
DebugMessage("%s -- Attempting %s.", tostring(Script), ability_name)
|
||||
Use_Ability_If_Able(object, ability_name)
|
||||
else
|
||||
DebugMessage("%s -- Nothing at diversion locaion; aborting.", tostring(Script))
|
||||
end
|
||||
|
||||
-- Reset everything; this try is done. If the victims moved too much, we'll need to start over.
|
||||
recent_enemy_units = {}
|
||||
aoe_pos = nil
|
||||
aoe_victim_threat = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OneOrMoreInRange(origin_unit, target_unit_list, range)
|
||||
for key, unit in pairs(target_unit_list) do
|
||||
if origin_unit.Get_Distance(unit) < range then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function PruneFriendlyObjects(obj_table)
|
||||
non_friendly_obj_table = {}
|
||||
for i, obj in pairs(obj_table) do
|
||||
if not (obj.Get_Owner() == PlayerObject) then
|
||||
table.insert(non_friendly_obj_table, obj)
|
||||
end
|
||||
end
|
||||
|
||||
return non_friendly_obj_table
|
||||
end
|
||||
|
||||
function Try_Garrison(tf, unit, offensive_only, range)
|
||||
|
||||
lib_nearest_garrison = Find_Nearest(unit, "GarrisonCanFire", unit.Get_Owner(), true)
|
||||
|
||||
if TestValid(lib_nearest_garrison) and unit.Can_Garrison(lib_nearest_garrison) then
|
||||
lib_dist_to_garrison = unit.Get_Distance(lib_nearest_garrison)
|
||||
|
||||
if lib_dist_to_garrison < range then
|
||||
unit.Activate_Ability("SPREAD_OUT", false)
|
||||
unit.Garrison(lib_nearest_garrison)
|
||||
|
||||
if TestValid(tf) then
|
||||
tf.Release_Unit(unit)
|
||||
unit.Lock_Current_Orders()
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if not offensive_only then
|
||||
lib_nearest_garrison = Find_Nearest(unit, "CanContainGarrison", unit.Get_Owner(), true)
|
||||
|
||||
if TestValid(lib_nearest_garrison) and unit.Can_Garrison(lib_nearest_garrison) then
|
||||
lib_dist_to_garrison = unit.Get_Distance(lib_nearest_garrison)
|
||||
|
||||
if lib_dist_to_garrison < range then
|
||||
unit.Activate_Ability("SPREAD_OUT", false)
|
||||
unit.Garrison(lib_nearest_garrison)
|
||||
if TestValid(tf) then
|
||||
unit.Lock_Current_Orders()
|
||||
tf.Release_Unit(unit)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function Try_Deploy_Garrison(object, target, health_threshold)
|
||||
lib_any_deployed = false
|
||||
lib_garrison_table = object.Get_Garrisoned_Units()
|
||||
if table.getn(lib_garrison_table) > 0 then
|
||||
for i,garrison in pairs(lib_garrison_table) do
|
||||
if garrison.Get_Hull() > health_threshold then
|
||||
if (not TestValid(target)) or garrison.Is_Good_Against(target) then
|
||||
garrison.Leave_Garrison()
|
||||
lib_any_deployed = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return lib_any_deployed
|
||||
end
|
||||
|
||||
function Get_Special_Healer_Property_Flag(unit)
|
||||
|
||||
if not TestValid(unit) then
|
||||
return nil
|
||||
end
|
||||
|
||||
if not special_healer_table then
|
||||
special_healer_table = {}
|
||||
special_healer_table["BOBA_FETT"] = "HealsInfantry"
|
||||
special_healer_table["EMPEROR_PALPATINE"] = "HealsInfantry"
|
||||
special_healer_table["HAN_SOLO"] = "HealsInfantry"
|
||||
special_healer_table["CHEWBACCA"] = "HealsInfantry"
|
||||
special_healer_table["MARA_JADE"] = "HealsInfantry"
|
||||
special_healer_table["OBI_WAN_KENOBI"] = "HealsInfantry"
|
||||
special_healer_table["DARTH_VADER"] = "HealsInfantry"
|
||||
special_healer_table["KYLE_KATARN"] = "HealsInfantry"
|
||||
special_healer_table["TACTICAL_R2_3PO_TEAM"] = "HealsVehicles"
|
||||
special_healer_table["GARGANTUAN_BATTLE_PLATFORM"] = "HealsVehicles"
|
||||
special_healer_table["LUKE_SKYWALKER_JEDI"] = "HealsInfantry"
|
||||
special_healer_table["YODA"] = "HealsInfantry"
|
||||
special_healer_table["BOSSK"] = "HealsInfantry"
|
||||
special_healer_table["IG-88"] = "HealsVehicles"
|
||||
special_healer_table["SILRI"] = "HealsInfantry"
|
||||
special_healer_table["TYBER_ZANN"] = "HealsInfantry"
|
||||
special_healer_table["URAI_FEN"] = "HealsInfantry"
|
||||
special_healer_table["PESTELOUS_THE_HUTT"] = "HealsVehicles"
|
||||
special_healer_table["CUARSON"] = "HealsInfantry"
|
||||
special_healer_table["XIZOR"] = "HealsInfantry"
|
||||
special_healer_table["SYKARIIUS"] = "HealsInfantry"
|
||||
special_healer_table["MPTL_SPOTTER"] = "HealsVehicles"
|
||||
special_healer_table["SCOUT_TROOPER"] = "HealsVehicles"
|
||||
special_healer_table["B1_BATTLEDROID"] = "HealsVehicles"
|
||||
special_healer_table["B2_BATTLEDROID"] = "HealsVehicles"
|
||||
special_healer_table["B1_REPAIRDROID"] = "HealsVehicles"
|
||||
special_healer_table["MAGNAGUARD"] = "HealsVehicles"
|
||||
end
|
||||
|
||||
return special_healer_table[unit.Get_Type().Get_Name()]
|
||||
|
||||
end
|
||||
|
||||
function Set_Land_AI_Targeting_Priorities(tf)
|
||||
|
||||
--First set up generic priorities
|
||||
tf.Set_Targeting_Priorities("Infantry_Attack_Move", "Infantry")
|
||||
tf.Set_Targeting_Priorities("Infantry_Attack_Move", "LandHero")
|
||||
tf.Set_Targeting_Priorities("Air_Attack_Move", "Air")
|
||||
tf.Set_Targeting_Priorities("Heavy_Vehicle_Attack_Move", "Vehicle")
|
||||
|
||||
--Now for some more specific stuff
|
||||
tf.Set_Targeting_Priorities("Rocket_Infantry_Attack_Move", "Plex_Soldier_Team")
|
||||
tf.Set_Targeting_Priorities("Rocket_Infantry_Attack_Move", "Pirate_Plex_Soldier_Team")
|
||||
tf.Set_Targeting_Priorities("Light_Vehicle_Attack_Move", "TIE_Crawler")
|
||||
tf.Set_Targeting_Priorities("Light_Vehicle_Attack_Move", "AT_RT_Walker")
|
||||
tf.Set_Targeting_Priorities("Light_Vehicle_Attack_Move", "AT_PT_Walker")
|
||||
tf.Set_Targeting_Priorities("Light_Vehicle_Attack_Move", "AT_ST_Walker")
|
||||
tf.Set_Targeting_Priorities("Light_Vehicle_Attack_Move", "T1C_Tank")
|
||||
tf.Set_Targeting_Priorities("Light_Vehicle_Attack_Move", "T2B_Tank")
|
||||
tf.Set_Targeting_Priorities("Light_Vehicle_Attack_Move", "Dark_Trooper_PhaseI")
|
||||
tf.Set_Targeting_Priorities("Light_Vehicle_Attack_Move", "Hutt_Modified_Skiff")
|
||||
tf.Set_Targeting_Priorities("Light_Vehicle_Attack_Move", "Hutt_Modified_Swamp_Speeder")
|
||||
tf.Set_Targeting_Priorities("Artillery_Attack_Move", "MPTL")
|
||||
tf.Set_Targeting_Priorities("Artillery_Attack_Move", "SPMAT_Walker")
|
||||
tf.Set_Targeting_Priorities("Artillery_Attack_Move", "MAL_Rocket_Vehicle")
|
||||
tf.Set_Targeting_Priorities("Artillery_Attack_Move", "HAG")
|
||||
end
|
||||
|
||||
function Try_Weapon_Switch(object, target)
|
||||
|
||||
lib_switcher_type = object.Get_Type()
|
||||
|
||||
if not lib_t4b_type then
|
||||
lib_t4b_type = Find_Object_Type("T4B_TANK")
|
||||
lib_t3b_type = Find_Object_Type("T3B_TANK")
|
||||
-- lib_marauder_type = Find_Object_Type("Marauder_Missile_Cruiser")
|
||||
-- lib_broadside_type = Find_Object_Type("Broadside_Class_Cruiser")
|
||||
-- lib_atst_type = Find_Object_Type("AT_ST_Walker")
|
||||
lib_bossk_type = Find_Object_Type("BOSSK")
|
||||
lib_b2battledroid_type = Find_Object_Type("B2_Battledroid")
|
||||
lib_destroyer_droid_type = Find_Object_Type("DESTROYER_DROID")
|
||||
lib_mal_type = Find_Object_Type("MAL_ROCKET_VEHICLE")
|
||||
-- lib_subjugator_type = Find_Object_Type("Malevolence")
|
||||
lib_vader_type = Find_Object_Type("TIE_Prototype")
|
||||
lib_vader_team_type = Find_Object_Type("Darth_Vader_TIE_Fighter_Container")
|
||||
end
|
||||
|
||||
if lib_switcher_type == lib_t4b_type then
|
||||
object.Activate_Ability("ROCKET_ATTACK", target.Is_Category("Structure") or target.Is_Category("Infantry"))
|
||||
elseif lib_switcher_type == lib_t3b_type then
|
||||
object.Activate_Ability("ROCKET_ATTACK", target.Is_Category("Structure") or target.Is_Category("Infantry"))
|
||||
-- elseif lib_switcher_type == lib_marauder_type then
|
||||
-- object.Activate_Ability("ROCKET_ATTACK", target.Is_Category("Structure") or target.Is_Category("Capital"))
|
||||
-- elseif lib_switcher_type == lib_broadside_type then
|
||||
-- object.Activate_Ability("ROCKET_ATTACK", target.Is_Category("Structure") or target.Is_Category("Capital"))
|
||||
-- elseif lib_switcher_type == lib_atst_type then
|
||||
-- object.Activate_Ability("ROCKET_ATTACK", target.Is_Category("Infantry") or target.Is_Category("Vehicle"))
|
||||
elseif lib_switcher_type == lib_bossk_type then
|
||||
object.Activate_Ability("SWAP_WEAPONS", target.Is_Category("Infantry") or target.Is_Category("Vehicle"))
|
||||
elseif lib_switcher_type == lib_b2battledroid_type then
|
||||
object.Activate_Ability("SWAP_WEAPONS", target.Is_Category("Infantry") or target.Is_Category("Vehicle"))
|
||||
elseif lib_switcher_type == lib_destroyer_droid_type then
|
||||
object.Activate_Ability("ROCKET_ATTACK", target.Get_Shield() > 0.0)
|
||||
elseif lib_switcher_type == lib_mal_type then
|
||||
object.Activate_Ability("SWAP_WEAPONS", (target.Is_Category("Infantry") or target.Is_Category("Vehicle")) and GameRandom.Get_Float() > 0.8)
|
||||
-- elseif lib_switcher_type == lib_subjugator_type then
|
||||
-- object.Activate_Ability("ROCKET_ATTACK", target.Is_Category("Structure") or target.Is_Category("Super") or target.Is_Category("Capital") and target.Get_Shield() > 0.0)
|
||||
elseif lib_switcher_type == lib_vader_type then
|
||||
object.Activate_Ability("SWAP_WEAPONS", target.Get_Shield() > 0.0)
|
||||
elseif lib_switcher_type == lib_vader_team_type then
|
||||
object.Activate_Ability("SWAP_WEAPONS", target.Get_Shield() > 0.0)
|
||||
elseif object.Should_Switch_Weapons(target) then
|
||||
object.Activate_Ability("SWAP_WEAPONS", not object.Is_Ability_Active("SWAP_WEAPONS"))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function Determine_Magic_Wait_Duration()
|
||||
|
||||
lib_magic_wait_time = 2400 - GetCurrentTime()
|
||||
if lib_magic_wait_time < 60 then
|
||||
lib_magic_wait_time = 60
|
||||
end
|
||||
|
||||
return lib_magic_wait_time
|
||||
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
|
||||
519
DATA/SCRIPTS/LIBRARY/PGEVENTS.LUA
Normal file
519
DATA/SCRIPTS/LIBRARY/PGEVENTS.LUA
Normal file
@@ -0,0 +1,519 @@
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
-- (c) Galyana's Ultimate Empire at War Modifications
|
||||
--
|
||||
-- ****** *** *** ************ *** ***
|
||||
-- * * * * * * * *
|
||||
-- * * * * * * *
|
||||
-- * * * * * * *
|
||||
-- * * * * * **** * * *
|
||||
-- * * * ****** * * * *
|
||||
-- * **** * * * * * * * *** *
|
||||
-- * * * * * * * * * *
|
||||
-- * * * * * * * * * *
|
||||
-- * * * * * * * ** * * *
|
||||
-- ****** ****** ************ **** ** *******
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
-- 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: GUEaW/Data/Scripts/Library/PGEvents.LUA
|
||||
--
|
||||
-- Original Editor: Giovanni Galyana
|
||||
--
|
||||
-- Final Edit By: Giovanni Galyana
|
||||
--
|
||||
-- Date: 7 March, 2015
|
||||
--
|
||||
-- Revisions: 0
|
||||
--
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
--
|
||||
-- Default Event Handlers.
|
||||
--
|
||||
|
||||
require("PGTaskForce")
|
||||
|
||||
function GoHeal(tf, unit, healer, release)
|
||||
|
||||
--If we can lay proximity mines, do so and then rely on a further call to kite the enemy over them
|
||||
--Add a random factor here since proximity mines currently have no cooldown and so we'll never run
|
||||
--because we can always use them
|
||||
if (GameRandom.Get_Float() > 0.5) and Try_Ability(unit, "PROXIMITY_MINES", unit) then
|
||||
return
|
||||
end
|
||||
|
||||
if Try_Ability(unit, "BUZZ_DROIDS", unit) then
|
||||
return
|
||||
end
|
||||
|
||||
if release then
|
||||
Try_Ability(unit,"JET_PACK", healer)
|
||||
Try_Ability(unit,"SPRINT")
|
||||
Try_Ability(unit, "FORCE_CLOAK")
|
||||
Try_Ability(unit, "STEALTH")
|
||||
unit.Move_To(healer, 10)
|
||||
unit.Lock_Current_Orders()
|
||||
tf.Release_Unit(unit)
|
||||
else
|
||||
Try_Ability(unit,"JET_PACK", healer)
|
||||
Try_Ability(unit,"SPRINT")
|
||||
Try_Ability(unit, "FORCE_CLOAK")
|
||||
Try_Ability(unit, "STEALTH")
|
||||
unit.Divert(healer)
|
||||
end
|
||||
end
|
||||
|
||||
function GoKite(tf, unit, kite_pos, release)
|
||||
|
||||
--If we can lay proximity mines, do so and then rely on a further call to kite the enemy over them
|
||||
--Add a random factor here since proximity mines currently have no cooldown and so we'll never run
|
||||
--because we can always use them
|
||||
if (GameRandom.Get_Float() > 0.5) and Try_Ability(unit, "PROXIMITY_MINES", unit) then
|
||||
return
|
||||
end
|
||||
|
||||
if Try_Ability(unit, "BUZZ_DROIDS", unit) then
|
||||
return
|
||||
end
|
||||
|
||||
if release then
|
||||
Try_Ability(unit,"Turbo") -- Enable Turbo mode, if we have it.
|
||||
Try_Ability(unit,"JET_PACK", kite_pos)
|
||||
Try_Ability(unit,"EJECT_VEHICLE_THIEF")
|
||||
Try_Ability(unit,"SPRINT")
|
||||
Try_Ability(unit, "SPOILER_LOCK")
|
||||
Try_Ability(unit, "REPLENISH_WINGMEN")
|
||||
Try_Ability(unit, "FORCE_CLOAK")
|
||||
Try_Ability(unit, "STEALTH")
|
||||
if unit.Get_Hull() > 0.5 then
|
||||
Try_Ability(unit, "STIM_PACK")
|
||||
end
|
||||
|
||||
unit.Move_To(kite_pos)
|
||||
unit.Lock_Current_Orders()
|
||||
tf.Release_Unit(unit)
|
||||
else
|
||||
if not unit.Is_On_Diversion() then
|
||||
--MessageBox("%s -- Diverting: %s", tostring(Script), tostring(unit))
|
||||
Try_Ability(unit,"Turbo") -- Enable Turbo mode, if we have it.
|
||||
Try_Ability(unit,"JET_PACK", kite_pos)
|
||||
Try_Ability(unit,"EJECT_VEHICLE_THIEF")
|
||||
Try_Ability(unit,"SPRINT")
|
||||
Try_Ability(unit, "SPOILER_LOCK")
|
||||
Try_Ability(unit, "REPLENISH_WINGMEN")
|
||||
Try_Ability(unit, "FORCE_CLOAK")
|
||||
Try_Ability(unit, "STEALTH")
|
||||
if unit.Get_Hull() > 0.5 then
|
||||
Try_Ability(unit, "STIM_PACK")
|
||||
end
|
||||
|
||||
unit.Divert(kite_pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Try_Good_Ground(tf, unit)
|
||||
|
||||
nearest_good_ground_indicator = Find_Nearest(unit, "Prop_Good_Ground_Area")
|
||||
if nearest_good_ground_indicator then
|
||||
dist_to_good_ground = unit.Get_Distance(nearest_good_ground_indicator)
|
||||
if (dist_to_good_ground < 300) and (dist_to_good_ground > 20) then
|
||||
|
||||
unit.Activate_Ability("SPREAD_OUT", false)
|
||||
unit.Move_To(nearest_good_ground_indicator)
|
||||
unit.Lock_Current_Orders()
|
||||
tf.Release_Unit(unit)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- This should be useful for getting units within the minimum attack range
|
||||
-- or outside the maximum attack range on opponents who behave like artillery
|
||||
function Respond_To_MinRange_Attacks(tf, unit)
|
||||
|
||||
DebugMessage("%s-- looking at attacker for minrange response", tostring(Script))
|
||||
|
||||
min_range_attackers = {
|
||||
"R_Ground_Turbolaser_Tower"
|
||||
,"E_Ground_Turbolaser_Tower"
|
||||
,"U_Ground_Turbolaser_Tower"
|
||||
,"H_Ground_Turbolaser_Tower"
|
||||
,"H_Ground_Heavy_Beam_Tower"
|
||||
,"FCU_E_Ground_Turbolaser_Tower"
|
||||
,"FCU_R_Ground_Turbolaser_Tower"
|
||||
,"FCU_U_Ground_Turbolaser_Tower"
|
||||
,"FCU_H_Ground_Heavy_Beam_Tower"
|
||||
,"MPTL"
|
||||
,"SPMAT_Walker"
|
||||
,"AALL6"
|
||||
,"Hutt_SailBarge"
|
||||
,"Marauder_Missile_Cruiser"
|
||||
,"Broadside_Class_Cruiser"
|
||||
}
|
||||
|
||||
deadly_enemy = FindDeadlyEnemy(unit)
|
||||
if TestValid(deadly_enemy) then
|
||||
deadly_enemy_type = deadly_enemy.Get_Type()
|
||||
if Is_Type_In_List(deadly_enemy_type, min_range_attackers) then
|
||||
DebugMessage("%s -- attacked by min range attacker", tostring(Script))
|
||||
|
||||
-- Move any units in the task force which are in range of the attacker
|
||||
-- to a position over the max range or under the min range
|
||||
approach_or_flee_range = ((deadly_enemy_type.Get_Max_Range() - deadly_enemy_type.Get_Min_Range()) * 2 / 3) + deadly_enemy_type.Get_Min_Range()
|
||||
for i, tf_unit in pairs(tf.Get_Unit_Table()) do
|
||||
DebugMessage("%s -- considering run or approach for %s", tostring(Script), tostring(tf_unit))
|
||||
distance = tf_unit.Get_Distance(deadly_enemy)
|
||||
if distance < deadly_enemy_type.Get_Max_Range() then
|
||||
if distance < approach_or_flee_range then
|
||||
DebugMessage("%s -- trying to run inside min attack range", tostring(Script))
|
||||
tf_unit.Move_To(deadly_enemy)
|
||||
tf_unit.Lock_Current_Orders()
|
||||
tf.Release_Unit(unit)
|
||||
else
|
||||
DebugMessage("%s -- trying to run outside max attack range", tostring(Script))
|
||||
GoKite(tf, tf_unit, Project_By_Unit_Range(deadly_enemy, tf_unit))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function Is_Type_In_List(unit_type, type_name_list)
|
||||
for i, type_name in pairs(type_name_list) do
|
||||
DebugMessage("%s -- type:%s checking match to:%s", tostring(Script), unit_type.Get_Name(), type_name)
|
||||
if unit_type == Find_Object_Type(type_name) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Check if the passed ability is one of the type that the AI wants to turn back on when cancelled
|
||||
function IsAbilityAllowedToRecover(ability)
|
||||
allowed_abilities = {
|
||||
"SPOILER_LOCK"
|
||||
,"Turbo"
|
||||
}
|
||||
|
||||
for i, allowed_ability in pairs(allowed_abilities) do
|
||||
if ability == allowed_ability then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function Default_Space_Conflict_Begin()
|
||||
DebugMessage("%s -- In Default_Space_Conflict_Begin.", tostring(Script))
|
||||
InSpaceConflict = true
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "CONTACT_OCCURED"), 0.0)
|
||||
end
|
||||
|
||||
function Default_Space_Conflict_End()
|
||||
DebugMessage("%s -- In Default_Space_Conflict_End.", tostring(Script))
|
||||
InSpaceConflict = false
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "CONTACT_OCCURED"), 0.0)
|
||||
end
|
||||
|
||||
function Default_Unit_Destroyed()
|
||||
DebugMessage("%s -- In Default_Unit_Destroyed.", tostring(Script))
|
||||
end
|
||||
|
||||
function Default_Unit_Damaged(tf, unit, attacker, deliberate)
|
||||
DebugMessage("%s -- In Default_Unit_Damaged.", tostring(Script))
|
||||
|
||||
if not TestValid(unit) or not TestValid(attacker) or attacker.Is_Category("Structure") then
|
||||
return
|
||||
end
|
||||
|
||||
lib_issued_movement_response = false
|
||||
|
||||
-- all units but Interdictors try to maneuver against artillery and turbolasers
|
||||
-- Interdictors should use missile shield instead
|
||||
if unit.Get_Type() ~= Find_Object_Type("Interdictor_Cruiser") then
|
||||
lib_issued_movement_response = Respond_To_MinRange_Attacks(tf, unit)
|
||||
end
|
||||
|
||||
if Should_Crush(unit, attacker) then
|
||||
unit.Divert(Project_By_Unit_Range(unit, attacker))
|
||||
lib_issued_movement_response = true
|
||||
end
|
||||
|
||||
-- If the unit is infantry, try to use any nearby garrisons or "good ground"
|
||||
if unit.Is_Category("Infantry") then
|
||||
|
||||
if not lib_issued_movement_response then
|
||||
lib_issued_movement_response = Try_Garrison(tf, unit, unit.Get_Hull() > 0.4, 300.0)
|
||||
end
|
||||
|
||||
if not lib_issued_movement_response then
|
||||
lib_issued_movement_response = Try_Good_Ground(tf, unit)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if attacker.Is_Category("Infantry") then
|
||||
Try_Deploy_Garrison(unit, attacker, 0.5)
|
||||
end
|
||||
|
||||
-- Use "Power to Shields" if this unit has it and it's ready
|
||||
lib_ability_activated = false
|
||||
lib_shield_level = unit.Get_Shield()
|
||||
if lib_shield_level < 0.2 then
|
||||
lib_ability_activated = Try_Ability(unit, "INVULNERABILITY")
|
||||
end
|
||||
|
||||
if (not lib_ability_activated) and (lib_shield_level < 0.8) then
|
||||
lib_ability_activated = Try_Ability(unit, "Defend")
|
||||
end
|
||||
|
||||
projectile_type = attacker.Get_Current_Projectile_Type()
|
||||
if TestValid(projectile_type) then
|
||||
if (not lib_ability_activated) and projectile_type.Is_Affected_By_Missile_Shield() then
|
||||
lib_ability_activated = Try_Ability(unit, "SENSOR_JAMMING") or Try_Ability(unit, "MISSILE_SHIELD")
|
||||
end
|
||||
|
||||
if (not lib_ability_activated) and projectile_type.Is_Affected_By_Laser_Defense() then
|
||||
lib_ability_activated = Try_Ability(unit, "LASER_DEFENSE")
|
||||
end
|
||||
end
|
||||
|
||||
--Everything below deals with movement orders
|
||||
if lib_issued_movement_response then
|
||||
return
|
||||
end
|
||||
|
||||
-- non-hero fighters will always willingly dogfight other fighters
|
||||
if deliberate and attacker.Is_Category("Fighter") and unit.Is_Category("Fighter") then
|
||||
|
||||
DebugMessage("%s -- Fighter shot by fighter, releasing unit from tf and attacking.", tostring(Script))
|
||||
tf.Release_Unit(unit)
|
||||
unit.Activate_Ability("SPOILER_LOCK", false)
|
||||
if not unit.Activate_Ability("BUZZ_DROIDS", attacker) then
|
||||
unit.Attack_Target(attacker)
|
||||
end
|
||||
|
||||
-- Default handling for a dying unit in both space and land modes.
|
||||
-- Is this unit not fodder AND do we have low health AND (we have a bad face off OR we're rapidly being killed for any reason)
|
||||
else
|
||||
|
||||
lib_time_till_dead = unit.Get_Time_Till_Dead()
|
||||
lib_attacker_is_good_vs_me = attacker.Is_Good_Against(unit)
|
||||
lib_i_am_good_vs_attacker = unit.Is_Good_Against(attacker)
|
||||
lib_current_health = unit.Get_Hull()
|
||||
lib_is_hero = unit.Get_Type().Is_Hero()
|
||||
lib_is_fodder = unit.Has_Property("Fodder")
|
||||
|
||||
if not lib_i_am_good_vs_attacker then
|
||||
Try_Ability(unit, "DEPLOY_TROOPERS")
|
||||
end
|
||||
|
||||
if ((not lib_is_fodder) and lib_time_till_dead < 20) or
|
||||
((not lib_is_fodder) and lib_current_health < 0.2) or
|
||||
(lib_is_hero and lib_current_health < 0.6) or
|
||||
(lib_current_health < 0.7 and lib_attacker_is_good_vs_me) or
|
||||
(lib_current_health < 0.4 and not lib_i_am_good_vs_attacker) then
|
||||
|
||||
--Certain factions have no self-preservation
|
||||
lib_faction_name = unit.Get_Owner().Get_Faction_Name()
|
||||
if lib_faction_name == "PIRATES" or lib_faction_name == "HUTTS" then
|
||||
return
|
||||
end
|
||||
|
||||
-- Turn off any abilities that would hinder self-preservation
|
||||
unit.Activate_Ability("Power_To_Weapons", false)
|
||||
|
||||
-- Try to find the nearest healing structure appropriate for this unit
|
||||
lib_healer_property_flag = Get_Special_Healer_Property_Flag(unit)
|
||||
if not lib_healer_property_flag then
|
||||
if unit.Is_Category("Infantry") then
|
||||
lib_healer_property_flag = "HealsInfantry"
|
||||
elseif unit.Is_Category("Vehicle") then
|
||||
lib_healer_property_flag = "HealsVehicles"
|
||||
end
|
||||
end
|
||||
|
||||
if lib_healer_property_flag then
|
||||
healer = Find_Nearest(unit, lib_healer_property_flag, PlayerObject, true)
|
||||
end
|
||||
|
||||
lib_should_release = lib_attacker_is_good_vs_me or lib_is_hero or (lib_current_health < 0.33)
|
||||
|
||||
-- Try to heal if we have a healer
|
||||
if healer then
|
||||
GoHeal(tf, unit, healer, lib_should_release)
|
||||
end
|
||||
|
||||
if not lib_is_fodder then
|
||||
-- Try to find a protected kiting location
|
||||
friendly = Find_Nearest(unit, PlayerObject, true)
|
||||
xfire_pos = Get_Most_Defended_Position(unit, PlayerObject)
|
||||
if xfire_pos then
|
||||
kite_pos = Project_By_Unit_Range(attacker, xfire_pos)
|
||||
elseif TestValid(friendly) then
|
||||
DebugMessage("Failed to find a Most Defended Position, using position of nearby friendly.")
|
||||
kite_pos = Project_By_Unit_Range(attacker, friendly)
|
||||
else
|
||||
kite_pos = Project_By_Unit_Range(attacker, unit)
|
||||
end
|
||||
|
||||
GoKite(tf, unit, kite_pos, lib_should_release)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Default_Original_Target_Destroyed()
|
||||
--DebugMessage("%s -- Original target destroyed. Aborting.", tostring(Script))
|
||||
Attacking = false
|
||||
--ScriptExit() Some plans now have behaviors to occur after this event.
|
||||
end
|
||||
|
||||
function Default_Current_Target_Destroyed(tf)
|
||||
--MessageBox("%s -- Current target destroyed. Aborting.", tostring(Script))
|
||||
Attacking = false
|
||||
|
||||
-- Turn off some unending abilities that might no longer be appropriate
|
||||
tf.Activate_Ability("SPREAD_OUT", false)
|
||||
|
||||
--ScriptExit() Some plans now have behaviors to occur after this event.
|
||||
end
|
||||
|
||||
function Default_Original_Target_Owner_Changed(tf, old_player, new_player)
|
||||
if InvasionActive == true then
|
||||
return
|
||||
end
|
||||
|
||||
DebugMessage("%s -- Original target ownership changed. Aborting.", tostring(Script))
|
||||
ScriptExit()
|
||||
end
|
||||
|
||||
function Default_Unit_Move_Finished(tf, unit)
|
||||
Try_Deploy_Garrison(unit, nil, 0.5)
|
||||
end
|
||||
|
||||
|
||||
function Should_Crush(unit, target)
|
||||
|
||||
-- don't crush in easy mode
|
||||
if (PlayerObject.Get_Difficulty() == "Easy") then
|
||||
return false
|
||||
end
|
||||
|
||||
-- don't try to crush again if already on a diversion
|
||||
if unit.Is_On_Diversion() then
|
||||
return false
|
||||
end
|
||||
|
||||
-- if the vehicle is good at it, the victim is infantry, and vulnerable to crushing
|
||||
if unit.Has_Property("GoodInfantryCrusher") and target.Is_Category("Infantry") then
|
||||
if target.Is_Ability_Active("SPREAD_OUT") then
|
||||
return true
|
||||
elseif GameRandom.Get_Float() > 0.8 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- if the vehicle can crush anything and is close enough
|
||||
if unit.Has_Property("IsSupercrusher") and (unit.Get_Distance(target) < 75) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function Default_Target_In_Range(tf, unit, target)
|
||||
--MessageBox("%s -- unit: Default_Target_In_Range for: %s.", tostring(Script), tostring(unit), tostring(target))
|
||||
|
||||
-- We'll assume that once the first unit within a task force is in range, the attack has begun.
|
||||
Attacking = true
|
||||
|
||||
-- Certain units like to try to crush other units, but we can't crush Rebel units that are spread out
|
||||
if Should_Crush(unit, target) then
|
||||
DebugMessage("%s -- Attempting to crush %s with %s", tostring(Script), tostring(target), tostring(unit))
|
||||
unit.Divert(Project_By_Unit_Range(unit, target))
|
||||
end
|
||||
|
||||
Try_Deploy_Garrison(unit, target, 0.5)
|
||||
|
||||
-- Turn various abilities that would be useful.
|
||||
-- The ability time-out or the plan ending will turn off the ability.
|
||||
Try_Ability(unit, "Power_To_Weapons")
|
||||
Try_Ability(unit, "SPREAD_OUT")
|
||||
Try_Ability(unit, "BARRAGE", target)
|
||||
Try_Ability(unit, "BUZZ_DROIDS", target)
|
||||
Try_Ability(unit, "FULL_SALVO")
|
||||
Try_Ability(unit, "BLAST")
|
||||
|
||||
if unit.Get_Hull() > 0.5 then
|
||||
Try_Ability(unit, "STIM_PACK")
|
||||
end
|
||||
|
||||
Try_Weapon_Switch(unit, target)
|
||||
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "CONTACT_OCCURED"), 1.0)
|
||||
end
|
||||
|
||||
function Default_Hardpoint_Target_In_Range(tf, unit, target)
|
||||
DebugMessage("%s -- A hardpoint of %s can now fire on target %s.", tostring(Script), tostring(unit), tostring(attacker))
|
||||
end
|
||||
|
||||
function Default_No_Units_Remaining()
|
||||
DebugMessage("%s -- All units dead or non-buildable. Abandonning plan.", tostring(Script))
|
||||
ScriptExit()
|
||||
end
|
||||
|
||||
function Default_Unit_Diversion_Finished(tf, unit)
|
||||
|
||||
if TestValid(unit) then
|
||||
-- Turn off turbo, if we happened to be using it to assist in a divert (evasive maneuver).
|
||||
unit.Activate_Ability("Turbo", false)
|
||||
unit.Activate_Ability("SPOILER_LOCK", false)
|
||||
end
|
||||
end
|
||||
|
||||
-- This fires if the countdown was going and it is now refreshed or if you come out of a nebula
|
||||
function Default_Unit_Ability_Ready(tf, unit, ability)
|
||||
|
||||
--MessageBox("%s ready for %s", ability, tostring(unit))
|
||||
|
||||
-- Try to recover use of interrupted abilities.
|
||||
if lib_cancelled_abilities[unit] and lib_cancelled_abilities[unit][ability] then
|
||||
--MessageBox("%s-- attempting to recover use of %s", tostring(Script), ability)
|
||||
unit.Activate_Ability(ability, true)
|
||||
lib_cancelled_abilities[unit][ability] = false
|
||||
end
|
||||
end
|
||||
|
||||
-- An ability was interrupted before naturally finishing.
|
||||
function Default_Unit_Ability_Cancelled(tf, unit, ability)
|
||||
DebugMessage("%s -- Ability %s of %s has been cancelled!", tostring(Script), ability, tostring(unit))
|
||||
|
||||
-- Track certain abilities that get cancelled, so we can recover them later
|
||||
if IsAbilityAllowedToRecover(ability) then
|
||||
|
||||
-- make a new ability table for this unit, if one doesn't yet exist
|
||||
if not lib_cancelled_abilities[unit] then
|
||||
lib_cancelled_abilities[unit] = {}
|
||||
end
|
||||
|
||||
lib_cancelled_abilities[unit][ability] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- An ability finished naturally by its duration running out or by being turned off.
|
||||
function Default_Unit_Ability_Finished(tf, unit)
|
||||
--DebugMessage("%s -- An ability for %s has finished!", tostring(Script), ability, tostring(unit))
|
||||
end
|
||||
133
DATA/SCRIPTS/LIBRARY/PGINTERVENTIONS.LUA
Normal file
133
DATA/SCRIPTS/LIBRARY/PGINTERVENTIONS.LUA
Normal file
@@ -0,0 +1,133 @@
|
||||
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGInterventions.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/PGInterventions.lua $
|
||||
--
|
||||
-- Original Author: Brian Hayes
|
||||
--
|
||||
-- $Author: Andre_Arsenault $
|
||||
--
|
||||
-- $Change: 37816 $
|
||||
--
|
||||
-- $DateTime: 2006/02/15 15:33:33 $
|
||||
--
|
||||
-- $Revision: #1 $
|
||||
--
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require("PGBaseDefinitions")
|
||||
|
||||
function Definitions()
|
||||
TaskForce = {
|
||||
{
|
||||
"Intervention",
|
||||
"TaskForceRequired",
|
||||
"DenyHeroAttach",
|
||||
},
|
||||
}
|
||||
|
||||
StartTime = GetCurrentTime()
|
||||
InterventionExclusionPeriod = 120.0
|
||||
|
||||
MinContrastScale = 1.1
|
||||
MaxContrastScale = 1.5
|
||||
PerFailureContrastAdjust = 0.1
|
||||
EnemyContrastTypes = {}
|
||||
FriendlyContrastTypes = {}
|
||||
ContrastTypeScale = {}
|
||||
|
||||
if Declare_Goal_Type then
|
||||
Declare_Goal_Type()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function Wait_On_Flag(flag_name, location)
|
||||
while not Check_Story_Flag(PlayerObject, flag_name, location, true) do
|
||||
Sleep(1)
|
||||
if GetCurrentTime() - StartTime > InterventionExclusionPeriod then
|
||||
Intervention.Unblock_Goal_Proposal()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Begin_Intervention()
|
||||
|
||||
if EvaluatePerception("Are_Interventions_Allowed", PlayerObject) == 0 then
|
||||
ScriptExit()
|
||||
end
|
||||
|
||||
Intervention.Block_Goal_Proposal()
|
||||
Intervention.Set_As_Goal_System_Removable(false)
|
||||
end
|
||||
|
||||
function End_Intervention()
|
||||
Intervention.Unblock_Goal_Proposal()
|
||||
Sleep(GameRandom(60, 300))
|
||||
ScriptExit()
|
||||
end
|
||||
|
||||
function Select_Reward_Unit(reward_table, player, min_value)
|
||||
|
||||
distribution = DiscreteDistribution.Create()
|
||||
|
||||
for i,possible_reward in pairs(reward_table) do
|
||||
|
||||
if not possible_reward.Is_Obsolete(player) and possible_reward.Is_Affiliated_With(player) then
|
||||
|
||||
tech_difference = possible_reward.Get_Tech_Level() - player.Get_Tech_Level()
|
||||
|
||||
if possible_reward.Is_Build_Locked(player) then
|
||||
if tech_difference == 0 then
|
||||
distribution.Insert(possible_reward, 7.0)
|
||||
end
|
||||
else
|
||||
if tech_difference <= 1 then
|
||||
distribution.Insert(possible_reward, 6.0 + tech_difference)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
reward = distribution.Sample()
|
||||
|
||||
if not reward then
|
||||
return nil
|
||||
end
|
||||
|
||||
reward_count = (min_value - 1) / reward.Get_Build_Cost() + 0.5
|
||||
|
||||
if reward_count < 1 then
|
||||
reward_count = 1
|
||||
elseif reward_count > 5 then
|
||||
reward_count = 5
|
||||
end
|
||||
|
||||
return reward, reward_count
|
||||
|
||||
end
|
||||
109
DATA/SCRIPTS/LIBRARY/PGMOVEUNITS.LUA
Normal file
109
DATA/SCRIPTS/LIBRARY/PGMOVEUNITS.LUA
Normal file
@@ -0,0 +1,109 @@
|
||||
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGMoveUnits.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/PGMoveUnits.lua $
|
||||
--
|
||||
-- Original Author: Brian Hayes
|
||||
--
|
||||
-- $Author: Andre_Arsenault $
|
||||
--
|
||||
-- $Change: 37816 $
|
||||
--
|
||||
-- $DateTime: 2006/02/15 15:33:33 $
|
||||
--
|
||||
-- $Revision: #1 $
|
||||
--
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require("PGBaseDefinitions")
|
||||
|
||||
|
||||
|
||||
-- This will move an entire unit list with simultaneous orders.
|
||||
-- They will block as a whole and pass when the last unit's move is complete.
|
||||
function Formation_Move(unit_list, target)
|
||||
if type(unit_list) == "table" then
|
||||
Cull_Unit_List(unit_list)
|
||||
for k, unit in pairs(unit_list) do -- An individual unit is needed to reach the Move_To function.
|
||||
BlockOnCommand(unit.Move_To(unit_list, target)) -- Note that the unit list is passed.
|
||||
return
|
||||
end
|
||||
DebugMessage("%s -- Formation_Move, unit_list is empty", tostring(Script))
|
||||
elseif type(unit_list) == "userdata" then
|
||||
BlockOnCommand(unit_list.Move_To(target))
|
||||
else
|
||||
DebugMessage("%s -- Formation_Move, expected table or userdata got %s", tostring(Script), tostring(unit_list))
|
||||
end
|
||||
end
|
||||
|
||||
function Formation_Attack(unit_list, target)
|
||||
if type(unit_list) == "table" then
|
||||
Cull_Unit_List(unit_list)
|
||||
for k, unit in pairs(unit_list) do
|
||||
BlockOnCommand(unit.Attack_Target(unit_list, target))
|
||||
return
|
||||
end
|
||||
DebugMessage("%s -- Formation_Attack, unit_list is empty", tostring(Script))
|
||||
elseif type(unit_list) == "userdata" then
|
||||
BlockOnCommand(unit_list.Attack_Move(target))
|
||||
else
|
||||
DebugMessage("%s -- Formation_Attack, expected table or userdata got %s", tostring(Script), tostring(unit_list))
|
||||
end
|
||||
end
|
||||
|
||||
function Formation_Attack_Move(unit_list, target)
|
||||
if type(unit_list) == "table" then
|
||||
Cull_Unit_List(unit_list)
|
||||
for k, unit in pairs(unit_list) do
|
||||
BlockOnCommand(unit.Attack_Move(unit_list, target))
|
||||
return
|
||||
end
|
||||
DebugMessage("%s -- Formation_Attack, unit_list is empty", tostring(Script))
|
||||
elseif type(unit_list) == "userdata" then
|
||||
BlockOnCommand(unit_list.Attack_Move(target))
|
||||
else
|
||||
DebugMessage("%s -- Formation_Attack, expected table or userdata got %s", tostring(Script), tostring(unit_list))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Formation_Guard(unit_list, target)
|
||||
if type(unit_list) == "table" then
|
||||
Cull_Unit_List(unit_list)
|
||||
for k, unit in pairs(unit_list) do
|
||||
BlockOnCommand(unit.Guard_Target(unit_list, target))
|
||||
return
|
||||
end
|
||||
DebugMessage("%s -- Formation_Guard, unit_list is empty", tostring(Script))
|
||||
elseif type(unit_list) == "userdata" then
|
||||
BlockOnCommand(unit_list.Guard_Target(target))
|
||||
else
|
||||
DebugMessage("%s -- Formation_Guard, expected table or userdata got %s", tostring(Script), tostring(unit_list))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
162
DATA/SCRIPTS/LIBRARY/PGSPAWNUNITS.LUA
Normal file
162
DATA/SCRIPTS/LIBRARY/PGSPAWNUNITS.LUA
Normal file
@@ -0,0 +1,162 @@
|
||||
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGSpawnUnits.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/PGSpawnUnits.lua $
|
||||
--
|
||||
-- Original Author: Brian Hayes
|
||||
--
|
||||
-- $Author: Andre_Arsenault $
|
||||
--
|
||||
-- $Change: 37816 $
|
||||
--
|
||||
-- $DateTime: 2006/02/15 15:33:33 $
|
||||
--
|
||||
-- $Revision: #1 $
|
||||
--
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require("PGBaseDefinitions")
|
||||
|
||||
|
||||
function Process_Reinforcements()
|
||||
for index, btable in ipairs(block_table) do
|
||||
for k, block in pairs(btable) do
|
||||
if not block.block then
|
||||
--Haven't yet issued the reinforcement command, or else a previous attempt failed
|
||||
block.block = Reinforce_Unit(block.ref_type, block.entry_marker, block.player, true, block.obey_zones)
|
||||
elseif block.block.IsFinished() then
|
||||
new_units = block.block.Result()
|
||||
if type(new_units) == "table" then
|
||||
for j, unit in pairs(new_units) do
|
||||
DebugMessage("%s -- Process_Reinforcements Block: %s, unit: %s, allow:%s, delete:%s", tostring(Script), tostring(block.block), tostring(unit), tostring(block.allow_ai_usage), tostring(block.delete_after_scenario))
|
||||
if block.allow_ai_usage then
|
||||
--MessageBox("allow_ai_usage: %s", tostring(unit))
|
||||
unit.Prevent_AI_Usage(false)
|
||||
end
|
||||
if block.delete_after_scenario then
|
||||
--MessageBox("deleting after scenario: %s", tostring(unit))
|
||||
unit.Mark_Parent_Mode_Object_For_Death()
|
||||
end
|
||||
table.insert(block.block_track.unit_list, unit)
|
||||
end
|
||||
block.block_track.type_count = block.block_track.type_count - 1
|
||||
if block.block_track.type_count <= 0 then
|
||||
if type(block.callback) == "function" then
|
||||
block.callback(block.block_track.unit_list)
|
||||
end
|
||||
table.remove(block_table, index)
|
||||
Process_Reinforcements()
|
||||
return
|
||||
end
|
||||
end
|
||||
block_table[index][k] = nil
|
||||
Process_Reinforcements()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
new_units = nil
|
||||
end
|
||||
|
||||
function Add_Reinforcement(object_type, player)
|
||||
|
||||
if type(object_type) == "string" then
|
||||
object_type = Find_Object_Type(object_type)
|
||||
end
|
||||
|
||||
Reinforce_Unit(object_type, false, player, true, false)
|
||||
end
|
||||
|
||||
|
||||
-- Reinforce units via transport, simultaneously.
|
||||
function ReinforceList(type_list, entry_marker, player, allow_ai_usage, delete_after_scenario, ignore_reinforcement_rules, callback)
|
||||
|
||||
if type(ignore_reinforcement_rules) == "function" then
|
||||
MessageBox("Received a function for 6th parameter; expected bool. Note the signature change, sorry.")
|
||||
return
|
||||
end
|
||||
|
||||
if player == nil then
|
||||
MessageBox("expected a player for 3rd parameter; aborting")
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(block_table, {})
|
||||
index = table.getn(block_table)
|
||||
|
||||
block_track = {
|
||||
type_count = table.getn(type_list),
|
||||
unit_list = {}
|
||||
}
|
||||
|
||||
for k, unit_type in pairs(type_list) do
|
||||
ref_type = Find_Object_Type(unit_type)
|
||||
btab = {
|
||||
block = nil,
|
||||
block_track = block_track,
|
||||
ref_type = ref_type,
|
||||
entry_marker = entry_marker,
|
||||
player = player,
|
||||
obey_zones = not ignore_reinforcement_rules,
|
||||
allow_ai_usage = allow_ai_usage,
|
||||
callback = callback,
|
||||
delete_after_scenario = delete_after_scenario
|
||||
}
|
||||
table.insert(block_table[index], btab)
|
||||
btab = nil
|
||||
ref_type = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Spawn units simultaneously.
|
||||
function SpawnList(type_list, entry_marker, player, allow_ai_usage, delete_after_scenario)
|
||||
|
||||
unit_list = {}
|
||||
|
||||
for k, unit_type in pairs(type_list) do
|
||||
ref_type = Find_Object_Type(unit_type)
|
||||
new_units= Spawn_Unit(ref_type, entry_marker, player)
|
||||
for j, unit in pairs(new_units) do
|
||||
table.insert(unit_list, unit)
|
||||
if allow_ai_usage then
|
||||
--MessageBox("allow_ai_usage: %s", tostring(unit))
|
||||
unit.Prevent_AI_Usage(false)
|
||||
else
|
||||
unit.Prevent_AI_Usage(true) -- This doesn't happen automatically, unlike for Reinforce_Unit
|
||||
end
|
||||
if delete_after_scenario then
|
||||
--MessageBox("deleting after scenario: %s", tostring(unit))
|
||||
unit.Mark_Parent_Mode_Object_For_Death()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
new_units = nil
|
||||
|
||||
return unit_list
|
||||
end
|
||||
197
DATA/SCRIPTS/LIBRARY/PGSTATEMACHINE.LUA
Normal file
197
DATA/SCRIPTS/LIBRARY/PGSTATEMACHINE.LUA
Normal file
@@ -0,0 +1,197 @@
|
||||
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGStateMachine.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/PGStateMachine.lua $
|
||||
--
|
||||
-- Original Author: Brian Hayes
|
||||
--
|
||||
-- $Author: Andre_Arsenault $
|
||||
--
|
||||
-- $Change: 37816 $
|
||||
--
|
||||
-- $DateTime: 2006/02/15 15:33:33 $
|
||||
--
|
||||
-- $Revision: #1 $
|
||||
--
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require("pgcommands")
|
||||
|
||||
--
|
||||
-- Define_State -- Define a new state in the state machine table.
|
||||
--
|
||||
-- @param state This is the tag used to identify the state. Usually
|
||||
-- a text value or a number
|
||||
-- @param function_value This is the function value that will process
|
||||
-- all the messages associated with the given state.
|
||||
-- @since 4/22/2005 7:26:01 PM -- BMH
|
||||
--
|
||||
function Define_State(state, function_value)
|
||||
local curproc = StateMachine[state]
|
||||
if curproc == nil then
|
||||
StateMachineIndexes[DefineStateIndex] = state
|
||||
StateMachineIndexLookup[state] = DefineStateIndex
|
||||
DefineStateIndex = DefineStateIndex + 1
|
||||
end
|
||||
|
||||
StateMachine[state] = function_value
|
||||
|
||||
if NextState == nil then
|
||||
NextState = state
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Advance_State -- Advance to the next state based on the
|
||||
-- order of state definition
|
||||
--
|
||||
-- @since 4/22/2005 7:26:01 PM -- BMH
|
||||
--
|
||||
function Advance_State()
|
||||
NextState = StateMachineIndexes[CurrentStateIndex + 1]
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Set_Next_State -- Set the next state to transition to.
|
||||
--
|
||||
-- @param state tag specifying the state to transition to.
|
||||
-- @since 4/22/2005 7:26:01 PM -- BMH
|
||||
--
|
||||
function Set_Next_State(state)
|
||||
if state == nil or StateMachine[state] ~= nil then
|
||||
NextState = state
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Get_Current_State -- Returns what the current state is.
|
||||
--
|
||||
-- @return object detailing what the current state is.
|
||||
-- @since 4/22/2005 7:12:14 PM -- BMH
|
||||
--
|
||||
function Get_Current_State()
|
||||
return CurrentState
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Get_Next_State -- Returns what the next state will be.
|
||||
--
|
||||
-- @return object detailing what the next state will be.
|
||||
-- @since 4/22/2005 7:12:14 PM -- BMH
|
||||
--
|
||||
function Get_Next_State()
|
||||
return NextState
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Process_States -- This function is called to advance the State Machine through it's states
|
||||
--
|
||||
-- @since 4/22/2005 7:12:14 PM -- BMH
|
||||
--
|
||||
function Process_States()
|
||||
|
||||
while NextState ~= nil do
|
||||
_curproc = StateMachine[NextState]
|
||||
if type(_curproc) == "function" then
|
||||
CurrentState = NextState
|
||||
CurrentStateIndex = StateMachineIndexLookup[CurrentState]
|
||||
_curproc(OnEnter)
|
||||
while CurrentState == NextState do
|
||||
_curproc(OnUpdate)
|
||||
if CurrentState == NextState then
|
||||
PumpEvents()
|
||||
end
|
||||
end
|
||||
_curproc(OnExit)
|
||||
DebugMessage("%s -- Advancing state from %s to %s.", tostring(Script), tostring(CurrentState), tostring(NextState))
|
||||
else
|
||||
ScriptError("%s -- Invalid State: %s, Function: %s", tostring(Script), tostring(NextState), tostring(_curproc))
|
||||
NextState = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Base_Definitions -- This function is called once when the script is first created.
|
||||
--
|
||||
-- @since 4/22/2005 6:04:55 PM -- BMH
|
||||
--
|
||||
function Base_Definitions()
|
||||
DebugMessage("%s -- In Base_Definitions", tostring(Script))
|
||||
|
||||
Common_Base_Definitions()
|
||||
|
||||
StateMachine = {}
|
||||
StateMachineIndexes = {}
|
||||
StateMachineIndexLookup = {}
|
||||
OnEnter = 1
|
||||
OnUpdate = 2
|
||||
OnExit = 3
|
||||
CurrentStateIndex = 1
|
||||
DefineStateIndex = 1
|
||||
NextState = nil
|
||||
CurrentState = nil
|
||||
_curproc = nil
|
||||
StoryModeEvents = nil
|
||||
|
||||
-- This controls how often the script is serviced.
|
||||
-- So try to process 5 times a second
|
||||
ServiceRate = 0.2
|
||||
|
||||
if Definitions then
|
||||
Definitions()
|
||||
end
|
||||
|
||||
if PG_Story_Mode_Init then
|
||||
PG_Story_Mode_Init()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- main -- This is the main thread function for this script.
|
||||
-- Upon return from this function the script will finish and be
|
||||
-- destroyed by the system.
|
||||
--
|
||||
-- @since 4/22/2005 6:04:55 PM -- BMH
|
||||
--
|
||||
function main()
|
||||
|
||||
-- Enter your list of commands to execute here...
|
||||
Process_States()
|
||||
|
||||
DebugMessage("%s -- Exiting.", tostring(Script))
|
||||
-- ScriptExit will end the script no matter what state it's in.
|
||||
ScriptExit()
|
||||
end
|
||||
|
||||
92
DATA/SCRIPTS/LIBRARY/PGSTORYMODE.LUA
Normal file
92
DATA/SCRIPTS/LIBRARY/PGSTORYMODE.LUA
Normal file
@@ -0,0 +1,92 @@
|
||||
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGStoryMode.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/PGStoryMode.lua $
|
||||
--
|
||||
-- Original Author: Brian Hayes
|
||||
--
|
||||
-- $Author: Andre_Arsenault $
|
||||
--
|
||||
-- $Change: 37816 $
|
||||
--
|
||||
-- $DateTime: 2006/02/15 15:33:33 $
|
||||
--
|
||||
-- $Revision: #1 $
|
||||
--
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require("PGStateMachine")
|
||||
require("PGSpawnUnits")
|
||||
require("PGMoveUnits")
|
||||
|
||||
-- Story mode scripts shouldn't pool themselves.
|
||||
ScriptPoolCount = 0
|
||||
|
||||
function PG_Story_Mode_Init()
|
||||
|
||||
Define_State("PG_Story_State_Init", PG_Story_State_Init);
|
||||
|
||||
if StoryModeEvents ~= nil then
|
||||
for key,value in pairs(StoryModeEvents) do
|
||||
if type(value) == "function" then
|
||||
Define_State(key, value)
|
||||
else
|
||||
MessageBox("%s--Invalid function object for Storyevent: %s, got a \"%s\" instead.", tostring(Script), tostring(key), type(value))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Story_Event_Trigger(name)
|
||||
|
||||
if StoryModeEvents == nil then
|
||||
return
|
||||
end
|
||||
|
||||
--MessageBox("%s--In Story_Event_Trigger: %s", tostring(Script), name)
|
||||
|
||||
local event = StoryModeEvents[name]
|
||||
if event ~= nil then
|
||||
if type(event) == "function" then
|
||||
if Get_Current_State() == Get_Next_State() then
|
||||
--MessageBox("%s--Setting next state %s", tostring(Script), name)
|
||||
Set_Next_State(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PG_Story_State_Init(message)
|
||||
if message == OnEnter then
|
||||
DebugMessage("%s -- PG_Story_State_Init(OnEnter)", tostring(Script))
|
||||
elseif message == OnUpdate then
|
||||
elseif message == OnExit then
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
606
DATA/SCRIPTS/LIBRARY/PGTASKFORCE.LUA
Normal file
606
DATA/SCRIPTS/LIBRARY/PGTASKFORCE.LUA
Normal file
@@ -0,0 +1,606 @@
|
||||
-- $Id: //depot/Projects/StarWars_Expansion/Run/Data/Scripts/Library/PGTaskForce.lua#6 $
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
--
|
||||
-- (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/PGTaskForce.lua $
|
||||
--
|
||||
-- Original Author: Brian Hayes
|
||||
--
|
||||
-- $Author: James_Yarrow $
|
||||
--
|
||||
-- $Change: 46700 $
|
||||
--
|
||||
-- $DateTime: 2006/06/21 14:40:55 $
|
||||
--
|
||||
-- $Revision: #6 $
|
||||
--
|
||||
--/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require("PGAICommands")
|
||||
|
||||
function FindStageArea(_target, taskforce)
|
||||
return _FindStageArea(PlayerObject, _target, taskforce);
|
||||
end
|
||||
|
||||
function AssembleForce(taskforce, stage_at_strongest_space)
|
||||
if stage_at_strongest_space then
|
||||
stage = FindTarget.Reachable_Target(PlayerObject, "FriendlySpaceForceStrength", "Friendly | Enemy | Neutral", "Enemy_undefended", 1.0, AITarget)
|
||||
DebugMessage("%s -- Using the enemy_undefended reachable system %s with the strongest space force for staging.", tostring(Script), tostring(stage))
|
||||
else
|
||||
stage = taskforce.Get_Stage()
|
||||
DebugMessage("%s -- Using default system %s (nearest faction system) for staging.", tostring(Script), tostring(stage))
|
||||
end
|
||||
|
||||
if not stage then
|
||||
DebugMessage("%s -- Unable to find a staging area. Abandonning plan.", tostring(Script))
|
||||
ScriptExit()
|
||||
end
|
||||
DebugMessage("%s -- Selected Stage: %s\n", tostring(Script), tostring(stage))
|
||||
BlockOnCommand(taskforce.Produce_Force(stage));
|
||||
end
|
||||
|
||||
function SynchronizedAssemble(taskforce, stage_at_strongest_space)
|
||||
if stage_at_strongest_space then
|
||||
stage = FindTarget(taskforce, "FriendlySpaceForceStrength", "Friendly | Enemy | Neutral", 1.0)
|
||||
DebugMessage("%s -- Using the system %s with the strongest space force for staging.", tostring(Script), tostring(stage))
|
||||
else
|
||||
stage = taskforce.Get_Stage()
|
||||
DebugMessage("%s -- Using default system %s (nearest faction system) for staging.", tostring(Script), tostring(stage))
|
||||
end
|
||||
|
||||
if not stage then
|
||||
DebugMessage("%s -- Unable to find a staging area. Abandonning plan.", tostring(Script))
|
||||
ScriptExit()
|
||||
end
|
||||
DebugMessage("%s -- Selected Stage: %s\n", tostring(Script), tostring(stage))
|
||||
BlockOnCommand(taskforce.Produce_Force(stage, true));
|
||||
end
|
||||
|
||||
function WaitMoveForce(taskforce, planet)
|
||||
DebugMessage("Moving Taskforce %s to object %s.", tostring(taskforce), tostring(planet))
|
||||
BlockOnCommand(taskforce.Move_To(FindPlanet(planet)))
|
||||
DebugMessage("Moving Command finished")
|
||||
end
|
||||
|
||||
function LandUnits(taskforce)
|
||||
DebugMessage("Landing on %s with taskforce %s.", tostring(Target), tostring(taskforce))
|
||||
BlockOnCommand(taskforce.Land_Units())
|
||||
DebugMessage("Land Units Command finished")
|
||||
end
|
||||
|
||||
function LaunchUnits(taskforce)
|
||||
DebugMessage("Launching units into orbit with taskforce %s.", tostring(taskforce))
|
||||
|
||||
block = taskforce.Launch_Units()
|
||||
if not block then
|
||||
return false
|
||||
end
|
||||
BlockOnCommand(block)
|
||||
BlockOnCommand(taskforce.Form_Units())
|
||||
DebugMessage("Launch Units Command finished")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function Invade(taskforce)
|
||||
DebugMessage("Invading %s with taskforce %s.", tostring(Target), tostring(taskforce))
|
||||
|
||||
InvasionActive = true
|
||||
invade_status = taskforce.Invade()
|
||||
if invade_status and BlockOnCommand(invade_status) then
|
||||
DebugMessage("Invasion successful. Waiting for planet conversion.");
|
||||
taskforce.Set_As_Goal_System_Removable(false)
|
||||
LandUnits(taskforce)
|
||||
InvasionActive = false
|
||||
return true
|
||||
else
|
||||
DebugMessage("Invasion failed!")
|
||||
InvasionActive = false
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function FundBases(player, target)
|
||||
|
||||
--Prefer starbases since they block enemy movement
|
||||
DebugMessage("%s -- giving desire bonus to build starbase", tostring(Script))
|
||||
BlockOnCommand(GiveDesireBonus(player, "Build_Initial_Starbase_Only", target, 15, 5))
|
||||
DebugMessage("%s -- waiting for starbase", tostring(Script))
|
||||
BlockOnCommand(WaitForStarbase(Target, 1))
|
||||
DebugMessage("%s -- giving desire bonus to build groundbase", tostring(Script))
|
||||
BlockOnCommand(GiveDesireBonus(player, "Build_Initial_Groundbase_Only", target, 15, 5))
|
||||
end
|
||||
|
||||
|
||||
-- Generally follow the task force we're escorting and attack it's attackers.
|
||||
-- Conservative style will avoid confrontation with non fighters/bombers
|
||||
function Escort(taskforce, target, conservative_style)
|
||||
|
||||
if not TestValid(target) then
|
||||
Sleep(1)
|
||||
return
|
||||
end
|
||||
|
||||
lib_enemy = FindDeadlyEnemy(target)
|
||||
|
||||
if lib_enemy then
|
||||
if Get_Game_Mode() == "Space" then
|
||||
if not conservative_style or (lib_enemy.Is_Category("Fighter") or lib_enemy.Is_Category("Bomber")) then
|
||||
|
||||
-- Lure them away from our escorted target if we can.
|
||||
Try_Ability(taskforce,"LURE")
|
||||
|
||||
-- Weave a bit.
|
||||
Weave(taskforce, lib_enemy)
|
||||
|
||||
-- engage the attackers for a duration
|
||||
if not TestValid(lib_enemy) then return end
|
||||
DebugMessage("%s -- In Escort: Attacking lib_enemy: %s for Target: %s", tostring(Script), tostring(lib_enemy), tostring(target))
|
||||
BlockOnCommand(taskforce.Attack_Target(lib_enemy), 15)
|
||||
else
|
||||
|
||||
-- run away a bit, then hold ground before resuming escort
|
||||
DebugMessage("%s -- In Escort: attempting to divert lib_enemy: %s for Target: %s", tostring(Script), tostring(lib_enemy), tostring(target))
|
||||
BlockOnCommand(taskforce.Move_To(Project_By_Unit_Range(lib_enemy, taskforce)), 15)
|
||||
|
||||
if not TestValid(target) then return end
|
||||
|
||||
BlockOnCommand(taskforce.Guard_Target(target, 5))
|
||||
end
|
||||
else
|
||||
BlockOnCommand(taskforce.Attack_Target(lib_enemy), 20)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not TestValid(target) then
|
||||
Sleep(1)
|
||||
return
|
||||
end
|
||||
|
||||
-- Make sure we're assisting the target provided we're not already assisting
|
||||
-- because reissuing a guard will cause the assisting escort to break off attack.
|
||||
-- Note: may receive a non tf "target" param, for example EscortPlan passes a unit
|
||||
if not Tf_Has_Attack_Target(taskforce) then
|
||||
|
||||
-- Escort forces should have attack priorities that allow them to attack structures by this point
|
||||
DebugMessage("%s on %s -- In Escort: Resuming escort of %s", tostring(Script), tostring(AITarget), tostring(target))
|
||||
taskforce.Guard_Target(target)
|
||||
end
|
||||
|
||||
Sleep(1)
|
||||
end
|
||||
|
||||
|
||||
-- Does any member of the given task force have an attack target?
|
||||
function Tf_Has_Attack_Target(tf)
|
||||
|
||||
if TestValid(tf) then
|
||||
for i, unit in tf.Get_Unit_Table() do
|
||||
if unit.Has_Attack_Target() == true then
|
||||
return true
|
||||
end
|
||||
end
|
||||
else
|
||||
DebugMessage("%s -- task force %s isn't valid", tostring(Script), tostring(tf))
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function Weave(tf, enemy)
|
||||
if not TestValid(enemy) then return end
|
||||
BlockOnCommand(tf.Attack_Target(enemy), 10)
|
||||
if not TestValid(enemy) then return end
|
||||
BlockOnCommand(tf.Move_To(Project_By_Unit_Range(enemy, tf)), 5)
|
||||
if not TestValid(enemy) then return end
|
||||
BlockOnCommand(tf.Attack_Target(enemy), 2)
|
||||
if not TestValid(enemy) then return end
|
||||
BlockOnCommand(tf.Move_To(Project_By_Unit_Range(enemy, tf)), 4)
|
||||
end
|
||||
|
||||
function WaitForAllReinforcements(taskforce, target)
|
||||
block = taskforce.Reinforce(target)
|
||||
if block then
|
||||
while block and not BlockOnCommand(block) do
|
||||
block = taskforce.Reinforce(target)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Keep a task force from being idle
|
||||
-- expects lib_tf_to_anti_idle and lib_enemy_to_avoid to be defined before use
|
||||
function Anti_Idle_Taskforce()
|
||||
DebugMessage("%s-- AntiIdle attempt", tostring(Script))
|
||||
if lib_tf_to_anti_idle and TestValid(lib_enemy_to_avoid) then
|
||||
DebugMessage("%s-- AntiIdle lib vars are defined", tostring(Script))
|
||||
|
||||
if lib_new_anti_idle == true then
|
||||
DebugMessage("%s-- AntiIdling %s", tostring(Script), tostring(lib_tf_to_anti_idle))
|
||||
lib_anti_idle_start_time = GetCurrentTime()
|
||||
lib_anti_idle_block = lib_tf_to_anti_idle.Move_To(Project_By_Unit_Range(lib_enemy_to_avoid, lib_tf_to_anti_idle))
|
||||
lib_new_anti_idle = false
|
||||
elseif lib_anti_idle_block then
|
||||
PumpEvents()
|
||||
|
||||
-- Reissue a new command if the old one has expired or some time has passed
|
||||
-- This ensures that newly landed reinforcements on the task force will also anti-idle
|
||||
if lib_anti_idle_block.IsFinished() == true
|
||||
or 2 + lib_anti_idle_start_time < GetCurrentTime() then
|
||||
lib_new_anti_idle = true
|
||||
end
|
||||
end
|
||||
else
|
||||
DebugMessage("%s-- needed global vars aren't defined for anti idle", tostring(Script))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Try to get units on the map in the most reasonable manner.
|
||||
-- Passing an escort_force is optional
|
||||
function QuickReinforce(player, target, tf_to_reinforce, second_try_tf)
|
||||
|
||||
if not player then
|
||||
DebugMessage("%s-- received nil player", tostring(Script))
|
||||
return
|
||||
end
|
||||
|
||||
-- Global plans can pass a nil target and rely on failsafes below to find a target
|
||||
-- if not target then
|
||||
-- DebugMessage("%s-- received nil target", tostring(Script))
|
||||
-- return
|
||||
-- end
|
||||
|
||||
if not tf_to_reinforce then
|
||||
DebugMessage("%s-- received nil tf_to_reinforce", tostring(Script))
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- Space mode will attempt various reinforce attempts with timeouts,
|
||||
-- then simply fail after the last option is exhausted.
|
||||
if Get_Game_Mode() == "Space" then
|
||||
|
||||
lib_reinforce_timeout = 3
|
||||
|
||||
-- If some units have landed, try land the remainder near the rest of the main tf
|
||||
if tf_to_reinforce.Get_Force_Count() ~= 0 then
|
||||
|
||||
-- Define some global vars for the anti idle
|
||||
lib_tf_to_anti_idle = tf_to_reinforce
|
||||
lib_enemy_to_avoid = Find_Nearest(tf_to_reinforce, PlayerObject, false)
|
||||
lib_new_anti_idle = true
|
||||
|
||||
-- Reinforce new units and anti-idle existing units waiting for the reinforce
|
||||
if BlockOnCommand(tf_to_reinforce.Reinforce(tf_to_reinforce), lib_reinforce_timeout, Anti_Idle_Taskforce) then
|
||||
DebugMessage("%s-- reinforced by task force", tostring(Script))
|
||||
lib_tf_to_anti_idle = nil
|
||||
lib_enemy_to_avoid = nil
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- If some of the escort force exists, try to land there
|
||||
if second_try_tf and second_try_tf.Get_Force_Count() ~= 0 then
|
||||
|
||||
-- Define some global vars for the anti idle
|
||||
lib_tf_to_anti_idle = second_try_tf
|
||||
lib_enemy_to_avoid = Find_Nearest(second_try_tf, PlayerObject, false)
|
||||
lib_new_anti_idle = true
|
||||
|
||||
-- Reinforce new units and anti-idle existing units waiting for the reinforce
|
||||
if BlockOnCommand(tf_to_reinforce.Reinforce(second_try_tf), lib_reinforce_timeout, Anti_Idle_Taskforce) then
|
||||
DebugMessage("%s-- reinforced by secondary task force", tostring(Script))
|
||||
lib_tf_to_anti_idle = nil
|
||||
lib_enemy_to_avoid = nil
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Try to land near the default starting point, or some base building, or finally the target itself.
|
||||
lib_start_loc = FindTarget(tf_to_reinforce, "Is_Friendly_Start", "Tactical_Location", 1.0)
|
||||
if lib_start_loc then
|
||||
DebugMessage("%s-- Trying to reinforce by start point", tostring(Script))
|
||||
BlockOnCommand(tf_to_reinforce.Reinforce(lib_start_loc), lib_reinforce_timeout)
|
||||
else
|
||||
lib_base_list = Find_All_Objects_Of_Type(player, "Structure")
|
||||
if lib_base_list[1] then
|
||||
DebugMessage("%s-- Trying to reinforce by friendly structure", tostring(Script))
|
||||
BlockOnCommand(tf_to_reinforce.Reinforce(lib_base_list[1]), lib_reinforce_timeout)
|
||||
else
|
||||
lib_base_list = Find_All_Objects_Of_Type(player, "Capital")
|
||||
if lib_base_list[1] then
|
||||
DebugMessage("%s-- Trying to reinforce by friendly capital", tostring(Script))
|
||||
BlockOnCommand(tf_to_reinforce.Reinforce(lib_base_list[1]), lib_reinforce_timeout)
|
||||
else
|
||||
DebugMessage("%s-- Trying to reinforce by plan target", tostring(Script))
|
||||
BlockOnCommand(tf_to_reinforce.Reinforce(target), lib_reinforce_timeout)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If we were unable to bring in any reinforcements within a reasonable amount of time
|
||||
-- then just abandon the plan; it's not worth holding up other units for too long
|
||||
if tf_to_reinforce.Get_Force_Count() == 0 then
|
||||
ScriptExit()
|
||||
end
|
||||
|
||||
-- Land mode: this will just return if the units are all available;
|
||||
-- otherwise we'll reinforce for a long time and then the plan will fail because it may no longer be relevant.
|
||||
else
|
||||
|
||||
if tf_to_reinforce.Are_All_Units_On_Free_Store() then
|
||||
|
||||
DebugMessage("%s-- All units available, proceeding with plan", tostring(Script))
|
||||
|
||||
-- form up any spread out infantry
|
||||
tf_to_reinforce.Activate_Ability("SPREAD_OUT", false)
|
||||
else
|
||||
|
||||
DebugMessage("%s-- Reinforcements required--waiting for them.", tostring(Script))
|
||||
|
||||
-- Generally, we want things reinforced near the target, if possible
|
||||
-- But this will try all of the reinforcement points, if needed.
|
||||
-- This typically takes a long time.
|
||||
if AITarget then
|
||||
WaitForAllReinforcements(tf_to_reinforce, target)
|
||||
else
|
||||
|
||||
-- find something to reinforce near, for global plans with a nil target
|
||||
friendly_loc = FindTarget(tf_to_reinforce, "Space_Area_Is_Hidden", "Tactical_Location", 1.0)
|
||||
WaitForAllReinforcements(tf_to_reinforce, friendly_loc)
|
||||
end
|
||||
|
||||
--WaitForAllReinforcements(tf_to_reinforce, tf_to_reinforce)
|
||||
DebugMessage("%s-- Reinforcements arrived. Abandonning plan for reproposal if still relevant", tostring(Script))
|
||||
|
||||
-- If the plan is still relevant, it will be proposed again.
|
||||
ScriptExit()
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function SetClassPriorities(tf, priority_set_type)
|
||||
|
||||
priority_set_name = "Fighter" .. "_" .. priority_set_type
|
||||
tf.Set_Targeting_Priorities(priority_set_name, "Fighter")
|
||||
|
||||
priority_set_name = "Bomber" .. "_" .. priority_set_type
|
||||
tf.Set_Targeting_Priorities(priority_set_name, "Bomber")
|
||||
|
||||
priority_set_name = "Corvette" .. "_" .. priority_set_type
|
||||
tf.Set_Targeting_Priorities(priority_set_name, "Corvette")
|
||||
|
||||
priority_set_name = "Frigate" .. "_" .. priority_set_type
|
||||
tf.Set_Targeting_Priorities(priority_set_name, "Frigate")
|
||||
|
||||
priority_set_name = "Capital" .. "_" .. priority_set_type
|
||||
tf.Set_Targeting_Priorities(priority_set_name, "Capital")
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- Move task force to asteroids or nebulae if within range and the asteroids aren't near an enemy
|
||||
-- Returns true if the task force is already obscured or this function obscured it
|
||||
function Obscure(tf, range, use_nebulae, path_through_fields)
|
||||
tf_unit_list = tf.Get_Unit_Table()
|
||||
if not UnitListIsObscured(tf_unit_list) then
|
||||
asteroids = Find_Nearest_Space_Field(tf, "Asteroid")
|
||||
|
||||
if asteroids and tf.Get_Distance(asteroids) < range then
|
||||
enemy_nearest_loc = Find_Nearest(asteroids, PlayerObject, false)
|
||||
if not TestValid(enemy_nearest_loc) or enemy_nearest_loc.Get_Distance(asteroids) < 750 then
|
||||
|
||||
--MessageBox("%s -- moving to asteroids:%s", tostring (Script), path_through_fields)
|
||||
BlockOnCommand(tf.Move_To(asteroids, 10, path_through_fields))
|
||||
return true
|
||||
end
|
||||
elseif use_nebulae then
|
||||
nebula = Find_Nearest_Space_Field(tf, "Nebula")
|
||||
if nebula and tf.Get_Distance(nebula) < range then
|
||||
enemy_nearest_loc = Find_Nearest(nebula, PlayerObject, false)
|
||||
if not TestValid(enemy_nearest_loc) or enemy_nearest_loc.Get_Distance(nebula) < 750 then
|
||||
|
||||
--MessageBox("%s -- moving to nebulae:%s", tostring (Script), path_through_fields)
|
||||
BlockOnCommand(tf.Move_To(nebula, 10, path_through_fields))
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false -- We're not obscured, and there's nothing in range to obscure us.
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-- Fix the unit or hide if appropriate.
|
||||
-- Return true if the unit was fixed.
|
||||
function ConsiderHeal(unit)
|
||||
unit_hull = unit.Get_Hull()
|
||||
if (unit_hull < 0.8) then
|
||||
bacta = Find_Nearest(unit, "HealsInfantry", PlayerObject, true)
|
||||
if TestValid(bacta) then
|
||||
if (unit_hull < 0.4) or (unit.Get_Distance(bacta) < 700) then
|
||||
unit.Activate_Ability("STEALTH", true)
|
||||
unit.Activate_Ability("FORCE_CLOAK", true)
|
||||
BlockOnCommand(unit.Move_To(bacta))
|
||||
while unit.Get_Hull() < 0.9 do
|
||||
DebugMessage("%s-- Waiting to heal", tostring(Script))
|
||||
BlockOnCommand(unit.Guard_Target(bacta), 2)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Fix the unit or hide if appropriate.
|
||||
-- Return true if the unit was fixed.
|
||||
function ConsiderRepair(unit)
|
||||
unit_hull = unit.Get_Hull()
|
||||
if (unit_hull < 0.8) then
|
||||
repair_station = Find_Nearest(unit, "HealsVehicles", PlayerObject, true)
|
||||
if TestValid(repair_station) then
|
||||
if (unit_hull < 0.4) or (unit.Get_Distance(repair_station) < 700) then
|
||||
|
||||
BlockOnCommand(unit.Move_To(repair_station))
|
||||
while unit.Get_Hull() < 0.9 do
|
||||
BlockOnCommand(unit.Guard_Target(repair_station), 2)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Note, this is safe for event response (because it doesn't block)
|
||||
function Release_To_Hide(tf, unit)
|
||||
|
||||
flee_loc = Find_Nearest(unit, "HealsInfantry", PlayerObject, true)
|
||||
if not flee_loc then
|
||||
flee_loc = FindTarget(tf, "Space_Area_Is_Hidden", "Tactical_Location", 1.0, 5000.0)
|
||||
end
|
||||
if flee_loc then
|
||||
unit.Move_To(flee_loc)
|
||||
unit.Lock_Current_Orders()
|
||||
tf.Release_Unit(unit)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- This is for some give and take pacing. The AI is allowed to attack without difficulty-based pause
|
||||
-- 1 to N times, then it must wait for the player to win 1 to N times before attacking without pause.
|
||||
function GalacticAttackAllowed(difficulty, ai_territories_just_gained)
|
||||
|
||||
num_ai_attacks_left = GetGlobalValueOrZero(PlayerObject, "num_ai_attacks_left")
|
||||
if num_ai_attacks_left > 0 then
|
||||
|
||||
-- If the AI has allowed attacks left, permit the attack and decrement
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "num_ai_attacks_left"), num_ai_attacks_left - 1)
|
||||
--MessageBox("%s -- ai has %d attacks left; not pausing before next attack", tostring(Script), num_ai_attacks_left)
|
||||
return true
|
||||
else
|
||||
|
||||
-- AI has to wait for player wins
|
||||
|
||||
-- Difficulty will dictate aggressiveness and amount of contrived breathing room the AI gives for free
|
||||
min_player_wins_unresponded = 4
|
||||
max_player_wins_unresponded = 8
|
||||
max_ai_attacks_allowed = 2
|
||||
if difficulty == "Normal" then
|
||||
min_player_wins_unresponded = 3
|
||||
max_player_wins_unresponded = 6
|
||||
max_ai_attacks_allowed = 2
|
||||
elseif difficulty == "Hard" then
|
||||
min_player_wins_unresponded = 1
|
||||
max_player_wins_unresponded = 2
|
||||
max_ai_attacks_allowed = 4
|
||||
end
|
||||
|
||||
-- Track the player's progress
|
||||
num_land_enemy_controlled = EvaluatePerception("Num_Enemy_Land_Territories", PlayerObject)
|
||||
num_space_enemy_controlled = EvaluatePerception("Num_Enemy_Space_Territories", PlayerObject)
|
||||
--MessageBox("%s -- num_land_enemy_controlled:%d num_space_enemy_controlled:%d", tostring(Script), num_land_enemy_controlled, num_space_enemy_controlled)
|
||||
|
||||
player_gains_before_attacking = GetGlobalValueOrZero(PlayerObject, "player_gains_before_attacking")
|
||||
if player_gains_before_attacking == 0 then
|
||||
|
||||
-- Establish how far the player can go unresponded
|
||||
player_gains_before_attacking = GameRandom(min_player_wins_unresponded, max_player_wins_unresponded)
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "player_gains_before_attacking"), player_gains_before_attacking)
|
||||
--MessageBox("%s -- Determined %d player gains allowed and recording current player territories.", tostring(Script), player_gains_before_attacking)
|
||||
|
||||
-- Record the state of the galaxy
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "recent_land_enemy_controlled"), num_land_enemy_controlled)
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "recent_space_enemy_controlled"), num_space_enemy_controlled)
|
||||
end
|
||||
|
||||
-- Check the player's progress (before our current attack)
|
||||
player_territories_gained = num_land_enemy_controlled + num_space_enemy_controlled
|
||||
- GlobalValue.Get(PlayerSpecificName(PlayerObject, "recent_land_enemy_controlled"))
|
||||
- GlobalValue.Get(PlayerSpecificName(PlayerObject, "recent_space_enemy_controlled"))
|
||||
-- + ai_territories_just_gained
|
||||
|
||||
if player_territories_gained >= player_gains_before_attacking then
|
||||
|
||||
-- Player has won all that he's allowed without AI response, time to start attacking again
|
||||
num_ai_attacks_left = GameRandom(0, max_player_wins_unresponded - 1)
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "num_ai_attacks_left"), num_ai_attacks_left)
|
||||
|
||||
-- Also reset the losses allowed, so that it will be randomized next time
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "player_gains_before_attacking"), 0)
|
||||
|
||||
--MessageBox("%s -- player has enough wins unresponded (%d); not pausing before next attack. \n AI gets %d attacks without pause", tostring(Script), player_territories_gained, num_ai_attacks_left)
|
||||
return true
|
||||
else
|
||||
|
||||
--MessageBox("%s -- %d player territories gained, %d allowed before responding so pausing before next attack"
|
||||
-- , tostring(Script), player_territories_gained, player_gains_before_attacking)
|
||||
if player_territories_gained < 0 then
|
||||
|
||||
-- Record the state of the galaxy
|
||||
--MessageBox("%s -- player lost ground; resetting recent territories records", tostring(Script))
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "recent_land_enemy_controlled"), num_land_enemy_controlled)
|
||||
GlobalValue.Set(PlayerSpecificName(PlayerObject, "recent_space_enemy_controlled"), num_space_enemy_controlled)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function DifficultyBasedMinPause(difficulty)
|
||||
|
||||
sleep_duration = 300
|
||||
if difficulty == "Normal" then
|
||||
sleep_duration = 200
|
||||
elseif difficulty == "Hard" then
|
||||
sleep_duration = 45
|
||||
end
|
||||
|
||||
return sleep_duration
|
||||
end
|
||||
|
||||
function GetGlobalValueOrZero(player, value_name)
|
||||
ret_value = GlobalValue.Get(PlayerSpecificName(player, value_name))
|
||||
if ret_value == nil then
|
||||
return 0.0
|
||||
end
|
||||
return ret_value
|
||||
end
|
||||
Reference in New Issue
Block a user