Construction Set Der Scriptthread

geht das nicht irgendwie anders...:huh:

das problem ist das:
falls ich den NPC noch nicht auf das topic angesprochen hab (wo ein neuer jornal entry gesetzt wird) und/oder den dialog beende redet der mich wieder an.., das sollte er aber nur einmal machen.
und wenn ich gleich ein neues jornal entry setze in dem greeting, dann siehe 2. problem.

ein anderes problem ist:
wenn ich ihn auf das topic anspreche und ich den dialog dann beende teleportiert der NPC weg..., und ich bekomme sofort das neue das neue greeting..., was ich erst bekommen sollte wenn ich in der zelle bin wo der NPC hin teleportiert ist.

ty
 
Also wenn ich dich richtig verstehe, willst du folgendes haben:

  1. Spieler mit entsprechendem Tagebucheintrag kommt dem NPC nahe
  2. NPC spricht ihn an, das löst neuen Tagebucheintrag aus
  3. Spieler entfernt sich vom NPC und kommt irgendwann wieder nahe
  4. NPC spricht ihn wieder an, das löst neuen Tagebucheintrag aus
  5. (wiederhole Schritt 3&4 beliebig oft)
  6. Spieler beendet Gespräch
  7. NPC teleportiert sich weg

:?:
 
genau.., naja fast.. ;)

zu 2: der npc spricht mich an.., der journal entry wird aber durch nen topic gesetzt nich durch das jeweilige greeting.

zu 3: auf das topic angesprochen wird der npc teleportiert.., via goodbye und startscript plus neuer journal entry.

und wenn ich den dialog beende.., ohne den npc nach dem topic gefragt zu haben spricht er mich immer wieder an..., könnte den neuen journal entry auch in dem greeting setzen..., wollte ich aber nicht unbedingt..., so ich kann mehr schreiben etc..
 
Du könntest auch aus einem Greeting mit einer Choice mit nur einer Antwortmöglichkeit einen beliebig langen Text bauen ;)

Aber was du suchst sieht dann etwa so aus, das andere ist dann viel zu kompliziert:

Code:
begin my_script

if ( MenuMode == 1 )
  return
endif

if ( GetJournalIndex, "my_topic" == 10 )
  if ( Get Distance, Player < 128 ) 
    ForceGreeting
  endif
endif

end

Wenn zwischen den Ansprachen jeweils eine Sekunde liegen soll, wird es nicht viel komplizierter:

Code:
begin my_script

float timer
short doonce

if ( MenuMode == 1 )
  return
endif

if ( doonce == 0 )
  if ( GetJournalIndex, "my_topic" == 10 )
    if ( Get Distance, Player < 128 ) 
      ForceGreeting
      set doonce to 1
    endif
  endif
else
  set timer to timer + GetSecondsPassed
  if ( timer > 1 ) 
    set doonce to 0
    set timer to 0
  endif
endif

end
 
Zuletzt bearbeitet:
das heißt ich könnte das erste script mit einer zusätzliche journal abfrage (oder mehreren) machen...?

Klar, warum nicht?

In dem Fall würde ich dann zwar ggf. die Ebenen der beiden if-Abfragen vertauschen, aber das ist ja egal. Du kannst 127 if-Abfragen in einem Script verwenden. Erst die 128. macht Probleme (die danach geht dann glaube ich wieder ;))
 
  • Like
Reaktionen: VDMap
Hallöchen,

ich hätte mal wieder eine Frage zu einem Skript. Das Skript soll folgendes machen: Nach Aktivierung eines Activators soll ein bestimmter Gegenstand, den der Spieler im Inventar hat, entfernt und an einer bestimmten Stelle in der gleichen Interiorzelle in einer bestimmten Position positioniert werden.

Mein Versuch sieht wie folgt aus (und klappt natürlich mal wieder nicht):
Begin script

if ( MenuMode == 1 )
return​
endif


if ( OnActivate = 1 )
if ( player->GetItemCount "Object ID" >= 1)​
Player->RemoveItem "Object ID" 1
PlaceItem "Object ID", 2230, 4441, 15885, 180
"Object ID"->SetAngle, Y, 270
endif​
endif

end

Kann es vielleicht daran liegen, dass das Objekt evtl. nicht references persist ist?
 
Kann es vielleicht daran liegen, dass das Objekt evtl. nicht references persist ist?
Ja.

Und selbst wenn du es RefPersist machst, wird es nicht richtig arbeiten, weil du zwei Referenzen installierst... Nummer 1 im Inventar (wird zerstört) und Nummer 2, was platziert würde. Idealerweise sollte man bei solch einer Konstellation folgermaßen vorgehen:

1. du erstellst das Item zweimal, eines trägt ein Script und ist RefPersist (ObjectID_uni), das andere ist zum Rumtragen
2. das Item mit dem Script kommt fertig rotiert an den Ort, wo es durch das Aktivator-Script platziert werden soll. Dann kriegt es dieses Script:

Code:
begin ObjectID_uni_sc
Short DoOnce

