World of Gothic Archiv > NWN-Hilfe
Toolset Fragen
Seite 1 von 2  1  2 
02.06.2004, 19:12 #1
Deathlord
Beiträge: 513
Toolset Fragen
Hab ein paar Fragen zum Toolset:

1.) Wenn ich nen Gegenstand mache, kann ich dann nicht einstellen wie viel der kostet? Je nachdem wie mächtig ich ihn mache ist der Preis höher oder?

2.) Wenn ich nen eigenen Gegenstand in die Liste von einem Händler ziehe, taucht er im Spiel trotzdem nicht auf. Häh?

3.) Hat jemand ein Skript mit dem man nen NPC auf der Schmiede hämmern lassen kann?

4.) Wie kann ich Waypoints für verschiedene Kreaturen setzen? Wenn ich zwei Kreaturen habe und für jede zwei Waypoints adde, verbindet es trotzdem alle vier.

5.) Hat einer ne Liste mit den Bedeutungen der Bedingungen für das Aufrufen eines Skripts bei NPCs (OnHeartbeat etc.)?

Danke schon mal.
02.06.2004, 19:42 #2
Alamar
Beiträge: 4.050

Bin zwar kein Toolset Genie, aber das müßte ich hinbekommen.

1. Ist AFAIK nicht möglich, wenn du einen besonderen Gegenstand zu einem besonderen Preis verkaufen willst, mach das per Gespräch.

2. Wie meinst du das? Welche 'Liste'? Du mußt ein Geschäft erstellen, und einen NPC damit Verknüpfen (im Gespräch per weitere Aktion das Geschäft auswählen). In den Eigenschaften des Geschäfts mußte auf 'Gepäck' klicken und dort reinlegen, was du verkaufen willst.

3. Wenn du HotU hast, kannst du dir den Schmied in Tiefwasser ansehen, wenn nicht, hier ist sein Script:

Beim Schmied 'On Heartbeat'

code\:
void main()
{
object oAnvil = GetNearestObjectByTag("townanvil");
if (GetIsObjectValid(oAnvil) == TRUE && IsInConversation(OBJECT_SELF) == FALSE && GetIsInCombat(OBJECT_SELF) == FALSE)
{
DelayCommand(1.5, (ClearAllActions(TRUE)));
ActionAttack(oAnvil);
}
}


Der Amboss bzw der Gegenstand, auf den gehämmert wird, muss die Kennzeichnung 'townanvil' tragen.

4. Klar geht das. Du mußt halt darauf achten, dass beide Kreaturen verschiedene Kennzeichnungen haben. Wenn sie beide die gleiche Kennzeichnung haben, heißen die Wegpunkte auch gleich und daher werden sie verbunden, bzw alle Kreaturen auf dieser Karte benutzen sie.

5. Vieles erklärt sich ja von selbst.

OnBlocked - Wenn der NPC bei seiner Aktion blockiert wird, du ihm z.b. in den Weg rennst (glaub ich!)
OnCombatRoundEnd - Was er macht wenn eine Kampfrunde endet (sind Afaik 6 Spielsekunden)
OnConversation - Was er macht wenn er angesprochen wird.
OnDamaged - Was er macht, wenn er verletzt wurde.
OnDeath - Was er macht, wenn er stirbt.
OnDisturbed - Was er macht, wenn er bei seiner Aktion gestört wird (z.b. durch Ansprechen)
OnHeartbeat - Herzschlag. Was also im Sekundentakt immer wiederholt werden soll (wie z.b. oben das hämmern).
OnPerception - Was er macht, wenn er dich bemerkt (Glaube ich!!)
OnPhysicalAttacked - Was er macht, wenn er physisch angegriffen wird.
OnRested - Was er nach (d)einer Rast macht (Glaube ich!!)
OnSpawn - Was er macht, wenn er spawnt, sprich: Wenn er im Spielgeschehen auftaucht, indem er zum ersten Mal vom Spieler gesehen wird.
OnSpellCastAt - Was er macht, wenn er das Ziel eines Zaubers wurde.
OnUserDefined - Hier kannst du selbst noch was scripten, was nicht in die anderen Gruppen gehört.
03.06.2004, 17:43 #3
Deathlord
Beiträge: 513

Hmm vielen Dank. Komisch hab gar keine Bestätigungsmail gekriegt. Egal. Wenn ich noch weitere Fragen hab poste ich hier wieder rein.
09.06.2004, 18:39 #4
Deathlord
Beiträge: 513

