Aller au contenu


Détecter Un Chargement De Sauvegarde


  • Veuillez vous connecter pour répondre
3 réponses à ce sujet

#1 elendell

elendell

    Mécano Dell'Arte


Posté 23 mai 2009 - 16:00

Bonjour,

Dans certains cas, on peut avoir besoin de détecter si le joueur a rechargé sa partie. Soit pour les besoins d'une quête (le joueur n'a le droit qu'à un seul essai), soit pour d'autres raisons. Par exemple, un véhicule qui se déplace ne se retrouve pas (après chargement) à l'endroit où il était lors de la sauvegarde mais à l'endroit par où il est entré dans la cellule. Il faut donc lui redonner les dernières coordonnées relevées. Il y a également d'autres cas où cette détection est utile (voir MSfD).

Le MSfD8 propose 5 manières de le détecter (page 143) mais elles ne fonctionnent que si Morrowind est quitté et relancé et pas dans le cas où le joueur recharge sans relancer le jeu. Sauf peut-être une façon que je n'ai pas essayée mais qui nécessite d'utiliser les scripts de démarrage de Tribunal ou Bloodmoon. Par ailleurs, une seule méthode est utilisable sans les extensions (ForceSneak) et je sais pour l'avoir déjà utilisée qu'elle est lourde à mettre en œuvre car elle nécessite un PNJ prévu à cet effet.

J'ai réalisé tout à l'heure qu'une particularité des scripts "ciblés" peut être utilisée pour cette détection qui se fera dans tous les cas, que le jeu soit relancé ou non. Si le script "ciblé" est lancé par le PJ, il perd sa cible dès qu'on recharge le jeu et les fonctions qui se référaient au PJ quand il était "ciblé" n'ont plus d'objet de référence. Il suffit donc d'en utiliser certaines. J'utilise "GetPos" (x, y et z) et "GetAngle" mais d'autres sont à tester.

Si elles n'ont aucune cible, les "GetPos" renvoient 0 et "GetAngle" renvoie 303.50. A l'extérieur, la "position 0, 0, 0, 303.5" n'est pas accessible au PJ (collision). Elle peut l'être dans une cellule intérieure mais le cas est très peu probable (et on peut même, si on pense que cela peut arriver malgré l'angle précis, faire une détection sur plusieurs frames).

Il faut donc faire un script global qui sera "ciblé" sur le PJ (lancé par lui) et stoppé s'il perd sa cible :

begin Elnd_Scr_DetecteRecharge

float XPL
float YPL
float ZPL
float APL

if ( MenuMode == 1 )
	return
endif

set XPL to GetPos x
set YPL to GetPos y
set ZPL to GetPos z
set APL to GetAngle z

if ( XPL == 0 )
	if ( YPL == 0 )
		if ( ZPL == 0 )
			if ( APL == 303.5 )
				StopScript "Elnd_Scr_DetecteRecharge"
			endif
		endif
	endif
endif

end

Il faut bien sûr ajouter les instructions pour le stopper aussi quand il n'est plus utile.
Ensuite, on place ce qui suit dans le script qui doit faire quelque chose en cas de recharge de sauvegarde :

if ( ScriptRunning "Elnd_Scr_DetecteRecharge" == 0 )
	"Player"->StartScript, "Elnd_Scr_DetecteRecharge"
;	Faire ici ce qui est prévu en cas de recharge
	MessageBox "Vous venez de recharger !"
endif

Il faut également faire lancer le script la première fois sans que cela entraine des conséquences (suivant les cas).

Pour essayer, j'ai fait un script indépendant que j'ai lancé à la console :

begin Elnd_Scr_TEST

short etape

if ( etape == 1 )

	if ( ScriptRunning "Elnd_Scr_DetecteRecharge" == 0 )
		"Player"->StartScript, "Elnd_Scr_DetecteRecharge"
;		Faire ici ce qui est prévu en cas de recharge
		MessageBox "Vous venez de recharger !"
	endif

elseif ( etape == 0 )

	"Player"->StartScript, "Elnd_Scr_DetecteRecharge"
	set etape to 1

endif

end

Voila, il ne me reste plus qu'à tester d'autres fonctions qui seraient peut-être plus simples que celles-ci et à changer ce que j'avais précédemment fait dans mes scripts...  :)

#2 Snaïpe

Snaïpe

    ...itset tnus otroh nI


Posté 23 mai 2009 - 16:33

j'y pense, corrigez-moi si j'ai tort, mais la Fonction DontSaveObject réinitialise les variables locales de l'objet, non ?

si ce que je dis est juste ( mais je n'en suis pas totalement sûr :good: ), on devrait pouvoir détecter la recharge d'une sauvegarde; il suffirait d'attacher un script du genre :

Begin MonScript

DontSaveObject

Short State

If ( Verifiy == 1 )
	If ( State == 0 ); on ignore la 1ere fois

		Set State to 1

	endif
else

	return

endif

If ( State == 0 )

   MessageBox, "Vous venez de recharger !"
   Set State to 1

endif
sur un editormarker, qui ne s'active que si la variable globale "verifiy" est mise a 1.

l'éditormarker est statique, mais on pourrait le faire suivre le joueur avec une autre condition :

If ( CellChanged == 1 )
	SetDelete 1
endif
suivi d'une commande dans un script global qui appelle de nouveau l'objet avec un PlaceAtPC.

bien sûr, ma théorie n'est fondée que sur le fait que DontSaveObject réinitialise les variables :good: si c'est faux, tant pis, j'aurai essayé :)

Modifié par Snaïpe, 23 mai 2009 - 16:35.


#3 elendell

elendell

    Mécano Dell'Arte


Posté 23 mai 2009 - 17:31

Je ne me suis jamais servi de "DontSaveObjet". Je vais donc de suite faire des essais car cette piste me semble prometteuse. J'en donnerai les résultats tout à l'heure.

En attendant, je venais signaler pour la solution que j'ai proposée qu'il y a effectivement une fonction plus simple à utiliser que les "GetPos"/"GetAngle" et qui ne comporte aucun risque. C'est le son. Voici donc le nouveau script "ciblé", plus simple. On peut utiliser n'importe quel son existant en le mettant à 0 et cela n'empêche pas si on le souhaite de faire jouer en plus par le PJ un son audible :

begin Elnd_Scr_DetecteRecharge

if ( MenuMode == 1 )
	return
endif

if ( GetSoundPlaying "Heart" == 0 )
	PlayLoopSound3DVP "Heart" 0.0 0.0
endif

if ( "Player"->GetSoundPlaying "Heart" == 0 )
	StopScript "Elnd_Scr_DetecteRecharge"
endif

end


EDIT : J'ai fait quelques essais avec "DontSaveObjet" mais ils n'ont pas été très concluants. Si je change l'état de l'objet de l'extérieur, le changement s'inscrit dans la sauvegarde. Je présume donc que ce n'est valable que si l'on fait les changements à partir du script local et dans ce cas, cela me semble moins intéressant car il faudrait le supprimer et en replacer un près du PJ à chaque changement de cellule.

PS : D'après ce que je comprends, "DontSaveObjet" ne réinitialise pas les variables mais empêche que les changements appliqués à l'objet (pas à son script) s'enregistrent dans la sauvegarde.

#4 Snaïpe

Snaïpe

    ...itset tnus otroh nI


Posté 23 mai 2009 - 20:12

tant pis.

de toute façons, ton script avec le détecteur de son est beaucoup plus intéressant :)




0 utilisateur(s) li(sen)t ce sujet

0 membre(s), 0 invité(s), 0 utilisateur(s) anonyme(s)