Benutzer-Werkzeuge

Webseiten-Werkzeuge


scripting:tutorials:level2:npcs

Dies ist eine alte Version des Dokuments!


NPCs

Grundsätzlich sind alle Nichtspielercharaktere (Non-Player-Characters) NPCs. Im Kontext von Siedler 5 sind allerdings speziell jene Charaktere gemeint, die dem Spieler über Helden Interaktionen anbieten, gekennzeichnet durch ein großes Ausrufezeichen über dem Kopf.

Theoretisch kann bei der Interaktion mit einem NPC jede beliebige Funktion ausgelöst werden. In der Regel ist das aber ein Briefing, weshalb wir diesen Fall zuerst anschauen.

NPCs werden mit der Funktion CreateNPC(_NpcDescription) erstellt. Die _NpcDescription ist ein Table, das einige notwendige Informationen enthalten muss und optionale Einstellungen darüber hinaus erlaubt. In der untenstehenden Tabelle sind alle Keys, die man angeben kann, aufgelistet. Im Anschluss werden wir sie nacheinander erklären.

Key Bedeutung Erforderlich?
name Skriptname des NPCs (kann im Editor gesetzt werden) Ja
callback Funktion, die bei der Interaktion mit dem NPC aufgerufen wird Ja
briefing Briefing, das bei der Interaktion mit dem NPC gestartet wird Nur, wenn kein callback angegeben wurde
heroName Wenn der NPC nur mit einem bestimmten Helden interagieren soll, wird hier dessen Skriptname eingetragen
(Standardmäßig kann mit allen Helden interagiert werden)
Nein
wrongHeroMessage Nachricht, die angezeigt wird, wenn der NPC mit dem falschen Helden angesprochen wird
(alle außer derjenige, der mit heroName vorgeschrieben wird)
Nein, sollte bei der Angabe von heroName aber ebenfalls angegeben werden
follow Kann entweder true oder ein Skriptname sein. Der NPC folgt bei true dem nächsten Helden, sonst der angegebenen Entity Nein
vanishPos Nach der Interaktion geht der NPC zur angegebenen Position und verschwindet, sobald er aus der Sichtweite des Spielers gerät Nein

Tatsächlich kann man einer _NpcDescription beliebige Key-Value-Paare geben. In der callback-Funktion kann dann darauf zugegriffen werden (siehe auch das Beispiel unten).

Hinweis: Wir werden im Folgenden nur mit der callback-Option arbeiten und die briefing-Angabe außen vor lassen. Das hat den Grund, dass der Weg über das callback deutlich übersichtlicher und flexibler ist.

Achtung: Die Entity, die bei name angegeben wird, muss eine Siedler-Einheit sein (also Präfix PU oder CU)! Andernfalls wird das Spiel abstürzen.

Der einfachste Fall ist ein NPC, der einfach nur ein Gespräch über ein Briefing anbietet:

-- Wir schreiben jeweils eine Funktion für die Erstellung des NPCs und eine für das Callback, in dem
-- Fall den Start des Briefings
function CreateNpcScout()
    local Npc = {
        -- Auf der Karte muss eine Einheit (am besten ein Kundschafter) mit dem Namen "Scout" existieren
        name = "Scout",
        -- Der Callback ist einfach nur der Name der Funktion
        callback = CreateBriefingScout
    }
 
    CreateNPC(Npc)
end
 
function CreateBriefingScout()
    local Briefing = {
        {
            title = "Kundschafter",
            text = "Alles ruhig hier an den Grenzen, mein Herr!",
            position = GetPosition("Scout")
        }
    }
 
    StartBriefing(Briefing)
end


Interaktion mit einem bestimmten Helden

Möglicherweise wollen wir den Kundschafter nur mit Dario sprechen lassen. Dafür muss die Dario-Entity den Skriptnamen „Dario“ besitzen:

-- Wir schreiben jeweils eine Funktion für die Erstellung des NPCs und eine für das Callback, in dem
-- Fall den Start des Briefings
function CreateNpcScout()
    local Npc = {
        name = "Scout",
        callback = CreateBriefingScout,
        heroName = "Dario",
        wrongHeroMessage = "Meine Informationen übergebe ich nur Dario persönlich!"
    }
 
    CreateNPC(Npc)
end
 
function CreateBriefingScout()
    local Briefing = {
        {
            title = "Kundschafter",
            text = "König Dario, hier ist immer noch alles ruhig.",
            position = GetPosition("Scout")
        }
    }
 
    StartBriefing(Briefing)
