Construction Set Der Scriptthread

In einer Spielszene sollen sich ein paar Bewohner von Balmora versammeln und später wieder ihren normalen Tagesabläufen nachgehen. Ich schick sie also erstmal zum "Treffpunkt" und stelle AiWander auf 0 0 0 0 0. danach schicke ich sie zurück, aber da komme ich mit dem AiWander-Befehl nicht ganz zurecht: Es sind insgesammt 12 variablen vorgesehen:

Entfernung, Dauer, Uhrzeit, idle1, idle2, idle3, idle4, idle5, idle6, idle7, idle8, idle9

Aber in den AI-Informationen aller NPCs fehlt der Wert idle1. Ich weiß, dass dieser Wert "Stillstehen" bedeutet, hab aber jetzt ka, was da für ein Wert hingehört.
Ich habe im Script eines anderen NPCs nachgeschaut, was dort angegeben. In seinem Standart-AI steht:

Entfernung: 0
Dauer: 5
Uhrzeit: 0
idle2: 60
idle3: 20
idle4: 10
idle5: 0
idle6: 0
idle7: 0
idle8: 0
idle9: 0

Das ist ja ganz normal (bis auf das fehlende idle1, das aber bei jeden NPC fehlt), aber dann im Script, in dem er nach einer Eskorte wieder normal herumlaufen soll, steht dann

AiWander 0 0 0 60 30 20 0 0 0 0 0 0

Das sind dann wieder 12 Werte. Und der Wert von idle2 findet sich jetzt in idle1 wieder. so, wie idle3 und 4 etwas umgewandelt in idle2 und 3. haben die da einfach etwas herumgeschoben? irgendeine 0 ist ja dann einfach außer acht gelassen.
 
Gut, dann stell ich jetzt mal Offiziell die Anfrage für folgendes, zweiteiliges Script:

Teil 1:
Teleportring - Fragt ab, ob und wenn ja, wohin teleportiert werden soll, markiert Ausgangsposition und teleportiert Spieler in die gewählte Zelle "FOO" an Position "XYZ".

Teil 2:
Portal - Teleportiert Spieler wieder zurück zur Ausgangsposition und löscht Markierung.

Teil 1 hab ich bereits angefangen:
Code:
Begin _HF_Teleportring_Script

short button
short reset
short OnPcEquip

;if ( MenuMode == 1 )
;	Return
;endif


if ( OnPCEquip == 0 )
	set reset to 0
endif

if ( reset == 1 )
	return
endif

if ( OnPCEquip == 1 )
	if ( reset == 0 )
		Set OnPCEquip to 0
		MessageBox "In die Hammerfeste teleportieren ?" "Ja" "Nicht jetzt"
	endif
endif

set button to GetButtonPressed

if ( button == 0 )
		playsound "conjuration hit"
		Player->PositionCell 19707, 1954, 18808, 0 "Hammerfeste: Große Halle"
		set reset to 1

;elseif ( button == 1 )
;		playsound "conjuration hit"
;		Player->PositionCell X, Y, Z, Rot "FOO"
;		set reset to 1

;elseif ( button == 2 )
;		playsound "conjuration hit"
;		Player->PositionCell X, Y, Z, Rot "FOO"
;		set reset to 1

;elseif ( button == 3 )
;		playsound "conjuration hit"
;		Player->PositionCell X, Y, Z, Rot "FOO"
;		set reset to 1

elseif ( button == 1 )
		set reset to 1
		return

endif

End _HF_Teleportring_Script
 
Zuletzt bearbeitet:
Ganz grundsätzlich ist das nicht möglich.

Du kannst keinen allgemeinen Ort zum Zurückkehren speichern. Das geht nur in einem "Spezialfall". Du kannst abfragen, ob sich der Spieler draußen aufhält (GetInterior == 0) und dann die Koordinaten dieses Ortes speichern. Mit dem Position Befehl könntest du ihn dann prinzipiell an diese Stelle zurückschicken. Leider kann dieser keine Variablen verarbeiten...
Also kannst du den Spieler an einen festen Punkt der Oberwelt absetzen und ihn dann in kleinen Schritten immer näher an den gewünschten Ort teleportieren. Auch das bringt wieder Probleme mit sich...

