Falls es sowas schon mal irgendwo gab: Sorry schon mal, aber mit der Suchfunktion im Forum kann ich so gut wie nichts anfangen und nachdem ich ein paar Seiten nach einem ähnlichen Thema durchsucht und nichts gefunden habe, kommt jetzt einfach das Thema hier.
Das Problem ist, dass nach einem Weltenwechsel die NPCs in der neuen Welt nicht spawnen, obwohl sie in der Startup stehen und auch nochmal explizit im Dialog gespawned werden sollten. Zumindest hat das immer in der Startwelt funktioniert.
"WELTNAME" ist natürlich nicht der richtige Name und die Namen der Waypoints stimmen auch alle.
Mit den Funktionen B_Kapitelwechsel und FF_ApplyExt kenne ich mich auch überhaupt nicht aus. Aber es wird zum 2. Kapitel gewechselt und der eigene Name für das Kapitel taucht auch auf. Wenn jemand die zusätzlich erklären könnte, bzw. mir sagen kann, wo ich sowas nachlesen kann, wäre das super.
Das du deinen code verfälschst bevor du postest macht es nicht unbedingt einfacher dir zu helfen. Auch sind screenshots von code eher nervig, besser du kopierst das in den post rein.
Allgemein macht es keinen Sinn zu Versuchen in Zen X einen NPC einzufügen während du gerade in Zen Y bist.
Auch werden die Startup Funktionen nur aufgerufen wenn du zum ersten mal die entsprechende zen betrittst.
Was du wahrscheinlich möchtest:
Code:
var int NPCsK2WurdenEingefuegt;
func void INIT_WELTNAME (){
if(!NPCsK2WurdenEingefuegt){ // nur genau einmal machen
if(kapitel >= 2){
NPCsK2WurdenEingefuegt = true; // merken das es einmal gemacht wurde
Wld_InsertNpc (X, "WP1");
Wld_InsertNpc (Y, "WP2");
[...]
};
};
};
Ist es denn überhaupt möglich, einen Weltenwechsel über einen Dialog zu machen? Also in dem Sinne, dass dann auch die NPCs spawnen. Weil der restliche Code des Dialogs wird ja vermutlich noch ausgeführt, während die Welt gerade gewechselt wird.
Wenn ich zum Beispiel beim FF_ApplyExt (Teleport, 10000, 1) eingebe, also 10 Sekunden warte, bevor ich teleportiert werde, dann wird der Kapitelwechsel schon gemacht, obwohl der erst nach dem Funktion aufgerufen wird.
Gibt es denn eine Möglichkeit, den Aufruf einer Funktion zu verzögern?
Und ich bin dann noch auf was Interessantes gestoßen. Beim B_Kapitelwelchsel(2, NEWWORLD_ZEN) steht ja hinten NEWWORLD_ZEN. Ich hab' mal ein bisschen im Code danach gesucht und es, wen wundert es, bei den Konstanten gefunden
Code:
const int NEWWORLD_ZEN = 1;
const int OLDWORLD_ZEN = 2;
const int DRAGONISLAND_ZEN = 3;
const int ADDONWORLD_ZEN = 4;
Aber wie und wo sind die Konstanten mit der .zen verknüpft? Weil vielleicht ist ja das das Problem. Vielleicht muss ja beim Kapitelwechsel als zweites Argument die richtige Variable angegeben werden.
Geändert von BusfahrerCharlie (18.02.2019 um 16:11 Uhr)
Gibt es denn eine Möglichkeit, den Aufruf einer Funktion zu verzögern?
Genau das machst du ja, wenn du "FF_ApplyExt (Teleport, 10000, 1)" aufrufst. Dann schreibt die Kapitelwechsel-Funtkion halt noch mit in die Teleportfunktion, die nach 10 Sekunden aufgerufen wird. Oder schreibe einfach eine neue FF_Apply-Funtkion!
Ist es denn überhaupt möglich, einen Weltenwechsel über einen Dialog zu machen? Also in dem Sinne, dass dann auch die NPCs spawnen. Weil der restliche Code des Dialogs wird ja vermutlich noch ausgeführt, während die Welt gerade gewechselt wird.
Wenn ich zum Beispiel beim FF_ApplyExt (Teleport, 10000, 1) eingebe, also 10 Sekunden warte, bevor ich teleportiert werde, dann wird der Kapitelwechsel schon gemacht, obwohl der erst nach dem Funktion aufgerufen wird.
Gibt es denn eine Möglichkeit, den Aufruf einer Funktion zu verzögern?
Und ich bin dann noch auf was Interessantes gestoßen. Beim B_Kapitelwelchsel(2, NEWWORLD_ZEN) steht ja hinten NEWWORLD_ZEN. Ich hab' mal ein bisschen im Code danach gesucht und es, wen wundert es, bei den Konstanten gefunden
Code:
const int NEWWORLD_ZEN = 1;
const int OLDWORLD_ZEN = 2;
const int DRAGONISLAND_ZEN = 3;
const int ADDONWORLD_ZEN = 4;
Aber wie und wo sind die Konstanten mit der .zen verknüpft? Weil vielleicht ist ja das das Problem. Vielleicht muss ja beim Kapitelwechsel als zweites Argument die richtige Variable angegeben werden.
Der Ansatz von Cryp18Struct ist schon der richtige Weg. Zeig uns mal den Code, den du dafür verwendet hast, mit dem es nicht funktioniert. Die Npc in der anderen Welt können erst nach Laden der Welt gespawnt werden -- aus deinem Dialog heraus also noch nicht.
Vor dem Wechsel der Welt musst du darauf warten, dass der Dialog komplett beendet ist. Das lässt sich zum Beispiel mit einer FrameFunction (LeGo) machen, die solange aufgerufen wird, bis Npc_IsInState(DIALOGPARTNER, ZS_Talk)FALSE zurückgibt.
Du kannst etwas abfragen wie CurrentLevel == NEWWORLD_ZEN, aber wie gesagt, das ist vermutlich nicht der zielführende Ansatz hier.
Zeig uns mal den Code, den du dafür verwendet hast, mit dem es nicht funktioniert.
Ich hoffe das ist, was du haben willst:
Code:
Instance DIA_HauptmannGarret_SKIPPROLOG (C_INFO) { // Im Moment unwichtig
npc = Mil_90004_HauptmannGarret;
nr = 100;
condition = DIA_HauptmannGarret_SKIPPROLOG_Condition;
information = DIA_HauptmannGarret_SKIPPROLOG_Info;
description = "Prolog überspringen";
};
Code:
Func int DIA_HauptmannGarret_SKIPPROLOG_Condition() {
return true;
};Func int DIA_HauptmannGarret_SKIPPROLOG_Info() {
AI_StopProcessInfos (self); // Dialog wird beendet
FF_ApplyExt (Teleport, 0, 1); // Funktion wird aufgerufen (ich weiß leider nur, was die 0 bedeutet. Nämlich nach wie viele Millisekunden man teleportiert werden will
B_Kapitelwechsel (2, NEWWORLD_ZEN); // Kapitelwechsel (Keine Ahnung, was das mit der ZEN hinten zu tun hat};
1.: Einfügen von NPCs nach Weltwechsel:
Es sollte für jede .zen jeweils eine Funktion STARTUP_WELTNAME und eine Funktion INIT_WELTNAME existieren.
Die STARTUP_WELTNAME Funktion wird nur beim 1. Betreten der WELTNAME.zen aufgerufen.
Die INIT_WELTNAME funktion wird jedes mal aufgerufen wenn man diese WELTNAME.zen betritt(auch wenn man einen Spielstand lädt und man sich in dieser WELTNAME.zen befindet).
Es sieht auch immer noch so aus als würdest du deinen code verfälschen bevor du ihn postest(STARTUP_Mod, STARTUP_WELT würden nur Sinn machen wenn du eine mod.zen und eine welt.zen hättest). Diese "Geheimniskrämerei" ist unnötig, niemand wird dir hier deine Story Ideen "klauen". Das macht es nur schwerer dir zu helfen.
2. Befehle werden noch im Dialog ausgeführt, du möchtest sie aber erst nach dem Dialog ausgeführt haben:
Das einfachste wäre wohl das du die AI_Function aus LeGo benutzt:
Code:
func void verzoegerteFunktion(){
B_Kapitelwechsel (2, NEWWORLD_ZEN);
Teleport();
};
Func int DIA_HauptmannGarret_SKIPPROLOG_Info() {
AI_StopProcessInfos (self); // In die AI-queue von NPC self wird geschrieben: Dialog beenden sobald die AI_Queue hier ankommt
AI_Function(self, verzoegerteFunktion); // In die AI-Queue von self wird geschrieben: Funktion "verzoegerteFunktion" aufrufen sobald die AI_Queue hier ankommt
};
Dadurch wird dann die Funktion "verzoegerteFunktion" erst aufgerufen nachdem der Dialog beendet wurde.
Was die Konstante NEWWORLD_ZEN angeht die in B_Kapitelwechsel als Parameter übergeben wird:
Wenn du dir den Inhalt von der normalen Gothic2 B_Kapitelwechsel anschaust, kannst du sehen das abhängig von der Konstante unterschiedliche Funktionen aufgerufen werden. Ob/Wie das in deiner Mod sinnvoll ist, musst du entscheiden.
Soll das eine "Erweiterungsmod" für Gothic 2 werden oder baust du dir eine "total conversion" mit eigenen Welten?
Ist jetzt schon eine ganze Weile her, in der ich hier im Forum war. Seit dem vor Kurzem ein Update zur Modifikation kam, habe ich wieder etwas mehr Motivation, hier weiterzuarbeiten. Deshalb jetzt nochmal der ganze und unverfälschte Code, damit man vielleicht einen besseren Einblick erhält, was schieflaufen könnte. Bisher bin ich nämlich nicht weitergekommen.
Wie heißt die .zen in welcher die NPCs eingefügt werden sollen?
Falls die Beach.zen heißt, dann kannst du eine Funktion mit dem Namen STARTUP_BEACH und eine Funktion mit dem Namen INIT_BEACH erstellen und diese werden dann von der engine automatisch aufgerufen(STARTUP_XXX nur beim ersten betreten, INIT_XXX jedes mal).
Schreib bitte mal wie alle Welten heißen. (Hast du wirklich eine .zen die Mod.zen heißt?)
Geändert von Cryp18Struct (11.08.2019 um 21:25 Uhr)
Der hier rot markierte Aufruf von STARTUP_MM_PART_BEACH innerhalb der STARTUP_Mod() macht eher keinen Sinn.
Keine der original gothic Welten haben Unterstriche(_) im Namen, evt. ist das ein Problem.
Du könntest testweise mal deine MM_PART_BEACH.zen umbenennen in BEACH.zen und dann allen code anpassen.
(Also den Weltwechsel und die INIT_XXX und STARTUP_XXX funktionen)
Ich hab die Datei umbenannt und aus der Funktion STARTUP_Mod den Aufruf von STARTUP_MM_PART_BEACH (jetzt STARTUP_BEACH) entfernt. Leider ist das Problem damit nicht behoben.
Zeig bitte nochmal allen code wie er jetzt aussieht.
Die Funktion Teleport bitte auch.
Ist das Problem das du in der beach.zen ankommst und keine NPCs gespawnt werden?
Und die waypoints "FALUA_TOWN_HARBOR_01", "FALUA_TOWN_GATE_01" und "FALUA_TOWN_GATE_02" existieren in der beach.zen?
This sadly didn't work. But I found out that zSpy prints an info when a NPC is inserted (AI: Inserted NPC : Hauptmann Garret / MIL_90004_HAUPTMANNGARRET …. <oNpc.cpp,#9188>)
After the world change nothing like this happens.
Ich denke es wäre sinnvoll erstmal zu prüfen ob die init/startup Funktionen überhaupt aufgerufen werden. probier mal bitte folgendes:
Diese beiden Funktionen irgendwo einfügen(ganz oben in der startup.d?)
Code:
func void printWorldName(){
print(MEM_World.worldName);
printDebug(MEM_World.worldName);
};
func void printInitBeachWasCalled(){
print("init_beach was executed");
printDebug("init_beach was executed");
};
Dann in der Funktion init_global ganz unten diesen FF_ApplyOneExt Aufruf einfügen:
Ich denke damit haben wir das Problem identifiziert. Entgegen meiner Erwartung werde ich nicht in die BEACH.zen teleportiert, sondern in die TEST.zen. Wo kann man denn festlegen, in welche .zen man teleportiert werden möchte?
sieht so aus als würde der hero zu einem waypoint teleportiert werden wo er dann in einem levelchange objekt(oCTriggerChangeLevel) landet.
Du müsstest also die mod.zen im spacer öffnen und dieses Objekt(nahe dem waypoint WP_CHANGE) suchen und dort in den vob Eigenschaften Veränderungen machen und die mod.zen abspeichern.