Construction Set Morrowind-Scriptkurs - Lektion 2

Dieses Thema im Forum "[MW] Plugins und Mods" wurde erstellt von IvanDaVile, 22. Oktober 2010.

  1. IvanDaVile

    IvanDaVile Abenteurer

    The Elder Scrolls III: Morrowind - Scriptkurs


    2. Inventar-Scripte

    Im letzten Teil haben wir die Funktion OnActivate kennengelernt. So wie man mit OnActivate viele Interaktionen des Spielers mit seiner Umwelt feststellen kann, gibt es auch Möglichkeiten verschiedene Interaktionen mit dem Inventar zu erkennen. In vielen fällen ist das zwar sehr viel komplizierter als man sich vielleicht vorstellt, in anderen aber auch sehr leicht. Was OnActivate für die Umgebung des Spielers ist, ist in gewisser Weise die Funktion OnPCEquip für das Inventar.

    Um OnPCEquip verwenden zu können, muss man es zuvor als lokale Variable short OnPCEquip deklarieren.


    Die Wirkung von "OnPCEquip" hängt vom Typ des Gegenstands ab, auf dem ein Script liegt.

    Kategorie 1; ausrüstbare Gegenstände: Rüstungen, Waffen, Kleidung, tragbare Lichter, Dietriche, Sonden



    OnPCEquip wird auf 1 gesetzt, wenn der Spieler den Gegenstand ausrüstet (auf sein Charakterbild im Inventar zieht oder per Hotkey benutzt).
    Die Variable wird beim ABLEGEN automatisch auf 0 zurückgesetzt, kann aber auch von Hand zurückgesetzt werden, via set OnPCEquip to 0.
    Ansonsten bleibt ihr Wert 1.


    Code:
    Begin IdV_EquipTest_equipable
    
    ; Armor, Weapons, Clothing, Lights, Picks, Probes
    
    short OnPCEquip
    short IsEquiped
    
    if ( OnPCEquip )
    	if ( IsEquiped == 0 )
    		MessageBox "Equiped"
    		set IsEquiped to 1
    	endif
    endif
    
    if ( IsEquiped )
    	if ( OnPCEquip == 0 )
    		MessageBox "Un-Equiped"
    		set IsEquiped to 0
    	endif
    endif
    
    End
    Kategorie 2; sonstige Gegenstände: alles unter Misc Item im Objekfenster des CS, außer geladenen Seelensteinen

    OnPCEquip wird auf 1 gesetzt, wenn der Spieler den Gegenstand ausrüstet und wird nicht automatisch zurückgesetzt, sondern bleibt 1. Man muss dies also von Hand tun oder alles im OnPCEquip Block wird jeden Frame ausgeführt.


    Code:
    Begin IdV_EquipTest_misc
    
    short OnPCEquip
    
    if ( OnPCEquip )
    	MessageBox "Equiped"
    	set OnPCEquip to 0
    endif
    
    End
    Bei geladenen Seelensteinen bleibt OnPCEquip auch beim ausrüsten 0, es aber eine andere Funktion mit der man das Benutzen eines Seelensteins erkennen kann.


    Kategorie 3; allen anderen Inventargegenständen: Zutaten, Tränke, Alchemie-Apparaten, Reparturwerkzeug, Bücher/schriftrollen

    OnPCEquip funktioniert nur in verbindung mit PCSkipEquip.


    short PCSkipEquip muss ebenfalls als lokale Variable deklatiert werden. Und kann dann auf 1 gesetzt werden.
    Wenn PCSkipEquip gleich 1 ist, dann verhält sich ein Gegenstand wie ein Misc-Item.


    Code:
    Begin IdV_EquipTest_else
    
    short OnPCEquip
    short PCSkipEquip
    
    set PCSkipEquip to 1
    
    if ( OnPCEquip )
    	MessageBox "Equiped"
    	set OnPCEquip to 0
    endif
    
    End
    Das lässt zwar die OnPCEquip Funktion korrekt auslösen macht den Gegenstand aber nutzlos, denn er kann so nicht mehr benutzt oder verbraucht werden. Das lässt sich zwar auch wieder umgehen, benötigt aber ein weiteres (globales) Script und ist uns im Moment noch zu kompliziert.
    Funktioniert nicht bei geladenen Seelensteinen.

    Ein weiteres Problem ist, dass Gegenstände, die ein Script tragen sich nicht mehr im Inventar stapeln lassen, was sehr hässlich aussehen kann.

    Man kann PCSkipEquip natürlich auch ohne OnPCEquip verwenden und somit verhindern dass der Spieler einen bestimmten Gegenstand verwendet.

    Eine besonderheit von PCSkipEquip ist, dass es bei Büchern beim Ausrüsten (= Lesen) auf 1 gesetzt wird (was bei allen anderen Gegenständen scheinbar nicht passiert).


    Code:
    Begin IdV_BookActivate
    
    short PCSkipEquip
    
    if ( PCSkipEquip )
    	MessageBox "Gelesen"
    	set PCSkipEquip to 0
    endif
    
    End

    Dies gilt nicht für Bücher die aus der Welt heraus gelesen werden, was sich aber durch OnActivate feststellen lässt.

    Bei Büchern kann man mit OnActivate drei verschiedene Aktionen festellen: Den Versuch das Buch mit der Maus ins geöffnete Inventar zu ziehen, Lesen (Benutzen) in der Welt und das anklicken von 'nehmen' beim Lesen.
    Der 'Activate' Befehl hingegen erzwingt immer lesen.

    Dies bedeutet man muss mit 'OnActivate' auf Büchern SEHR vorsichtig sein, da man sonst einen Gegenstand erschafft den man nicht mehr aufheben kann falls man ihn einmal ablegt. Hier ist zum Beispiel ein Script das verhindert, dass man ein Buch aufheben kann, es wurde von Dave Humphrey entdeckt:

    Code:
    Begin DontPickMeUp_Simple
    
    if ( OnActivate )
    	Activate
    endif
    
    End

    Es gilt also festzustellen ob das Buch bereits gelesen wird oder jemand nur versucht es in das Inventar zu ziehen. Um diese Ereignisse abzufangen, brauchen wir folgende Funktionen:


    MenuMode

    Gibt 1 zurück, wenn irgendein Menü geöffnet ist. Dies betrifft das Spielmenü (Esc-Taste), Inventar, Dialoge, Messageboxen, Wartezeiten beim Schlafen und Reisen, Bücher lesen sowie Alchemie-Menüs etc., gilt aber nicht für eine auf dem HUD fixierte Karte.

    return

    Wenn man return aufruft, wird jeglicher Code unterhalb davon für den momentanen Frame ignoriert. Bereits durchlaufener Code wird NICHT rückgängig gemacht.

    häufige verwendung:

    Code:
    if ( Menumode )
    	return
    endif


    Aufgaben

    1) Probiert die Beispiel-Scripte aus, weißt sie unpassenden Objekten zu und seht euch an was passiert.

    2) Erschafft eine tragbare Uhr, die dem Spieler beim Ausrüsten die Zeit anzeigt.

    3) Erschafft ein Buch, aus dem beim ersten lesen ein Schlüssel fällt und dabei einen Tagebucheintrag erstellt.

    4) Erschafft ein Schwert, das der Spieler nur tragen kann wenn er einen bestimmten Tagebucheintrag hat, zum Beispiel den von oben.

    Tipps: am anspruchsvollsten ist 3), es gilt hier aber eigentlich nur den Inhalt der Beispielscripte in eine "sinnvolle" Reihenfolge zu bringen (und euer wissen aus den vorherige Lektionen anzuwenden)
     
    Zuletzt von einem Moderator bearbeitet: 7. November 2010
    Araneos, Mercarryn und Zeitgeist gefällt das.
  2. Werbung (Nur für Gäste)
  3. Killfetzer

    Killfetzer Super-Moderator Mitarbeiter

    Möchte sich denn niemand an den Aufgaben versuchen?
     
  4. Mercarryn

    Mercarryn Ehrbarer Bürger

    Momentan bin ich noch nicht dazu gekommen, die Aufgaben anzugehen, weil viel zeit mit RL eingeplant ist, sorry. Ich hoffe, dass ich es dieses Wochenende hinbekomme.
     
  5. Diarrhoe

    Diarrhoe Vertrauter

    Vielleicht mag auch keiner Inventarskripte... :p

    Meine Versuche:

    Code:
    Begin digitaluhr_script
    
    short OnPCEquip
    
    short hours
    short minutes
    
    if ( OnPCEquip )
     set hours to GameHour
     set minutes to ( ( GameHour - hours ) * 60 )
     if minutes < 10
      MessageBox, "Es ist jetzt %.0f:0%.0f Uhr!", hours, minutes
     else
      MessageBox, "Es ist jetzt %.0f:%.0f Uhr!", hours, minutes
     endif
     set OnPCEquip to 0
    endif
    
    end

    Code:
    Begin buch_script
    
    short OnPCEquip
    short PCSkipEquip
    
    set PCSkipEquip to 1
    
    if ( MenuMode )
     return
    endif
    
    if ( OnActivate )
     if ( GetJournalIndex, "buch_quest" < 10 )
      "Player"->AddItem, "schluessel_id", 1
      Journal, "buch_quest", 10
      activate
     endif
    endif
    
    end

    Code:
    Begin schwert_script
    
    short OnPCEquip
    
    if ( OnPCEquip )
     if ( GetJournalIndex, "schwert_quest", < 20
      return
     endif
    endif
    
    end

    Btw. wie lautet denn das Gegenstück zu "Equip"? Hab jetzt keinen Befehl à la "Unequip" gefunden.
     
    Zuletzt bearbeitet: 27. Oktober 2010
  6. Teridan

    Teridan Mr. Morrowind 2007

    Geduld, Geduld. Ich habe die Hälfte der Aufgaben geschafft. Ich wollte aber nur mal kurz melden, dass so ein Erfolgserlebnis wie das Gelingen von Aufgabe 2 sehr angenehm ist. ;)

    Morgen habe ich mehr Zeit und versuche mich an den anderen beiden Aufgaben.
     
  7. Crashtestgoblin

    Crashtestgoblin Freund des Hauses

    Ich werd mich auch mal in den nächsten Tagen darum kümmern, hab bloß wenig Zeit diese Woche und komm kaum zur Ruhe, um mich mal damit zu beschäftigen.
     
  8. Killfetzer

    Killfetzer Super-Moderator Mitarbeiter

    Den gibt es nicht. Entweder du verhinderst mit PCSkipEquip das Ausrüsten von vorne herein oder du rüstest einen anderen Gegenstand zwangsweise mit Equip aus, der den entsprechenden Slot belegt. Dann wird das vorher angezogene Item abgelegt.
     
  9. IvanDaVile

    IvanDaVile Abenteurer

    Juhu es geht los :)

    die 2) ist natürlich als Erfolgserlebnis gedacht und wird von mir auch vorerst nicht kommentiert. (Sonst müsst ihr noch mal zurück zu Lektion 1)


    @Diarrhoe

    3) ist schon mal zur hälfte in Ordnung, aber im Inventar sollte dich das Buch auch öffnen lassen.

    4) ihr könnt natürlich auch ein ein Script schreiben das den Gegenstand wieder ablegt, aber eigentlich ist das übertrieben.
     
  10. Diarrhoe

    Diarrhoe Vertrauter

    Ich dachte, dann ließe sich das Objekt nie wieder ausrüsten... :huh:

    Code:
    Begin buch_script
    
    short OnPCEquip
    short PCSkipEquip
    
    set PCSkipEquip to 1
    
    if ( GetJournalIndex, "buch_quest" < 10 )
     if ( OnPCEquip )
      "Player"->AddItem, "schluessel_id", 1
      Journal, "buch_quest", 10
      set OnPCEquip to 0
     elseif ( OnActivate )
      if ( MenuMode )
       return
      endif
      "Player"->AddItem, "schluessel_id", 1
      Journal, "buch_quest", 10
      activate
     endif
    endif
    
    end
     
  11. Teridan

    Teridan Mr. Morrowind 2007

    Also, Aufgabe 1-3 habe ich hinbekommen, aber ich verzweifel an Aufgabe 4:

    Begin Teri_Axt_Script

    short OnPCEquip
    short PCSkipEquip

    if ( OnPCEquip )
    if ( GetJournalIndex "Teri_Key" >=10 )
    Set OnPCEquib to 1
    else
    MessageBox "Eine geheimnisvolle Macht reisst Euch die Waffe aus den Händen."
    set PCSkipEquip to 1
    set OnPCEquip to 0
    endif
    endif

    End Teri_Axt_Script

    So wie ich es jetzt eingestellt habe, kann ich die Waffe nicht mehr anlegen, wenn ich den Tagebucheintrag habe und wenn ich den Tagebucheintrag nicht habe, kann ich die Waffe anlegen, aber die Messagebox erscheint korrekt. Ich habe auch schon versucht die Werte einfach mal zu tauschen, aber dann wirft er mir ohne Ende Messageboxen raus und das Anlegen funktioniert auch nicht richtig.

    Achja, der Vollständigkeit halber:

    begin Teri_Tragbare_Uhr_Script

    short OnPCEquip
    short hour
    short min
    float time

    if ( OnPCEquip )
    set time to GameHour
    set hour to time
    set min to ( time - hour ) * 60
    if ( min < 10 )
    MessageBox, "Es ist %.0f:0%.0f Uhr.", hour, min, Day, Month, Year, "OK"
    set OnPCEquip to 0
    else
    MessageBox, "Es ist %.0f:%.0f Uhr.", hour, min, Day, Month, Year, "OK"
    set OnPCEquip to 0
    endif
    endif

    end Teri_Tragbare_Uhr_Script
    Begin Teri_KeyBook_Script

    short OnPCEquip
    short PCSkipEquip

    if ( GetJournalIndex, "Teri_Key" >= 10 )
    return
    endif

    if ( OnActivate )
    MessageBox "Als Ihr das Buch öffnet, fällt ein kleiner Metallschlüssel heraus."
    Player->AddItem "Teri_Key_01l" 1
    Journal "Teri_Key" 10
    activate
    endif

    if ( OnPCEquip )
    MessageBox "Als Ihr das Buch öffnet, fällt ein kleiner Metallschlüssel heraus."
    Player->AddItem "Teri_Key_01" 1
    Journal "Teri_Key" 10
    set OnPCEquip to 0
    endif

    End Teri_KeyBook_Script
     
  12. Diarrhoe

    Diarrhoe Vertrauter

    Wo ich Teridans Ansatz gerade gesehen habe, ist mir noch ein Möglichkeit für 4 eingefallen:

    Code:
    Begin schwert_script
    
    short OnPCEquip
    short PCSkipEquip
    
    if ( GetJournalIndex, "schwert_quest" < 20 )
     set PCSkipEquip to 1
    else
     set PCSkipEquip to 0
    endif
    
    if ( OnPCEquip )
     if ( PCSkipEquip )
      set OnPCEquip to 0
      MessageBox "Ihr könnt das Schwert noch nicht ausrüsten!"
     endif
    endif
    
    end
     
  13. IvanDaVile

    IvanDaVile Abenteurer

    ja so geht das.

    Ich sags zur Sicherheit noch mal ganz deutlich: Weder mit PCSkipEquip noch mit OnPCEquip kann man das anlegen nachträglich rückgängig machen, aber den Wert von PCSkipEquip kann man jederzeit änderen um den Gegenstand wieder anlegbar zu machen (sofern er das im Normalzustand überhaupt ist).

    Noch eine kleine Anmerkung: die Uhr kann man durchaus als Amulett oder so realisieren, das kann man den auf einen Hotkey legen, was mit Miscs ja nicht geht.
     
  14. Killfetzer

    Killfetzer Super-Moderator Mitarbeiter

    Will sonst noch jemand? Sonst wird es wohl Zeit für Lektion 3.
     
  15. Mercarryn

    Mercarryn Ehrbarer Bürger

    Ich werkel noch an den Aufgaben, leider war letztes Wochenende keine Zeit dafür. Werd sobald möglich meine Lösungen hier reinstellen. Aber von mir aus könnt ihr mit Lektion 3 langsam starten, sofern die anderen nix dagegen haben.
     
  16. Ich würde gerne noch.:D Aber fangt ruhig mit 3 an. Ich habe wenn am Wochenende dafür Zeit.
     
  17. Zeitgeist

    Zeitgeist Ehrbarer Bürger

    Ich seh es wie Kallor.Ich versuch mich mal an den Aufgaben und mit 3. könnt ihr schonmal anfangen.
     
  18. Killfetzer

    Killfetzer Super-Moderator Mitarbeiter

    Dann warten wir noch. Wir müssen uns ja nicht hetzen.

    Wollt ihr die 3. Lektion eigentlich lieber als einen ganz großen Klotz (so hab ich sie derzeit) oder soll ich sie in mehrere aufteilen? Nach den etwas ernüchternden Erfahrungen mit meiner ersten Lektion hatte ich eigentlich beschlossen, meine 3. Lektion in 4 (!) Einzellektionen aufzuteilen, die wären dann aber wirklich klein.
     
  19. Teridan

    Teridan Mr. Morrowind 2007

    Ich denke, das spielt keine Rolle. Wenn die Elemente von Lektion 3 aufeinander aufbauen und miteinander verflechtet sind (davon gehe ich mal einfach aus), dann wäre es wohl sinnvoller alles auf einem Blick zu haben.
    Nur ist sind kleine Lektionsbausteine motivierender als eine große Textwüste. Aber wie gesagt, im Grunde ist das egal. ;)
     
  20. Mercarryn

    Mercarryn Ehrbarer Bürger

    Ich bin mal langsam dazu gekommen, mich an deine Aufgaben ranzuwagen, Ivan.

    Aufgabe 2:

    PHP:
    begin Merc_TragbareUhr_Script


    short hour
    short minute
    short OnPCEquip
    float time

    if (OnPCEquip ==1)

        
    set time to GameHour
        set hour to time
        set minute to 
    time hour ) * 60

        
    if ( minute 10 )
            
    MessageBox"Es ist %.0f:0%.0f Uhr."hourminute"OK"
        
    else
            
    MessageBox"Es ist %.0f:%.0f Uhr."hourminute"OK"
        
    Set OnPCEquip to 0
        
    endif
    endif
    end

    Aus reinem Interesse hab ich mich mal an eine Variante gewagt, die ständig die Uhrzeit angibt. Das geht logischerweise am besten mit Items der Kategorie 1:

    PHP:
    begin Merc_TragbareUhr2_Script


    short hour
    short minute
    short OnPCEquip
    float time

    if (OnPCEquip ==1)

        
    set time to GameHour
        set hour to time
        set minute to 
    time hour ) * 60

        
    if ( minute 10 )
            
    MessageBox"Es ist %.0f:0%.0f Uhr."hourminute
        
    else
            
    MessageBox"Es ist %.0f:%.0f Uhr."hourminute
        
        
    endif
    endif
    end
    Sieht nur ingame etwas bescheuert aus mit den drei gleichzeitig geöffneten Messageboxen. Gibt es evtl dafür ne Lösung, in der immer nur eine Messagebox ingame angezeigt wird?

    Aufgabe 3: Lösung folgt

    Aufgabe 4:
    PHP:
    begin Merc_SchwertAnlegen_Script


    short journal
    short OnPCEquip
    short PCSkipEquip

    set PCSkipEquip to 1
    if ( OnPCEquip == )
        if ( 
    GetJournalIndexJournal "A1_Sleepers_Assi" )
        
    set PCSkipEquip to 1
        set OnPCEquip to 0
        MessageBox
    "Euch fehlt ein Eintrag im Tagebuch!"          
       
    else
        
    set OnPCEquip to 1
        set PCSkipEquip to 0
        
    endif
    endif

    end
    Hier hab ich aber ein Problem:
    Wenn ich versuche, nach dem Tagebucheintrag das Schwert anzulegen, klappt das erst beim zweiten Versuch.
     
    Zuletzt bearbeitet: 7. November 2010
  21. Tommy

    Tommy Hausvetter

    Das kannst du realisieren, indem du vor deiner MessageBox mehrmals folgendes aufrufst:
    Code:
    messagebox, ""
    wie in Lektion 1 gelernt, entspricht die Darstellungszeit der Zeichennanzahl * fMessageTimePerChar ... bei Zeichenanzahl 0 ist entsprechend die Darstellungszeit auch 0, aber trotzdem gilt es als abgesetzte Message ... wenn du das nun also 3 mal aufrufst hast du den Bildschirm wieder leer und kannst deine MessageBox absetzen, die dann auch alleine dasteht
     
  22. Werbung (Nur für Gäste)
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deiner Erfahrung anzupassen und dich nach der Registrierung angemeldet zu halten.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden