Skriptthread zum Creation Kit

@ Drakons: Ich würde eine Dummy-Cell erstellen (Zelle mit nichts drin) und dann darin einen Container reinstellen. Diesem wird dann durch removeItem das Item hinzugefügt und Du entfernst es dann wieder vom Container. Wenn das alles im OnEquipped-Event wieder zu einem einmaligen Skriptstart führt, probiere mal, ob ein OnItemAdded-Event mit removeItem (Spieler als Ziel) auf dem Container funktioniert.
 
Beide Varianten entfernen das Item. Im Menü erscheint es jedoch erst wieder nachdem man das Menü einmal geschlossen und wieder geöffnet hat.
Zuschade dass ich nur Möglichkeiten kenne das Menü zu schließen, nicht es erneut zu öffnen.

Edit:
Folgendes funktioniert!

- Ein DummyItem erstellen ohne Namen, Modell oder sonstwas, welches den selben Typ hat wie das zu überprüfende Item (In diesem Fall ne EH-Waffe)

Im Skript: Wenn das Item abgelegt werden soll: Es unequippen, DummyItem adden, equippen und sofort wieder entfernen.
Geht beliebig oft, funktioniert und es ist kein Grafikfehler zu sichten.

Nachteile der Methode:
- Wahrscheinlich recht großer Aufwand für so ein Feature
- Waffen und Rüstungen müssen getrennte Skripte haben
- Falls der Spieler in der rechten Hand ein Item hält und das "unanlegbare" Item links anzieht, werden beide Items abgelegt, in allen anderen Fällen wird nur das "unanlegbare" Item abgelegt

Falls wer ne bessere Idee hat trotzdem immer raus damit :D
Und was mich interessiert: Bei Remove- und AddItem liegt das Problem hieran: ich hole mir testweise das BaseItem:
Form tmpItem = Self.GetBaseObject() und gebe es dann mit Debug.Notification(tmpItem) aus.
Beim ersten Aufruf klappt immer alles und es wird "[Form" ausgegeben. Danach nur noch "None", aka: Das Item scheint überhaupt keinen funktionablen Referenzwert mehr zu besitzen :/
 
Zuletzt bearbeitet:
Hallo,

ich habe ein Skript erstellt, das testet, ob der Spieler einen oder mehrere bestimmte Gegenstände im Inventar hat. Funktioniert auch einwandfrei. Jetzt stehe ich vor folgendem Problem: ich würde z.B. gerne testen, ob der Spieler einen Daedra-Bogen im Inventar hat; hierbei ist es vollkommen egal, um welchen es sich handelt. Ich könnte jetzt natürlich für jeden (verzauberten) Daedra-Bogen die passende ID aus dem CK im Skript abfragen, was aber wohl etwas übertrieben ist. Kann ich das Problem auch mit einer FormList angehen? Wenn ja, wie kann ich das realisieren?

Gruß, mde.
 
Hmm, Keywords hört sich nicht schlecht an, aber dann müsste ich ja jedes Teil aus dem Inventar nach dem passenden Keyword testen oder nicht ?
 
Das musst Du mit einer FormList genauso machen (abfragen, ob es in der FormList vorhanden ist). Der Unterschied ist bloß, dass die Keywords bereits zugewiesen sind und Du die FormLists erst erstellen musst.
 
Ich suche ein Skript, das folgendes kann:

Man stelle sich vor, man reise durch einen Dungeon, töte mehrere Monster - und alle diese Monster haben Schlüssel bei sich, um Türen zu öffnen. So kann es sein, dass man am Ende des Dungeons viele überschüssige Schlüssel bei sich trägt. Das ist die Ausgangslage.

Der Dungeon sei außerdem an eine kleine Quest geknüpft, es gibt also einen Questgeber, zu dem man am Ende auch zurückgeht, um ihm seinen geforderten Questgegenstand zu überreichen.

Ich kenne also das Skript, das GENAU EINEN Gegenstand an einen NPC übergibt, nämlich dieses aus dem Quest-Tutorial von Bathesda:

Alias_Bendu.GetReference().AddItem(Alias_Amulet.GetReference())

Was ich nun bräuchte, wäre (so vermute ich laienhaft) eine Abwandlung dieses Skripts, sodass ALLE VORHANDENEN EXEMPLARE EINES TYPS (eben der Schlüssel) an den NPC überreicht werden.

Kann mir da jemand helfen?

Vielen Dank.
Darmok


 
Code:
Function RemoveItem(Form akItemToRemove, int aiCount = 1, bool abSilent = false, ObjectReference akOtherContainer = None) native

Beispielsweise:

