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...