Construction Set Morrowind-Scriptkurs - Lektion 4

Wie versprochen, hab ich mich heute mal mit dieser Lektion näher beschäftigt:

Sag mal Killfetzer, an deinem ersten Script bekomme ich die Fehlermeldung " script kf_sk_bewegung_bsp1 You need to enter a value in line 21? Compiled script not saved", wenn ich es jetzt mal so rüberkopiere
Da ist doch aber ein Wert angegeben?

Weil ich da ein Z vergessen hatte.

Ich nehme an, der timer muss als float-Variable angelegt werden, da die Zeit fliessend ist und kein fester Wert festgelegt werden kann, da man nicht genau weiss, WANN der Spieler das Objekt aktiviert.

Nicht wirklich. Schau dir die Antworten von Diarrhoe oder £exa an.
 
Ich packs nicht. Für Aufgabe 5 habe ich nicht den geringsten Ansatzpunkt. Ich könnte euch die MW.ini editieren, sodass die FPS immer angezeigt werden. ;)

Es hakt auch bei Aufgabe 6:

Code:
Begin Teri_L4_Aufzug2_Script

short status
short unten
float timer

if ( MenuMode == 1 )
    return
endif

if ( OnActivate == 0 )
    if ( Unten == 1 )
        set status to 0
    endif
endif

if ( OnActivate == 1 )
    if ( status == 0 )
        set timer to timer + GetSecondsPassed
        if ( timer < 6 ) 
            if ( GetPos, Z < 473.000 )
                MoveWorld, Z, 100
            endif
        else
            set status to 1
            set timer to 0
        endif
    elseif ( status == 1 )
        set timer to timer + GetSecondsPassed
        if ( timer < 6 )
            if ( GetPos, Z > 109.000 )
                MoveWorld, Z, -100
            endif
        else
            set timer to 0
            set unten to 1
        endif
    endif
endif

End Teri_L4_Aufzug2_Script
Als einzigen Erfolg kann ich das korrekte Funktionieren des Aufzugs in Aufgabe 2 vermelden:

Code:
Begin Teri_L4_Aufzug1_Script

short status
float timer

if ( MenuMode == 1 )
    return
endif

if ( status == 0 )
    set timer to timer + GetSecondsPassed
    if ( timer < 6 ) 
        if ( GetPos, Z < 473.000 )
            MoveWorld, Z, 100
        endif
    else
        set status to 1
        set timer to 0
    endif
elseif ( status == 1 )
    set timer to timer + GetSecondsPassed
    if ( timer < 6 )
        if ( GetPos, Z > 109.000 )
            MoveWorld, Z, -100
        endif
    else
        set status to 0
        set timer to 0
    endif
endif

End Teri_L4_Aufzug1_Script

Edit: Achja, zu Aufgabe 3 habe ich auch noch was zu sagen, aber das war wohl eher rethorischer Natur.

Der Aufzug setzt seinen Weg während des geöffneten Menüs einfach fort und verhart in der gerade aktiven IF-Phase. Erst wenn das Menü wieder geschlossen wird, läuft das Script weiter ab. Bei mir war der Aufzug für 20 rätselhafte Sekunden im Boden versunken. ;)
 
Zuletzt bearbeitet:
Ich packs nicht. Für Aufgabe 5 habe ich nicht den geringsten Ansatzpunkt. Ich könnte euch die MW.ini editieren, sodass die FPS immer angezeigt werden. ;)

Man muss sich nur zu helfen wissen ;)

Dann mal einen Tipp: GetSecondsPassed liefert den Kehrwert der aktuellen FPS.

Es hakt auch bei Aufgabe 6:

Ich nehme an, der Aufzug verhält sich genauso wie in Aufgabe 2, oder?

Du brauchst zwei verschiedene Aktivierungen. Je nachdem ob der Lift oben oder unten steht. Als ganz grundsätzliche Aufstellung brauchst du so eine Konstruktion:

Code:
if ( state == 0 )
  if ( OnActivate == 1 )
    set state to 1
  endif
elseif ( state == 1 )
  ;hier hochfahren lassen und danach in state 2 gehen
elseif ( state == 2 )
  if ( OnActivate == 1 )
    set state to 3
  endif
elseif ( state == 3 )
  ;hier wieder runterfahren lassen und alle Werte zurücksetzen
endif
 
Ich glaube, Teridan und ich haben das gleiche Problem mit Aufgabe 6:
Wie kriegen wir es hin, dass der Aufzug ein paar Sekunden oben wartet und dann wieder herunterfährt und dabei alles auf 0 setzt, um die Prozedur wiederholen zu können?

