[[http://www.siedler-games.de|{{:sg-link.jpg|}}]]
==== Beschreibung ====
Der [[http://forums-de.ubi.com/groupee/forums/a/tpc/f/500109972/m/8461014453|Alarm/Überstundentrick]] bewirkt, daß die Siedler sehr viel länger arbeiten, ohne daß ein Motivationsverlust auftritt. Dies wird erreicht, indem der Alarm oder die Überstunden regelmässig aktiviert, und Sekundenbruchteile später wieder deaktiviert wird. Spieler, die diesen Fehler im Spiel ausnutzen, können so in kürzerer Zeit deutlich mehr Resourcen abbauen als die, die es nicht tun.
\\
\\
Der Fehler ist in allen Version einschliesslich 1.05 vorhanden und ausnutzbar.
**Ab Version 1.06 wird dieser Code nichtmehr benötigt!** Dort wurde die Nutzung von Alarm und Overtime auf "alle 3 bzw 4 Minuten" beschränkt.
==== Einzelspielermodus ====
=== Alarmlimit ===
Die folgende Funktion kann an eine beliebige Stelle ins Mapscript kopiert werden. Sie bewirkt, daß der Alarm mindestens 60 Sekunden aktiviert bleibt. Durch diesen Stillstand der Wirtschaft zieht man keinen Gewinn mehr aus der längeren Arbeitszeit. Somit ist es nurnoch sinnvoll, den Alarm zu seinem ursprünglichen Zweck, der Verteidigung, einzusetzen.
Am Ende der FirstMapAction() muss die Funktion einmal aufgerufen werden:
EnableAlarmLimit();
Dies ist die Funktion:
function EnableAlarmLimit()
GUIAction_ActivateAlarmOrig = GUIAction_ActivateAlarm;
GUIAction_ActivateAlarm = function()
alarmWait = Logic.GetCurrentTurn() + 600;
GUIAction_ActivateAlarmOrig();
end
GUIAction_QuitAlarmOrig = GUIAction_QuitAlarm;
GUIAction_QuitAlarm = function()
local turns = Logic.GetCurrentTurn();
if turns >= alarmWait then
GUIAction_QuitAlarmOrig();
else
Sound.PlayFeedbackSound( Sounds.VoicesWorker_WORKER_FunnyNo_rnd_10, 0 );
Message( "Der Alarm kann erst in " .. math.floor( ( alarmWait - turns ) / 10 ) .. " Sekunden wieder aufgehoben werden." );
end
end
end
=== Überstundenlimit ===
Die folgende Funktion kann an eine beliebige Stelle ins Mapscript kopiert werden. Sie bewirkt, daß die Überstunden in einem Gebäude mindestens 60 Sekunden aktiviert bleiben. Hierdurch tritt der reguläre Motivationsverlust bei längerer Arbeitszeit in Kraft. Somit hat man also keinen unfairen Vorteil mehr davon, da man sie nurnoch nutzen kann, wenn man den Motivationsverlust mit einer Kirche oder Zierobjekten kompensieren kann.
Am Ende der FirstMapAction() muss die Funktion einmal aufgerufen werden:
EnableOvertimeLimit();
Dies ist die Funktion:
function EnableOvertimeLimit()
tOvertimes = {};
GUI.ToggleOvertimeAtBuildingOrig = GUI.ToggleOvertimeAtBuilding;
GUI.ToggleOvertimeAtBuilding = function( _id )
LimitOvertime( _id, GUI.ToggleOvertimeAtBuildingOrig );
end
GUI.ForceSettlerToWorkOrig = GUI.ForceSettlerToWork;
GUI.ForceSettlerToWork = function( _id )
LimitOvertime( _id, GUI.ToggleOvertimeAtBuildingOrig );
end
LimitOvertime = function( _id, _func )
local knowntime = tOvertimes[_id];
local turns = Logic.GetCurrentTurn();
if not knowntime or turns > knowntime then
_func( _id );
tOvertimes[_id] = turns + 600;
else
Sound.PlayFeedbackSound( Sounds.VoicesWorker_WORKER_FunnyNo_rnd_10, 0 );
Message( "Die Ueberstunden dauern noch mindestens " .. math.floor( ( knowntime - turns ) / 10 ) .. " Sekunden." );
end
end
end
==== Mehrspielermodus ====
Da die Sperrung der Funktionen für eine Minute die Spieler im Mehrspielermodus zu stark behindern könnte, gibt es hier Alternativfunktionen.
=== Alarmlimit ===
Anstatt die Deaktivierung des Alarms erst wieder nach einer Minute zu ermöglichen, kann den anderen Spielern auf einfach angezeigt werden, wer seinen Alarm (de)aktiviert hat. Somit sind andere Spieler in der Lage zu erkennen, wer den Fehler im Spiel ausnutzen will.
Mehrspielerkarten, die diesen Fix benutzen, sollten dies dem Spieler mitteilen. Beispielsweise durch eine Nachricht bei Spielstart. \\
\\
Natürlich sollte man, wenn man diese Alarmvariante verwendet, nicht noch zusätzlich die Funktion zur //Alarm//beschränkung verwenden. \\
\\
Am Ende von GameCallback_OnGameStart() muss die Funktion einmal aufgerufen werden:
EnableAlarmNotice();
Dies ist die Funktion:
function EnableAlarmNotice()
tAlarmCheckHQs = {};
tAlarmCheckHQs.tStatus = {};
tAlarmCheckHQs.tPlayers = {};
tAlarmCheckHQs.tNames = {};
local playerID = GUI.GetPlayerID();
local playerID = 99
assert( playerID );
local tHQTypes = { Logic.GetBuildingTypesInUpgradeCategory( UpgradeCategories.Headquarters ) };
local nHQTypes = table.remove( tHQTypes, 1 );
assert( nHQTypes > 0 );
assert( nHQTypes == table.getn( tHQTypes ) );
for currID = 1, 8 do
if currID ~= playerID then
for i = 1, nHQTypes do
local tTempHQs = { Logic.GetPlayerEntities( currID, tHQTypes[i], 48 ) };
local nTempHQs = table.remove( tTempHQs, 1 );
assert( nTempHQs == table.getn( tTempHQs ) );
for k = 1, nTempHQs do
local nHQID = tTempHQs[k];
assert( type( nHQID ) == "number" );
table.insert( tAlarmCheckHQs, nHQID );
tAlarmCheckHQs.tStatus[nHQID] = false;
tAlarmCheckHQs.tPlayers[nHQID] = currID;
local sHQName = Logic.GetEntityName( nHQID );
if not sHQName or sHQName == "" then
sHQName = "DoNotChange" .. nHQID;
Logic.SetEntityName( nHQID, sHQName );
end
tAlarmCheckHQs.tNames[nHQID] = sHQName;
end
end
end
end
Trigger.RequestTrigger( Events.LOGIC_EVENT_EVERY_TURN, "", "CheckAlarmNotice", 1 );
end
function CheckAlarmNotice()
assert( type( tAlarmCheckHQs ) == "table" );
for i = table.getn( tAlarmCheckHQs ), 1, -1 do
local nID = tAlarmCheckHQs[i];
assert( type( nID ) == "number" );
local bIsDestroyed = false;
if Logic.IsEntityDestroyed( nID ) then
bIsDestroyed = true;
local sHQName = tAlarmCheckHQs.tNames[nID];
assert( sHQName );
local nNewID = Logic.GetEntityIDByName( sHQName );
if nNewID and nNewID > 0 then
bIsDestroyed = false;
tAlarmCheckHQs[i] = nNewID;
tAlarmCheckHQs.tStatus[nNewID] = tAlarmCheckHQs.tStatus[nID];
tAlarmCheckHQs.tStatus[nID] = nil;
tAlarmCheckHQs.tPlayers[nNewID] = tAlarmCheckHQs.tPlayers[nID];
tAlarmCheckHQs.tPlayers[nID] = nil;
tAlarmCheckHQs.tNames[nNewID] = tAlarmCheckHQs.tNames[nID];
tAlarmCheckHQs.tNames[nID] = nil;
nID = nNewID;
end
end
if bIsDestroyed then
table.remove( tAlarmCheckHQs, i );
tAlarmCheckHQs.tStatus[nID] = nil;
else
local oldAlarmStatus = tAlarmCheckHQs.tStatus[nID];
assert( type( oldAlarmStatus ) == "boolean" );
if Logic.IsAlarmModeActive( nID ) ~= oldAlarmStatus then
tAlarmCheckHQs.tStatus[nID] = not oldAlarmStatus;
local nPlayerID = tAlarmCheckHQs.tPlayers[nID];
assert( type( nPlayerID ) == "number" );
Message( string.format( "Spieler %d (%s) hat %s.",
nPlayerID, UserTool_GetPlayerName( nPlayerID ),
oldAlarmStatus and "den Alarm aufgehoben" or "seine Siedlung in Alarmzustand versetzt" )
);
end
end
end
end
=== Überstundenlimit ===
Hier kann das gleiche Script wie im Einzelspielermodus verwendet werden. Möglicherweise ist 60 Sekunden eine zu lange Zeit für den Mehrspielermodus.
Um diese auf beispielsweise 35 Sekunden zu reduzieren, muss die Zeile ''tOvertimes[_id] = turns + 600;'' durch ''tOvertimes[_id] = turns + 350;'' ersetzt werden. \\
Der Aufruf erfolgt hier nicht aus der FirstMapAction(), sondern vom Ende der Funktion GameCallback_OnGameStart().