[Editor1] Skript für Schmied

Mordos

Senior Member
Registriert
05.06.2001
Beiträge
691
Ich will, dass mein Schmied mir einige Gegenstände anfertigt und dabei zu seinem Amboss geht und mit dem Hammer darauf haut. Der Schmied nimmt mir die Gegenstände, welche für den neuen Gegenstand benötigt werden ab und geht dann zum Amboss um auf ihn einzuschlagen, jedoch kommt er nicht mehr zurück und ich kann das Gespräch nicht weiterführen. Die Gesprächsoption nach dem Hämmern sollte durch "waffe 3" gestartet werden, wenn er jedoch wieder ansprechbar ist (dauert ein wenig nach dem Hämmern), startet das Gespräch wieder von neuem. Und hier ist mein Skript:
void main()
{
SetLocalInt(GetPCSpeaker(), "waffe", 3);
// Gegenstände aus dem Gepäck des Spielers entfernen
object oItemToTake;
oItemToTake = GetItemPossessedBy(GetPCSpeaker(), "NW_WAXMGR002");
if(GetIsObjectValid(oItemToTake) != 0)
DestroyObject(oItemToTake);
oItemToTake = GetItemPossessedBy(GetPCSpeaker(), "NW_IT_GEM012");
if(GetIsObjectValid(oItemToTake) != 0)
DestroyObject(oItemToTake);
{
//Bash the object!
DoPlaceableObjectAction(GetObjectByTag("amboss1"), PLACEABLE_ACTION_BASH);

}
}

Ich hab eigentlich keine Ahnung vom Skripten und hab einfach aus ein paar anderen Skripts, die ich im Internet gefunden habe die einzelnen Stellen herauskopiert. Also gebt mir bitte keine Ratschläge, wie ich das Skript verändern kann, sondern postet mir gleich ein fertiges.
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Du brauchst auch noch Starting-Conditionals für die Dialogoptionen. Es muß ja schließlich abgefragt werden, welchen Status die Variable "waffe" hat. Ich denke eher, daß da irgendwo der Fehler steckt. Womöglich steckt er aber auch in der Dialogstruktur.


Kleine Verbesserungsmöglichkeit am Rande: Beim Ausdruck

if(GetIsObjectValid(oItemToTake) != 0)

dreht sich mir inzwischen der Magen um :rolleyes:! Ich würde eher folgendes benutzen:

if (oItemToTake != OBJECT_INVALID)

Dadruch wird
a) klarer, was gemeint ist und
b) sparst Du Dir somit den Aufruf der Funktion GetIsObjectValid und damit verringerst Du die Laufzeit des Skripts.
 

Mordos

Senior Member
Registriert
05.06.2001
Beiträge
691
@Tingil
Naja, an der Dialogstruktur liegst meiner Meinung nach nicht, an der Stelle, an der der (<- sieht irgendwie komisch aus :D ) Dialog weitergehen soll, wird wohl geprüft, welchen Status die Variable "waffe" hat, der Dialog wird also nur dann weitergeführt, wenn "waffe" == 3 ist.
Was deinen Verbesserungsvorschlag angeht kann ich nur sagen: Ich hab alles nur aus anderen Skripts herauskopiert und es irgendwie zusammengebastelt, ich hab ganz einfach keine Ahnung vom Skripten. :rolleyes:
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Wie sieht denn die Dialogstruktur aus? Welche Äste sind bei welchem Stand er Variable zugänglich? Ich kann im Skript keinen Fehler finden, also muß er an anderer Stelle liegen.
Am besten wäre es, ich könnte mit den Dialog 'mal anschauen. Am einfachsten wäre es da, Du würdest Dein Modul 'mal ZIPen und hier anhängen oder mir schicken.
 

Mordos

Senior Member
Registriert
05.06.2001
Beiträge
691
Ich hab jetzt mal versucht dem Dialog eine andere Struktur zu geben bzw. habe ich einmal die Variablen weggelassen, das hilft jedoch nicht.
Der Fehler düfte wohl hier liegen:
{
//Bash the object!
DoPlaceableObjectAction(GetObjectByTag("amboss1"), PLACEABLE_ACTION_BASH);

}

Nach dieser Aktion geht es nicht mehr weiter, kann man hier nicht vielleicht ein "int DURATION_TYPE_TEMPORARY" einfügen oder geht das in diesem Fall nicht?
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Nein, das geht hier nicht. Die Deklaration von DoPlaceableObjectAction läßt dies nicht zu.

void DoPlaceableObjectAction(object oPlaceable, int nPlaceableAction)


Was meinst Du mit "geht es nicht mehr weiter"? Wird der Dialog beendet? In diesem Falle solltest Du den Dialog entsprechend darauf ausrichten und dem Schmied den Befehl geben, danach den Dialog wieder aufzunehmen (mit ActionStartConversation).


Ich kann Dir leider kaum helfen, wenn ich keinen detailierten Einblick in die Dialogstruktur habe, denn diese Struktur hat einen essentiellen Einfluß darauf, ob ein Skript überhaupt ausgeführt wird. Ich hoffe Dir ist klar, daß das Programm von der Wurzel des Dialoges ausgeht und dann die erste Abzweigung nimmt, dessen Startbedingung zutrifft. Wenn es einmal eine zutreffende Startbedingung gefunden hat, sucht es nicht mehr weiter, sondern nimmt diese Abzweigung. Wenn man das nicht berücksichtigt, kann man durchaus Dialogpunkte schreiben, die niemals zur Ausführung kommen können.
 

Curom

Schussel-Magier
Registriert
21.07.2000
Beiträge
1.329
Geh ich recht in der annahme das der Schmied nicht zu dir zurückgehumpelt kommt um das Gescpräch wieder aufzunehmen?
 

Mordos

Senior Member
Registriert
05.06.2001
Beiträge
691
@Tingil
Das der Dialogbaum vom Anfang an nach der richtigen Abzweigung durchsucht wird, weiß ich wohl, ich hab schon an die 30 Gebiete in meinem Modul und die Hälfte davon ist schon fertig, daher hab ich schon ein wenig Ahnung von den Dialogen, aber eben nur ein wenig.
Ich hab den Dialogbaum am Stamm in zwei Äste verzweigt, der erste öffnet sich, wenn waffe kleiner 1, der andere wenn waffe = 3. Wenn ich den Schmied anspreche öffnet er also Ast 1 und ich gebe ihm den Auftrag, etwas für mich anzufertigen, hier füge ich bei "Erfolgte Aktionen" das oben gepostete Skript ein. Nun geht er zum Amboss und hämmert darauf ein, wenn ich ihn danach wieder anspreche, startet er jedoch wieder Ast 1, obwohl er ja bei "Erfolgte Aktionen" "waffe 3" zuweist und somit Ast 2 gestartet werden sollte.
Ich werde jetzt aber ganz einfach einmal deinen Vorschlag mit ActionStartConversation befolgen, wenn das nicht funktioniert, dann häng ich hier mein Modul einmal als ZIP an.

@Curom
Es stimmt schon, dass er nicht mehr zurück kommt, jedoch hab ich das gar nicht so vorgehabt, ich hab mir nämlich gleich gedacht, das so etwas zu kompliziert für mich wird. Wenn du aber eine Idee hast, wie ich das umsetzen könnte, wäre ich dir dankbar, wenn du es posten würdest.
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
Nein, in diesem Fall sollte das mit ActionStartConversation nicht funktionieren, bzw. es sollte schon an sich funktionieren, aber keinen Unterschied machen.

Etwas anderes, worauf Du bei Variablennamen achten solltest, ist die Groß- und Kleinschreibung. Das solltest Du berücksichtigen, wenn Du Dir eine Variable mit einer Get-Funktion holst. Die erste Startbedingung sollte also z.B. so aussehen...

Code:
int StartingConditional()
{
    int iWaffe = GetLocalInt(GetPCSpeaker(), "waffe");
    return (iWaffe < 1);
}

...die zweite z.B. so...

Code:
int StartingConditional()
{
    int iWaffe = GetLocalInt(GetPCSpeaker(), "waffe");
    return (iWaffe == 3);
}

Übrigens brauchst Du für den ersten Ast auch überhaupt keine Startbedingung. Du mußt lediglich die Startbedingung löschen und die Positionen der beiden Äste tauschen. Dann überprüft das Programm zuerst, ob "waffe" gleich 3 ist, ist dies nicht der Fall, geht es zum nächsten Ast. Da dieser Ast nun aber keine Startbedingung hat, nimmt es diesen Ast.
Ein Ast, der keine Startbedingung hat, wird also immer genommen, sobald das Programm darauf trifft. Ein solcher Ast sollte daher immer der letzte Ast an einem Knoten sein. Damit stellt er, sozusagen, das ELSE bei einer IF-Abfrage dar, wenn Du weißt, was ich meine.
 
Zuletzt bearbeitet:

Curom

Schussel-Magier
Registriert
21.07.2000
Beiträge
1.329
Dann nächste Frage. Wird die Dialogbox geschlossen wenn der Chmied anfängt zu Hämmern?

Folgender Hintergrund. Ich habe festgestellt das Lokale Werte in Skripten erst bearbeitet werden wenn der Dialog beendet wird. Bsp. Meine Leiche sagt dem spieler das sie geplündert wurde und sollte damit den Local Wert auf 2 setzen. Solange ich dies als ein Zeilen Dialog hatte wurde dieses einfache Skript pardout nicht ausgeführt, erst als ich als Spielerantwort '"OK" beenden' angefügt habe klappte es, war kurz vorm verzweifeln.

D.h. geht dein Schmied zum Amboss um zu hämmern muß er wieder zurückkommen um dir sein Teil zu geben.

BspSkript:

void main()
{
object o1 = GetNearestObjectByTag("tisch1");
object o2 = GetObjectByTag("gefngnisschlssel1");
object o3 = GetNearestObjectByTag("Portcullis1");
ClearAllActions();
ActionPauseConversation();
ActionTakeItem(o2, o1);
ActionAttack(o1);
ActionAttack(o1);
ActionResumeConversation();
ActionMoveToObject(o3);

}

Die Kreatur soll zu einem Tisch gehen ihn angreifen und anschließend mit einem Schlüssel zurückkommen. Dabei bleibt die Dialogbox geöffnet.


(@Tingil: warscheinlich ist das Skript furchtbar falsch weil ich null Ahnung hab aber es funktioniert und das ist alles was ich brauch. ;):) )
 

Mordos

Senior Member
Registriert
05.06.2001
Beiträge
691
@Curom
Hab jetzt dein Skript ausprobiert, aber das funktioniert noch immer nicht. Der Schmied geht nun zum Amboss, hämmert darauf ein, die Dialogbox bleibt geöffnet aber nach dem hämmern funktioniert das mit dem "ActionResumeConversation" nicht und ich kann ihn auch nicht mehr ansprechen. Das Skript hab ich leicht abgeändert, da ich object o3 nicht habe. Ich häng meine Schmiede einmal hier an, vielleicht kannst du ja einmal einen Blick darauf werfen und vielleicht findest du ja meinen Fehler.

@Tingil
Danke für deine Bemühungen, aber ich es funktioniert mit meinem Skript einfach nicht, vielleicht kannst du ja auch mal in die angehängte Datei schaun, vielleicht findest du, was ich beim neuen Skript falsch gemacht habe.

Ich hab da noch eine andere Frage: Wie kann ich einen neuen Loadscreen nach NWN importieren? Ich hab schon zwei Bilder in den richtigen Größen und im TGA Format, aber ich ich kann die nirgends abspeichern. Die Loadscreens sind ja in einer .bif abgespeichert und da kann man nichts mehr hinzufügen und im NWN Viewer finde ich auch nur die Option etwas zu exportieren.
 

Curom

Schussel-Magier
Registriert
21.07.2000
Beiträge
1.329
Noch eine Erklärung zu meinem Skript.

Die funzt wie diese Sachen welche man unter 'anderes' im Dialogeditor einstellen kann. (Grüßen,Salutieren...) D.h. wenn dein Dialog erst beendet wird und dann der Schmied loslegen soll, dann funzt Resume Conversation nicht, sondern Start Conversation muß das dann glaub ich heisen. Ich muß nur erst patchen dann schau ich mal.
 

Curom

Schussel-Magier
Registriert
21.07.2000
Beiträge
1.329
Ok also es funzt. Ich häng es mal an.

Kurz gesagt was passiert.

void main()
{
object ol1 = GetObjectByTag("amboss");
object oamboss = GetNearestObjectByTag("amboss1");
object opc = GetFirstPC();
location ll1 = GetLocation(ol1);


ActionPauseConversation();
ActionAttack(oamboss);
ActionResumeConversation();
ActionForceMoveToObject(opc);
CreateObject(OBJECT_TYPE_PLACEABLE, "amboss1", ll1);
}

Hab das unsichtbare Objekt umbenannt und nicht benutzbar gemacht. Außerdem zerstörbar was anscheinend sein muß da es bei einem Mißerfolg hämmern anscheinend zu einem Abbruch des Scriptes kommt, deshalb hing es anscheinend auch immer. Nun passiert folgendes der Zwerg hämmert drauf los und zerstört nach 2-3 Schlägen das Objekt(Amboss) zufrieden kehrt er zurück und überreicht uns die Axt welche eigentlich völlig aus der Luft gezaubert wird. Anschließend wird ein neuer Amboss an die Stelle des alten gestellt und das Spiel kann von vorne losgehen.

Ist mit Sicherheit ein IKEA Skript(voll unprofessionell aber tauglich).

Wenn hier natürlich jemand eine etwas elegantere Lösung weis bitte posten. Vor allem bei diesen if or if not Murks blick ich nicht so ganz durch.
 
Zuletzt bearbeitet:

Curom

Schussel-Magier
Registriert
21.07.2000
Beiträge
1.329
Ich binn natürlich DER (schussel)Held.
Also hier der Anhang...
 

Tingil

Lord of the Links
Registriert
14.07.2000
Beiträge
7.884
@Curom: Nö, ist schon in Ordnung. Ich würde Dir nur den Tip geben, Deinen Variablen aussagekräftige Namen zu geben. Das macht die Skripte um einiges übersichtlicher. :)

@Mordos: Soll ich ehrlich sein :D? Ich hab' bei den Skripten in dem Modul überhaupt nicht durchgeblickt. Das war irgendwie wie Kraut und Rüben :rolleyes:. Ich hab' lieber alles neu geschrieben.
Ich hab' übrigens den Fehler entdeckt: Der Dialog wurde zu früh nach dem "Angriff" auf das Object angefangen. Wenn man sich noch im "Kampf" befindet, kann man nicht reden. Daher muß man den entsprechenden Befehl verzögern. Ich hab' 'mal ein Beispiel angehängt.
 
Zuletzt bearbeitet:

Mordos

Senior Member
Registriert
05.06.2001
Beiträge
691
Erst einmal DANKE das ihr beiden euch die Mühe gemacht habt, werd jetzt mal die Anhänge downloaden.

@Curom
Ob es jetzt ein IKEA Skript ist oder nicht ist ja egal, besser als meine ist es sicherlich und das reicht dann schon.

@Tingil
Wie ich schon bei meinem ersten Post geschrieben hab, ich hab keine Ahnung vom Skripten, ich hab bis jetzt alle Skripte die ich verwende nur aus dem Internet und wenn ich mal was neues brauche, wie in diesem Fall, dann versucht ich mir aus ein paar anderen Skripten was zu bauen. Aber da kommt eben nur "Kraut und Rüben" heraus. :D

Wollt nur noch einmal wegen dem Einbinden von Loadscreens nachfragen, vielleicht weiß ja doch jemand wie das geht und hat es beim letzten Post nur überlesen.
 
Zuletzt bearbeitet:
Oben