Es gibt eine ganze Reihe von Umsetzungen dazu, welche mir dazu einfallen wären das tragbare Zelt oder meine eigenen Stadtportale. Solltest du noch Interesse an diesem Script haben, solltest du dir mal die Scripts in diesen PIs angucken.

Ich editiere mal mein Script dazu rein, wenn ich es finde.

/EDIT:

Dieses Script liegt auf der Schriftrolle, die einen an einen Punkt teleportiert (müsstest du so für dein Amulett abwandeln können):

Code:
begin sp_rolle_aldruhn_script

short state
short button
short OnPCEquip
short PCSkipEquip
float xpos
float ypos
float zpos
float timer


if ( state == 0 )
	Set PCSkipEquip to 1
	Set state to 1
endif

; Hier wird überprüft, ob die Schriftrolle ausgewählt wird
if ( OnPCEquip == 1 )
	set state to 2
	set OnPCEquip to 0
endif

if ( state == 2 )
	MessageBox "Was wollt Ihr tun?" "Schriftrolle benutzen" "Anleitung lesen"
	set state to 3
endif

if ( state == 3 )
	set button to GetButtonPressed
	if ( button == 0 )
		set state to 4
		set button to -1
	endif
	if ( button == 1 )
		Activate
		set state to 0
		set button to -1
	endif
endif

if ( state == 4 )
	; Hier wird überprüft ob man sich in der Stadt befindet oder nicht
	if ( GetPCCell "Ald'ruhn" == 1 )
		MessageBox "Ihr befindet Euch bereits in der Stadt. Ihr könnt kein Portal öffnen."
		set state to 0
	else
		; Hier wird geprüft, ob man in einer Interior oder Exterior-Zelle ist
		if ( GetInterior == 0 )
			MessageBox "Wollt zurück nach Ald'ruhn?" "Ja." "Nein."
			set state to 5
		else
			MessageBox "Zu diesem Ort könnt Ihr nicht zurückreisen. Wollt Ihr trotzdem zurück nach Ald'ruhn?" "Ja." "Nein."
			set state to 5
		endif
	endif
endif

if ( state == 5 )
	set button to GetButtonPressed

	if ( button == 0 )
		if ( GetInterior == 0 )
			; Hier wird gespeichert wohin man zurückreisen kann
			set sp_xpos_a to Player -> GetPos, X
			set sp_ypos_a to Player -> GetPos, Y
			set sp_zpos_a to Player -> GetPos, Z	
			set sp_offen_aldruhn to 1
		endif
		;Hier reist man nach Ald'ruhn
		PlaySound "mysticism cast"
		Player->PositionCell -12500 55040 2432 90 "Ald'ruhn"
		set state to 0
		set button to -1
		StartScript "sp_entfernen_aldruhn_global"
	endif

	if ( button == 1 )
		set button to -1
		set state to 0
	endif
endif

end

Und dieses Script liegt auf dem Portal, welches einen zurückbringt:

Code:
begin sp_abstand_aldruhn_script

short state
short button
float timer
float xpos
float ypos
float zpos

if ( state == 0 )
	if ( sp_offen_aldruhn == 1 )
		set state to 1
	endif
endif

if ( state == 1 )
	if ( GetDistance, Player < 128 )
		MessageBox "Wollt Ihr das Portal betreten?" "Ja." "Nein."
		set state to 2
	endif
endif

if ( state == 2 )
	set button to GetButtonPressed

	if ( button == 0 )
		if ( sp_xpos_a == 0 )
			if ( sp_ypos_a == 0 )
				MessageBox "Es ist kein Ort gespeichert zu dem Ihr zurückreisen könntet."
				set state to 0
				set button to -1
				return
			endif
		endif
		;Hier wird man zurückteleportiert
		PlaySound "mysticism cast"
		FadeOut 0.1
		ToggleMenus
		set state to 3
		set timer to 0
		set button to -1
	endif

	if ( button == 1 )
		set state to 5
		set button to -1
	endif
endif