Wenn ich das richtig erkenne, wäre dein Grundgerüst eher auf Aufgabe 7 zu beziehen, Killfetzer, wegen der zwei benötigten Aktivierungen. Bei Aufgabe 6 soll es aber nur eine sein. Korrigier mich aber, falls ich mich irren sollte.
 
Ich glaube, Teridan und ich haben das gleiche Problem mit Aufgabe 6:
Wie kriegen wir es hin, dass der Aufzug ein paar Sekunden oben wartet und dann wieder herunterfährt und dabei alles auf 0 setzt, um die Prozedur wiederholen zu können?

Wenn ich das richtig erkenne, wäre dein Grundgerüst eher auf Aufgabe 7 zu beziehen, Killfetzer, wegen der zwei benötigten Aktivierungen. Bei Aufgabe 6 soll es aber nur eine sein. Korrigier mich aber, falls ich mich irren sollte.

Ja, kann sein. Ich hab mir die Aufgaben nicht noch mal angeguckt. Sah nur nach der Lösüng mit den zwei Aktivierungen aus.

Für den mit warten müsst ihr eigentlich das gleiche Konzept nehmen. Statt der Aktivierung müsst ihr halt ein wenig warten:

if ( state == 0 )
if ( OnActivate == 1 )
set state to 1
endif
elseif ( state == 1 )
;hier hochfahren lassen und danach in state 2 gehen
elseif ( state == 2 )
;hier warten lassen (einfach den timer zählen lassen)
elseif ( state == 3 )
;hier wieder runterfahren lassen
endif
 
Mal ein kleiner Statusreport von meiner Seite.

Momentan hänge ich noch immer an Aufgabe 6, wobei ich Timer und Positionsabfrage berücksichtigt habe, aber sobald der Aufzug oben ist, bleibt er dort auch.
PHP:
begin merc_aufzug_warten

float timer
float zpos
short state

if ( MenuMode == 1 )
  return
endif

if    (state==0)
    if    (OnActivate==1)
        set zpos to GetPos, Z
            set zpos to zpos + 300
        set state to 1
    endif
elseif    (state==1)
        if    (Getpos, Z <=zpos)
            MoveWorld, Z, 100
        else
            set state to 2

        endif
elseif    (state==2)
        if (Getpos, Z==zpos)
        set timer to timer + GetSecondsPassed
            if    (timer>=5)
                set state to 3
                set timer to 0
            endif
        endif
elseif ( state == 3 )
          if    ( GetPos, Z >= zpos )
                MoveWorld,  Z, -100
            else
                set state to 0
            endif
        endif
endif
end

Wo liegt dann also bei mir der Fehler?
 
Dein Fehler liegt hier:

if (Getpos, Z==zpos)

Diese Abfrage ist nie erfüllt, da Move keine einheitengenaue Bewegungen ausführt. Somit können die Werte niemals gleich werden. Du musst für solche Verlgleich immer größer-gleich oder kleiner-gleich verwenden.
 
Moment, Lösung 7 folgt auf dem Fuße. Bei Nr.6 bin ich ganz nach dran.

Desweiteren wollte ich anmerken, dass ich für die Lektion 5 in der nächsten Woche keine Zeit habe (für Lektion 4 war es schon schwer ;) ). Mal schauen, was ich zwischen den Jahren schaffe. Danach fahre ich erstmal für knapp zwei Wochen weg (Urlaub, juchee :hah:), also werde ich möglicherweise vor Mitte Januar gar nicht mehr weitermachen können.

Wartet also nicht auf mich, ich hole das dann nach. :)

Code:
Begin Teri_L4_Aufzug3_Script

short status

if ( status == 0 )
    if ( OnActivate == 1 )
        set status to 1
    endif
elseif ( status == 1 )
    if ( GetPos, Z < 473.000 )
        MoveWorld, Z, 100
    else
        set status to 2
    endif
elseif ( status == 2 )
    if ( OnActivate == 1 )
        set status to 3
    endif
elseif ( status == 3 )
    if ( GetPos, Z > 109.000 )
        MoveWorld, Z, -100
    else
        set status to 0
    endif
endif

End Teri_L4_Aufzug3_Script

Edit: Tippfehler entfernt.... "Aufgabe 70", die erreiche ich in diesem Leben nicht. :D
 
