Faire d'une créature une statue

Répondre
Partager Rechercher
Un jour, une mappeuse m'avait dit qu'il était possible de créer sa propre statue avec des créatures existantes.

Elle me disait de leur mettre l'effet peau de pierre et de les immobiliser. Sauf que je ne sais pas faire. Est-ce que quelqu'un saurait m'aider ?
Script à placer dans le onSpawn de la créature :

Code PHP:

// petrify the "statues" in the sculptor's workshop (on spawn of the object)

void main()
{
    
effect ePetrify EffectPetrify();
    
ApplyEffectToObject(DURATION_TYPE_INSTANTePetrifyOBJECT_SELF);    

(tiré d'une célèbre campagne )
Je rebondis sur ce post, est-il possible de faire redevenir humaine les statues obtenues avec cette méthode via un parchemin "transformation de la pierre en chair" ?
Oui, on peut supprimer l'effet pétrification. Si on ne fait pas attention, c'est d'ailleurs un risque pour "faire des statues".

En dehors des effets spéciaux ( pétrification / immobilisation ) il faut rendre insensible à la magie, invincible, faire un script pour que la statue ne se tourne pas quand on veut lui adresser la parole, choisir des animations et les arrêter au bon moment pour que les poses soient sympas. Et je dois en oublier.
Il est évidemment préférable de placer les "statues" dans une zone sans combats.

Une fois figées elles ne répondent pas à une conversation. J'ai cependant mis par précaution une conversation d'une seule phrase flottante "[Ces statues sont très réalistes]", mais je ne sais plus si ça sert vraiment, en tous cas elles ne se tournent pas.

Pour le risque "magie" voilà un script à placer dans OnEnterClient (connexion client) de la zone :

Code PHP:

// prevent magic in the sculptor's house. Targeted : Anne and PC in case PC has magic)

void NoMagic(object oCreature)
{
    
effect eAnti EffectSpellFailure(100);
    
eAnti SupernaturalEffect(eAnti);
    
    
ApplyEffectToObject(DURATION_TYPE_PERMANENTeAntioCreature);    
}

void main()
{
    
NoMagic(GetObjectByTag("anne"));
    
NoMagic(GetFirstPC());

A adapter en fonction des compagnons qui pourraient disposer du sort de dé-pétrification .

Et pour rendre les possibilités de sorts à la sortie de la zone, à placer dans le OnExit :
Code PHP:

// restore magic when exiting sculptor's house. (anne and pc)

void RemoveNoMagic(object oCreature)
{
    
effect eEffect GetFirstEffect(oCreature);
    while (
GetIsEffectValid(eEffect) == TRUE)
    {
        if (
GetEffectSubType(eEffect) == SUBTYPE_SUPERNATURAL)
        {
            if (
GetEffectType(eEffect) == EFFECT_TYPE_SPELL_FAILURE)
            {
                
RemoveEffect(oCreatureeEffect);
            }
        }
        
eEffect GetNextEffect(oCreature);
    }    
}

void main()
{
    
RemoveNoMagic(GetObjectByTag("anne"));
    
RemoveNoMagic(GetFirstPC());

De même à adapter en fonction des compagnons susceptibles de disposer du sort de dé-pétrification.
Pour un PW, la solution la plus clean serait peut-être de placer des variables sur tes blueprints / créatures ( ex "STATUE" = 1, "POSE" = 3 ) et de lancer les scripts via l'événement onSpawn.
Je remonte ce vieux post qui fonctionne très bien pour faire une statue, mais j'ai un petit souci, le personnage parait trop "vivant". N'y aurait-il pas un moyen simple de teinter en gris par exemple tant qu'il est sous forme de statue pour qu'ensuite il retrouve ses couleurs lorsque l'on utilise un sort contre la pétrification ?
Il te faut 2 fois le même personnage : un que tu teintes avec du blanc ou du gris léger ça marche bien, et un avec ses couleurs normales une fois dé-pétrifié.

Quand le sort est lancé, déclenche un script qui détruit le premier et "spawne" le second.
Je viens de tester et c'est exactement ce qu'il me fallait ! Il me reste toutefois deux légers problèmes ... je n'arrive pas à détruire la statue de départ et surtout comme j'ai placé le script du spawn sous le "déclenchement par un sort" n'importe quel sort lancé sur la statue fait spawner le personnage.
Après plusieurs essais infructueux je me retourne vers vous, je n'ai trouvé aucun "check" possible lorsqu'il s'agit de sorts ... comment puis-je conditionner l'exécution de mon script à l'utilisation d'un sort particulier ou d'un parchemin particulier ?
Lorsqu'un sort est lancé dans le jeu, tu peux ajouter de façon générique des traitements spécifiques dans le script "gen_spellhook" (nom à initialiser dans le module).

Je te donne un exemple issu de notre module des Iles du couchant :

Code:
// Script permettant de rependre la main sur le système de sort de NWN
// Le script est activé sur lancement d'un sort, son nom est fixé dans mod_start par la commande SetModuleOverrideSpellscript("gen_spellhook");
 
#include "x2_inc_switches"
void main() 
{ 
    // Si le réceptacle du sort est un atelier d'enchantement, activation du script d'enchantement, inhibition du sort.
 object oTarget = GetSpellTargetObject();
 if(GetTag(oTarget)=="TS_ATELIER_ENCHANTEUR")
 {
  int iSort = GetSpellId();  // Sort lancé sur l'atelier
  SetLocalInt(OBJECT_SELF, "iSort", iSort);
  SetLocalObject(OBJECT_SELF,"oTarget", oTarget);
  SetModuleOverrideSpellScriptFinished(); // inhibition du sort
  ExecuteScript("ts_enchanteur", OBJECT_SELF);
 }
    return; 
}
Dans cet exemple, un magicien lance un sort sur un atelier pour enchanter un objet.
Le sort est récupéré par la commande iSort = GetSpellId();
Il est ensuite sauvegardé en variable locale du lanceur du sort : SetLocalInt(OBJECT_SELF, "iSort", iSort);
Pour info, nous sauvegardons aussi l'objet cible du sort, et le sort lui-même est inhibé dans notre cas particulier car utilisé uniquement pour activer l'enchantement (SetModuleOverrideSpellScriptFinished(); // inhibition du sort). Si tu veux que le sort s'exécute normalement, il ne faut pas mettre cette commande.

Ensuite, tu peux utiliser dans un autre script (dans notre exemple ts-enchanteur) le nom du sort lancé pour conditionner les effets, tu récupères la variable locale et tu la compares à la constante correspondant au sort que tu recherches.
Les constantes de sort sont de la forme SPELL_NomDuSort, par exemple SPELL_STONE_TO_FLESH, ou SPELL_FLESH_TO_STONE.

Tu peux peut-être faire plus simple et spécifique en utilisant GetSpellId() directement dans ton script de "déclenchement par un sort" (je ne suis pas sur que ça fonctionne) sur la statue, et en faisant ensuite la comparaisons avec la constante du sort attendu pour activer la suite de tes traitements.
Je voudrais une simple vérification du sort utilisé en fait, j'utilise ce script mais il ne vérifie pas le sort :

Code PHP:

void main()
{
object oSpell;
object oTarget;
oTarget GetObjectByTag("c_bran_statue");    
oSpell GetObjectByTag("transmu_pierre_chair");
DestroyObject(oTarget0.0);
CreateObject(OBJECT_TYPE_CREATURE"c_branwen"GetLocation(GetWaypointByTag("spawn_branwen")));


Je ne l'ai pas essayé mais à priori j'attacherais un script à la créature à dé-pétrifier. L'attacher à Script déclenché par le lancer d'un sort.

Dans ce script je testerais alors le sort de dé-pétrification :
if (GetLastSpell() == SPELL_STONE_TO_FLESH) ...
J'ai modifié mon script de la façon suivante :

Code PHP:

#include "x2_inc_switches"

object oTarget;
object oSpell
void main()
{    
oTarget GetObjectByTag("c_bran_statue");
if (
GetLastSpell() == SPELL_STONE_TO_FLESH)
{
DestroyObject(oTarget0.0);
CreateObject(OBJECT_TYPE_CREATURE"c_branwen"GetLocation(GetWaypointByTag("spawn_branwen")));
}    

Malheureusement, non seulement ça ne vérifie pas le sort mais en plus ça semble bloquer la destruction de la statue.
Est que le script est bien attaché à Script déclenché par le lancer d'un sort de la statue?

Pour vois s'il passe bien dans le script et quel est le sort effectivement testé : ajoutes avant le if (GetLastSpell ...

int nSpell = GetLastSpell();
object oPC = GetFirstPC();
SendMessageToPC (oPC, "Spell : "+IntToString(nSpell));

tu pourras alors voir s'il passe bien dans le script et quel est le N° de sort renvoyé
C'est bon, j'ai trouvé, ce devait être le "SPELL_" qui posait problème.

J'ai modifié le script comme suit et ça fonctionne parfaitement :

Code PHP:

#include "x2_inc_switches"

object oTarget;
object oPC GetFirstPC();
void main()
{    
oTarget GetObjectByTag("c_bran_statue");
int nSpell GetLastSpell();
if (
GetLastSpell() == 486)
{
DestroyObject(oTarget0.0);
{
CreateObject(OBJECT_TYPE_CREATURE"c_branwen"GetLocation(GetWaypointByTag("spawn_branwen")));
}    
}

Un grand merci pour votre aide !
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés