[[http://www.siedler-games.de|{{:sg-link.jpg|}}]]
====== ChangeLeader ======
Oftmals möchte man im Spielverlauf Truppen einem anderen Spieler übergeben. Selten sollen aber dabei einfach alle Truppen des Spielers übergeben werden, sondern nur die, die sich in einem bestimmten Gebiet befinden, bzw. nur spezielle Truppenarten. Genau für diesen Verwendungszweck ist die Funktion gedacht.
==== Wie funktioniert's? ====
Zunächst einmal müssen wir alle Leader des entsprechenden Spielers, dessen Truppen übergeben werden sollen, ermitteln. Dazu rufen wir eine andere "Hilfsfunktion" auf, nämlich [[utilfunctions:getallleader|GetAllLeader]]. Diese liefert uns 2 Table zurück - eins mit den IDs der Leader und eins mit den IDs der Kanonen des Spielers (sofern welche existieren). Sofern der Spieler auch über Kanonen verfügt, fügen wir deren IDs mit in das Table der Leader-Ids ein.
Nun gehen wir die einzelnen Leader-Ids der Reihe nach durch, und prüfen, wenn nur bestimmte Leader-Typen übergeben werden sollen, ob die jeweilige Einheit einem der angegebenen Typen entspricht, ob sie sich innerhalb des angegebenen Radius befindet und ob die angegebene Anzahl an zu übergebenden Einheiten noch nicht erreicht ist. Fallen alle diese Prüfungen positiv aus, wird die jeweilige Einheit dem anderen Spieler übergeben.
==== Funktionsaufruf ====
Die Funktion wird wie folgt aufgerufen:
ChangeLeader(_oldPlayer, _newPlayer, _type, _pos, _range, _amount)
Wobei die Parameter folgendes bedeuten: \\
* **_oldPlayer** = Id des Players, dessen Einheiten übergeben werden sollen. \\ (muss immer eine Zahl sein)
* **_newPlayer** = Id des Players, dem die Einheiten übergeben werden sollen. \\ (muss immer eine Zahl sein)
* **_type** = hier kann ein oder mehrere Einheiten-Typen angegeben werden, wenn nur bestimmte Typen übergeben werden sollen, oder "all" für alle Typen. \\ (kann ein String, wie etwa "all" oder "PU_LeaderSword2" sein, oder auch ein Table wie etwa {"PV_Cannon1" , "PV_Cannon2" , "PV_Cannon3" , "PV_Cannon4"} )
* **_pos** = Positionsangabe um die herum, im Radius (_range), sich die zu übergebenden Einheiten befinden müssen. \\ (kann sowohl ein Entity-Name, eine Entity-Id, als auch ein Positions-Table sein)
* **_range** = Radius in Siedlerzentimetern in dem, um den Mittelpunkt (_pos) herum, sich die zu übergebenden Einheiten befinden müssen. \\ (muss immer eine Zahl sein)
* **_amount** = Anzahl der maximal zu übergebenden Einheiten. Kann im Prinzip beliebig groß gewählt werden (z.B. 1000), um sicher zu gehen, dass auch alle Einheiten in dem betreffenden Gebiet übergeben werden. \\ (muss immer eine Zahl sein)
==== Zur Beachtung ====
Mittels dieser Funktion können beliebige, militärische Einheiten von einem Spieler an einen anderen übergeben werden. Jede militärische Einheit im Spiel hat immer einen sogenannten "Leader". Jeder Leader kann, je nach Typ, unterschiedlich viele Soldaten (gleichen Typs) "bei sich" haben. Es genügt aber, den Spieler des Leaders zu wechseln - die zugehörigen Soldaten wechseln automatisch mit. Kanonen haben eine Sonderstellung, werden aber von der Funktion auch erfasst, wobei jede einzelne Kanone als 1 Leader zählt (wichtig für _amount).
==== Code ====
An eine beliebige freie Stelle (nicht innerhalb einer anderen Funktion) ins Script packen:
function ChangeLeader(_oldPlayer, _newPlayer, _type, _pos, _range, _amount)
local _counter = 0
local _all = 0
local _leaderIds, _cannonIds = GetAllLeader(_oldPlayer)
if _cannonIds then
for i=1,table.getn(_cannonIds) do
table.insert(_leaderIds, _cannonIds[i])
end
end
local _types = {}
if type (_type) == "table" then
for i=1,table.getn(_type) do
_types[_type[i]] = true
end
elseif type (_type) == "string" and _type ~= "all" then
_types[_type] = true
elseif type (_type) == "string" and _type == "all" then
_all = 1
else Message("Die Angabe der Entities ist fehlerhaft!")
end
if type (_pos) == "string" or type (_pos) == "number" then
_pos = GetPosition(GetEntityId(_pos));
end
for i=1,table.getn(_leaderIds) do
if _all == 0 and not _types[Logic.GetEntityTypeName(Logic.GetEntityType(_leaderIds[i]))] then
else
if _counter < _amount then
local _posLeader = GetPosition(_leaderIds[i])
if (math.sqrt((_pos.X - _posLeader.X)^2 + (_pos.Y - _posLeader.Y)^2) <= _range) then
ChangePlayer(_leaderIds[i],_newPlayer)
_counter = _counter + 1
end
end
end
end
end
Wichtig! \\
Die Funktion [[utilfunctions:getallleader|GetAllLeader]] muss sich ebenfalls im Script befinden:
function GetAllLeader(_player)
local leaderIds = {}
local cannonIds = {}
local numberOfLeaders = Logic.GetNumberOfLeader(_player)
local cannonCount = 0
local prevLeaderId = 0
local existing = {}
for i=1,numberOfLeaders do
local nextLeaderId = Logic.GetNextLeader( _player, prevLeaderId )
if existing[nextLeaderId] then
cannonCount = cannonCount + 1
else
existing[nextLeaderId] = true;
table.insert(leaderIds,nextLeaderId)
end
prevLeaderId = nextLeaderId
end
if cannonCount > 0 then
local tempCannonIds = {}
for i=1,4 do
local counter = 0
counter = Logic.GetNumberOfEntitiesOfTypeOfPlayer(_player, Entities["PV_Cannon"..i])
if counter > 0 then
tempCannonIds = {Logic.GetPlayerEntities(_player, Entities["PV_Cannon"..i], counter)}
table.remove(tempCannonIds,1)
for j=1,table.getn(tempCannonIds) do
table.insert(leaderIds,tempCannonIds[j])
table.insert(cannonIds,tempCannonIds[j])
end
end
end
end
return leaderIds, cannonIds
end
==== Demo-Map ====
Hier könnt ihr euch das Ganze mal live in Aktion angucken: \\
{{utilfunctions:changeleader_demo.rar|(Legenden) Map: ChangeLeader_Demo}}