Trigger-Fix

Diese Seite beinhaltet den Trigger-Fix. Bei technischen Problemen bitte an Old McDonald oder Chromix eine private Nachricht schreiben oder direkt in der Scriptecke posten.

Aktuelle Features1):

FIXME Hier sollten noch kurze Verwendungsbeispiele hin:

Code

CxTools = CxTools or {}; 
 
function CxTools:Init()
	CxTools:InitUnpackFix();
	CxTools:InitTriggers();
end
 
--#########################################################################
--###
--###	 Utility Functions
--###
 
function CxTools.Panic(_text)
	Message("-----------------------------------------");
	Message("Error: " .. tostring(_text));
	Message("-----------------------------------------");
 
	local _table = { text = _text };
	StartSimpleJob(CxTools.GlobalTriggerDebug, _table);
end
 
--#########################################################################
--###
--###	 unpack()-Fix
--###
 
function CxTools:InitUnpackFix()
    if not unpack{true} then
        local unpack2;
        unpack2 =
            function(_table, _i)
                _i = _i or 1;
                assert(type(_table) == "table");
                if _i <= table.getn(_table) then
                    return _table[_i], unpack2(_table, _i + 1);
                end
            end
 
        unpack = unpack2;    
    end
end
 
--#########################################################################
--###
--###	 Trigger Functions
--###
 
--Trigger-Fix / improvement
function CxTools:InitTriggers()
	CxTools.tTriggers = {};
	CxTools.nTriggerNum = 0;
	CxTools.GlobalTriggerConditionCallbackWrapperName = "TriggerConditionCallbackWrapper";
	CxTools.GlobalTriggerActionCallbackWrapperName = "TriggerActionCallbackWrapper";
	CxTools.GlobalTriggerDebug = "MessageTriggerDebug";
 
	CxTools.Mission_OnSaveGameLoaded = Mission_OnSaveGameLoaded;
	Mission_OnSaveGameLoaded = function() CxTools:HookAPITrigger(); CxTools.Mission_OnSaveGameLoaded(); end;
	CxTools:HookAPITrigger();
 
	assert( not _G[CxTools.GlobalTriggerConditionCallbackWrapperName] );
	_G[CxTools.GlobalTriggerConditionCallbackWrapperName] = 
		function(_sId)
			return CxTools:callbackWrapperCondition(_sId);
		end
 
	assert( not _G[CxTools.GlobalTriggerActionCallbackWrapperName] );
	_G[CxTools.GlobalTriggerActionCallbackWrapperName] = 
		function(_sId)
			return CxTools:callbackWrapperAction(_sId);
		end
 
	--Comfort Functions
	CxTools.StartSimpleJobOrig = StartSimpleJob;
	StartSimpleJob = 
		 function(...)
			 return CxTools:StartSimpleJob(unpack(arg));
		 end
 
	CxTools.StartSimpleHiResJobOrig = StartSimpleHiResJob;
		StartSimpleHiResJob = 
			function(...)
				return CxTools:StartSimpleHiResJob(unpack(arg));
			end
 
	CxTools.StartJobOrig = StartJob;
	StartJob = 
		function(...)
			return CxTools:StartJob(unpack(arg));
		end
 
	CxTools.StartHiResJobOrig = StartHiResJob;
	StartHiResJob = 
		function(...)
			return CxTools:StartHiResJob(unpack(arg));
		end
 
	assert( not _G[CxTools.GlobalTriggerDebug] );
	_G[CxTools.GlobalTriggerDebug] = 
	    function(_table)
	        assert(type(_table) == "table");
			_table.seconds = _table.seconds or 0;
			_table.seconds = _table.seconds + 1;
			if math.mod(_table.seconds, 15) == 0 then
	                    Message("-----------------------------------------");
	                    Message("Error: " .. tostring(_table.text));
	                    Message("-----------------------------------------");
		        if _table.seconds == 45 then
				return true;
			end
			end
		end
end
 
function CxTools:HookAPITrigger()
	CxTools.RequestTriggerOrig = Trigger.RequestTrigger;
	CxTools.UnrequestTriggerOrig = Trigger.UnrequestTrigger;
	Trigger.RequestTrigger = 
		function(_event, _fCond, _fAction, _isActive, _pCond, _pAction)
			return CxTools:AddTrigger(_event, _fCond, _fAction, _isActive, _pCond, _pAction);
		end
	Trigger.UnrequestTrigger =
		function( _id )
			CxTools:UnrequestTrigger( _id );
		end
end
 
function CxTools:AddTrigger( _eventType, _funcCondition, _funcAction, _isActive, _paramsCond, _paramsAction )
	assert(type(_eventType) == "number");
	assert(not _funcCondition or type(_funcCondition) == "string" or type(_funcCondition) == "function" );
	assert(type(_funcAction) == "string" or type(_funcAction) == "function");
 
	if _isActive == true then
		_isActive = 1;
	elseif _isActive == false then
		_isActive = 0;
	else
		assert( type(_isActive) == "number" and (_isActive == 0 or _isActive == 1) );
	end
 
	_paramsCond = _paramsCond or {};
	_paramsAction = _paramsAction or {};
 
	local sTriggerId = table.getn(CxTools.tTriggers) + 1;
	if sTriggerId > CxTools.nTriggerNum then
		CxTools.nTriggerNum = sTriggerId;
	end
 
	local entry = {};
	entry.sId = sTriggerId;
	if _funcCondition ~= "" then
		 entry.funcCondition = _funcCondition;
	end
	entry.funcAction = _funcAction;
	entry.paramsCond = _paramsCond;
	entry.paramsAction = _paramsAction;
 
	local condition = CxTools.GlobalTriggerConditionCallbackWrapperName;
	local action = CxTools.GlobalTriggerActionCallbackWrapperName;
	if not _funcCondition or _funcCondition == "" then
		condition = nil;
	end
 
	local realTriggerId = CxTools.RequestTriggerOrig( _eventType, condition, action, _isActive, {sTriggerId}, {sTriggerId} );
	entry.realId = realTriggerId;
 
	CxTools.tTriggers[sTriggerId] = entry;
 
	return realTriggerId;
end
 
function CxTools:callbackWrapperCondition( _sTriggerId )
	local tRes = { xpcall( function() return CxTools:callbackWrapperConditionReal( _sTriggerId ); end, CxTools.Panic ) };
	table.remove( tRes, 1 );
	return unpack( tRes );
end
 
function CxTools:callbackWrapperConditionReal( _sTriggerId )
	assert(type( _sTriggerId) == "number" );
	local entry = CxTools.tTriggers[_sTriggerId];
	assert( entry );
	assert( entry.sId == _sTriggerId );
	assert( entry.funcCondition );
	assert( entry.paramsCond );
 
	local tRes;
	if type(entry.funcCondition) == "function" then
		tRes = { xpcall( function() return entry.funcCondition( unpack( entry.paramsCond ) ); end, CxTools.Panic ) };
	else
		local f = _G[entry.funcCondition];
		assert(type(f) == "function");
		tRes = { xpcall( function() return f( unpack( entry.paramsCond ) ); end, CxTools.Panic ) };
	end
 
	local bNoErr = table.remove( tRes, 1 );
 
	if not bNoErr then
		CxTools.tTriggers[_sTriggerId].err = true;
	end
 
	return bNoErr and unpack( tRes ) or not bNoErr;
end
 
function CxTools:callbackWrapperAction( _sTriggerId )
	local tRes = { xpcall( function() return CxTools:callbackWrapperActionReal( _sTriggerId ); end, CxTools.Panic ) };
	table.remove( tRes, 1 );
	return unpack( tRes );
end
 
function CxTools:callbackWrapperActionReal( _sTriggerId )
	assert(type( _sTriggerId) == "number" );
	local entry = CxTools.tTriggers[_sTriggerId];
	assert( entry );
	assert( entry.sId == _sTriggerId );
	assert( entry.funcAction );
	assert( entry.paramsAction );
 
	local bNoErr = true;
	local tRes;
	if not entry.err then
		if type(entry.funcAction) == "function" then
			tRes = { xpcall( function() return entry.funcAction( unpack( entry.paramsAction ) ); end, CxTools.Panic ) };
		else
			local f = _G[entry.funcAction];
			assert(type(f) == "function");
			tRes = { xpcall( function() return f( unpack( entry.paramsAction ) ); end, CxTools.Panic ) };
		end
 
		bNoErr = table.remove( tRes, 1 );
	end
 
	-- check return value
	if not bNoErr or entry.err or tRes[1] == true then
		-- Remove this entry, as the trigger is destroyed
		CxTools.tTriggers[_sTriggerId] = nil;
	end
 
	return entry.err or (bNoErr and unpack( tRes ) or not bNoErr);
