La Bibliothèque de Neverwinter Nights
Aide et informations diverses sur Neverwinter Nights ainsi que D&D3.
La date/heure actuelle est 23/11/2024 21:31:38


  Page 1 sur 1 ¤

Voir le sujet précédent ¤ Voir le sujet suivant 
Auteur Message
Serguai
Grand Chevalier
Inscrit le: 07 Déc 2002
Messages: 104
Répondre en citant
Posté le : 05/02/2003 13:05:10 Sujet du message : Test des puissances

Salut tlm,

Je suis en train d'implémenter pour mon module le système des règles des puissances de ravenloft. Voici comment ca doit fonctionner:

Dans le ondeath:

Code :

#include "NW_I0_GENERIC"
#include "rav_puissance"

void main()
{
    int nClass = GetLevelByClass(CLASS_TYPE_COMMONER);
    int nAlign = GetAlignmentGoodEvil(OBJECT_SELF);
    if(nClass > 0 && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL))
    {
        object oKiller = GetLastKiller();
        AdjustAlignment(oKiller, ALIGNMENT_EVIL, 5);
        PowerCheck(oKiller,100); //C'est ici que ca se passe
       //J'effectue un test des puissances avec 100% de succes (pour le test=
    }

    SpeakString("NW_I_AM_DEAD", TALKVOLUME_SILENT_TALK);
    //Shout Attack my target, only works with the On Spawn In setup
    SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK);
    if(GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
    {
        SignalEvent(OBJECT_SELF, EventUserDefined(1007));
    }
}


Evidemment il y'a un problème, le test fait planter le jeu au bout de deux ou trois essais.
Voici le code inclu dans rav_puissance :
J'espère que quelqu'un aura le temps d'y jeter un coup d'oeil.
Les objets recompense sont des creature item de type peau avec des propriétés du genre augmentation de certaines caractéritiques et diminution d'autres caractéristiques.
En commentant les différentes lignes et en faisant des tests il semblerait que c'est au moment d'équiper les peau (et seulement au bout de la deuxième ou troisième fois, ca varie) que ca plante. Evidemment j'ai vérifié les resref (pour que le pj n'équipe pas un truc invalid) et j'ai même essayé de mettre une condition pour que l'objet ne soit pas équipé s'il est invalide, mais ca plante quand même. Donc si quelqu'un a le courage de regarder et a une idée, je lui serai reconnaissant Smile

Code :
//::///////////////////////////////////////////////
//:: TEST DES PUISSANCES
//:: rav_puissance
//:://////////////////////////////////////////////
/*
    Gestion des tests des puissances.
    Regles du monde de jeu Ravenloft
*/
//:://////////////////////////////////////////////
//:: Cree par: Serge GANDOLPHE
//:: Cree le: 3 fevrier 2003
//:://////////////////////////////////////////////

void PowerCheck(object pc, int pourcent);
int AppropriateLevel(object pc, int degre);
void Caresse(object pc);
void Incitation(object pc);
void Invitation(object pc);
void Etreinte(object pc);
void Creature(object pc);
void Seigneur(object pc);


/*
Effectue l'objet effectue un test des puissances
avec pourcent % de risques.
Tout acte malefique devrait provoquer un test des puissances
Toutefois, le degre maximum devrait etre de 10 (dans le cas
d'un meurtre d'innocent).
Le self defense ne provoque pas de test des puissances
*/
void PowerCheck(object pc, int pourcent){

    if(!GetIsPC(pc))
        return;

    object innocence = GetLocalObject(pc,"innocence");
    if(GetIsObjectValid(innocence)){
        DestroyObject(innocence,0.5f);
        SendMessageToPC(pc,"Vous avez perdu votre innocence.");
    }

    //On regarde si le joueur a deja echoue a des tests de puissance
    int degre = GetLocalInt(pc,"RAV_DEGREPUISSANCE");

    //On fait le test proprement dit et s'il echoue on envoie un avertissement
    if(d100(1)>pourcent || degre == 6)
    {
        //Cas ou le personnage est deja au dernier stade
        if(degre == 6){
            SendMessageToPC(pc,"Vous continuez a perpetrer vos actions malefiques. Les puissances de Ravenloft sont satisfaites de vous.");
        }
        else SendMessageToPC(pc,"Vous attirez l'attention des puissances du mal.");
        return;
    }

    //On regarde si le pj a le niveau approprie
    if(!AppropriateLevel(pc,degre))
    {
        SendMessageToPC(pc,"Les puissances du mal vous ont remarque, mais vous n'etes pas encore assez puissant pour le stade suivant.");
        return;
    }

    //On lui enleve son precedent don.
    object prevskin = GetItemInSlot(INVENTORY_SLOT_CARMOUR,pc);
    if(GetIsObjectValid(prevskin))
        DestroyObject(prevskin,0.5f);

    //Selon le degre, on lui donne le don du degre superieur
    switch(degre){
        case 0: Caresse(pc);
                break;
        case 1: Incitation(pc);
                break;
        case 2: Invitation(pc);
                break;
        case 3: Etreinte(pc);
                break;
        case 4: Creature(pc);
                break;
        case 5: Seigneur(pc);
                break;
        default: break;
    }

     //Effet visuel
    ApplyEffectAtLocation(DURATION_TYPE_INSTANT,EffectVisualEffect(VFX_BEAM_LIGHTNING),GetLocation(pc));
}

/*Renvoie true si le personnage a le niveau approprie*/
int AppropriateLevel(object pc, int degre){
    int totallevel = GetHitDice(pc);
    switch(degre){
        case 0: if(totallevel>=6) return TRUE; else return FALSE;
                break;
        case 1: if(totallevel>=8) return TRUE; else return FALSE;
                break;
        case 2: if(totallevel>=12) return TRUE; else return FALSE;
                break;
        case 3: if(totallevel>=16) return TRUE; else return FALSE;
                break;
        case 4: if(totallevel>=19) return TRUE; else return FALSE;
                break;
        case 5: if(totallevel>=20) return TRUE; else return FALSE;
                break;
        default: return FALSE;
                break;
    }
    return FALSE;
}

/*Premier stade: La caresse*/
void Caresse(object pc){
    //SendMessageToPC(pc, "CARESSE"); //Pour le debug
    object recompense = CreateItemOnObject("lacaresse",pc);
    if(GetIsObjectValid(recompense)){
        AssignCommand(pc,ClearAllActions(TRUE));
        AssignCommand(pc,ActionWait(1.0f));
        AssignCommand(pc,ActionEquipItem(recompense,INVENTORY_SLOT_CARMOUR));
    }
    else SendMessageToPC(pc, "ERREUR:PAS DE CREATION DE LA RECOMPENSE");
    SetLocalInt(pc,"RAV_DEGREPUISSANCE",1);
    SendMessageToPC(pc,"Les puissances de Ravenloft vous ont recompense pour cet acte. En contrepartie, vous ne pourrez plus jamais avoir le benefice d'augmentations de caracteristiques autre que celles donnees par les puissances");
    SendMessageToAllDMs(GetName(pc)+" a echoue son test de puissance. Il a ete caresse");
}

/*Deuxieme stade: L'incitation*/
void Incitation(object pc){
    //SendMessageToPC(pc, "INCITATION"); //Pour le debug
    object recompense = CreateItemOnObject("lincitation",pc);
    if(GetIsObjectValid(recompense)){
        AssignCommand(pc,ClearAllActions(TRUE));
        AssignCommand(pc,ActionWait(1.0f));
        AssignCommand(pc,ActionEquipItem(recompense,INVENTORY_SLOT_CARMOUR));
    }
    else SendMessageToPC(pc, "ERREUR:PAS DE CREATION DE LA RECOMPENSE");
    SetLocalInt(pc,"RAV_DEGREPUISSANCE",2);
    SendMessageToPC(pc,"Les puissances de Ravenloft vous ont recompense pour cet acte.");
    SendMessageToAllDMs(GetName(pc)+" a echoue son test de puissance. Il a ete incite");
}

/*Troisieme stade: L'invitation*/
void Invitation(object pc){
    //SendMessageToPC(pc, "INVITATION"); //Pour le debug
    object recompense = CreateItemOnObject("linvitation",pc);
    if(GetIsObjectValid(recompense)){
        AssignCommand(pc,ClearAllActions(TRUE));
        AssignCommand(pc,ActionWait(1.0f));
        AssignCommand(pc,ActionEquipItem(recompense,INVENTORY_SLOT_CARMOUR));
    }
    else SendMessageToPC(pc, "ERREUR:PAS DE CREATION DE LA RECOMPENSE");
    SetLocalInt(pc,"RAV_DEGREPUISSANCE",3);
    SendMessageToPC(pc,"Les puissances de Ravenloft vous ont recompense pour cet acte.");
    SendMessageToAllDMs(GetName(pc)+" a echoue son test de puissance. Il a ete invite");
}

