Le replicateur ( petit script )

Répondre
Partager Rechercher
Voila, je vous propose se petit script a placer sur le ondeath d une creature

QU es ce qu il fait ?

Lorsque que la creature meure, il cree un nombre de replique de la creature morte egale à 2 fois son niveau. Les nouvelles creatures crées auront un niveau egal a la creature morte +1.

Exemple :

Creature niveau 1

Elle meure, 2 creatures de niveau 2 apparaissent
L une d elle meure , 4 creatures niveau 3 apparaissent

Etc etc.

Le processus est infini, mais il est assez simple d arreter le processus en scriptant une condition ( genre tuer la craeture avec une arme particuliere, etc ...)

Le script :

Code PHP:

// a placer sur le Ondeath de la creature
#include "nw_i0_generic"
void main()
{
    
object attaquant GetLastKiller();

    
int generation GetHitDice(OBJECT_SELF);
    
int new_generation generation++;
    
int nbr generation *2;
    
int i;
    
int angle;
    
int rand;
    
location new_loc;
    
location loc_rep;
    
object new_creat;
    
int XP;
    for (
0i++; nbr )
    {
     
angle Random(180);
     
rand Random(1);
    if (
rand == ) {angle=angle*-1;}    
    
new_loc=GenerateNewLocationFromLocation(GetLocation(OBJECT_SELF),5.0f,IntToFloat(angle),1.0f);
    
loc_rep=CalcSafeLocation(OBJECT_SELF,new_loc,10.0f,FALSE,FALSE);    
    
new_creat=CreateObject(OBJECT_TYPE_CREATURE,"horreur multiple",loc_rep,TRUE);
     
XP = (( new_generation * ( new_generation 1)) / 2) * 1000;
    
ResetCreatureLevelForXP(new_creat,XP,FALSE);
    
ForceRest(new_creat);
    
SetIsTemporaryEnemy(attaquantnew_creat);
    
AssignCommand(new_creatActionAttack(attaquant));
    
AssignCommand(new_creatDetermineCombatRound(attaquant));
    
DelayCommand(0.5ApplyEffectToObject(DURATION_TYPE_INSTANTEffectVisualEffect(VFX_FNF_SUMMON_MONSTER_1),new_creat));

    }

Par contre tu peux alléger quelques parties du script.

Une chose qui me turlupine, c'est :

int new_generation = generation++;

Avec cette commande, la variable "generation" n'aura pas déjà augmenté de 1 avant d'être multipliée par 2 ? De mémoire, ça aurait donc pour effet de créer 4 créatures de niveau 2, puis 6 de niveau 3, puis 8 de niveau 4, etc...

La manière la plus sûre est d'augmenter generation après avoir déterminé le nombre de créatures qui apparaîtront (j'ai marqué nLevel par habitude, on ne se refait pas...).

Il me semble aussi que "DetermineCombatRound()" engage le combat. De ce fait, pas besoin d'un "ActionAttack()". Mais bon... rien ne vaut le test pour savoir :
Code PHP:

#include "nw_i0_generic"
void main()
{
    
object attaquant GetLastKiller();
    
object oSelf OBJECT_SELF;

    
int nLevel GetHitDice(oSelf);
    
int nbr nLevel*2;
    
nLevel++;

    
effect eVis EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_1);
    
int i,angle,rand,XP;
    
location lSelf GetLocation(oSelf);
    
location new_loc,loc_rep;
    
object new_creat;

    for(
i=0;i++;i<nbr)
    {
        
angle Random(180);
        
rand Random(1);
        if(
rand==1)
            
angle *= -1;    

        
new_loc GenerateNewLocationFromLocation(lSelf,5.0,IntToFloat(angle),1.0);
        
loc_rep CalcSafeLocation(oSelf,new_loc,10.0,FALSE,FALSE);
        
new_creat CreateObject(OBJECT_TYPE_CREATURE,"horreur multiple",loc_rep,TRUE);

        
XP = (nLevel*(nLevel-1))*500;
        
ResetCreatureLevelForXP(new_creat,XP,FALSE);
        
ForceRest(new_creat);

        
SetIsTemporaryEnemy(attaquant,new_creat);
        
AssignCommand(new_creat,DetermineCombatRound(attaquant));

        
DelayCommand(0.5,ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,new_creat));
    }

Citation :
Publié par Deyonara
Par contre tu peux alléger quelques parties du script.

Une chose qui me turlupine, c'est :

int new_generation = generation++;

Avec cette commande, la variable "generation" n'aura pas déjà augmenté de 1 avant d'être multipliée par 2 ? De mémoire, ça aurait donc pour effet de créer 4 créatures de niveau 2, puis 6 de niveau 3, puis 8 de niveau 4, etc...

La manière la plus sûre est d'augmenter generation après avoir déterminé le nombre de créatures qui apparaîtront (j'ai marqué nLevel par habitude, on ne se refait pas...).

Il me semble aussi que "DetermineCombatRound()" engage le combat. De ce fait, pas besoin d'un "ActionAttack()" :
Code PHP:

#include "nw_i0_generic"
void main()
{
    
object attaquant GetLastKiller();
    
object oSelf OBJECT_SELF;

    
int nLevel GetHitDice(oSelf);
    
int nbr nLevel*2;
    
nLevel++;

    
effect eVis EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_1);
    
int i,angle,rand,XP;
    
location lSelf GetLocation(oSelf);
    
location new_loc,loc_rep;
    
object new_creat;

    for(
i=0;i++;i<nbr)
    {
        
angle Random(180);
        
rand Random(1);
        if(
rand==1)
            
angle *= -1;    

        
new_loc GenerateNewLocationFromLocation(lSelf,5.0,IntToFloat(angle),1.0);
        
loc_rep CalcSafeLocation(oSelf,new_loc,10.0,FALSE,FALSE);
        
new_creat CreateObject(OBJECT_TYPE_CREATURE,"horreur multiple",loc_rep,TRUE);

        
XP = (nLevel*(nLevel-1))*500;
        
ResetCreatureLevelForXP(new_creat,XP,FALSE);
        
ForceRest(new_creat);

        
SetIsTemporaryEnemy(attaquant,new_creat);
        
AssignCommand(new_creat,DetermineCombatRound(attaquant));

        
DelayCommand(0.5,ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,new_creat));
    }

Oui, tu doit avoir raison, j ai ecrit ce script a la va vite sans prendre le soin de l optimiser.

Merci
Je viens de tester avec engouement, mais malheureusement cela ne fonctionne pas pour moi !

J'ai cherché dans tous les sens je n'ai pas réussi à voir d'où venait le problème.

Conditions dans lesquelles le test a été réalisé :

Area Interieur = Standard Castle
Créature utilisée pour être répliquée = gobelin (copié module, tag/nom de ressource etc changé adéquatement)
Script placé dans le OnDeath de la créature
On peut commencer par plus simple, pour voir où ça ne marche pas. J'ai également inclus des messages pour vérifier qu'au moins, la créature se réplique elle-même, et qu'elle gagne un niveau :
Code PHP:

#include "nw_i0_generic"
void main()
{
    
object oKiller GetLastKiller();
    
object oSelf OBJECT_SELF;
    
int nLevel GetHitDice(oSelf);

    
SpeakString(GetName(oKiller)+" m'a tuer ! Et en plus j'étais niveau "+IntToString(nLevel)+" !");

    
location lLoc GetLocation(oSelf);
    
string sResRef GetResRef(oSelf);
    
nLevel++;
    
int nXP nLevel*(nLevel-1)*500;
    
effect eVis EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_1);

    
object oCreature CreateObject(1,sResRef,lLoc,0);
    
AssignCommand(oCreature,ResetCreatureLevelForXP(oCreature,nXP,0));
    
AssignCommand(oCreature,ForceRest(oCreature));
    
AssignCommand(oCreature,ApplyEffectToObject(0,eVis,oCreature));
    
AssignCommand(oCreature,SpeakString("Haha ! Je suis plus fort que mon copain, car je suis niveau "+IntToString(GetHitDice(oCreature))+" !"));
    
AssignCommand(oCreature,DetermineCombatRound(oKiller));

J'avais reussi a faire spawner les nouvelles generations en recodant la boucle, cependant je ne suis pas sur que les creatures gagnaient un niveau, je vais tester tout ca quand je rentrerai du travail
Je vais tester ton code ce soir Deyonara, bien vu les speakstring histoire de voir ce qu'il se passe.

J'avais réussi a faire fonctionner le script un tant soit peu (premier spawn 2x niveau de creature ancienne gen), en modifiant la boucle "for" par un "while".
Ceci dit apres le premier spawn, ce n'etait plus exponentiel evidemment puisque le niveau de la creature n'augmentait pas.

Je me demandait s'il ne fallait pas incrementer directement nLevel de cette maniere : ++nLevel
Comme ca on est certain qu'elle est directement augmentee de 1 avant meme qu'elle ne soit utilisee.

Aussi pour la boucle "for", je pensais qu'il fallait l'ecrire ainsi :
for(i=0;i<nbr;i++)

Au lieu de :
for(i=0;i++;i<nbr)

Mais peut etre que cela n'a pas d'importance ?

Hate de rentrer pour tester, je m'en inspirerai pour creer un moment cle dans une quete, un monstre qui devient de plus en plus fort lorsqu'on le tue, qui ne trouverait la mort que par le biais d'une arme speciale.^^



ps : navre pour le made in qwerty...
A partir du moment où ça marche, on peut un peu simplifier le script, et lui redonner la forme qu'il avait quand Ariok l'a soumis.

Sinon, il me semble bien que l'ordre des paramètres de la boucle for est bien "for(i=0;i<nNum;i++)" :
Code PHP:

#include "nw_i0_generic"

void ReplicateCreature(string sBluePrintlocation lLocationint nExpobject oHostileobject oSource=OBJECT_SELFint nVisualEffect=VFX_FNF_SUMMON_MONSTER_1)
{
    
int nAngle Random(180);
    if(
Random(1)==1)
        
nAngle *= -1;
    
location lSafeLoc GenerateNewLocationFromLocation(lLocation,5.0,IntToFloat(nAngle),1.0);
    
lSafeLoc CalcSafeLocation(oSource,lSafeLoc,10.0,0,0);
    
effect eVisualEffect EffectVisualEffect(nVisualEffect);

    
object oCreature CreateObject(1,sBluePrint,lSafeLoc,0);
    
AssignCommand(oCreature,ResetCreatureLevelForXP(oCreature,nExp,0));
    
AssignCommand(oCreature,ForceRest(oCreature));
    
AssignCommand(oCreature,ApplyEffectToObject(0,eVisualEffect,oCreature));
    
AssignCommand(oCreature,SetIsTemporaryEnemy(oHostile,oCreature));
    
AssignCommand(oCreature,DetermineCombatRound(oHostile));

    
// Petit détail mignon, si on veut augmenter un peu la taille
    // de la créature répliquée, par la même occasion :
    // Pour donner une idée, une créature de niveau 20 doublera de volume.
    
float fScale 1.0+ (IntToFloat(GetHitDice(oCreature))/20.0);
    
AssignCommand(oCreature,ApplyEffectToObject(2,ExtraordinaryEffect(EffectSetScale(fScale)),oCreature));
}

void main()
{
    
object oKiller GetLastKiller();
    
object oSelf OBJECT_SELF;
 
    
string sResRef GetResRef(oSelf);
    
location lLoc GetLocation(oSelf);
    
int nLevel GetHitDice(oSelf);
    
int nXP = (nLevel+1)*nLevel*500;

    
int i;
    
int nNum nLevel*2;
    for(
i=0;i<nNum;i++)
    {
        
ReplicateCreature(sResRef,lLoc,nXP,oKiller);
    }

Il est possible que mes doigts aient bégayé, donc à vérifier quand même...
Répondre

Connectés sur ce fil

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