-- $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 $ -- --///////////////////////////////////////////////////////////////////////////////////////////////// ---@diagnostic disable 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