Code:
PlayerRef.RemoveItem(BaseItem_DeinSchluessel, maxItem, true, Ref_DeinNPC)
Erklärung:
PlayerRef: Eine Property mit der Referenz des Spielers (Kommt aufs selbe hinaus wie game.getplayer() is aber schneller)
BaseItem_DeinSchluessel: Der EditorName des zu übergebenden Items
true/false: Sollen die Items ohne Meldung entfernt werden (true) oder mit (false)
Ref_DeinNPC: Die Referenz deines NPCs. Achtung: Die Referenz des in der 3D-Ansicht platzierten NPCs ist hier wichtig. (NPC auf Unique + ne EditorID zuweisen sind hier praktisch)
maxItem: Zwei Möglichkeiten:
(a) Durch ne hohe Zahl ersetzen, die größer gleich der maximalen aufnehmbaren Schlüssel im Dungeon ist. Wenn das so geht ist es wahrscheinlich besser.
(b) Ansonsten, in einer Zeile darüber: int maxItem = PlayerRef.GetItemCount(BaseItem_DeinSchlüssel)
 
  • Like
Reaktionen: Bosmerland
Code:
Function RemoveItem(Form akItemToRemove, int aiCount = 1, bool abSilent = false, ObjectReference akOtherContainer = None) native

Beispielsweise:

Code:
PlayerRef.RemoveItem(BaseItem_DeinSchluessel, maxItem, true, Ref_DeinNPC)
Erklärung:
PlayerRef: Eine Property mit der Referenz des Spielers (Kommt aufs selbe hinaus wie game.getplayer() is aber schneller)
BaseItem_DeinSchluessel: Der EditorName des zu übergebenden Items
true/false: Sollen die Items ohne Meldung entfernt werden (true) oder mit (false)
Ref_DeinNPC: Die Referenz deines NPCs. Achtung: Die Referenz des in der 3D-Ansicht platzierten NPCs ist hier wichtig. (NPC auf Unique + ne EditorID zuweisen sind hier praktisch)
maxItem: Zwei Möglichkeiten:
(a) Durch ne hohe Zahl ersetzen, die größer gleich der maximalen aufnehmbaren Schlüssel im Dungeon ist. Wenn das so geht ist es wahrscheinlich besser.
(b) Ansonsten, in einer Zeile darüber: int maxItem = PlayerRef.GetItemCount(BaseItem_DeinSchlüssel)

Hallo, Drakons.

Das klingt super - aber ich bin Laie! Ich muss mir alles hart erarbeiten, und deine Erklärungen verstehe ich leider nicht komplett.

Nachfragen:

1. Muss ich jetzt "PlayerRef" noch durch irgendwas ersetzen oder nicht?
2. Wenn ich möchte, dass die Schlüssel mit einer Meldung an den NPC übergeben werden, dann trage ich "false" ein an der Stelle, wo bei deinem Muster "true" steht?
3. Mein NPC ist "unique" schon aus dem Quest-Tutorial. Ich schreibe dann also "Ref_Halkuur"?
4. "maxItem" ersetze ich durch z.B. "18"?
5. Wenn ich 8 verschiedene Schlüssel habe, gebe ich den Code dann 8 Mal ein, jeweils identisch bis auf den Namen des Items?
6. Trage ich das Skript genau an derselben Stelle ein, wo auch das Quest-Item übergeben wird? Ist die Skriptmenge nicht begrenzt?
7. Könnte man die Schlüssel auch einer Tür übergeben, in dem Moment, wo man sie aufschließt?

Könnte mein Skript also z.B. so aussehen:

Code:
PlayerRef.RemoveItem(BaseItem_NyraerisSchlüssel-1, 18, false, Ref_Halkuur)

Gruß
Darmok
 
Zuletzt bearbeitet:
Code:
int Menge = 0

Menge = Game.GetPlayer().GetItemCount(NyraeSchluessel1)	
Game.GetPlayer().RemoveItem(NyraeSchluessel1, Menge, False)
Ref_Halkuur.Additem(NyraeSchluessel1, Menge, False)
 
Gut, also ne ausführliche Erklärung.

Meine Annahme: Das Skript was du erstellst, erstellst du im Dialog/Quest-Menü, wo du nur ein kleines Fenster hast und dort Code eintragen kannst. (Scripts - Begin/End - Papyrus Fragment)
Ausserdem nehme ich an, dass das Tutorialskript dort bereits lauffähig erstellt worden ist.

Konvention: Im folgendem Code-Abschnitt werden Kommentare durch #text gekennzeichnet. (Die musst und solltest du NICHT übernehmen, sonst gibs Fehler)

Fangen wir an: Du öffnest deinen Quest und gehst an die Stelle wo das Skript laufen soll (also Dialog Views, irgendeine Queststage etc etc).
In der rechten Box(Scriptname) wählst du dein Script (TIF__irgendneKennung) und klickst auf Properties.

Dort jetzt: Add Property: Type: Actor; Name: PlayerRef, Rest unverändert. Bestätigen.
Add Property: Type: Actor; Name: Ref_Halkuur (Den nötigen Namen findest du SO: Deinen NPC im 3D Fenster aufsuchen, anwählen, rechtsklicken: Edit. Dort den Namen verwenden der unter "Reference Editor ID" steht. Falls keiner dort steht denk dir einen aus, schreib ihn dort rein und verwende den. (Anmerkung: Evtl geht mit unique-Npcs auch die Base-Reference aber das müsste ein erfahrenerer Modder sagen)
Add Property: Type: MiscItem; Name: DeinSchlüssel (Den hierfür nötigen Namen findest du wenn du im ObjectWindow dein Item öffnest unter "ID").

Anschließend klickst du auf Auto-Fill All.
Wenn jetzt unter Value in der Liste überall was steht hast du alles richtig gemacht.
Danach gehst du ins Code Fenster ("Papyrus Fragment" wahrscheinlich unter "Begin:")
und fügst folgendes wie von mir gesagtes und von nnw zusammengefassten Code hinzu:

Code:
int count;     #Ein Zahlenwert der die Menge der aufgenommen Schlüssel eines Typs repräsentieren soll
count = PlayerRef.GetItemCount(DeinSchlüssel)    #Abfrage wieviele Schlüssel der Spieler hat
PlayerRef.RemoveItem(DeinSchlüssel, count, false, Ref_Halkuur) #Entfernen der Schlüssel aus deinem Inventar (mit Meldung) und platzieren im Inventar deines NPCs

Wenn du nicht möchtest dass dein NPC mehrere Schlüssel des gleichen Typs hat mach es so wie nnw es geschrieben hat.

Jetzt zu deinen spezifischen Nachfragen (Die obiger Text wahrscheinlich schon zT hoffentlich beantwortet hat):

1. Siehe oben, du musst eine Property namens PlayerRef anlegen
2. Ja genau, es muss dann dort false stehen
3. Siehe oben, ja.
4. Entweder schätzt du den Wert ab oder machst es wie oben genannt durch GetItemCount
5. Du fügst sieben weitere Propertys zu den bisher bestehenden hinzu, die den Wert und Namen deiner anderen Schlüssel haben. Dann wiederholst du die letzten beiden Zeilen des Skripts und änderst jeweils den Namen zu einem der anderen Items um.
6. Du fügst den Code genau da hinzu wo du möchtest dass er abläuft :p Wenn das genau dann ist wenn auch das Questitem übergeben wird, schreibst du es auch dorthin (Einfach dadrüber oder drunter). Eine spürbare Längenbegrenzung haben die Skripte meines Wissens nach nicht.
7. Ja kann man. Ist jedoch ein wenig anders (wenn auch nicht viel).

@nnw/unten: ups, sry, habs total vergessen dass die auch in arrays gespeichert werden können
 
Zuletzt bearbeitet:
  • Like
Reaktionen: Bosmerland
5. Du fügst sieben weitere Propertys zu den bisher bestehenden hinzu, die den Wert und Namen deiner anderen Schlüssel haben. Dann wiederholst du die letzten beiden Zeilen des Skripts und änderst jeweils den Namen zu einem der anderen Items um.

Oder er verwendet ein Property Array
 
Guten Morgen,

ich bin gerade wieder etwas am Skripten und stelle mich dabei mal wieder doof an ;)

Was muss ich denn hier für xxx angeben, wenn ich auf ein LightingTemplate oder einen Imagespace zugreifen will ?

xxx Property MeinLichtTemplate Auto

Vielen Dank.

Gruß, mde.
 
Oder er verwendet ein Property Array

Okay, Drakons und nnw - ich danke euch für eure Hilfe, aber erstens ist der "er" eine "sie" (und die stellt sich doof an, wie es sich für ihr Geschlecht gehört), und zweitens habe ich mich nun dafür entschieden, die Schlüssel einfach Schlüssel sein zu lassen, damit ich mit dem Dungeon langsam fertig werde. Immerhin soll er ja in den Adventskalender. Vielleicht versuche ich es nachher nochmal, aber wenn ihr den dungeon ausprobieren solltet, seid nicht überrascht, wenn die Schlüssel noch da sind.

Liebe Grüße
Darmok
 