end 
 
function CxTools:UnrequestTrigger( _id )
	assert( type( _id ) == "number" );
	for i = 1, CxTools.nTriggerNum, 1 do
		local t = CxTools.tTriggers[i];
		if t and t.realId == _id then
			CxTools.tTriggers[i] = nil;
			break;
		end
	end
	CxTools.UnrequestTriggerOrig( _id );
end
 
 
--#########################################################################
--###
--###	 Trigger Comfort Functions
--###
 
function CxTools:StartSimpleJob( _functionname, ...)
	assert(type(_functionname) == "string" or type(_functionname) == "function");
 
	if type(_functionname) == "string" then
		if arg[1] == nil then 
			return CxTools.StartSimpleJobOrig( _functionname );
 
		else
			assert(type(_G[_functionname]) == "function");
			return Trigger.RequestTrigger( Events.LOGIC_EVENT_EVERY_SECOND, "", _functionname, 1, {}, arg );
		end
 
	else
		assert(type(_functionname) == "function");
		return Trigger.RequestTrigger( Events.LOGIC_EVENT_EVERY_SECOND, "", _functionname, 1, {}, arg );
	end
end
 
function CxTools:StartSimpleHiResJob( _functionname, ...)
	assert(type(_functionname) == "string" or type(_functionname) == "function");
 
	if type(_functionname) == "string" then
		if arg[1] == nil then 
			return CxTools.StartSimpleHiResJobOrig( _functionname );
 
		else
			assert(type(_G[_functionname]) == "function");
			return Trigger.RequestTrigger( Events.LOGIC_EVENT_EVERY_TURN, "", _functionname, 1, {}, arg );
		end
 
	else
		assert(type(_functionname) == "function");
		return Trigger.RequestTrigger( Events.LOGIC_EVENT_EVERY_TURN, "", _functionname, 1, {}, arg );
	end
end
 
function CxTools:StartJob( _functionname, ... )
	assert(type(_functionname) == "string" or (type(_functionname) == "function" and type(arg[1]) == "function"));
 
	if type(_functionname) == "string" then
 
		assert(type(_G["Action_".._functionname]) == "function" and type(_G["Condition_".._functionname]) == "function");
 
		if arg[1] == nil then
			return CxTools.StartJobOrig(_functionname);
 
		else
			assert(type(arg[1]) == "table" and (not arg[2] or type(arg[2]) == "table"));
			return Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_SECOND, "Condition_".._functionname, "Action_".._functionname, 1, arg[2], arg[1]);
		end
	else
		 assert((not arg[2] or type(arg[2]) == "table") and (not arg[3] or type(arg[3]) == "table"));
		 return Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_SECOND, arg[1], _functionname, 1, arg[3], arg[2]);
	 end
end
 
function CxTools:StartHiResJob( _functionname, ... )
	assert(type(_functionname) == "string" or (type(_functionname) == "function" and type(arg[1]) == "function"));
 
	if type(_functionname) == "string" then
 
		assert(type(_G["Action_".._functionname]) == "function" and type(_G["Condition_".._functionname]) == "function");
 
		if arg[1] == nil then
			return CxTools.StartHiResJobOrig(_functionname);
 
		else
			assert(type(arg[1]) == "table" and (not arg[2] or type(arg[2]) == "table"));
			return Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_TURN, "Condition_".._functionname, "Action_".._functionname, 1, arg[2], arg[1]);
		end
	else
		assert((not arg[2] or type(arg[2]) == "table") and (not arg[3] or type(arg[3]) == "table"));
		return Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_TURN, arg[1], _functionname, 1, arg[3], arg[2]);
	end
end
 
--#########################################################################
--###
--###	 Init!
--###
 
CxTools:Init();
1)
Eigenschaften