[[http://www.siedler-games.de|{{:sg-link.jpg|}}]]
\\
[[http://www.siedler-portal.de/vb3/member.php?u=2109|Tenji]]
Da wir uns ja keine eigenen Helden editieren können, habe ich mir da etwas Abhilfe geschafft! \\
\\
\\
===== Create Superfighter - Version 2.00 =====
Diese Version wurde komplett neu geschrieben und ist viel umfangreicher als die erste. Der Code allerdings auch, der bei ca. 86kB liegt. Das komplette Script mit den Zusatzfunktionen und Parameterbeschreibung findet ihr als Lua-Datei {{utilscripts:superfighter-2-00.lua|hier}}. \\
\\
Die Version ist zum Vorgänger "kompatibel", das heißt ihr könnt einfach den 1.01-Version durch die 2.00 ersetzen. Allerdings müssen sich alle Zusatzfunktionen der neuen Version im Script befinden. Diese stehen am Ende der Lua-Datei, nach dem Kommentar "Ende der Superfighter Funktionen".
\\
== Features: ==
\\
* Es gibt 8 verschiedene Superfighter-Typen. Sie unterscheiden sich durch ihre Stärke und Fähigkeiten: "Warrior", "Sorcerer", "Ninja", "Barbarian", \\ "WolfsLeader", "Samurai", "Jedi" oder "Saiyajin".
* Die Stärke der Superfighter steigt mit ihrem Level, der dem Rang (Sterne eines Hauptmanns) entspricht.
* Einen gefallenen Superfighter kann man wie einen Helden wiederbeleben, wobei er allerdings um einen oder mehrere (nur Major: zum Leader) Ränge degradiert wird.
* Wenn ein Superfighter den höchsten Rang erreicht und noch nicht maximal Ausgebildet ist (zB: Langschwertkämpfer), kann er von euch aufgerüstet werden.
* Allgemeine Infos zur Bedienung werden angezeigt, wenn ihr einen Superfighter selektiert und den "?" - Button (unter den Resourcenübersicht) betätigt.
\\
\\
**- Zum Aufrufen eines Superfighters genügt wie bisher der folgende Aufruf, solange sich eine Entity (Hauptmann, Kundschafter oder Dieb) mit diesem Namen auf der Karte befindet. \\**CreateSuperfighter(_name)
\\
**- Der erweiterte Aufruf um den Typ und Rang des Superfighters zu bestimmen lautet: **
CreateSuperfighter(_name, _typ, _experience)
_experience muss zwischen 0 und 3 liegen, was den Variablen (VERYLOW_EXPERIENCE =) LOW_EXPERIENCE, MEDIUM_EXPERIENCE, HIGH_EXPERIENCE und VERYHIGH_EXPERIENCE entspricht. \\
\\
\\
**- Befindet sich keine Entity auf der Karte, müssen weitere Angaben gemacht werden: **
CreateSuperfighter(_name, _type, _experience, _entityType, _position, _player)
Wobei _player optional und standardmaßig 1 ist und _type wenn, durch "" oder nil eingesetzt, nicht angegeben immer "Warrior". \\
\\
\\
Weitere verwendbare Aufrufe sind:
--IsSuperfighter(_entity) -- gibt true und false zurück
--IsSuperfighterFeeling(_entity, _feeling) -- gibt true und false zurück
--GetNumberOfPlayerSuperfighters(_player) -- gibt die Anzahl an Superfightern zurück, die dem Spieler gehören
--GetSuperfighterType(_entity) -- gibt den Superfightertyp als String auf englisch zurück
--GetSuperfighterTypeName(_entity) -- gibt den Superfightertyp als String auf deutsch zurück
--GetSuperfighterLevel(_entity) -- gibt den Level als Zahl zurück
--GetSuperfighterLevelName(_entity) -- gibt den Rang des Superfighters als String zurück
--GetSuperfighterDetails(_kind, _entity) -- kann für alle Werte zurückgeben, die für einen Superfighter gespeichert werden
--ChangeSuperfighterType(_entity, _type) -- ändert den Superfightertyp
--ChangeSuperfighterLevel(_entity, _experience) -- ändert den Level des Superfighters
--DestroySuperfighter( _entity, _notEntity) -- löscht oder tötet einen Superfighter
-- _entity kann die Id oder der Name der Entity, sowie der Table des Superfighters sein.
-- _feeling ist ein String mit bored, sad, happy oder angry, die Gefühlen des Superfighters entsprechen
-- wenn _notEntity true ist, wird nur der Superfightertable gelöscht, die normale Entity bleibt bestehen
-- _kind steht für den Index des Wertes, den man aus dem Fightertable abfragen möchte
===== Create Superfighter - Version 1.01 =====
\\
Es sollte zwar nur eine Funktion für meine Bedürfnisse sein, (ich wollte mal einen Reiter als Helden) doch da ich die Funktion jetzt ja schon einmal habe, dachte ich mir ich machs wie Robert mit seinem Bauernhof, und stell das ganze in den Wiki! \\
Vielleich hat der eine oder andere noch ein paar Tolle einfälle hierzu! \\
\\
\\
===== Die Fähigkeiten eines Superfighters sind: =====
* schnelle Selbstheilung \\
* wiederbelebbar wie ein Held \\
* zwei Spezialfähigkeiten: \\
* einen automatischern "Power-Boost" \\
* manuel einen "Drehschlag" \\
\\
== Die Spezialfähigkeiten kann er alle 50 Sekunden: ==
* 1. Der automatischer "Power-Boost": \\
Wenn die Gesundheit des Superfighters unter 15% sinkt, dann heilt er sich komplett auf 100%
( zumindest, wenn die 50 Sekunden seit der letzten Heilung um sind!) \\
\\
* 2. Der manuelle "Drehschlag": \\
Beim betätigen des "Einheit entlassen" - Buttons wird eine Spezialattacke aktiviert, die ich bisher Drehschlag nenne: \\
Alle feindlichen Einheiten im Umkreis von 500 werden um die Hälfte ihrer Gesammtgesundheit geschwächt. Alle Soldaten (in Truppen) im Umkreis von 300 vernichtet! Also so ähnlich wie bei Erec! \\
\\
\\
===== Mit diesem Code ... =====
=== kann man sich beliebig viele Superfigter erschaffen! ===
(auch gegnerische (jedoch nicht ausführlich getestet)) \\
\\
Einfach da, wo mann den Superfighter erschaffen will diese Zeile einfügen:
CreateSuperfighter("Name") -- "Name" ist der Skriptname eures Superfighters!
Natürlich muss dann auch eine Entity diesen Namen haben! \\
Ansonsten einfach dashier vor den Aufruf setzen:
CreateEntity(1,Entities.PU_LeaderHeavyCavalry1,GetPosition("Pos1"),"Name") -- natürlich anpassen!
Bitte nur einzelne Hauptmännern, also solche die keine Soldaten bei sich haben, zu Superfightern machen! \\
\\
Vernichten kann man einen Superfighter dann ganz einfach durch:
DestroySuperfighter("Name")
Natürlich wird dann nur die "Superkraft" abgeschaltet, die Entity ist noch da! \\
\\
\\
===== Damit das ganze funktioniert ... =====
=== muss das hier einfach in euer Skript eingefügt werden: ===
( Ihr müsst nichts aufrufen, oder verändern [und bitte auch nicht in die "FirstMapAction" rein! ;-)] )
------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Comfort functions zum Erschaffen eines Superfighters Version 1.01 by Tenji
------------------------------------------------------------------------------------------------------------------------------------------------------------
function CreateSuperfighter( _name)
-- Wenn der globale SuperFighters-Table noch nicht erstellt wurde, tue es hier und starte den Control-Job -- und ändere seine Button
SuperFighters = SuperFighters or {
SuperFighterJobID = StartSimpleJob("ControlSuperfighters"),
InitSuperfighterButtons(),
}
-- merke Daten des aktuellen Superfighter
local superfighter = {
name = _name,
player = GetPlayer( _name),
entityType = Logic.GetEntityType(GetEntityId( _name)),
npcIsObservedID = GetEntityId( _name),
counter = 0,
counterCA = 0,
callbackDone = true,
}
-- füge den aufgerufenen Superfighter dem globalen Table hinzu
table.insert(SuperFighters,superfighter)
end
-------------------------------------------------------------------------
-- Lösche diesen Superfighter aus dem globalen Table:
function DestroySuperfighter( _name)
-- Gehe alle Superfighter durch ...
for i = 1,table.getn(SuperFighters) do
-- ... und lösche den aus dem globalen Table, der zerstöhrt werden soll
if SuperFighters[i].name == _name then
table.remove(SuperFighters,i)
return true
end
end
end
-------------------------------------------------------------------------
-- Der Superfighter-Control-Job:
function ControlSuperfighters()
-- Kontrolliere alle Superfighter im globalen Table:
for i = 1,table.getn(SuperFighters) do
-- hohle die notwendigen Daten aus dem jeweiligen Table
local fighter = SuperFighters[i]
local name = fighter.name
local health = GetHealth( name)
local deadName = "Dead"..name
local pos = GetPosition( name)
local deadPos = GetPosition( deadName)
-- wenn er nicht tot ist, ...
if not IsDead( fighter.name) then
-- steure den Health-Effekt je nach Counter-Stand
if fighter.counter == 0 then
Logic.CreateEffect(GGL_Effects.FXSalimHeal, pos.X, pos.Y, 0)
elseif math.mod( fighter.counter, 3 ) == 2 then
Logic.CreateEffect(GGL_Effects.FXSalimHeal, pos.X, pos.Y, 0)
end
-- wenn der counter der CircularAttack über 0 ist, zähle runter
if fighter.counterCA > 0 then
fighter.counterCA = fighter.counterCA -1
-- bei 1 melde, das du bereit bist
if fighter.counterCA == 1 then
Logic.CreateEffect(GGL_Effects.FXDarioFear, pos.X, pos.Y, 0)
end
-- bei 0 aktualisiere den Button, fals nötig
elseif fighter.counterCA == 0 and not fighter.callbackDone and GUI.GetSelectedEntity() == GetEntityId( fighter.name) then
GameCallback_GUI_SelectionChanged()
fighter.callbackDone = true
elseif fighter.counterCA == 0 and not fighter.callbackDone then
fighter.callbackDone = true
end
-- wenn der counter über 0 ist, zähle runter
if fighter.counter > 0 then
fighter.counter = fighter.counter -1
-- bei 1 melde, das du bereit bist
if fighter.counter == 1 then
Logic.CreateEffect(GGL_Effects.FXDarioFear, pos.X, pos.Y, 0)
end
end
-- verbessere seine Selbstheilung, durch einen konstanten "+5" und einen alle 30 sek. möglichen "=100" Health-Boost
if ( health < 100 and health > 15 ) or ( health < 100 and fighter.counter > 0 ) then
SetHealth( name, health +5)
elseif health < 15 then
SetHealth( name, 100)
fighter.counter = 50
Sound.PlayGUISound(Sounds.VoicesHero7_HERO7_Madness_rnd_01, 0)
Logic.CreateEffect(GGL_Effects.FXDarioFear, pos.X, pos.Y, 0)
end
end
-- wenn er tot ist, ...
if IsDead( fighter.name) then
-- wenn seine Überreste nicht herum liegen, dann erstelle sie und setze den "rivive"- counter auf 10
if not IsExisting( deadName) then
CreateEntity( 1, Entities.XD_BoneHuman1, pos, deadName)
CreateEntity( 1, Entities.XD_Sparkles, pos, "Sparkles"..name)
Logic.CreateEffect(GGL_Effects.FXDieHero, pos.X, pos.Y, fighter.player)
Explore.Show("Explore"..deadName, deadName, 100)
Sound.PlayGUISound(Sounds.VoicesHero7_HERO7_NO_rnd_01, 0)
Message( name.." ist zusammengebrochen!")
fighter.counter = 10
end
-- verdeutliche seine Position zu dem "Sparkles" noch durch den "FXSalimHeal"
Logic.CreateEffect(GGL_Effects.FXSalimHeal, deadPos.X, deadPos.Y, 1)
-- wenn keine Gegner in der Nähe sind, aber eigene oder befreundete Truppen schon, dann ...
if ( not AreEnemiesInArea( fighter.player, deadPos, 500) and AreAlliesInArea( fighter.player, deadPos, 500) ) or
( not AreEnemiesInArea( fighter.player, deadPos, 500) and AreEntitiesInArea( 1, 0, deadPos, 500, 1) ) then
-- Zähle von 10 runter ...
fighter.counter = fighter.counter -1
MapLocal_StartCountDown( fighter.counter)
-- und bei 0: Lass ihn wieder auferstehen!
if fighter.counter == 0 then
fighter.counter = 25
Explore.Hide("Explore"..deadName)
local replacedEntity = ReplaceEntity( deadName, fighter.entityType)
SetEntityName( replacedEntity, name)
SetHealth( name, 50)
DestroyEntity("Sparkles"..name)
Sound.PlayGUISound(Sounds.VoicesHero7_HERO7_Yes_rnd_01, 0)
-- aktualisiere alle npc.ids in den Npc-briefings, die für isObserved fungieren
table.foreach(NPC,NpcIsObservedIDUpdate)
fighter.npcIsObservedID = GetEntityId( name)
end
else
MapLocal_StopCountDown()
end
end
end
end
-------------------------------------------------------------------------
-- Ändere die Button des Superfighters!
function InitSuperfighterButtons()
-- Die Original-Funktionen einem Index zuordnen
GameCallback_GUI_SelectionChangedOrig = GameCallback_GUI_SelectionChanged;
GUIAction_ExpelSettlerOrig = GUIAction_ExpelSettler;
-- Beim Selektieren einer Einheit wird diese Funktion aufgerufen:
GameCallback_GUI_SelectionChanged = function()
-- alle Superfighter durchgehen ...
for i = 1,table.getn(SuperFighters) do
-- wenn die selektierte Einheit ein Superfighter ist, dann die Button umstellen!
if GUI.GetSelectedEntity() == GetEntityId(SuperFighters[i].name) then
local entity = SuperFighters[i].name
local ti = i
GameCallback_GUI_SelectionChangedOrig()
XGUIEng.ShowWidget(gvGUI_WidgetID.BuySoldierArea, 0)
if SuperFighters[i].counterCA == 0 then
XGUIEng.DisableButton(gvGUI_WidgetID.ExpelSettler, 0)
-- Beim Klicken des "Einheiten entlassen"-Buttons ...
GUIAction_ExpelSettler = function()
if GUI.GetSelectedEntity() == GetEntityId( entity) then
-- ... wird meine Funktion aufgerufen!
GUIAction_ExpelSettler_Action( entity)
XGUIEng.DisableButton(gvGUI_WidgetID.ExpelSettler, 1)
-- und den Counter auf 30 setzen
SuperFighters[ti].counterCA = 50
SuperFighters[ti].callbackDone = false
else
GUIAction_ExpelSettlerOrig();
end
end
else
XGUIEng.DisableButton(gvGUI_WidgetID.ExpelSettler, 1);
end
return true
else
GameCallback_GUI_SelectionChangedOrig();
end
end
end
end
-------------------------------------------------------------------------
-- Statt des Entlassens der Einheit wird das hier gemacht:
function GUIAction_ExpelSettler_Action( _entity)
-- Alle gegnerischen Einheiten im Umkreis von 500 [s]cm um die Hälfte Schwächen
local actionPos = GetPosition( _entity)
Logic.CreateEffect(GGL_Effects.FXKerberosFear, actionPos.X, actionPos.Y, 1)
Sound.PlayGUISound(Sounds.VoicesHero7_HERO7_InflictFear_rnd_01, 0)
for i = 1,8 do
if Logic.GetDiplomacyState(GetPlayer( _entity), i) == Diplomacy.Hostile then
local data = {Logic.GetPlayerEntitiesInArea( i, 0, actionPos.X, actionPos.Y, 500, 10)}
for i = 2, data[1] + 1 do
if Logic.IsBuilding(data[i]) == 0 then
if Logic.IsLeader(data[i]) == 1 then
local data2 = {Logic.GetSoldiersAttachedToLeader( data[i])}
for j = 2, data2[1] + 1 do
if IsNear( _entity, data2[j], 300) then
SetHealth( data2[j], 0)
end
end
if data2[1] == 0 then
SetHealth( data[i],GetHealth( data[i]) -50)
end
else
SetHealth( data[i],GetHealth( data[i]) -50)
end
end
end
end
end
end
-------------------------------------------------------------------------
-- Hier wird die npc.id in den Npc-briefings aktualisiert
function NpcIsObservedIDUpdate( _id)
for i = 1,table.getn(SuperFighters) do
local fighter = SuperFighters[i]
local npc = NPC[_id]
if npc.briefing ~= nil then
for j = 1, table.getn(npc.briefing) do
if npc.briefing[j].npc ~= nil then
if npc.briefing[j].npc.id == fighter.npcIsObservedID or npc.briefing[j].npc.id == 0 then
npc.briefing[j].npc.id = GetEntityId(fighter.name)
end
end
end
end
end
end
\\
===== Zusätzlich benötigte Code: =====
Zusätzlich braucht ihr nur noch drei kleine Funktion:
Die [[GetHealth|GetHealth-Funktion]] von Chromix und [[AreEnemiesInArea|zwei kleinen Funktionen]] von mir, die ich zwar intern machen hätte können, doch so könnt ihr sie auch für eure Zwecke benützen, ohne sie nochmals einfügen zu müssen!
== Auch das hier muss einmal in eurem Skript vorhanden sein: ==
------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Comfort function zum Abfragen der Health einer Entity by Chromix
------------------------------------------------------------------------------------------------------------------------------------------------------------
function GetHealth( _entity )
local entityID = GetEntityId( _entity );
if not Tools.IsEntityAlive( entityID ) then
return 0;
end
local MaxHealth = Logic.GetEntityMaxHealth( entityID );
local Health = Logic.GetEntityHealth( entityID );
return ( Health / MaxHealth ) * 100
end
------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Comfort functions zur Abfrage, ob Feinde/Verbündete in einem bestimmten Bereich sind by Tenji
------------------------------------------------------------------------------------------------------------------------------------------------------------
function AreEnemiesInArea( _player, _position, _range)
return AreEntitiesOfDiplomacyStateInArea( _player, _position, _range, Diplomacy.Hostile )
end
function AreAlliesInArea( _player, _position, _range)
return AreEntitiesOfDiplomacyStateInArea( _player, _position, _range, Diplomacy.Friendly )
end
function AreEntitiesOfDiplomacyStateInArea( _player, _position, _range, _state )
for i = 1,8 do
if Logic.GetDiplomacyState( _player, i) == _state then
if AreEntitiesInArea( i, 0, _position, _range, 1) then
return true
end
end
end
return false
end
\\
===== Schlusswort =====
Vielen Dank an Chromix, Robert und nevermind für Hilfe und Tipps! :-) \\
\\
Das npc.isObserved-Problem ist jetzt behoben! Tenji [2005/11/12 19:22] \\
\\
\\
Bei Problemen bitte [[http://www.siedler-portal.de/vb3/forumdisplay.php?f=95|hier]] im Forum melden! \\
\\
\\
[[:tutorials:index|Zur Tutorial-Übersicht]]
\\