if ( state == 3 )
	set timer to timer + GetSecondsPassed
	if ( timer > 0.2)
		; Hier reist man noch immer zurück
		set xpos to sp_xpos_a
		set ypos to sp_ypos_a
		set zpos to sp_zpos_a
		Player->COE 0 0
		Player->SetPos, X, xpos
		Player->SetPos, Y, ypos
		Player->SetPos, Z, zpos
    		FixMe
    		Player -> SetPos, X, xpos
    		Player -> SetPos, Y, ypos
    		Player -> SetPos, Z, zpos
    		ToggleMenus
    		MenuTest
    		MenuTest
   	 	FadeIn, 0.1
		set timer to 0
		set sp_offen_aldruhn to 0
		set state to 0
	endif
endif

if ( state == 6 )
	if ( GetDistance Player > 128 )
		set state to 1
	endif
endif

end
 
Zuletzt bearbeitet:
  • Like
Reaktionen: Pyro Phoenix
Ich war der Meinung, mal irgendein Plugin gesehen zu haben, bei dem das möglich war. Da wurde das dann AFAIK mittels Markieren/Rückkehr Zauber gelößt.
 
Wenn du das so lösen willst, wird das klappen. Allerdings ist es nicht die "feine Art" einfach die Markierung, die ein Spieler vielleicht mit viel Mühe an einem schwer erreichbaren Punkt gesetzt hat, unwiederbringlich zu versetzen.
 
Könnte man ja dann so regeln, dass der Spieler gefragt wird, ob die aktuelle Position gespeichert werden soll ... Wenn Nein, findet die Rückkehr zu einem fest definierten Punkt statt.

Nur ich weiß leider nicht, wie ich das mit den Zaubern Scripttechnisch Realisiere. Das Plugin hab ich schon lange nichtmehr - sonst würde ich da mal schnell reinschaun.
 
Zuletzt bearbeitet:
Konnte man den Spieler mit "Cast ZauberID Ziel" nicht zwingen, einen Zauber zu wirken? Und wenn ich mich richtig erinnere, wurde dabei kein Mana oder so verbraucht, weiß aber nicht mehr genau. Alternativ kann man ja einen neuen Zauber mit 0 Kosten dazu erstellen, den der Player wirken muss :)
mfg erc
 
Sorry für DP aber es gibt Neuigkeiten. (Nen Edit würde niemand bemerken)

Ich hab die Scripte jetzt soweit "fertig". Es gibt nurnoch 3 Probleme:

1: OnPCEquip -> Eventabfrage verursacht CTD. (Absturz)
2: Ringscript -> Code zum Markierung setzen fehlt.
3: Portalscript -> Code zum Rückkehren fehlt.

g_debugmode & _HF_s_PortalMarkerState sind Globale Variablen.

Ringscript:

Code:
Begin _HF_SCP_Teleportring

short s_state
short s_button_01
short s_button_02

short OnPCEquip

; Check for "player is equipping item" event becomes true.

	if ( s_state == 0 )
		if ( OnPCEquip == 1 )
			if ( g_debugmode )
				MessageBox "PC EQUIPPED"
			endif
			set OnPCEquip to 0
			set s_state to 1
		endif
	endif

; Ask player, if he wants to beam or just equip the item.

	if ( s_state == 1 )
		MessageBox "Wollt ihr die Hammerfeste betreten ?", "Ja.", "Jetzt nicht."
		set s_state to 2
	endif

; Wait for the player to choose an answer.

	if ( s_state == 2 )
		set s_button_01 to GetButtonPressed
		if ( g_debugmode )
			MessageBox "BUTTON PRESSED: %g", s_button_01
		endif
		if ( s_button_01 != -1 )
			set s_state to 3
		endif
	endif

; Check if player wants to equip.

	if ( s_state == 3 )
		if ( s_button_01 == 0 )
			if ( g_debugmode )
				MessageBox "USE BEAM"
			endif
			set s_state to 4
		elseif ( s_button_01 == 1 )
			if ( g_debugmode )
				MessageBox "ONLY EQUIP"
			endif
			set s_state to 0
			return
		endif
	endif

; If player want to beam, ask him if he want to to use markers or just instant beam.

	if ( s_state == 4 )
		MessageBox "Rückreisepunkt diesem Ort setzen ? (Verschiebt "Markieren"-Zauber !)", "Ja.", "Nein."
		set s_state to 5
	endif

; Wait for the player to choose an answer.

	if ( s_state == 5 )
		set s_button_02 to GetButtonPressed
		if ( g_debugmode )
			MessageBox "BUTTON PRESSED: %g", s_button_01
		endif
		if ( s_button_02 != -1 )
			set s_state to 6
		endif
	endif

; Check if player want to use markers or not.

	if ( s_state == 6 )
		if ( s_button_02 == 0 )
			if ( g_debugmode )
				MessageBox "BEAM MARKER"
			endif
			set "_HF_s_PortalMarkerState" to 1

			; INSERT MARKER CODE HERE

			playsound "mysticism area"
			Player->PositionCell 19707, 1954, 18808, 180 "Hammerfeste: Große Halle"
			set s_state to 0
			return
		elseif ( s_button_02 == 1 )
			if ( g_debugmode )
				MessageBox "BEAM SOLID"
			endif
			set "_HF_s_PortalMarkerState" to 0
			playsound "mysticism area"
			Player->PositionCell 19707, 1954, 18808, 180 "Hammerfeste: Große Halle"
			set s_state to 0
			return
		endif
	endif

End _HF_SCP_Teleportring

Portalscript:
Code:
begin _HF_SCP_Portal_Exit

short s_state
short s_button

; Reset portal, if player gets out of reach.

	if ( s_state == -1 )
		if ( GetDistance, Player > 128 )
			if ( g_debugmode )
				MessageBox "PORTAL RESET"
			endif
			set s_state to 0
		endif
	endif

; Wait for player comes in reach, or if portal is activated manually.

	if ( s_state == 0 )
		if ( GetDistance, Player < 128 )
			set s_state to 1
		endif
	endif
	if ( OnActivate )
		set s_state to 1
	endif

; Show up menue when toggled.

	if ( s_state == 1 )
		MessageBox "Wollt Ihr das Portal betreten?", "Ja.", "Nein."
		set s_state to 2
	endif

; Save the chosen answer.

	if ( s_state == 2 )
		set s_button to GetButtonPressed
		if ( g_debugmode )
			MessageBox "BUTTON PRESSED: %g", s_button
		endif
		if ( s_button != -1 )
			set s_state to 3
		endif
	endif

; Send the player either back to the marked point or to the solid return point in XXX depending on the option which he chosed at the teleportring menue.

	if ( s_state == 3 )
		if ( s_button == 0 )
			if ( "_HF_s_PortalMarkerState" == 0 )
				playsound "mysticism area"
				if ( g_debugmode )
					MessageBox "BEAM SOLID"
				endif
				Player->PositionCell 12, 219, -501, 0 "Vivec, Hoher Tempel"
				set s_state to -1
			endif

			if ( "_HF_s_PortalMarkerState" == 1 )
				if ( g_debugmode )
					MessageBox "BEAM MARKER"
				endif

				; INSERT RETURN SCRIPT HERE

			endif
		endif
		if ( s_button == 1 )
			if ( g_debugmode )
				MessageBox "BEAM ABORT"
			endif
			set s_state to -1
			return
		endif
	endif

end _HF_SCP_Portal_Exit
 
Ich bin zwar wahrlich kein Experte, was die Scripte bei Morrowind angeht, aber mir fällt immer wieder folgende Zeile auf:
if ( g_debugmode )
Du fragst damit: Wenn Variable. Gleich was? 1? 0? 5000000?
Wozu hast du die überhaupt drin?
Eigentlich ein Wunder, dass der Script-Editor beim kompilieren nicht gemeckert hat.
mfg erc
 
Ich bin zwar wahrlich kein Experte, was die Scripte bei Morrowind angeht, aber mir fällt immer wieder folgende Zeile auf:
if ( g_debugmode )
Du fragst damit: Wenn Variable. Gleich was? 1? 0? 5000000?
Wozu hast du die überhaupt drin?
Eigentlich ein Wunder, dass der Script-Editor beim kompilieren nicht gemeckert hat.
mfg erc

Leitet sich eigentlich schon fast vom Variablennamen ab. Da ich mit den Scripten keine Fehlerabfrage durchführen kann, hab ich das in Form von Message Boxen gelößt. Wenn eine Operation erfolgreich durchgefüht wird, wird eine Meldung ausgegeben. Wenn die Meldung mal nicht ausgegeben wird, kann ich also ungefähr feststellen, wo sich in etwa der Fehler im Script versteckt hat. Nicht wirklich genau, aber so lässt sich der Fehler schon ziemlich gut eingrenzen. Kann ja dann zum Release entfernt werden - dadurch optimiert man die Performance, da nich jedes mal geprüft werden muss, ob der Debugmodus gesetzt ist.

Zu der Frage warum da die Vergleichsoperanden fehlen:

g_debugmode stellt einen boolschen Wert dar. Wenn der Wert = 0 ist, ist die Bedingung FALSE. Ist g_debugmode != 0 (1) ist die Bedingung TRUE.

Die IF Funktion überprüft ja bekanntermaßen, ob eine gegebene Bedingung TRUE ist und führt dann den darin enthaltenen Code aus.

g_debugmode = nicht 0

if ( g_debugmode ) == if ( !0 ) == if ( !FALSE ) == if ( g_debugmode != 0 )

also

Codeblock ausführen.​

Ebenfalls funktioniert folgendes Statement:

g_debugmode = 0

if ( !g_debugmode ) == if ( 1 ) == if ( TRUE ) == if ( g_debugmode != 1 )

also

Codeblock ausführen.​

Auf einen Vergleichsoperator kann hier also getroßt verzichtet werden. Ebenso bei allen Funktionen, die entweder 1 oder 0 zurückliefern. 8) Puh. Ich hoffe mal, dass das alles so korrekt ist, wie ich es geschrieben hab.
 
Zuletzt bearbeitet:
Nur so ganz nebenbei:

Morrowind Script ist keine höhere Sprache. Viele der aus anderen Sprachen gewohnten Bequemlichkeitsformeln sind nicht anwendbar. Also code sauber, sonst führt das zu unvorhersagbarem Verhalten.
 
Okay aber selbst wenn ich sauber code, sorgt folgender Scriptteil für nen Totalabsturz:

Code:
	if ( s_state == 0 )
		if ( OnPCEquip == 1 )
			if ( g_debugmode == 1 )
				MessageBox "PC EQUIPPED"
			endif
			set OnPCEquip to 0
			set s_state to 1
		endif
	endif

Warum ? Ich find den Fehler einfach nich.
 
Zuletzt bearbeitet:
Ja. Ist eine Globale short Variable mit dem Wert 1

Aber ich glaub, ich hab den Käfer inzwischen ausgetrieben ...
MW kam wohl nicht damit klar, dass der Ring bereits ausgerüßtet war. Beim versuch, das Ding dan abzulegen gabs nen komplettabsturz. Script im CS "deaktiviert" -> geladen -> Ring aus dem Inventar entfernt -> Gespeichert -> Script im CS "aktiviert" -> Game geladen -> geht.
 
Zuletzt bearbeitet:
Hallo Leute,

ich bin gerade dabei mir einen Söldner zu basteln und vermute ohne Script wird das nicht funktionieren. Da es aber zumindest in Tribunal Söldner gibt, muss das Script dafür schon vorhanden sein. Kann mir jemand sagen welches das ist bzw. wenn es ohne Script funktioniert was ich machen muss ?

(Ziel der ganzen Sache soll es sein, dass ich zu dem Typen hingehen kann, ihn anlabere und ihn für Geld anheuern kann)
 
Öhm, danke erstmal :)

Das ist ja alles auf Englisch...:?

Prinzipiell ist das kein problem, aber das ist so viel, kennst du auch was auf Deutsch ? :huh:

Muss ja keine ganze Schablone sein, mir reicht der Script (auch der von Tribunal), ich mach das nur son bisschen nebenbei und hab da keine hohen Ansprüche :D
 
Das Script heisst Mercenary_Calvus, ist - in englisch - kommentiert.
hat damit zwar recht wenig zu tun: aber bei der Hand voll Leuten die ein Script gern auf deutsch kommentiert sehen würden, wird sich auch keiner die Mühe machen. Zumal man dann entweder total genial sein muss und sich alles selbst beigrebracht hat oder irgend wann man eines der vielen auf englisch kommentierten gelesen.
 
  • Like
Reaktionen: haheho
Ich hab jetzt einfach diesen Calvus Horatius genommen und ihm eine neue Rüstung, eine neue Waffe und ein neues Level gegeben, aber bietet mir nichts an, woran kann das liegen ?

(bipolares Schwert, komplette adamantium rüstung, lvl 1000)