How add your custom data into gamecore.

Pusperk

Chieftain
Joined
Dec 24, 2015
Messages
30
Scenario BlackDeath from last DLC solve how add your custom data into gamecore. Save and load then automatically work with your data. DLC also solve exchange data from UI thread and Script thread.
Code:
-- ===============================================================================================
-- STATE / CACHE from BlackDeathScenario
-- Custom data are kept in cache and set into game as a property on the Game object from script thread
-- Set your custom data = pObject:SetProperty(sPropertyName, value)
-- Get your custom data = pObject:GetProperty(sPropertyName)
-- Object can be Game, pCity, pPlayer, pUnit, pPlot
-- Value are variable, field, structure
-- Name of Value (sPropertyName) are stored in g_PropertyKeys
-- Handle among script thread and UI thread guarantee function in this file
-- This file must be insert on start every file using "include" command (from UI and script)
-- When save, load game system do it with yours custom data
-- ===============================================================================================

g_PropertyKeys = {
    Turn    = "Turn",        -- your custom data
};

-- Every time SetObjectState is called, the script-side cache is updated to prevent unnecessary
-- calls down to gamecore.
local USE_CACHE : boolean = true;
local g_ObjectStateCache = {};

-- ===========================================================================
function SetObjectState(pObject : object, sPropertyName : string, value)
    if (sPropertyName == nil) then
        return nil;
    end

    if (pObject == nil) then
        print("StateUtils SetObjectState: ERROR: object is nil!");
        return nil;
    end

    if (USE_CACHE == true) then
        if (g_ObjectStateCache[pObject] == nil) then
            g_ObjectStateCache[pObject] = {};
        end

        -- update cache
        g_ObjectStateCache[pObject][sPropertyName] = value;
    end
    
    -- when you call this function from UI thread you must update data on script thread
    if UI ~= nil then
        -- We are on the UI side of things.  We must sent a command to change the game state
        local kParameters:table = {};
        kParameters.propertyName = sPropertyName;
        kParameters.value = value;
        kParameters.objectID = pObject:GetComponentID();
        -- Send this GameEvent when processing the operation
        kParameters.OnStart = "OnPlayerCommandSetObjectState";

        UI.RequestPlayerOperation(Game.GetLocalPlayer(), PlayerOperations.EXECUTE_SCRIPT, kParameters);
    else
    -- when you call this function from script thread you send data into gamecore
        if (pObject.SetProperty ~= nil) then
            pObject:SetProperty(sPropertyName, value);
        end
    end
end

-- ====================================================================================
-- This function is called from UI thread using function "UI.RequestPlayerOperation" as event
function OnPlayerCommandSetObjectStateHandler(ePlayer : number, params : table)

    local pObject = Game.GetObjectFromComponentID(params.objectID);

    if pObject ~= nil then
        SetObjectState(pObject, params.propertyName, params.value);
    end
        
end

-- This file gets includes on both the UI and GameCore side, we only want to handle the event on the Game Core side.
if UI == nil then
    GameEvents.OnPlayerCommandSetObjectState.Add( OnPlayerCommandSetObjectStateHandler );
end

-- ===================================================================================
function GetObjectState(pObject : object, sPropertyName : string, bCacheCheckOnly : boolean)
    if (sPropertyName == nil) then
        return nil;
    end

    if (pObject == nil) then
        print("StateUtils GetObjectState: ERROR: object is nil!");
        return nil;
    end

    bCacheCheckOnly = bCacheCheckOnly or false;

    if (USE_CACHE == true) then
        if (g_ObjectStateCache[pObject] == nil) then
            g_ObjectStateCache[pObject] = {};
        end

        if (g_ObjectStateCache[pObject][sPropertyName] ~= nil) then
            return g_ObjectStateCache[pObject][sPropertyName];
        else
            if (bCacheCheckOnly) then
                return nil;
            else
                return RefreshObjectState(pObject, sPropertyName);
            end
        end
    else
        return pObject:GetProperty(sPropertyName);
    end
end

-- ===========================================================================
-- Forces a call to gamecore and cache update.
function RefreshObjectState(pObject : object, sPropertyName : string)
    if (sPropertyName == nil) then
        return nil;
    end

    if (pObject.GetProperty == nil) then
        return nil;
    end   

    local propResult = pObject:GetProperty(sPropertyName);

    if (g_ObjectStateCache[pObject] == nil) then
        g_ObjectStateCache[pObject] = {};
    end

    g_ObjectStateCache[pObject][sPropertyName] = propResult;
    return propResult;
end
Simple application in your code on script thread
Code:
include "StateUtils"

function Initialize()

    print("Test initialize");
    GameEvents.OnGameTurnStarted.Add(OnGameTurnStarted);

    -- Initialize current turn
    local Turn = GetObjectState(Game, g_PropertyKeys.Turn);
    if (Turn == nil) then
        SetObjectState(Game, g_PropertyKeys.Turn, 0);
        print("Initialize turn:  ", Turn);
    end
end

function OnGameTurnStarted( currentTurn:number )

    print("Current turn:  ", currentTurn);
    local lastTurn = GetObjectState(Game, g_PropertyKeys.Turn);
    print("Last turn:  ", lastTurn);
    SetObjectState(Game, g_PropertyKeys.Turn, currentTurn);

end

Initialize();
 
Back
Top Bottom