IF ( DoOnce == 0 )
  set DoOnce to 1
  disable
ElseIF ( DoOnce == 2 )
  Enable
  set DoOnce to 3
ElseIF ( DoOnce == 3 )
  IF ( OnActivate )
    Player->AddItem "ObjectID" 1
    set DoOnce to 1
    Disable
  EndIF
EndIF

end

Dein Aktivator kriegt danach dieses Script:

Code:
begin Activator_sc

IF ( MenuMode )
  return
ElseIF ( OnActivate == 1 )
  IF ( ( Player->GetItemCount "ObjectID" ) > 0 )
    set ObjectID_uni.DoOnce to 2
    Player->RemoveItem "ObjectID" 1
  Else
    MessageBox "Euch fehlt der richtige Gegenstand."
  EndIF
EndIF

end
Müsste eigentlich funktionieren.
 
Dein Aktivator kriegt danach dieses Script:

Code:
begin Activator_sc

IF ( MenuMode )
  return
ElseIF ( OnActivate == 1 )
  IF ( ( Player->GetItemCount "ObjectID" ) > 0 )
    [COLOR=#ff0000][B]set ObjectID_uni.DoOnce to 2[/B][/COLOR]
    Player->RemoveItem "ObjectID" 1
  Else
    MessageBox "Euch fehlt der richtige Gegenstand."
  EndIF
EndIF

end
Müsste eigentlich funktionieren.

Bei der markierten Textzeile meckert das CS. Ich gehe davon aus, dass ich den genauen Scriptname, welches auf dem zu erscheinenden Objekt liegt, mit .DoOnce verwenden muss. Habe ich auch gemacht und bekomme die Meldung, dass er die Variable aus der Zeile nicht kennt.
 
Zuletzt bearbeitet:
Bei der markierten Textzeile meckert das CS. Ich gehe davon aus, dass ich den genauen Scriptname, welches auf dem zu erscheinenden Objekt liegt, mit .DoOnce verwenden muss. Habe ich auch gemacht und bekomme die Meldung, dass er die Variable aus der Zeile nicht kennt.
Nein, nicht den Scriptnamen. Die Objekt ID. Du musst aber die Reihenfolge einhalten;
Erst das RefPersist Objekt erstellen, dann das Script für dieses Objekt erstellen und verlinken - die Variable DoOnce muss deklariert sein. Dann das Objekt in der Interior platzieren. Erst dann kann das Aktivator Script sauber kompiliert werden.
 
  • Like
Reaktionen: Lyali
Hey, ich würd mich wieder mal über eure Hilfe freuen.
Irgendwie glaub ich verwende ich DoOnce und die GetCurrenAI funktion falsch und nach dem 7. Anlauf weiß funktionierts immer noch nicht so wie ich will.
Sinn des Scripts wäre es, ein Skelett nur dann erscheinen zu lassen, wenn ein bestimmter NPC dem Spieler folgt und mit dem Tod einen Journaleintrag auszulösen.
Inzwischen habe ich alle Stadien durch, Skelett erscheint zu früh, erscheint gar nicht, der Tod wird nicht detektet etc.
Code:
begin "FR_SH_Skl9q_Skelettscr"


Short Doonce

if DoOnce == 2
    return
elseif DoOnce == 1
    if ( GetDeadCount, "FR_SH_Skl9q_Skelett" >= 1 )
        Journal "FR_SH_Skl9_j" 2
        Set DoOnce to 2
    endif
elseIf Doonce == 0
        "FR_SH_Skl9q_Skelett"->disable
    if  ("FR_SH_Sklave9"->GetCurrentAIPackage == 3)
        Set Doonce to 1
        "FR_SH_Skl9q_Skelett"->enable
    endif
endif

end
 
Irgendwie glaub ich verwende ich DoOnce und die GetCurrenAI funktion falsch...
Ohne Gewähr, da ich mit den AI-Funktionen nie wirklich gearbeitet hab und mein Morrowind-Scripthandbuch grad nicht zur Stelle ist. Versuch das hier:

Code:
begin "FR_SH_Skl9q_Skelettscr"
Short DoOnce

IF ( GetDisabled )
	IF ( "FR_SH_Sklave9"->GetCurrentAIPackage == 3 )
		set DoOnce to 1
		Enable
	EndIF
	return
ElseIF ( DoOnce <= 0 )
	IF ( DoOnce == 0 )
		Disable
	EndIF
	return
EndIF

IF ( GetHealth <= 0 )
	Journal "FR_SH_Skl9_j" 2
	Set DoOnce to -1
EndIF

end
 
  • Like
Reaktionen: Freelancer_T
Wenn das Skelett nicht sichtbar wird, ist diese Zeile:

IF ( "FR_SH_Sklave9"->GetCurrentAIPackage == 3 )

das Problem. Das Script ist ansonsten aber einwandfrei und müsste daher auch funktionieren. Das bedeutet, entweder funktioniert GetCurrentAIPackage nicht in diesem Zusammenhang, der Indexwert 3 ist falsch oder der NPC nutzt statt Follow das Escort, Travel oder sonstein Package. Ich würde das sowieso anders lösen, da ich AI Funktionien in Morrowind nicht weiter traue, als ich meinen Rechner werfen kann.

Lösung:
Gib dem Sklaven ein Script, wenn er nicht ohnehin eines hat. In diesem Script deklarierst du eine Variable und setzt folgenden Codeblock - wenn schon ein Script existiert, pack meinen Kram einfach dazu, ganz nach oben:

Code:
begin SlaveScriptName_scr
short IsInJail

If ( GetPCCell "ID der Zelle wo das Skelett steht" == 1 )
	set IsInJail to 1
Else
	set IsInJail to 0
EndIF
end
Und dann ersetzt du in dem Script des Skelettes die obige rote Zeile durch diese:

IF ( "FR_SH_Sklave9".IsInJail == 1 )

In diesem Fall würde das Skelett erstmal disabled. Wenn du ohne den Sklaven in die Zelle mit dem Skelett gehst, passiert gar nichts. Wenn du mit dem Sklaven hinein gehst, erkennt der Sklave, daß der Spieler in der Zelle ist - da das Script auf dem Sklaven nur läuft, wenn er und der Spieler in der gleichen Zelle ist, muss er dann folglich auch in dieser Zelle sein und setzt seine Variable auf 1. Und genau diese Variable fragt das Skelett dann ab. Sie kann nur 1 sein, wenn sowohl der Spieler als auch der Sklave in der Zelle mit dem Skelett sind. Und dann wird es aktiviert.

Das funktioniert allerdings nur, wenn dein Sklave nicht schon von Anfang an in der gleichen Zelle wie das Skelett steht. In dem Fall müsste eine andere Lösung her, aber die könnte ich erst konzipieren, wenn ich Informationen über die Sachlage in der Mod habe. Eine kleine, grobe Questbeschreibung.
 
  • Like
Reaktionen: Freelancer_T
Meine tiefste ehrerbietung. Das ist genial. Da das Skelett in einer anderen Zelle steht, ist diese Lösung ideal und ich kann an der Originalstoryline festhalten.^^
Hatte inzwischen versucht es über die Dialogresultbox zu machen. Das hätte auch funktioniert, aber das hier gefällt mir besser.
EDIT: Anmerkung, es funktioniert nur, wenn man IsinJail als Global setzt^^
 
Zuletzt bearbeitet:
Hallo zusammen, habe mal wieder ein kleines Skript-Problem.

Ich möchte eine Tasche erstellen, die ich anziehen kann (als Rüstungsteil), bei einer Abfrage aber auch einen Container öffnen kann. Hier mal das Skript:
Begin _ly_bag_carry

Short button
Short status
Short OnPCEquip

if ( OnPCEquip ==1 )
MessageBox, "Was soll getan werden?", "Rucksack anziehen", "Rucksack öffnen"​
Set OnPCEquip to 0​
Set status to 1​
Endif

If ( status == 1)
Set button to GetButtonPressed​

If ( button == -1 )​
return
Elseif ( button == 0 )​
Set status to 0
Elseif ( button == 1 )​
"LY_bag_carry_01"->Activate, player
Set status to 0
Endif
Endif

End

Ich habe erst den Container erstellt (References Persist), in der Zelle ToddTest platziert, das Skript geschrieben und gespeichert und dann das Rüstungsteil erstellt (ohne References Persist). Beim Anziehen kommt die Abfrage, das Anziehen klappt auch nur der Container öffnet sich nicht. Über Hilfe würde ich mich freuen.

PS: Als esm-Abhängigkeit habe ich Morrowind und Tribunal
 
Wenn ich mich richtig erinnere, muss sich der Container in der gleichen Zelle wie der Spieler befinden. Es gab da auf jeden Fall sehr massive Einschränkungen.

In einem meiner Plugins (Magischer Zirkel) habe ich so etwas ähnliches gemacht (ein magischer Hut, in dem Gegenstände verschwinden können, frei nach HP :p) und dort habe ich es so gelöst, dass der Container ein NPC mit Begleiterstatus war, auf dessen Inventar ich über ForceGreeting und dann den Teilen-Befehl zugreifen konnte.
 
Wenn es nur die Sache mit der gleiche Zelle wäre... es ist viel viel schlimmer. Meine Rat - vergiss es. Ohne Script-Extender ist dieser Sch... so dermaßen verbuggt, daß einem die Haare ergrauen, wenn man das zum Laufen bringen will.

Um nur mal einen Stolperstein zu nennen: Der Spielercharakter muss in der gleiche Zelle gewesen sein und den Container manuell geöffnet haben. Jedes Mal, wenn das Spiel geladen wird bzw. jedes Mal wenn 72 ingame Stunden vergangen sind. Viel Spaß beim Prüfen.
 
Ok, schade eigentlich. Die Idee eines solchen Containers hat sich in SfD 9 so wunderbar einfach angehört. Trotzdem danke für eure Hilfe.