Moinsen! Ich habe noch ein paar Fragen an unsere Skript-Profis. Könntet ihr mir folgende Skripts geben:

1.) Die Kreatur/Der NPC spricht mich an sobald er mich bemerkt. (muss afaik bei OnPerception rein oder ?)

2.) Ok ist kein Skript aber wie kann ich verhindern dass NPCs an jedem Waypoint kurz warten bevor sie weitergehen?

3.) Wie kann ich generell in einem Skript den player (PC?) ansprechen? mit oPlayer oder wie? Und wo muss das hin? Wenn ich ein neues Skript mache, kralle ich mir von rechts aus der Liste z.B eine Aktion und wo füge ich dann das "Objekt" ein, dass die Aktion ausführt? Ich muss da immer den Namen der Kreatur nehmen (also die Bezeichnung oder wie das heißt) oder?

4.) Noch was generelles. Kann jemand ein paar "Grundregeln" fürs Skripten auflisten oder verlinken? Also z.B ;nach Anweisungen etc. Eine if-then-else Entscheidung wär auch hilfreich (kann ich halt in c++ net)

Danke schonmal. Ich hoffe ich langweile euch mit den Fragen nicht.

Gr33tz Deathlord
09.06.2004, 19:46 #5
Kardor
Beiträge: 523

OK! :D

quote:
1.) Die Kreatur/Der NPC spricht mich an sobald er mich bemerkt. (muss afaik bei OnPerception rein oder ?)


Jupp. Zumindest ist es so am einfachsten, Bioware hätte zwar gerne das man nur den OnUserDefined Slot für eigene Scripts nimmt, aber warum bieten sie einem dann die vielen praktischen Slots an? :D

So ein Script gibt es natürlich schon tausendmal, aber ich machs mal recht ausführlich und mit Kommentaren, um deine Frage 3) gleich noch bisschen zu beantworten.

Vorab ein paar grundsätzliche Dinge zum Skript-Editor, die imho seeehr hilfreich sind:

Erstelle zur Übung mal ein neues Scipt, im Hauptfenster steht momentan nur:

code\:

void main()
{

}



rechts vom eigentlichen Script gibt es einen Filter mit 4 Buttons: Funktionen, Variablen, Konstanten und Schablonen.

Für dich interessant dürften momentan vor allem die Buttons Funktionen und Konstanten sein.

Wenn du etwas bestimmtes machen möchtest und du kennst nicht den richtigen Befehl dazu, dann gib mal das entsprechende Wort in das Filter-Feld.
Du möchtest dafür sorgen, dass der Spieler angesprochen wird, also gib in den Filter das Wort "Conversation" ein.

Es werden alle Funktionen ausgespuckt, die das Wort Conversation beinhalten in diesem Fall:
code\:

ActionPauseConversation
ActionResumeConversation
ActionStartConversation
BeginConversation
EventConversation
IsInConversation
SpeakOneLinerConversation



Markiere mit der Maus eine der Funktionen, z.B.
ActionStartConversation, dann erscheint unter dem Scriptfenster in grüner Schrift eine kurze , meist recht hilfreiche Beschreibung. In unserem Fall dürfte da stehen:
code\:

// Starts a conversation with oObjectToConverseWith - this will cause their
// OnDialog event to fire.
// - oObjectToConverseWith
// - sDialogResRef: If this is blank, the creature's own dialogue file will be used
// - bPrivateConversation
// Turn off bPlayHello if you don't want the initial greeting to play


Unter der Beschreibung ist ein Beispiel aufgeführt, wie die Funktion auszusehn hat:
code\:

void ActionStartConversation(object oObjectToConverseWith, string sDialogResRef="", int bPrivateConversation=FALSE, int bPlayHello=TRUE)


die einzelnen Punkte was was ist werden ja in der Beschreibung erklärt.
Am einfachsten ist es, du machst einen Doppelklick auf die Beispielzeile, dann steht die ohne Rechtschreibfehler in deinem Script.

So und dann ersetzt du nach und nach die
Beispielparameter durch deine eigenen ( das Wort "Void" am Anfang der Beispielzeile löschst du.

Dabei musst du dir klar machen, dass ein Script erstmal nicht weiss was in einem anderen steht. So ist z.B. oPlayer nur der Name einer Variable, solange du diese aber in deinem Script noch nicht Initalisiert hast , sprich dem Programm nicht erklärt hast
wer denn nun genau oPlayer sein soll, kennt es diesen nicht und wird dir ne Fehlermeldung ausgeben.

Ich würde noch mehr schreiben, aber ich hab grad Besuch bekommen....für die Zwischenzeit empfehle ich dir unbedingt dieses Tutorial hier mal zu machen:

http://www.neverwinternights.de/tut...s_lektionen.php

Wenn du danach noch Fragen hast, einfach posten.


___________________________

Pilze Band I - das NWN Modul ;)
Niemand hat die Absicht eine Mauer zu baun. Außer uns!
[/font]
09.06.2004, 23:51 #6
$tormRider
Beiträge: 208

Ein gutes Tutorial ist auch das hier
Hab mit dem auch das scripten gelernt(und dank Hoellenbestie wieder gefunden :) )

Zu 2). Warum lässt du ihn nicht gleich zum letzen Wegpunkt laufen?

Zu 1).
code\:
void main()
{
object oPC = GetLastPerceived(); //Hier legst du fest, dass das Objekt oPC die Person sein soll,
die der NPC zuletzt gesehen hat. Bei Einzelspielermodulen kannst
du auch GetFirstPC() oder GetNextPC() nehmen.
if(GetIsPC(oPC)) //Hier wird überprüft, ob das Objekt oPC wirklich der Spieler ist.
Falls ja dann spricht er ihn an. Wenn nicht(else) dann passiert hier gar nichts.
Die Überprüfung ist unnötig wenn du oben GetNextPC() oder GetFirstPC() benutzt hast.
Die Überprüfung brauchst du eigentlich nicht immer, aber bei manchmal können damit ganz lustige Sachen passieren.
{
ActionStartConversation(oPC); //Hier wird oPC angesprochen.
}
}

10.06.2004, 00:08 #7
Alamar
Beiträge: 4.050

quote:
Zitat von $tormRider
Zu 2). Warum lässt du ihn nicht gleich zum letzen Wegpunkt laufen?



1. Weil der NPC vielleicht einen bestimmten Weg gehen soll und nicht z.b. über Blumenbeete trampeln darf.

2. Weil selbst an diesen zwei Endpunkten der NPC ne kurze Verschnaufspause macht.
10.06.2004, 11:56 #8
Kardor
Beiträge: 523

also das mit der Verschnaufpause nervt mich auch, ist aber nicht so leicht abzustellen.

Es sei denn man schreibt ein eigenes WalkWaypoint-Script, aber selbst dann...man muss ja regeln wie oft abgefragt wird, dass der NPC zum nächsten WP läuft und das geschieht i.d.R über den Heartbeatcase der aber nur alle 6 Sekunden ausgelöst wird.
Genau diese 6 Sekunden sind die Verzögerung, die man sieht.
10.06.2004, 18:15 #9
Deathlord
Beiträge: 513

Danke@all. Ist echt nett dass ihr euch so gut um die "Frager" kümmert.
Ich werd mir jetzt mal euere posts genauer ansehen und mir die verlinkten tuts reinziehen.
Nur noch eine Frage:
Wie kann ich im Gesprächst Editor ein "weiter" bei einem text vom npc einbauen, also dass das gespräch verteilt wird?
Deathlord
10.06.2004, 18:20 #10
Alamar
Beiträge: 4.050

Musst einen leeren Spielertext einfügen.

Beispiel:

NPC: Bla bla...
Spieler:
NPC: ...bla bla!

Die leere Antwort wird im Spiel dann durch 'weiter' ersetzt.
10.06.2004, 19:20 #11
$tormRider
Beiträge: 208

Nochmal zu den Pausen an den Wegpunkten.
Das Script bei On Spawn einfügen:
code\:
void main()
{
object oWP1 = GetObjectByTag("tag des ersten wps");
object oWP2 = GetObjectByTag("tag des zweiten wps");
object oWP3 = GetObjectByTag("tag des dritten wps");

int nCounter;
float fTime;


while(fTime >= 0.0)
{
switch(nCounter)
{
case 0:
DelayCommand(fTime, ActionForceMoveToObject(oWP2));
fTime = fTime + 1.0; //für 1.0 die zeit, die der NPC von WP1 zu WP2 braucht
nCounter = 1;
break;

case 1:
DelayCommand(fTime, ActionForceMoveToObject(oWP3));
fTime = fTime + 1.0; // Zeit von WP2 zu WP3
nCounter = 2;
break;

case 2:
DelayCommand(fTime, ActionForceMoveToObject(oWP2));
fTime = fTime + 1.0; //von WP3 zu WP2
nCounter = 3;
break;

case 3:
DelayCommand(fTime, ActionForceMoveToObject(oWP1));
fTime = fTime + 1.0; //von WP2 zu WP1
nCounter = 0;
break;
}
}
}