end


Zusätzliche Parameter der Callback-Funktion

Im vorigen Beispiel haben wir gesehen, dass es ganz schön sein kann, wenn der NPC den Helden, mit dem er angesprochen wird, direkt beim Namen nennen kann bzw. generell der Heldenname im Callback verfügbar ist.

Tatsächlich werden sowohl die _NpcDescription als auch die Entity-Id des interagierenden Helden an das Callback übergeben. Über die Entity-Id wiederum lässt sich der Skriptname des Helden ermitteln.

In diesem Beispiel haben wir zuvor auf der Karte Dario mit dem Skriptnamen „Dario“ und Ari mit dem Skriptnamen „Ari“ auf der Karte platziert.

-- An der Erstellung des NPCs ändert sich nichts
function CreateNpcScout()
    local Npc = {
        name = "Scout",
        callback = CreateBriefingScout
    }
 
    CreateNPC(Npc)
end
 
function CreateBriefingScout(_NpcDescription, _HeroId)
    -- Mit der Funktion GetEntityName kann der Skriptname einer Entity anhand der Entity-Id
    -- ermittelt werden
    -- Weil der Skriptname genau dem Anzeigenamen der Helden entspricht, bekommen wir so den
    -- korrekten Namen für jeden Helden
    -- Hätten wir Dario den Skriptnamen "Karl" gegeben, würden wir hier stattdessen auch "Karl" erhalten
    local HeroName = GetEntityName(_HeroId)
 
    -- Mit dieser Information können wir nun festlegen, wie der Kundschafter den Helden anspricht
    local Address = ""
    if HeroName == "Ari" then
        Address = "Herrin"
    else
        Address = "Herr"
    end
 
    local Briefing = {
        {
            title = "Kundschafter",
            text = Address..", hier ist weiterhin alles ruhig.",
            position = GetPosition("Scout")
        },
 
        {
            -- Der Name des Helden kann hier benutzt werden, um den Titel und die Position der 
            -- Briefingseite korrekt zu setzen
            title = HeroName,
            text = "Sehr gut, weitermachen!",
            position = GetPosition(HeroName)
        }
    }
 
    StartBriefing(Briefing)
end


Weitere Parameter

Im nächsten Beispiel wollen wir weitere Parameter für NPCs demonstrieren und zeigen, dass auf eine NPC-Interaktion nicht notwendigerweise ein Briefing folgen muss. Außerdem zeigen wir, dass einem NPC noch weitere, frei wählbare Werte gegeben werden können, auf die in der NPC-Interaktion zugegriffen werden kann.

Hierfür haben wir Drake (Skriptname „Drake“) und vier Schafe (Skriptnamen „Sheep1“ bis „Sheep4“) auf der Karte platziert.

function SetupSheep()
    -- Alle 4 Schafe sollen zum NPC werden
    for i = 1, 4 do
        CreateNpcSheep(i)
    end
end
 
function CreateNpcSheep(_Number)
    local Npc = {
        -- Weil wir die Namen der Schafe durchnummeriert haben, können wir hier an das Präfix "Sheep" einfach
        -- die Zahl anhängen
        name = "Sheep".._Number,
        -- Zusätzlicher Wert: Wir merken uns die Nummer des Schafs. Das wird im Callback wichtig
        number = _Number,
        -- Alle Schafe benutzen das gleiche Callback!
        callback = SheepInteraction,
        -- Alle Schafe sollen Drake folgen
        follow = "Drake"
    }
 
    CreateNPC(Npc)
end
 
function SheepInteraction(_NpcDescription, _HeroId)
    -- Sobald Drake mit einem der Schafe interagiert, soll es einfach nur "Määh" machen
    Sound.PlayGUISound(Sounds.AmbientSounds_Sheep_rnd_1)
    -- Damit das "angesprochene" Schaf Drake weiterhin folgt, muss der Schaf-NPC erneut erstellt werden
    -- Dazu benutzen wir die oben definierte Funktion CreateNpcSheep und geben als Parameter die Nummer
    -- an, die wir uns beim ersten Erstellen des Schaf-NPCs gemerkt haben
    CreateNpcSheep(_NpcDescription.number)
end

Funktionen für NPCs

DestroyNPC

SetNPCWaypoints

SetNPCFollow

TalkedToNPC

scripting/tutorials/level2/npcs.1694352043.txt.gz · Zuletzt geändert: 2023/09/10 13:20 von fritz_98