/*Quatrieme stade: L'etreinte*/
void Etreinte(object pc){
    //SendMessageToPC(pc, "ETREINTE"); //Pour le debug
    object recompense = CreateItemOnObject("letreinte",pc);
    if(GetIsObjectValid(recompense)){
        AssignCommand(pc,ClearAllActions(TRUE));
        AssignCommand(pc,ActionWait(1.0f));
        AssignCommand(pc,ActionEquipItem(recompense,INVENTORY_SLOT_CARMOUR));
    }
    else SendMessageToPC(pc, "ERREUR:PAS DE CREATION DE LA RECOMPENSE");
    SetLocalInt(pc,"RAV_DEGREPUISSANCE",4);
    SendMessageToPC(pc,"Les puissances de Ravenloft vous ont recompense pour cet acte.");
    SendMessageToAllDMs(GetName(pc)+" a echoue son test de puissance. Il a ete etreint");
}

/*Cinquieme stade: La creature*/
void Creature(object pc){
    //SendMessageToPC(pc, "CREATURE"); //Pour le debug
    object recompense = CreateItemOnObject("lacreature",pc);
    if(GetIsObjectValid(recompense)){
        AssignCommand(pc,ClearAllActions(TRUE));
        AssignCommand(pc,ActionWait(1.0f));
        AssignCommand(pc,ActionEquipItem(recompense,INVENTORY_SLOT_CARMOUR));
    }
    else SendMessageToPC(pc, "ERREUR:PAS DE CREATION DE LA RECOMPENSE");
    SetLocalInt(pc,"RAV_DEGREPUISSANCE",5);
    SendMessageToPC(pc,"Les puissances de Ravenloft vous ont recompense pour cet acte.");
    SendMessageToAllDMs(GetName(pc)+" a echoue son test de puissance. Il est desormais une creature");
}

/*Dernier stade: Le seigneur des tenebres*/
void Seigneur(object pc){
    //SendMessageToPC(pc, "SEIGNEUR"); //Pour le debug
    object recompense = CreateItemOnObject("leseigneur",pc);
    if(GetIsObjectValid(recompense)){
        AssignCommand(pc,ClearAllActions(TRUE));
        AssignCommand(pc,ActionWait(1.0f));
        AssignCommand(pc,ActionEquipItem(recompense,INVENTORY_SLOT_CARMOUR));
    }
    else SendMessageToPC(pc, "ERREUR:PAS DE CREATION DE LA RECOMPENSE");
    SetLocalInt(pc,"RAV_DEGREPUISSANCE",6);
    SendMessageToPC(pc,"Vos actes malefiques ont paye. Vous etes desormais un seigneur des tenebres.");
    SendMessageToAllDMs(GetName(pc)+" a echoue son test de puissance. Il est desormais un seigneur des tenbres");
}


Edit:
-Corrigé l'erreur dans le appropriatelevel()
-ActionWait()
Dernière édition par Serguai le 07/02/2003 12:30:09; édité 2 fois
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Numéro ICQ Ignorer l'utilisateur
 
Jedaï
Chevalier
Inscrit le: 14 Nov 2002
Messages: 89
Localisation: Le Havre, ville pourrie
Répondre en citant
Posté le : 06/02/2003 13:10:28 Sujet du message :

Mmmmmhh... Je vois pas l'erreur... Surprised

Bon la fonction AppropiateLevel() est erronée, mais sinon... Vérifie tes resrefs.

Code :

int AppropriateLevel(object pc, int degre){
    int totallevel = GetHitDice(pc);
    switch(degre){
        case 0: if(totallevel>=6) return TRUE; else return FALSE;
                break;
        case 1: if(totallevel>=9) return TRUE; else return FALSE;
                break;
        case 2: if(totallevel>=12) return TRUE; else return FALSE;
                break;
        case 3: if(totallevel>=14) return TRUE; else return FALSE;
                break;
        case 4: if(totallevel>=18) return TRUE; else return FALSE;
                break;
        case 5: if(totallevel>=20) return TRUE; else return FALSE;
                break;
        default: return FALSE;
                break;
    }
    return FALSE;
}


Si tu nous donnait la succession exacte des messages de debug, on pourrait peut-être t'aider plus ?

[Edit] Peut-être trop de DelayCommand(), supprimes en quelques uns, d'autant qu'il y en a beaucoup d'inutiles. Sad
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Serguai
Grand Chevalier
Inscrit le: 07 Déc 2002
Messages: 104
Répondre en citant
Posté le : 06/02/2003 18:55:28 Sujet du message :

Merci de ta réponse.
En ce qui concerne les delaycommands, initialement j'en avais mis beaucoup moins mais j'en ai rajouté par la suite pour éviter les conflits (genre équiper un objet qu'on ne possède pas encore). Ca plantait déjà avant, mais je vais voir si en supprimant ca va mieux. Je vais refaire un test et noter la succession des messages de debug.

Sinon, en ce qui concerne les resref, c'est évidemment la première chose que j'ai vérifié Smile
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Numéro ICQ Ignorer l'utilisateur
 
Serguai
Grand Chevalier
Inscrit le: 07 Déc 2002
Messages: 104
Répondre en citant
Posté le : 07/02/2003 01:58:32 Sujet du message :

J'ai continué mes tests et c'est effectivement la ligne suivante qui pose problème:

Code :
AssignCommand(pc,ActionEquipItem(recompense,INVENTORY_SLOT_CARMOUR));


Si je la met en commentaire, ca résoud les problèmes de plantage. Et les objets sont tous bien créé dans l'inventaires (donc ce n'est pas un problème de resref)

Peut être est-ce dut au fait que ActionEquipItem est mis en haut de la pile des actions , et donc si elle est appelée pendant un combat (ce qui est le cas), elle ne peut pas s'éxécuter tout de suite?

Je vais essayer de mettre un clearallactions avant le ActionEquipItem.
En attendant, si vous avez d'autres idées, je suis preneur Smile

EDIT:
Pas d'amélioration avec le clearallactions, ca continue de planter au moment d'équiper. Le plus étrange c'est que ce n'est pas toujours pour le même fonction que ca plante... parfois pour Invitation() , parfois pour Incitation() ...
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Numéro ICQ Ignorer l'utilisateur
 
Jedaï
Chevalier
Inscrit le: 14 Nov 2002
Messages: 89
Localisation: Le Havre, ville pourrie
Répondre en citant
Posté le : 07/02/2003 08:43:17 Sujet du message :

Ca doit pas être ça mais de toute façon tu y gagneras en clarté : essaie de changer les noms de tes objets (met un petit o devant par exemple) de façon à ce qu'il ne ressemble pas autant au nom de fonction. Ouais... c'est sûr que c'est pas ça mais bon... Sad
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Serguai
Grand Chevalier
Inscrit le: 07 Déc 2002
Messages: 104
Répondre en citant
Posté le : 07/02/2003 12:29:00 Sujet du message :

Pour les noms de fonction et de variables, j'utilise la norme suivante:

Les nom de variables en minuscule et les noms de fonction avec la première lettre en majuscule. De cette façon, pas de confusion possible. Mais merci du conseil. Bon sinon quelques améliorations dans mon problème: il semblerait que mettre un ActionWait() entre le CreateObject et le ActionEquipItem diminue sensiblement la fréquence des plantages. C'est sans doute pour la même raison qui m'avait conduit a mettre des DelayCommands, a savoir qu'il faut attendre que l'objet soit créé avant de l'équiper.
Donc avec cette méthode j'ai put faire plusieurs test et passer tout les paliers sans que ca ne plante, mais pas de chance alors que je faisais un dernier test ca a planté...
Donc trois possibilités:
-Soit le plantage n'avait rien a voir
-Soit le ActionWait était trop court
-Soit justement le ActionWait a déclenché le plantage. Il faudrait peut être que je mette une variable locale pour interdire de relancer ce script pendant qu'il est en cours (si par exemple le joueur tue un innocent et doit effectuer un test des puissances alors que le premier test n'est pas fini, à cause du ActionWait()...

Voilà donc c'est une bonne chose à savoir en tout cas (je l'ai lu sur des forums bioware), mettez des ActionWait() entre vos CreateObject() et vos ActionEquipItem().

Merci encore à Jedaï d'avoir eut le courage de s'intéresser a ce problème. J'édite le code ci dessus pour le mettre en l'état actuel.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Numéro ICQ Ignorer l'utilisateur
 
Montrer les messages depuis :
Page 1 sur 1 ¤


Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum


Sauter vers:
FAQ | Rechercher | Liste des Membres | Groupes d'utilisateurs | S'enregistrer | Profil | Se connecter pour vérifier ses messages privés | Connexion
Powered by phpBB 2.* [m] © 2001, 2002 phpBB Group
Theme rewritten in beautiful XHTML code by Baldurien.
Thème "La Bibliothèque de Neverwinter" crée par Kruger
Traduction par : phpBB-fr.com
Page generated in 65.299ms