Während des Spiels kommt aber ein Hinweis, dass der NPC zu viele Aktionen hat, was dazu führt, dass das Spiel fürchterlich ruckelt. Naja, aber es ist wenigstens ein Anfang :D
btw. könnte es nicht sein, dass während dieser Pause der Weg zum nächsten Wegpunkt berechnet wird?
10.06.2004, 19:38 #12
Kardor
Beiträge: 523

@$tormRider

die idee mit der while Schleife hatte ich auch schon, aber wie es scheint reagiert NWN allergisch auf Scripts , die "die ganze Zeit" laufen, dann passiert genau das was dir passiert ist, es kommt die Fehlermeldung "zu viele Befehle..."

Es scheint, der kürzeste Zeitrahmen ein Script erneut zu starten sind die 6 Sekunden des Heartbeat-Falls, was einem nicht wirklich weiter hilft, da das auch die maximale "Verschnaufspause" der NPCs an den Wypoints ist.
11.06.2004, 09:46 #13
Deathlord
Beiträge: 513

Wie kann man den Char mit einem Gegenstand sprechen lassen? Also z.B. Gespräch:"Dies ist ein Schild... bla bla bla"
Ich muss den Gegenstand benutzbar machen, Hanlung ankreuzen, und bei OnUsed ein Skript einfügen dass die Konversation startet?
Bin aber (noch!) nicht fähig es selber zu schreiben, und in der Kampagne finde ichs nicht.
Bei einem NPC kann ich auch nicht das aus OnConversation nehmen.
11.06.2004, 10:29 #14
Kardor
Beiträge: 523

Mach den Gegenstand benutzbar, gib ihm ein
Gespräch und unter OnUsed fügst du einfach folgendes Script ein:

code\:

void main()
{
ActionStartConversation(GetLastUsedBy());
}



___________________________

Pilze Band I - das NWN Modul ;)
Niemand hat die Absicht eine Mauer zu baun. Außer uns!
[/font]
11.06.2004, 10:54 #15
Deathlord
Beiträge: 513

Danke!

Schau dir mal an was ich bisher produziert hatte:D :
OK ich weiß dass dieses Skript falsch ist, aber vielleicht hab ich ja irgenwas richtig interpretiert?

void main()
{
object oUser=GetLastUsedBy /*oUser ist derjenige der das Skript ausgelöst hat (ist ja bei OnUsed drin) */

ActionStartConversation(oUser, sDialogResRef="mein_Gespräch", /*der erste legt fest dass mit oUser geredet wird, sDialogResRef legt fest dass das Gespräch "mein_Gespräch" benutzt wird */
int bPrivateConversation=FALSE, /*kann ich nichts mit anfangen */
int bPrivateConversation=FALSE) /*keine Hello-Animation?*/
}

Das hier produziert immer die Fehlermeldung:"FEHLER: KEINE LINKE KLAMMER IN ARG-LISTE"

Ich hoffe man kann den Post hier verstehen:D
11.06.2004, 11:16 #16
$tormRider
Beiträge: 208

Naja so falsch ist es ja nicht :D

object oUser = GetLastUsedBy();

die Klammern müssen eigentlich immer hin, auch wenn nichts drinsteht, außerdem muss man ende jeder funktion ein ; stehen.

ActionStartConversation(oUser, "mein_Gespräch", FALSE, FALSE);

Das sDialogResRef, bPrivateConversation und bPlayHello kannst(bzw muss :D) du weglassen. Die stehen eigentlich nur zur Hilfe da. bPrivateConversatione bedeutet, ob das Gespräch nur zwischen dem PC und dem NPC stattfinden soll oder ob es auch alle andere Spieler "hören" können(also irgendwas für multiplayer :D). Außerdem hat wieder der ; hinter der Klammer gefehlt.
11.06.2004, 11:34 #17
Deathlord
Beiträge: 513

Danke:D
Verdammt, diese Klammern und das Semikolon... Kann sich das Aurora nicht einfach dazudenken...:D
Das Skript von Kardor funktioniert perfekt, außer bei ner Tür, da will ich die Conversation wenn sie nicht aufgeht, bzw. wenn sie aufgeht. Muss da woanders rein oder? (OnFailToOpen oder so bzw. in OnOpen glaub ich, aber es geht net.) Egal, ich probier dann noch ein bischen rum. Freut euch schon mal auf die nächste Frage;)
11.06.2004, 11:55 #18
$tormRider
Beiträge: 208

