Construction Set Skriptthread zum Construction Set

Das ist ja schon vorhanden. Für jedes einzelne Item. Mit Bedingung GetItemCount. Ich dachte nur, man könnte es vielleicht über ein Skript regeln.
 
Wo genau versprichst du dir einen Vorteil es über ein Skript zu regeln? Du weisst, daß ich von der Questerei und den Dialogen nix verstehe (und von Skripten nicht viel mehr), aber ich bin mir nicht sicher ob's wirklich einen Vorteil bringt das GetItemCount in ein Skript zu verlagern. Gehen würde es wahrscheinlich, aber ich bin mir noch nicht ganz im klaren was du dir exakt davon versprichst.
 
Ich verstehe vom Skripten genau so wenig wie du, meine Stärken liegen eher in der Questerei. Aber da ich es in diesem Fall nicht hinkriege, das Spiel erkennen zu lassen, wann ich ein Item von bspw. 20 gesuchten Items in meinem Inventar habe, wollte ich es alternativ über ein Skript versuchen. Dabei ist mir noch nicht ganz klar, ob ich dafür noch zusätzlich eine globale Variable definieren muss, und wie genau ich sie einsetzen muss. Solange mir keiner von den skriptkundigen Helfern ein bisschen auf die Sprünge hilft, kann ich diese Quest nicht inszenieren.
 
Hi Arielle

meilenweit davon entfernt ein Fachmann in diesen Sachen zu sein und leider auch meilenweit von meinem CS entfernt schlage ich vor es so zu versuchen:


scn Suppentalk

begin onactivate

short Tomate
short Kuerbis
................

Set Tomate to (gewünschter Endbestand)
.............

playerif getdead != 1 && isincombat != 1 && player.issneaking == 0

if player.getitemcount (TomateId) >> 0 && Tomate >>0
startconversation player (tomatentalk)
remove (TomateID) 1
set tomate to Tomate -1
endif

elseif player.getitemcount (KürbisId) >> 0 && Kürbis >> 0
startconversation player (kuerbistalk)
remove (KürbisID) 1
set Kuerbis to Kuerbis -1
endif

elseif...................................

elseactivate

endif

end


oder die Removes als resultskript an das jeweilige Dialogtopic hängen.

edit: Sieh dir mal das Skript zum Vanilla Mainquest an, auf dem Queststage, bei dem man Bruder Martin die daedrischen Artefakte bringen soll. Wenn man mehr als ein daedrisches Artefakt im Inventar hat, gliedern sich die Dialogoptionen nach meiner Erinnerung genau so auf, wie du es dir vorstellst.

Harvald
 
Zuletzt bearbeitet:
  • Like
Reaktionen: Arielle 1000
Blöde Frage vielleicht, aber wenn man das so skriptet und der Spieler eine Tomate im Gepäck hat wird der entsprechende Dialog gestartet und die Tomate abgeliefert.

Was passiert aber wenn der Spieler später mit Tomate und Kürbis im Gepäck ankommt? Wird dann nicht wieder nur die Tomate abgeliefert und das Skript endet bevor der Bestand an Kürbissen überhaupt abgefragt wird? So wie ich das "elseif" verstehe greift es doch nur wenn die ursprüngliche Bedingung (die "Tomatenabfrage") nicht erfüllt ist, oder?


Okay. Vergiss das. Hatte irgendwie völlig das auf -1 setzen der Variable übersehen. Da fehlt mir wohl doch der gewohnte Mittagsschlaf. :D
 
Zuletzt bearbeitet:
Vielen Dank euch beiden für eure Tipps.

Harvald, ich hab mir nun mal die von dir vorgeschlagene Mainquest angesehen, wo der Player die Artefakte für Martin besorgen muss. Ich glaube, man kann die Item-Abfrage doch komplett über die Dialoge klären, denn dort ist auch nichts anderes als das GetItemCount bei den Conditions angegeben. Wie es scheint, habe ich bei mir lediglich die Bedingung geringfügig falsch eingestellt, falls man das so sagen kann. :D
Wenn das so funktionieren sollte, kann ich also komplett auf ein Skript verzichten.

Falls das jemanden später mal interessieren sollte:
Bei Greetings die Frage: "Habt Ihr die Zutaten gefunden?"
Bei den Conditions kommt neben GetIsID und GetStage eben noch das GetItemCount ... ItemID ... > 0 mit Target Yes und or anhakeln, und das bei jedem einzelnen Item, das gefunden werden muss. Bei 10 Zutaten eben 10 mal GetItemCount untereinander.
Bei Choices gibt man dann zwei Antworten an, "Nein, ich habe nichts gefunden", oder "Ja, ich habe (bspw.) eine Zwiebel gefunden."
Bei der "Ja"-Antwort müssen die Conditions ähnlich aussehen wie im Greeting, aber bei GetItemCount nun nicht das "or" anhakeln.
Bei der "Nein"-Antwort reicht ein GetIsID.
Ich habe es nun mit 1 Item versucht, und auf diese Weise scheint es zu funktionieren. Ich bin gespannt, ob es immer noch funktioniert, wenn ich alle anderen Items auch eingefügt habe. :lol: Ich berichte dann........
 
  • Like
Reaktionen: Harvald
Ich brauch nochmal eure Hilfe.

Es soll beim Anklicken eines Aktivators erst eine Message erscheinen, nach Wegklicken der Message soll dann eine Stage hochgeschaltet werden.
Ich dachte, das geht am besten mit einem Timer. Aber in dieser Form funktioniert das Skript nicht. Die Messagebox erscheint, aber die Stage wird nicht geschaltet. Könntet ihr mir das korrigieren? Danke schon mal.

PHP:
scn MeineQuest

short Ablauf
float timer

begin OnActivate

	if ( IsActionRef Player == 1 ) && ( GetStage MeineQuest  == 50)
	Messagebox "Blablabla!"

	endif

		if Ablauf == 0
			set Ablauf to 1
			set timer to 5
		endif

		if Ablauf == 1
   			set Timer to Timer - GetSecondsPassed 

         			if Timer < 0
           			set Ablauf to 2
				Setstage MeineQuest 60

         			endif
		endif

end
 
  • Like
Reaktionen: Harvald
Timer können in einem OnActivate-Block nicht funktionieren, da dieser nur einmal durchläuft. Die Frage ist, hat die Stage einen Logeintrag, oder nicht?

Wenn nicht, reich doch das:

Code:
Variablen keine!

begin OnActivate

    if IsActionRef Player == 1 && GetStage MeineQuest == 50
        SetStage MeineQuest 60
        Messagebox "Blablabla!"
    endif 

End

Ansonsten eben mit Timer

Code:
short Ablauf
float Timer

begin OnActivate

     if IsActionRef Player == 1 && GetStage MeineQuest == 50
        Set Ablauf to 1
      endif 
 
End

Begin GameMode

    if Ablauf == 1
       set Ablauf to 2
       set Timer to 5
       Messagebox
    endif

    if Ablauf == 2
       set Timer to Timer - GetSecondsPassed 

                if Timer < 0
                   set Ablauf to 3
                   Setstage MeineQuest 60
                endif
    endif

End
 
  • Like
Reaktionen: Arielle 1000
Ich hatte an folgendes gedacht. Eine Creatur die den Player nicht angreift solange man sich nicht bewegt. Nur lässt sich das nicht richtig abfragen.

So hab ich jetzt erst mal gemacht und es funktioniert als Test soweit. Nur nicht mit Bewegung sondern mit laufen. Das mit dem Schleichmodus sollte auch so nicht sein.

Toll wäre es auch, wenn die Creatur sobald sie einen wittert nicht angreift, wenn man sich nicht bewegt, sondern auch noch auf den Player zukommt. So als ob sie wüsste da ist etwas und möchte es näher untersuchen.

Jemand eine Idee wie sich das verbessern lässt?

Auch die Schadenserhöhung die die Creatur per Script verursachen soll, ist leider noch nicht gelöst.

Code:
scn A0CreaAttackDistance1K

;Creatur greift bei bestimmten Ereignissen sofort an. Unabhängig der Settings.

short Schaden
short Level

ref Creatur

ref Distance1
ref Distance2


Begin Onload

	set Creatur to getSelf

	set Level to player.getLevel
	set Schaden to Level*1000
	;modAV Attackbonus SCHADEN	 ;nicht bei Creaturen. Schadenseingabe deshalb direkt zB.10000

End


Begin Gamemode
	
if getgameloaded
		
	set Distance1 to 256*			5		;Felderabstand neuer Attackradius "5" =1280
	set Distance2 to 256*			7		;Felderabstand neuer Attackradius "7" =1792

;===================ENDE DER EINGABEN============================================================

	MessageEX" Witterungsradius=%.0f, Bei schneller Bewegung=%.0f"Distance1, Distance2  3
	MessageEX"Level des Players=%.0f,    Schaden der Creatur=%.0f"Level, Schaden  3

endif
	


if getdistance player < 	Distance1
	
	 	 if player.isSneaking ==1 && player.isRunning !=1
			 MessageEX"2 Sneakmodus, Creatur sieht und hört einen nicht"
			 Creatur.stopcombat player
		 else
			 MessageEX"3 tschüss, Creatur hat einen gewittert"
			 Creatur.startcombat player
		 endif
			

elseif getdistance player <	Distance2
		
		 if player.isRunning	|| player.IsRidingHorse 
			 MessageEX"1 Runmodus, Creatur wird aggressiv und beginnt die Jagd"
			 Creatur.startcombat player
		 else
			 Creatur.stopcombat player		
		 endif

else
		
 Creatur.stopcombat player

endif				


End
 
Zuletzt bearbeitet:
Ja super, nee natürlich mit OBSE (ich selbst nutze die 20) vergas ich zu sagen.

Doch gibt es auch eine allgemeine Abfrage oder ist es nötig alle Bewegungsrichtungen abzufragen? Und wie plaziere ich den Player in die Ref. Das Script liegt ja so wie es jetzt ist, auf der Creatur.

Dank dir schon mal.
 
Ja hast recht, habe ich dann beim Schreiben auch bemerkt. Keine Ahnung was ich da gedacht habe.

Sobald die Werte direkt in den Bedingungen abgefragt werden, läuft es soweit. Siehe Code

Code:
scn A0CreaAttackDistance1K

;Creatur greift bei Witterung und Bewegung sofort an. Unabhängig der Settingeinstellungen.

;short Schaden
;short Level
short Mov

ref Creatur

ref Distance1
ref Distance2


Begin Onload

	set Creatur to getSelf

	;set Level to player.getLevel                     ; steht auf 0, warum. Player ist Level 12
	;set Schaden to Level*1000                     ; steht auch auf 0
	;modAV Attackbonus SCHADEN	      ;geht nicht bei Creaturen. Schadenseingabe deshalb direkt zB.10000

End


Begin Gamemode
	
if getgameloaded
		
	set Distance1 to 256*			5		;Witterungsradius klein "5" =1280
	set Distance2 to 256*			7		;Witterungsradius gross "7" =1792
	set Mov to					0		;Bewegungsvariable
		
;===================ENDE DER EINGABEN============================================================

	MessageEX" Witterungsradius=%.0f, Bei Bewegung=%.0f"		Distance1, Distance2  3
	;MessageEX"Level des Players=%.0f, Schaden der Creatur=%.0f"	Level, Schaden  3

endif
	


if getdistance player < 	Distance1
	
	if player.isMovingForward || player.isMovingBackward || player.isMovingLeft || player.isMovingRight
		set Mov to 1			
	;elseif player.isTurningLeft || player.isTurningRight || player.isSneaking==1
	;	set Mov to 2
	;elseif player.IsRidingHorse || player.isRunning
	;	set Mov to 3	
	else
		set Mov to 0
	endif
		
		

elseif getdistance player <	Distance2

	if player.isRunning || player.IsRidingHorse	
	set Mov to 4

			if Mov==4							
			MessageEX"4 agressiv weit"
			set mov to 6
			endif
	else	
			
		if player.isMovingForward || player.isMovingBackward || player.isMovingLeft || player.isMovingRight
		set Mov to 5
	
			if Mov==5				
			MessageEX"5 gewittert weit"
			set mov to 6
			endif			
		endif
			
	set Mov to 0		
	endif
			
;else		
;Creatur.stopcombat player
		
endif				

	
; Ausserhalb funktioniert die Abfrage nicht.
			
if Mov ==0
set mov to 6		
endif
		
;if Mov 	==1	
;	MessageEX"1 gewittert nah" 
		
	;Creatur.startcombat player
	;MessageEX"1 Creatur hat einen gewittert"
;	set mov to 6
;endif	
;	
;if Mov	==2
						
;	MessageEX"2 weniger gewittert"
;	set mov to 6
;endif
;	
;if Mov	==3
;								
;	MessageEX"3 agressiv nah"
;	set mov to 6
;endif
	

	;Creatur.startcombat player
	;MessageEX"2 Creatur wird aggressiv und beginnt die Jagd"


;	
;	Creatur.stopcombat player
;	MessageEX"3 Creatur sieht und hört einen nicht"
	
	
	
		;if player.isSneaking ==1 && player.isRunning !=1
		;if player.isswimming ==1

End

Doch wieso funktioniert das nicht wenn ich das ausserhalb mit Hilfe der Variablen abfrage.
Code:
;Achtung alle auskommentiert da im Spiel keine Funktion.

;if Mov 	==1	
;	MessageEX"1 gewittert nah" 
		
	;Creatur.startcombat player
	;MessageEX"1 Creatur hat einen gewittert"
;	set mov to 6
;endif	
;	
;if Mov	==2
						
;	MessageEX"2 weniger gewittert"
;	set mov to 6
;endif
;	
;if Mov	==3
;								
;	MessageEX"3 agressiv nah"
;	set mov to 6
;endif
Auch als elseif Syntax hatte das Ganze keinerlei Funktion. Hast du eine Erklärung dafür?


Hast du eine Idee, wie sich der Schadenswert der Creatur per Script ändern lässt. Wie lässt es sich umsetzten, das die Kreatur einen folgt aber nicht angreift solange man sich nicht bewegt, aber sie einen zuvor gewittert hat.

Derzeit bleibt die Creatur obwohl erst rasend vor Zorn, da sie einen gewittert hat und man sich bewegt hat, einfach an dem Punkt stehen an dem sie den Angriff begann. Das kann auch ziemlich weit entfernt sein. Je nach Eingabe des Radius.
Es wäre schön wenn sie sich zu dem Target hinbewegt um dort die Lage zu untersuchen. Denn sie hat ja das Ziel dort vorher ausgemacht. Du merkst schon warauf ich hinaus will. Die Kreatur kann das Ziel nur sehen, wenn das Ziel sich bewegt.

Gruss robin
 
Zuletzt bearbeitet:
Naja die Idee war ja ganz Nett. Aber so nicht Sinnvoll. Ich glaub es macht mehr Sinn die Agression der Creatur zu steuern. Und bei normaler Bewegung ab einem bestimmten Radius lieber die Creatur per Fraktion zum Freund machen, und sie den Player in einem Abstand folgt. Sodas es den Anschein hat, die Creatur verfolgt den Player. Kommt man der Creatur zu nah, wird sie Agressiv und greift an. Bleibt man auf Abstand ist die Creatur zahm. Fängt man in Sichtweite (radius) zu laufen an, wird sie dagegen Agressiv und beginnt die Jagd. So wie bei Wölfen.

Nur wie lässt es sich hinbekommen, das die Creatur nicht gleich wieder zahm wird, sobald der Player wieder normale Bewegungen ausführt. Das wäre dann genauso dumm, wie bei der Methode zuvor.
 
Hallo Leute,

könntet ihr mir nochmal bei einem Skript helfen? Es liegt auf einer Schriftrolle, die beim Aufnehmen ins Inventar folgendes auslösen muss in dieser Reihenfolge:


1. Messagebox soll erscheinen
2. Queststage soll steigen

Vielleicht reicht es, an der entsprechenden Stelle einen Timer einzusetzen. Ich weiß nur nicht wie.
Ich danke euch schon mal für eure Hilfe.


PHP:
Scriptname Meine Quest

short learned
short controlvar
short button
short doonce

Begin OnAdd Player

if ( learned == 0 )
	if ( controlvar == 0 )		
		MessageBox "Wollt Ihr den Zauber erlernen?" "Ja" "Nein"
		set controlvar to 1
	endif
endif

If DoOnce == 0 
         if getstage "MeineQuest" == 8
             SetStage "MeineQuest" 10
         		Set DoOnce to 1
      	Endif
   	Endif

End

Begin GameMode

if ( controlvar == 1 )
	set button to GetButtonPressed

	if ( button == -1 )
		return
	elseif ( button == 0)
		set controlvar to 2
		set learned to 1
		PlaySound UIStatsSkillUp
		Player.AddSpell 000NKGoIsland
	elseif ( button == 1 )
		set controlvar to 0
	endif
endif

End
 
Ich hätte eine kurze Frage die wahrscheinlich jeder der nicht ganz so ein Newbie im scripten ist wie ich auf Anhieb beantworten kann.

Der Spieler findet eine Leiche. Wenn man sie anklickt soll zunächst das Inventar des NSC aufgehen udn wenn dieses geschlossen wird eine Quest Stage geschaltet werden. Da es in der Gegend auch Monster gibt soll das ganze nur stattfinden wenn die unmittelbare Bedrohung beseitigt ist. Ist es o einfach wie ich es mir vorstelle, nämlich so etwas als Object Script auf die Leiche zu legen:

PHP:
 Scn A67HQ01JakirLeiche
 

 short activated
 

 begin OnActivate
 

 if activated == 0 && isActionRef player == 1 && player.isInCombat == 0
     activate
     set activated to 1
 endif
 end

 

 begin GameMode
 

 if activated == 1 && getstage A67HQ01 == 70
     setstage A67HQ01 80
 endif
 end

Überseh ich irgendwas, geht es noch einfacher, oder passt das so?
 
Hast du es denn schon mal getestet? Wenn es bei deinen Tests funktionierte, wird es wohl gehen, wenn nicht, erläutere bitte den Fehler.

Ich bin schon etwas länger raus aus dem Oblivion Scripting, für mich sieht es aber in Ordnung aus. Ich hätte nur statt "set activated to 1" sofort "setstage A67HQ01 80" geschrieben und die Stage-Abfrage in den If-Block von "Begin OnActivate" genommen. So würde der GameMode-Block rausfallen. Musst du aber nicht ;)
 
  • Like
Reaktionen: Andy1967
Getestet hab ich es noch nicht, da das ganze recht spät in der Queste kommt und ich da mal mit einem richtig sauberen Save ran muss um alles von Anfang an gründlich auszuprobieren. Aber da es für dich okay aussieht mach ich mir da keine großen Sorgen. :)

Das Hochschalten der QuestStage in den GameMode Block zu nehmen soll vermeiden, daß der entsprechende Questlog Eintrag schon aufschlägt solange man noch im Inventar der Leiche ist. Da soll sich der Spieler ruhig erst mal in Ruhe austoben.
 
Liebe Community, helft bitte noch mal einem Anfänger beim denken. In meiner Queste gibt es mehrere Stellen an denen die nächste Stage geschaltet wird wenn der Spieler einen Tag gewartet hat. Ich wollte nun nicht unbedingt für jeden "Tagescounter" ein extra Script machen, sondern ganz gerne alles in ein Script packen, u.a. weils damit für mich übersichtlicher wird. Ich dachte mir ich steuere das ganz über eine Variable ("timerstart") die jeweils auf einen bestimmten Wert gesetzt wird wenn der entsprechende Tageszähler starten soll und dabei heraus kam das hier:

PHP:
Scn A67HQ01Warten


 short doonce
 short startday
 short timerstart
 

 float timer
 float fQuestDelayTime
 

 begin GameMode
 

 if timerstart == 0
     return
 

 elseif doonce == 0 && timerstart > 0
         set startday to GameDaysPassed + 1
         set doonce to 1
 

 elseif doonce == 1
         if Gamedayspassed >= startday && timerstart == 60
             setstage A67HQ01    65
             set doonce to 0
             set timerstart to 0
         if Gamedayspassed >= startday && timerstart == 210
             setstage A67HQ01    220
             set doonce to 0
             set timerstart to 0
         if Gamedayspassed >= startday && timerstart == 230
             setstage A67HQ01    240
             set doonce to 0
             set timerstart to 0    
         endif
         endif
         endif
 endif
 

 end
Getestet habe ich es noch nicht, da ich ganz gerne erst mal die Queste "auf dem Papier" / im CS fertigstellen würde um dann alles in einem Rutsch zu testen.

Sieht das für euch Experten so aus als würde es so funktionieren wie ich es gerne hätte? Gibt es bessere Alternativen? Überseh ich irgendwas / begehe einen Denkfehler?

Schon mal herzlichen Dank im Voraus für alle Antworten. :)