Könnte mir vielleicht jemadn bitte einen Skript erstellen der:
Bei der Aktivierung eines Objektes die Rasse ändert?
 
Ich habe eine Frage. Ich möchte testen, ob der Spieler einen bestimmten Gegenstand ausgerüstet hat. Das habe ich hiermit versucht:
Code:
If (Game.GetPlayer().IsEquipped(Objekt) == true)
Jedoch klappt es nicht. Egal ob der Gegenstand ausgerüstet ist oder nicht. Es ist immer false. Was muss ich tun damit das klappt?

Edit: Das steht übrigends am Anfang des Scripts:
Code:
Armor Property Objekt Auto

Edit 2: Noch eine Frage: Wie kann ich eigentlich auf Variablen aus anderen Scripts zugreifen, falls das überhaupt möglich ist?

Edit 3: Ich hab die zwei Scripts mal komplett aufgeschrieben:

Code:
ScriptName RingScript Extends ObjectReference

Armor Property Objekt Auto   

Event OnEquipped(Actor akPlayer)
    If (akPlayer == Game.GetPlayer())    
        Game.GetPlayer().AddItem(Objekt, 1, true)
        Game.GetPlayer().EquipItem(Objekt, false, true)
    EndIf
EndEvent


Event OnUnequipped(Actor akPlayer)
    If (akPlayer == Game.GetPlayer())
        Game.GetPlayer().RemoveItem(Objekt, 2, True)
    EndIf
EndEvent

Code:
ScriptName ObjektScript Extends ObjectReference


Armor Property Objekt  Auto 
Armor Property Objekt2 Auto

Event OnEquipped(Actor akPlayer)
    If (akPlayer == Game.GetPlayer())
        Game.GetPlayer().RemoveItem(Objekt2, 10, True)
    EndIf
EndEvent


Event OnUnequipped(Actor akPlayer)
    If (akPlayer == Game.GetPlayer())
        [FONT=Verdana]If (Game.GetPlayer().IsEquipped(Objekt) == true)[/FONT]
            Game.GetPlayer().AddItem(Objekt2, 1, true)
            Game.GetPlayer().EquipItem(Objekt2, False, True)
        EndIf
    EndIf
EndEvent

Noch mal eine komplette Erklärung: Also man rüstet den Ring aus. Daraufhin erhält man ein Objekt welches direkt ausgerüstet wird. Wenn man dieses auszieht soll Objekt 2 ausgerüstet werden. Sobald das Objekt wieder angelegt wird, verschwindet Objekt2 wieder. Wenn man jedoch den Ring wieder ablegt soll Objekt2 nicht mehr ausgerüstet sein. Hoffentlich hab ich das verständlich beschrieben.:D
 
Zuletzt bearbeitet:

Game.GetPlayer().EquipItem(Objekt, false, true)

Ich hab mich bisher noch nicht mit dem Scripten im CK beschäftigt, aber an der markierten Stelle stehen bei den anderen, ähnlichen Stellen grundsätzlich Zahlen, warum steht hier ein false? Ansonsten wirken deine Scripts auf mich sehr verwirrend. Welches der beiden Scripts ist für welches der beiden Items und warum steht "Armor Property" bei einem, dort aber für beide?
 
Ich habe das aus einer Mod raus genommen und möchte das für mich selber umändern. Da der Befehl trotzdem klappt hab ich es einfach so gelassen.
In dem Namen der Scripts steht welches Gegenstand den Skript hat. Objekt2 hat jedoch keinen Script nur Objekt und Ring.
Wenn ich "Armor Property" weg lasse, kommt eine Fehlermeldung.

EDIT: Problem gelöst!
 
Zuletzt bearbeitet:
Guten Morgen,

ich hab mal wieder ein kleines Problem mit folgendem Skript, das auf einem Aktivator liegt:

Code:
Scriptname Hinlegen extends ObjectReference  

Actor Property PlayerRef Auto
ObjectReference Property Liegemarker Auto

Event OnActivate (ObjectReference akActionRef)
  if (akActionRef == PlayerRef)
    Liegemarker.Activate(PlayerRef)
  EndIf
EndEvent

Wenn ich jetzt als Object z.B. DA11AltarInvisibleBed nehme, dann passiert beim Aktivieren gar nichts. Wenn ich BedrollGround nehme, dann legt er sich hin und die Abfrage, wie lange ich schlafen will, erscheint.
Gibt es keine Möglichkeit, dass sich der Spieler einfach nur hinlegt und dann wieder aufstehen kann ?
Wenn ich einen beliebigen unsichtbaren Sitzmarker verwende, dann funktioniert das problemlos, nur mit dem Hinlegen funktioniert es nicht.

Gruß, mde.