Wenn die Tür die ansprechen soll, wenn du die tür öffnest muss es so heißen:
code\:
void main()
{
ActionStartConversation(GetLastOpenedBy()); //Also jetzt wird der angesprochen, der die Tür als letztes geöffnet hat
}


Das Skript muss dann bei On Open eingefügt werden.
11.06.2004, 12:57 #19
Deathlord
Beiträge: 513

Ach so! Stimmt. *versteh* Ich hatte nicht dran gedacht dass man dann ja nicht GetLastUsedBy nehmen darf, weil das nicht zutrifft. Danke, da hätte ich auch selber drauf kommen können.
11.06.2004, 14:27 #20
Deathlord
Beiträge: 513

So, noch ne Frage, so langsam wird das ja schon eine Goldgrube für andere Newbies im Skripten.

So kann ich ja die Variable "COUNTER" auf 10 setten, aber nur bezogen auf OBJECT_SELF, wenn ich ein anderes gültiges Objekt nehme, das es im Modul gibt, kommt aber eine Fehlermeldung. Wie kann das sein? Mann müsste doch eigentlich auf ein beliebiges Objekt verweisen können.
Normalerweise packt man so was ja in OnSpawn rein, für einen Anfangszustand, aber diese Variable soll sich auf eine Türe beziehen, und die hat kein OnSpawn, also nehme ich einfach das Gebiet mit OnEnter. Aber ich kann nicht auf die Türe verweisen, sondern nur auf OBJECT_SELF, also auf das Gebiet.

void main()
{
SetLocalInt(OBJECT_SELF, "COUNTER", 10);
}

So! Dieses Script stimmt aber jetzt!:D :D
11.06.2004, 16:04 #21
Kardor
Beiträge: 523

doch du kannst natürlich auch auf andere Objekte verweisen, du musst sie nur richtig an das Programm übergeben.

Eine solche Übergabe sieht z.B. so aus:
code\:

object oDoor = GetObjectByTag("KennzeichenDesObjekts");



danach kannst du den Variablennamen oDoor im selben Script als Objektnamen weiter verwenden, also z.B so :

code\:

SetLocalInt(oDoor, "COUNTER", 10);



@Semikoli ( äh..oder wie ist die korrekte Mehrzahl? :D ) und Klammern:
Am Anfang hat mich die C# - Syntax auch wahnsinnig gemacht, vor allem wenn man vorher nur irgendwelche BASIC- artigen Sprachen gewohnt war, aber man gewöhnt sich dran und mit der Zeit merkt man, dass die Sprache mächtige Vorteile bietet.


___________________________

Pilze Band I - das NWN Modul ;)
Niemand hat die Absicht eine Mauer zu baun. Außer uns!
[/font]
11.06.2004, 16:05 #22
$tormRider
Beiträge: 208

code\:
void main()
{
SetLocalInt(GetObjectByTag("Kennzeichnung der Tür"), "COUNTER", 10);
}


Abrufen kannst du sie dann wieder mit
GetLocalInt(GetObjectByTag("Kennzeichnung der Tür"), "COUNTER");

Mit OBJECT_SELF würdest du dich in diesem Fall auf das Gebiet, dass gerade betreten wird beziehen.

Außerdem solltest du mit On Enter vorsichtig sein, weil in diesem Fall die Variable immer, wenn irgendjemand(nicht nur der Spieler) das Gebiet betritt, auf 10 gesetzt wird.
12.06.2004, 10:23 #23
Deathlord
Beiträge: 513

Bei OnOpen nimmt man z.B GetLastOpenedBy() um auf den Spieler zu verweisen der das Objekt geöffnet hat, oder bei OnLock GetLastLockedBy() usw.
Aber bei OnFailToOpen habe ich nichts dergleichen gefunden. Wie kann ich dann (oder generell in solchen Fällen) auf den Spieler verweisen der etwas getan hat?
12.06.2004, 11:22 #24
Kardor
Beiträge: 523

hmmm GetLastUsedBy sollte da eigentlich auch funktionieren
12.06.2004, 11:29 #25
$tormRider
Beiträge: 208

In dem Fall brauchst du GetClickingObject() (Also der, der als letztes auf die Tür geklickt hat)

Schau mal hier , ist ganz nützlich ;)

Edit: GetLastUsedBy() funktioniert nicht.
Seite 1 von 2  1  2