Zuletzt bearbeitet:
Lösungen

  • Erstellt einen einfachen Aufzug, der ständig hoch und runter fährt und an jedem Ende jeweils kurz anhält.
    Code:
    begin kf_sk_aufzug1_script
    
    short state
    float timer
    
    if ( MenuMode == 1 )
      return
    endif
    
    if ( state == 0 )				;Aufzug fährt hoch
    
    	if ( GetPos, Z < 300 )
    		MoveWorld, Z, 50
    	else
    		set state to 1
    	endif
    
    elseif ( state == 1 )		;Aufzug hält oben
    
    	set timer to timer + GetSecondsPassed
    	if ( timer > 1 )
    		set timer to 0
    		set state to 2
    	endif
    
    elseif ( state == 2 )		;Aufzug fährt runter
    
    	if ( GetPos, Z > 0 )
    		MoveWorld, Z, -50
    	else
    		set state to 3
    	endif
    
    else							;Aufzug hält unten
    
    	set timer to timer + GetSecondsPassed
    	if ( timer > 1 )
    		set timer to 0
    		set state to 0
    	endif
    
    endif
    
    end

  • Warum muss timer im zweiten Beispielscript eine float-Variable sein?
    Da die Funktion GetSecondsPassed die Zeit seit dem letzten Frame in Sekunden angibt, liegt dieser Wert normalerweise deutlich unter 1 (bei 30 FPS wäre der Wert 0,03). Somit würde sich der Wert von timer nie ändern und immer auf 0 bleiben, wenn man in einer short-Variable nur die Vorkommastellen speichert.

  • Erstellt einen Activator, der euch beim Aktivieren die aktuelle Framerate (fps) ausgibt.
    Code:
    begin kf_sk_fps_script
    
    float fps
    
    if ( OnActivate == 1 )
    	set fps to 1 / GetSecondsPassed
    	MessageBox, "Die aktuelle Bildrate pro Sekunde (FPS) ist %.0f", fps
    endif
    
    end

    Wie euch vielleicht beim Test aufgefallen ist, kostet die eingebaute Funktion zum Anzeigen der Framerate (tdt) einen etwa 15 FPS. Somit kann dieses Script zu Testzwecken von Modifikationen (ob diese zu viel Leistung fressen) durchaus nützlich sein, da es die Geschwindigkeit von Morrowind nicht beeinflusst. Alternativ kann man natürlich auch den entsprechenden Ini-Eintrag ändern und sich die FPS immer anzeigen lassen.

  • Erstellt einen Aufzug, der anfangs still steht. Wenn er aktiviert wird, bewegt sich der Aufzug nach oben, wartet dort einen Moment und fährt wieder runter.
    Code:
    begin kf_sk_aufzug2_script
    
    short state
    float timer
    
    if ( MenuMode == 1 )
      return
    endif
    
    if ( state == 0 )				;Aufzug wartet auf Aktivierung
    
    	if ( OnActivate == 1 )
    		set state to 1
    	endif
    
    elseif ( state == 1 )		;Aufzug fährt hoch
    
    	if ( GetPos, Z < 300 )
    		MoveWorld, Z, 50
    	else
    		set state to 2
    	endif
    
    elseif ( state == 2 )		;Aufzug hält oben
    
    	set timer to timer + GetSecondsPassed
    	if ( timer > 1 )
    		set timer to 0
    		set state to 3
    	endif
    
    elseif ( state == 3 )		;Aufzug fährt runter
    
    	if ( GetPos, Z > 0 )
    		MoveWorld, Z, -50
    	else
    		set state to 0
    	endif
    
    endif
    
    end

  • Erstellt einen Aufzug, der nach Aktivieren nach oben beziehungsweise unten fährt und dort bleibt, bis er erneut aktiviert wird. Danach fährt er wieder in seine andere Position und wartet dort.
    Code:
    begin kf_sk_aufzug3_script
    
    short state
    float timer
    
    if ( MenuMode == 1 )
      return
    endif
    
    if ( state == 0 )				;Aufzug wartet auf Aktivierung
    
    	if ( OnActivate == 1 )
    		set state to 1
    	endif
    
    elseif ( state == 1 )		;Aufzug fährt hoch
    
    	if ( GetPos, Z < 300 )
    		MoveWorld, Z, 50
    	else
    		set state to 2
    	endif
    
    elseif ( state == 2 )		;Aufzug hält oben und wartet auf erneute Aktivierung
    
    	if ( OnActivate == 1 )
    		set state to 3
    	endif
    
    elseif ( state == 3 )		;Aufzug fährt runter
    
    	if ( GetPos, Z > 0 )
    		MoveWorld, Z, -50
    	else
    		set state to 0
    	endif
    
    endif
    
    end
 
Zuletzt bearbeitet: