[Tutoriel] SCRIPT - Les invocations d'acteurs et d'objets

Vous trouverez ici les tutoriels et l'entraide sur les outils et techniques de modding spécifiques à Oblivion.
Répondre
Avatar du membre
beeratwork
Légende de la Confrérie
Légende de la Confrérie
Messages : 1881

SCRIPT - Les invocations d'acteurs et d'objets

Message par beeratwork »

Tuto - Index des tutos de Beeratwork - INFO


"SCRIPT - LES INVOCATIONS D'ACTEURS ET D'OBJETS"
Apparitions et disparitions.


Vous désirez créer votre propre créature invoquée ? Ou votre propre personnage invoqué ? Vous désirez faire apparaître un lit pour vous reposer ? Plusieures solutions s'offrent à vous. Vous devez avoir un minimum de connaissance en script, références persistentes et être capable de créer des objets et cellules pour suivre ce tuto.

Les références persistentes :
Les références persistente peuvent être utiles lorsque votre sort d'invocation ne sera utilisé que par un seul acteur : le joueur, un PNJ spécifique ou une créature spécifique. Comme l'acteur invoqué est unique, il ne peut y avoir deux personnages le convoquant au même moment sous peine de "bug". L'acteur à invoquer doit être iniialement positionné dans une cellule vide. Il doit aussi être déclaré en référence persistente.

Pour faire une apparition :

Code : Tout sélectionner

Begin ScriptEffectStart
	set Self to GetSelf
	RefPersistenteInvoquee.Enable
	RefPersistenteInvoquee.Ressurect
	RefPersistenteInvoquee.MoveTo Self
End
Pour faire une disparition :

Code : Tout sélectionner

Begin ScriptEffectStart
	RefPersistenteInvoquee.Disable
End
Cet exemple-ci ne sera efficace que si vous l'utilisez dans un sort de disparition. Si vous désirez faire disparaître l'acteur à la fin d'un sort d'invocation, vous devez utiliser non pas le bloc ScriptEffectStart mais le bloc ScriptEffectFinish.

Vous pourriez aussi renvoyer l'acteur quelque part lorsqu'il disparait à l'aide d'un XMarker placé dans une cellule vide :

Code : Tout sélectionner

Begin ScriptEffectFinish
	RefPersistenteInvoquee.MoveTo RefXMarkerCelluleVide
	RefPersistenteInvoquee.Disable
End
Un exemple pour un sort d'invocation/disparition avec contrôle de faction (script effect, sur soi, 30s) :

Code : Tout sélectionner

scn NomDuScript

ref	Self

Begin ScriptEffectStart
	set Self to GetSelf
	Self.SetFactionRank IDFactionRefPersistenteInvoquee 1
	RefPersistenteInvoquee.Enable
	RefPersistenteInvoquee.Ressurect
	RefPersistenteInvoquee.MoveTo Self
End

Begin ScriptEffectFinish
	Self.SetFactionRank IDFactionRefPersistenteInvoquee -1
	RefPersistenteInvoquee.MoveTo RefXMarkerCelluleVide
	RefPersistenteInvoquee.Disable
End
Bien entendu, la faction "IDFactionRefInvoquee" doit être une faction dont les membres s'aiment si on désire que l'acteur invoqué n'attaque pas l'invocateur. La référence persistente invoquée doit également faire partie de cette faction.
Attention ! La faction n'a pas besoin d'être connue du joueur, puisqu'il s'agit d'agir en douce pour que l'acteur et son invocant soient "copains". Dans le cas de l'invocation d'un compagnon par le joueur, vous aurez mis votre compagnon dans la faction "playerfaction" et donc il sera inutile d'utiliser l'astuce "SetFactionRank".

Si on désire que l'acteur invoqué attaque l'invocateur, il peut-être aussi plus sûr d'utiliser StartCombat :

Code : Tout sélectionner

Begin ScriptEffectStart
	set Self to GetSelf
	RefPersistenteInvoquee.Enable
	RefPersistenteInvoquee.Ressurect
	RefPersistenteInvoquee.MoveTo Self
	RefPersistenteInvoquee.StartCombat Self
End
Invocation à la volée :
Si n'importe quel acteur peut invoquer votre créature vous pouvez utiliser PlaceAtMe. Rappelez-vous que le TESC détruit les bandits que vous tuez au bout de 3 jours, mais pas les épées, plumes, etc que vous placeriez à l'aide de PlaceAtMe. Le script c-dessous ne convient donc pas aux invocations d'objets.

Invocation d'acteur à la volée (script effect, sur soi, 30s)

Code : Tout sélectionner

scn NomDuScript

ref	Self
ref	Summoned

Begin ScriptEffectStart
	set Self to GetSelf
	Self.SetFactionRank IDFactionAmie 1
	set Summoned to Self.PlaceAtMe IDActeur Nombre Distance Direction
	Summoned.SetFactionRank IDFactionAmie 1
End

Begin ScriptEffectFinish
	Self.SetFactionRank IDFactionAmie -1
	Summoned.Kill
	Summoned.Disable
End
Vous pourrez invoquer autant de créatures que vous voudrez. Les créatures mourront au bout de 30s (si vous avez mis le même temps que moi) et disparaîtront de votre vue. Mais elles ne seront détruites qu'au bout de 3 jours. Vous pouvez toujours les renvoyer dans une cellule vide si vous préférez, mais le jeu se chargera de toute façon de les détruire.

Une autre méthode consiste à placer l'acteur en référence persistente dans une cellule vide et à le cloner. Vous pouvez toujours utiliser le système des factions si vous voulez.

Code : Tout sélectionner

scn NomDuScript

ref	Self
ref	SummonedClone

Begin ScriptEffectStart
	set Self to GetSelf
	set SummonedClone to RefPersistenteOriginal.CreateFullActorCopy
	SummonedClone.MoveTo Self
End

Begin ScriptEffectFinish
	SummonedClone.DeleteFullActorCopy
End
Invocation d'objet :
Invoquer une épée ou un lit, c'est différent. Vous ne pourrez pas faire un sort d'invocation d'objet tel qu'un lit et que ce sort soit utilisable par tous les PNJs ! Vous devrez utiliser l'invocation de référence persistente. Pourquoi ? Vous savez bien que vous ne pouvez pas "mettre le lit dans l'inventaire" et que vous ne pouvez vous résoudre à utiliser PlaceAtMe sans faire gonfler la sauvegarde.
Si vous décider d'invoquer une épée, vous pourrez choisir entre deux types d'invocation. L'invocation classique et l'invocation qui conserve l'état. Désirez vous que le joueur, lorsqu'il lance le sort, se voie équipé d'un épée de fer neuve, ou bien d'un glaive de feu qui a conservé son usure et sa charge magique ?

Un exemple pour un sort d'invocation/disparition d'objet en référence persistente (script effect, sur soi, 30s) :

Code : Tout sélectionner

scn NomDuScript

ref	Self

Begin ScriptEffectStart
	set Self to GetSelf
	RefPersistenteObjet.Enable
	RefPersistenteObjet.MoveTo Self
End

Begin ScriptEffectFinish
	RefPersistenteObjet.MoveTo RefXMarkerCelluleVide
	RefPersistenteObjet.Disable
End
Rien ne vous interdit d'utiliser "RefPersistenteObjet.SetOwnership Self" pour que l'invocant soit définit comme le propriétaire de l'objet. Attention ! Inutile de rendre le joueur propriétaire d'un static... Vous devrez toujours utiliser une cellule vide pour y positionner initialement vos objets et les y faire revenir à la fin de l'invocation ou au renvoi.
Deplus, selon les cas, vous aurez peut-être besoin d'utiliser les fonctions de position pour positionner plus ou moins correctement l'objet :

Code : Tout sélectionner

set XAng to RefPersistenteObjet.GetAngle X
set XNew to (XAng + 1)
RefPersistenteObjet.SetAngle X XNew
Un exemple de l'utilisation des fonctions de position :

Code : Tout sélectionner

scn ShadaoeMiscUniqueAlphaSablierScript

short	step
float	OldXPos
float	OldYPos
float	OldZPos
float	OldXAng
float	OldYAng
float	OldZAng
float	NewXPos
float	NewYPos
float	NewZPos
float	NewXAng
float	NewYAng
float	NewZAng
float	timer

Begin OnDrop
	if (step == 0)
		set step to 1
	endif
End

Begin GameMode
	if (step == 1)
		set OldXPos to ShadaoeRefMiscUniqueAlphaSablier.GetPos X
		set OldYPos to ShadaoeRefMiscUniqueAlphaSablier.GetPos Y
		set OldZPos to ShadaoeRefMiscUniqueAlphaSablier.GetPos Z
		set OldXAng to ShadaoeRefMiscUniqueAlphaSablier.GetAngle X
		set OldYAng to ShadaoeRefMiscUniqueAlphaSablier.GetAngle Y
		set OldZAng to ShadaoeRefMiscUniqueAlphaSablier.GetAngle Z
		set step to 2
		set timer to 1
	elseif (step == 2)
		if (timer > 0)
			set timer to (timer - GetSecondsPassed)
		else
			set step to 3
		endif
	elseif (step == 3)
		set NewXPos to ShadaoeRefMiscUniqueAlphaSablier.GetPos X
		set NewYPos to ShadaoeRefMiscUniqueAlphaSablier.GetPos Y
		set NewZPos to ShadaoeRefMiscUniqueAlphaSablier.GetPos Z
		set NewXAng to ShadaoeRefMiscUniqueAlphaSablier.GetAngle X
		set NewYAng to ShadaoeRefMiscUniqueAlphaSablier.GetAngle Y
		set NewZAng to ShadaoeRefMiscUniqueAlphaSablier.GetAngle Z
		if (OldXPos != NewXPos || OldYPos != NewYPos || OldZPos != NewZPos || OldXAng != NewXAng || OldYAng != NewYAng || OldZAng != NewZAng)
			set step to 1
		else
			set step to 4
		endif
	elseif (step == 4)
		set step to 0
		ShadaoeRefContUniqueAlphaCoffre.Enable
		ShadaoeRefContUniqueAlphaCoffre.MoveTo ShadaoeRefMiscUniqueAlphaSablier
		ShadaoeRefMiscUniqueAlphaSablier.Disable
		ShadaoeRefContUniqueAlphaCoffre.SetPos X NewXPos
		ShadaoeRefContUniqueAlphaCoffre.SetPos Y NewYPos
		ShadaoeRefContUniqueAlphaCoffre.SetPos Z NewZPos
		ShadaoeRefContUniqueAlphaCoffre.SetAngle X NewXAng
		ShadaoeRefContUniqueAlphaCoffre.SetAngle Y NewYAng
		ShadaoeRefContUniqueAlphaCoffre.SetAngle Z NewZAng
	endif
End
Un script de positionnement et de détection de mouvement. Shadaoe m'avait une fois demandé de l'aide pour son "Packs d'extensions Fournitures Impériales". Il a bien sûr adapté ce script selon les objets à positionner. Ce script attaché à un sablier devait faire en sorte que lorsque quelqu'un le posait à terre, s'il ne bougeait plus au bout de une seconde, il disparaîssait et une armoire apparaîssait à la place. L'armoire était bien sûr un container. Ce script fonctionne donc avec des objets qui ne peuvent pas être mis dans l'inventaire.

Pour faire un coffre transportable, par exemple, il faut créer un objet diver et lui lier le meshe du coffre désiré. Il faut placer un coffre en référence persistente dans une cellule vide. L'objet diver servira en fait de coffre tandis que le coffre réel, le joueur ne le verra jamais. L'activation de l'objet diver, par exemple en mode discrétion ou sous l'effet d'un sort, servira à remettre le coffre dans l'inventaire, tandis qu'une activation normale activera le coffre distant. Le code de l'objet diver :

Code : Tout sélectionner

scn ScriptObjetManipulable

ref	Actor

Begin OnActivate
	set Actor to GetActionRef
	if (Actor.IsSneaking == 1)
		Activate
	else
		RefPersitenteDuCoffreDansLaCelluleVide.Activate Actor
	endif
End
Ici, il faudra être en mode discrétion pour prendre l'objet, sinon, on ouvre le coffre.

Pour invoquer une épée neuve à la volée (script effect, sur soi, 30s) :

Code : Tout sélectionner

scn InvocationEpeeNeuve

ref	Self
short	RemoveCount

Begin ScriptEffectStart
	set Self to GetSelf
	Self.AddItem IDEpeeInvoquee 1
	Self.EquipItem IDEpeeInvoquee 1
End

Begin ScriptEffectFinish
	Self.UnEquipItem IDEpeeInvoquee 1
	set RemoveCount to Self.GetItemCount IDEpeeInvoquee
	Self.RemoveItem IDEpeeInvoquee RemoveCount
End
L'épée invoquée doit être un objet de quête puisque le joueur ne doit pas pouvoir s'en débarrasser ou l'enchanter. Vous pouvez aussi utiliser "Self.EquipItem IDEpeeInvoquee 1" pour forcer l'utilisateur à prendre l'épée et à ne pas pouvoir en utiliser une autre durant le temps du sort. Evidement, avant de la retirer, il faudra faire un "Self.UnEquipItem IDEpeeInvoquee 1". Comme l'utilisateur ne peut avoir qu'une seule épée invoquée à la fois, autant retirer celles qu'il aurait réussi à prendre par la triche ou suite à un bug.
Dans le cas ou l'on utiliserait éventuellement une épée classique, donc qui ne serait pas nécessairement en objet de quête, etc, il vaut mieux compter le nombre d'épée avant et après invocation pour retirer le nombre d'épée ajouté :

Code : Tout sélectionner

scn InvocationEpeeClassique

ref	Self
short	OldCount
short	NewCount
short	RemoveCount

Begin ScriptEffectStart
	set Self to GetSelf
	set OldCount to Self.getItemCount IDEpeeInvoquee
	Self.AddItem IDEpeeInvoquee 1
End

Begin ScriptEffectFinish
	set NewCount to Self.GetItemCount IDEpeeInvoquee
	set RemoveCount to (NewCount - OldCount)
	Self.RemoveItem IDEpeeInvoquee RemoveCount
End
L'invocation d'une épée enchantée qui conserve son usure et sa charge se fait à l'aide d'une quête en "start game enabled" à laquelle on rattache un script pour conserver les valeurs d'usure. Il faut utiliser les fonctions d'OBSE pour pouvoir connaître les caractéristiques de l'épée.
Le code de la quête :

Code : Tout sélectionner

scn ScriptDeQueteEpeeInvoquee

short	Initialisation		; Pour pouvoir reseter l'arme
short	VarAttackDamage		; Pour stocker les dégâts que l'arme inflige
short	VarCurrentCharge	; Pour stocker la charge actuelle
short	VarCurrentHealth	; Pour stocker l'usure actuelle
Le code du sort :

Code : Tout sélectionner

scn InvocationEpeeInvoquee

ref	Self
ref	RefWeapon
short	RemoveCount

Begin ScriptEffectStart
	if (IDDeLaQuete.Initialisation == 0)
		set IDDeLaQuete.Initialisation to 1
		set IDDeLaQuete.VarAttackDamage to 20
		set IDDeLaQuete.VarCurrentCharge to 500
		set IDDeLaQuete.VarCurrentHealth to 100
	endif
	set Self to GetSelf
	Self.AddItem IDEpeeEnConserve 1
	Self.EquipItem IDEpeeEnConserve 1
	set RefWeapon to player.GetEquippedObject 16
	SetAttackDamage IDDeLaQuete.VarAttackDamage RefWeapon
	SetCurrentCharge IDDeLaQuete.VarCurrentCharge RefWeapon
	SetCurrentHealth IDDeLaQuete.VarCurrentHealth RefWeapon
End

Begin ScriptEffectFinish
	set IDDeLaQuete.VarAttackDamage to RefWeapon.GetAttackDamage
	set IDDeLaQuete.VarCurrentCharge to RefWeapon.GetCurrentCharge
	set IDDeLaQuete.VarCurrentHealth to RefWeapon.GetCurrentHealth
	Self.UnEquipItem IDEpeeInvoquee 1
	set RemoveCount to Self.GetItemCount IDEpeeInvoquee
	Self.RemoveItem IDEpeeInvoquee RemoveCount
End
Si il y a un problème avec l'épée et qu'on veut lui faire retrouver sa valeur initiale car on n'arrive pas à la réparer, recharger, etc, on peut soit faire un script spécial pour mettre "IDDeLaQuete.Initialisation" à 0 et ainsi réinitialiser l'épée en lançant à nouveau le sort, soit mettre les variables de la quête en variables globale (plus besoin de la quête). Cela permettra de passer en mode console pour agir sur le sort. Attention la triche !

Un autre principe plus simple consisterait à transférer l'épée d'un coffre à l'utilisateur au début de l'invocation puis à renvoyer l'épée dans le coffre quand le sort est terminé. Je vous invite à essayer si ça vous permet d'éviter d'utiliser OBSE, mais je n'y suis pas encore arrivé.

Les invocation du TESC :
Pourquoi je n'ai pas commencé par ça ? Pour vous faire réfléchir ! Ahahah ! Vous avez sans doute constaté que la fenêtre de création des PNJs propose une option "Summonable" (invocable). Si vous l'utilisez, le PNJ peut être utilisé dans les types de sorts pour la configuration d'un effet d'invocation "bonus". Autant dire que si Bethesda sort une extension avec une autre invocation d'Haskil dans ce genre là, votre mod risque d'être incompatible. Il est impossible de faire ça avec les créatures et les objets. En fait, les effets d'invocation sont implémentés dans le jeu.
Répondre

Retourner vers « Modder Oblivion »