Peuplement automatique de ville

Répondre
Partager Rechercher
Yop à toutes et tous!

voila j'ai créé une choulie grande ville j'ai créé les PNJ principaux => tout va pour le mieux mais le probleme est que j'aimerais savoir si il existe un script pour générer des PNJ "no-name" aléatoirement ?
Voilà... Ca ça devrait aller. C'est sûrement truffé de fautes, notamment au niveau des switch car je ne me souvient plus de la procédure exacte ( [case 0: return 0;break;] ou quelque chose comme ça)... Si quelqu'un pouvait relire ce serait sympa. Enfin l'essentiel y est. Tu peux régler le niveau de précision en supprimant des lignes (par exemple si tu ne veut pas que ça bouffe trop de CPU, tu mets moins de possibilités, etc.)...
Si ce n'est pas clair, préviens moi, je mettrais des précisions. J'ai fait ça un peu vite donc bon.
Code PHP:

/////////////////////////////////////////////
///    "Dans ville il y a vie" tome 2,    ///
///    - generation aleatoire de PNJ -    ///
/////////////////////////////////////////////
  /*
     Ce script cree aleatoirement dans une ville dont les zones sont donnees
      un nombre donne de PNJ choisis aleatoirement parmis une liste donnee.
                                                                            */
/////////////////////////////////////////
///        By Ange Musicien           ///
/////////////////////////////////////////                                  


// Generate a random fonction and create a PNJ.
// If oArea is not a valid area, nothing will happen.
void GenerateRandomPNJ(object oArea=OBJECT_INVALIDint Xmax=10int Ymax=10);

void main()
{
object zone1,zone2,zone3/*etc*/;    //Inscrivez autant de zoneX que d'areas de votre ville
int Xmax1,Xmax2,Xmax3/*etc*/;       //Inscrivez autant de Xmax que d'areas de votre ville
int Ymax1,Ymax2,Ymax3/*etc*/;       //Inscrivez autant de Ymax que d'areas de votre ville
int fois;
object PNJ;

zone1 GetObjectByTag("nom de la zone"); // Inscrivez le Tag des zones en face.
zone2 GetObjectByTag("deuxieme  zone");
zone3 GetObjectByTag("troisieme zone");

Xmax1 80;                         // Inscrivez les valeurs de vos terrains
Xmax2 80;                         // en abcisse.
Xmax3 80;                         // Note : 1 carre de terrain = 10.

Ymax1 80;                         // De meme en ordonnee Y. N'oubliez pas
Ymax2 80;                         // Que 1 carre vaut 10 : les trois zones donnees
Ymax3 80;                         // en exemple ici valent donc toutes 8x8 carres.

fois 20;                          // entrez derriere "fois" le nombre de PNJ que vous
                                    // voulez generer

while(fois!=0)
 {
 
int r,X,Y;
 
object z;
 
Random(4);                     // remplacez 4 par le nombre de zones +1
 
switch(r)
  {
  case 
1:
  
zone1Ymax1Xmax1; break;  // ajoutez une case par zone et completez
  
case 2:                                  // comme ci-contre.
  
zone2Ymax2Xmax2; break;
  case 
3:
  
zone3Ymax3Xmax3; break;
  }
 
GenerateRandomPNJ(z,X,Y);
 
fois--;
 }
}

void GenerateRandomPNJ(object oArea,int Xmax,int Ymax)
{

if(
oArea==OBJECT_INVALID)
 {}
else if(
oArea!=OBJECT_INVALID)
 {
 
string sint LX,LY,Rvector LVlocation L;
 
LX Random(Xmax+1);
 
LY Random(Ymax+1);
 
LV Vector(IntToFloat(LX),IntToFloat(LY),0.0);
 
Location(oArea,LV,0.0);
 
Random(5);                          // Ou 5 est le nombre de PNJ differents pouvant
 
switch(R)                               // peupler la ville
  
{
  case 
1"PNJ_TYPE_1"; break;       // Adaptez de faon identique a votre schema
  
case 2"PNJ_TYPE_2"; break;
  case 
3"PNJ_TYPE_3"; break;
  case 
4"PNJ_TYPE_4"; break;
  case 
5"PNJ_TYPE_5"; break;
  }
 
CreateObject(OBJECT_TYPE_CREATURE,s,L,FALSE);
 }

Hmm la question n'est pas si bête puisque si tu met se script dans le OnModuleLoad, tu risques de te retrouver avec un bug bien senti : pour une raison inconnue (de moi du moins ), le OnModuleLoad ne gère pas les create object et probablement les copy object à l'entrée... Donc il te reste à trouver un endroit pour le caser si le bug survient : un trigger est trop instable, mais peut-être dans le OnEnter de la zone avec la mention 'une seule fois' ( tu rajoutes une variables au début qui prend +1 à la fin). Bref, tu vois ce qui t'arranges... Si tu n'y arrives pas, je te trouverais bien quelque chose.
L'idée d'une variable qui prend plus un est bien tentante mais je ne vois pas franchement à quoi l'assigner :
un SetIntToObject (Tag d'un objet invisible) - euh je dis ça de tete, je ne sais pas si la syntaxe est bonne-

et en plus, il faudrait que j'en mette un différent sur toutes les zones où je compte l'utiliser...

Ma foi, si tu as une autre suggestion, tu feras plus d'un heureux

Prince Nexus.
Tu l'assignes a la zone, genre SetLocalInt(OBJECT_SELF, "spawnpnj", 1)

OBEJCT_SELF correspond a la zone si tu le fous dans le OnEnter de la zone.

Donc en gros, tu peux mettre le meme script pour toutes les zones.
Bah moi j'ai deux autres questions, qui n'ont rien à voire.

Elle sert à quoi la variable int Z ?
Code PHP:

int Z,fois
Tu lui donnes la valeur 0, mais tu ne l'utilises pas.


Et dans ta fonction GenerateRandomPNJ, tu fais un premier test
Code PHP:

if(oArea==OBJECT_INVALID)
 {}
else if(
oArea!=OBJECT_INVALID)
 {...} 
Pourquoi tu ne fais pas simplement
Code PHP:

if(oArea!=OBJECT_INVALID)
{...} 
Euh merci Zunder pour tes précisions : ça va mieux maintenant (chavais pas qu'on pouvait mettre des Int même sur les aréas -en fait sur tous les Objets quels qu'ils soient- : on en apprend tous les jours)

Sinon pour répondre à Nermir à la place d'Ange musicien, eh ben c'est passke il a fait ça à l'arrache Mais c'est vrai qu'il faudrait qu'il arrange ça .....

Prince Nexus.

Message modifié pour faire plaisir à Zunder !
Citation :
Provient du message de Prince Nexus
-en fait sur tous les Tags quels qu'ils soient-
Sur les objets hein, pas sur les tags, le tag c'est qu'une caractéristique de l'objet.
De même que :
Code PHP:

 R Random(5);                          // Ou 5 est le nombre de PNJ differents pouvant
switch(R)                               // peupler la ville
{
case 
1"PNJ_TYPE_1"; break;       // Adaptez de faon identique a votre schema
case 2"PNJ_TYPE_2"; break;
case 
3"PNJ_TYPE_3"; break;
case 
4"PNJ_TYPE_4"; break;
case 
5"PNJ_TYPE_5"; break;

qui deviendrais plutôt :
Code PHP:

 R Random(5);
"PNJ_TYPE_"+IntToString(R+1); 
mais bon, lui au moins a scripté quelque chose
Citation :
mais bon, lui au moins a scripté quelque chose
Mais s'il a scripté quelque chose en si peu de temps, c'est qu'il s'y connais mieux que moi, et c'est pour sa que je demande pourquoi il a choisi de faire comme sa et pas autrement. Peut-être y avait-il une autre raison que "il a fait ça vite", peut-être pour des raisons de Débugage par exemple, ou de rapidité d'exécution. Etant novice dans le monde de la programmation, je m'intéresse à ce que font les autres, et je me demande comment ça marche et pourquoi ça marche. Il ne s'agissait absolument pas d'une critique, mais bel et bien d'une interrogation.
Pour Nermir : Pour le Z c'est tout bêtement que j'avais prévu autre chose à l'origine, et puis je l'ai délaissé, donc il ne sert à rien. Tu peux le supprimer. Pour le deuxième, c'est une simple mesure de sécurité, un protocole. Tu peux l'enlever aussi, mais il est aussi bien de le laisser, étant donné que nous sommes dans une fonction (j'ai créé une fonction pour une meilleure lisibilité et pour un script remaniable, et réutilable (il suffit d'écrire #include "nomduscript" pour avoir accès à cette fonction), ce qui évite pas mal de problème et économise du CPU). C'est une mesure de sécurité si tu veux.

Pour Taern : En fait pas du tout ^^. C'est parfaitement voulu, ce sont des "cases" dans lesquelles PNJ_TYPE_5 sont remplacés par les ResRef des PNJ... Quand tu mets deux villes avec ce script, est qu'un est une ville d'orcs et l'autre une ville d'elfe, le script est le même : il va appeler les mêmes personnages (à savoir PNJ_TYPE_1, etc.) dans les deux villes opposée. Des citoyens elfes chez les orcs, ça fait bizarre... C'est afin que le script soit adaptable. Et ça n'oblige pas le Créateur à changer la ResRef de ses PNJ. En bref, il ne faut surtout pas mettre ce que tu as mis... Mais c'est moi qui n'ai pas été clair. Je corrige
Autant pour moi alors

@ Nemir : désolé j'ai pas été clair non plus j'ai simplement dit ça pour ne pas qu'Ange Musicien croie que je critique son script gratuitement. C'est tout à fait normal et correct de poser des questions
Citation :
Provient du message de Ange Musicien
(il suffit d'écrire #include "nomduscript" pour avoir accès à cette fonction),
euh, sauf que la t'as un void main()
donc tu risque un bo

DOUBEUL IMPLEMENTATION OF FONCTIONS

ou un truc du genre dès que tu voudras rajouter une fonction main (un script quoi) ^_^

fin je dis ca au cas oû quelqu'un voudrais éssayer
il faut mettre les fonction danx un autre script, que tu appel en include ds celui donné au dessus (avec que le void main dedans) et dans un autre script si tu veux

fin, juste pour plus de rigeur
Exact. J'ai oublié de préciser qu'il fallait scinder en deux le script au cas d'une utilisation différente. Mais les personnes susceptibles d'utiliser des #include sont capables de diviser des scripts par deux, donc bon.
Hum..... je n'y connais scriptement rien au script (pourtant je me suis lance dans la creation d'un module et essayer de decouvrir le script c plutot interessant meme si je reussis pas grd chose :/ ).
Je n'arrive pas a savoir ce qu'il faut enlever ou pas dans ce script.
Est ce qu'il est possible d'en avoir une version a jour svp ?

Merci d'avance
Je pense qu'il parle des trucs à remplacer... C'est marqué en face. Chaque champs quasiment est modelable... N'oublie pas de modifier les variables au début selon ton nombre de zones. Si ta ville fait 5 zones, par exemple.

Ces scripts vont bientôt subir des corrections et une version fusionnée des deux "dans ville il y a vie", afin d'obtenir un script très efficace, où le dev aura juste à remplir une vingtaine de champs au début, expliqués dans les dérails, et qui permettront de créer et de donner vie en même temps aux PNJ. Les options rajoutées : possibilité de dialogues courts avec marchand entre PNJ par floating text, possibilité de créer des chemins spéciaux suivis par des PNJ spéciaux (ex : tour de garde), possibilité de recréer des PNJs si ceux-ci sont tués au bout de 1 minute (les nouveaux PNJs sont créés dans des endroits déserts où à l'entrée de ville. Le tueur est alors fiché. Très pratique pour les PW. Vous trouverez tout ça sur le site des Mains Noires quand il sera prêt... Et évidemment je mettrais le script ici pour les JOLiens.
Tout d'abord bine nommer les TAG de ses zones (Area). J'utilise une norme simple :
A01
A02
etc...
Tout d'abord une librairie (bibliothèque suivant les goût) sera utiliser pour le peuplement de la ville zinclude_aera



Code PHP:

 // =================================================
// initialisation des fonctions de chatgement de PNJ
// =================================================
void ChargeUnPNJ (string sNOMZONEstring sTypePNJint iNombrePNJint iNombreWPstring iNumTag "0") {
    
location la;
    
object   PNJ;
    
string   sNomTag;                   // nom du tag des waypoint
    
string   sNomRef;                   // nom de la reference
    
int      iR;
    
string   sR;

    
sNomTag =  "WP_" sNOMZONE "_";
    
// =============================================================
    // attention tous ces elments sont en majuscule, mais par contre
    // pour la rfrence, il faut utiliser les minuscules
    // =============================================================
    
sNomRef =  GetStringLowerCase(sTypePNJ);
    
int i 1;
    while (
<= iNombrePNJ)      {
        
iR Random(iNombreWP) + 1;
        if (
iR 10)       sR =  iNumTag "0" IntToString(iR);
        else               
sR =  iNumTag IntToString(iR);
        
la   GetLocation(GetObjectByTag(sNomTag sR ));
        
CreateObject(OBJECT_TYPE_CREATUREsNomRefla);
        
i++;
    }
}

// ========================================================================
// cette procedure permet de charger la zone en fonction de celle-ci et de
// sa structure
// ========================================================================
void ChargementPNJaera(object oZONE)
{
    
string sNOMZONE =   GetTag(oZONE);
        if (
sNOMZONE == "") {}
            
// SI LA ZONE EST BLANCHE ONT FAIT RIEN BIEN-SUR
            // =============================================
        
else if (sNOMZONE == "A07" )
        {
             
ChargeUnPNJ (sNOMZONE"MARIN"       510"0");
             
ChargeUnPNJ (sNOMZONE"CAPTAINE"    110"0");
             
ChargeUnPNJ (sNOMZONE"ANCIPIEL"    410"0");
             
ChargeUnPNJ (sNOMZONE"DOMEST_HOMME"310"0");
             
ChargeUnPNJ (sNOMZONE"DOMEST_FEMME"510"0");
             
ChargeUnPNJ (sNOMZONE"NOBLE_HOMME" 310"0");
             
ChargeUnPNJ (sNOMZONE"NOBLE_FEMME" 510"0");
             
ChargeUnPNJ (sNOMZONE"PRETRE"      210"0");
             
ChargeUnPNJ (sNOMZONE"LETTRE"      110"0");
             
ChargeUnPNJ (sNOMZONE"MOYEN_F"     410"0");
             
ChargeUnPNJ (sNOMZONE"MOYEN_H"     410"0");
             
ChargeUnPNJ (sNOMZONE"MOYEN_E"     810"0");
             
ChargeUnPNJ (sNOMZONE"FRAPPE"      310"0");
             
ChargeUnPNJ (sNOMZONE"MARCHAND"    6,  1"1");
             
ChargeUnPNJ (sNOMZONE"GARDE_ARMEE" 5,  2"1");
        }
        else if (
sNOMZONE == "A25" )
        {
             
// AREA 25 RDC DU CHATEAU
             // ======================
             
ChargeUnPNJ (sNOMZONE"DOMEST_HOMME"511"0");
             
ChargeUnPNJ (sNOMZONE"DOMEST_FEMME"511"0");
             
ChargeUnPNJ (sNOMZONE"ENFANT_NOBLE"411"0");
             
ChargeUnPNJ (sNOMZONE"NOBLE_HOMME" 511"0");
             
ChargeUnPNJ (sNOMZONE"NOBLE_FEMME" 311"0");
             
ChargeUnPNJ (sNOMZONE"GARDE_ARMEE" 4,  3"1");
             
ChargeUnPNJ (sNOMZONE"LETTRE"      2,  2"2");
        }
        else {}
}

// ========================================================================
// cette procedure permet de charger la zone en fonction de celle-ci et de
// sa structure  Ce chargeent est pour la nuit
// ========================================================================
void ChargementPNJaeraNUIT(object oZONE)
{
    
string sNOMZONE =   GetTag(oZONE);
        
// if block - silly!
        
if (sNOMZONE == "") {}
        }
        else if (
sNOMZONE == "A07" )
        {
             
ChargeUnPNJ (sNOMZONE"MARIN"      510"0");
             
ChargeUnPNJ (sNOMZONE"CAPTAINE"   110"0");
             
ChargeUnPNJ (sNOMZONE"ANCIPIEL"   410"0");
             
ChargeUnPNJ (sNOMZONE"FRAPPE"     310"0");
             
ChargeUnPNJ (sNOMZONE"GARDE_ARMEE"5,  2"1");
        }
         else if (
sNOMZONE == "A25" )
        {
             
// AREA 25 RDC DU CHATEAU
             // ======================
             
ChargeUnPNJ (sNOMZONE"DOMEST_HOMME"511"0");
             
ChargeUnPNJ (sNOMZONE"DOMEST_FEMME"511"0");
             
ChargeUnPNJ (sNOMZONE"ENFANT_NOBLE"411"0");
             
ChargeUnPNJ (sNOMZONE"NOBLE_HOMME" 511"0");
             
ChargeUnPNJ (sNOMZONE"NOBLE_FEMME" 311"0");
             
ChargeUnPNJ (sNOMZONE"GARDE_ARMEE" 4,  3"1");
             
ChargeUnPNJ (sNOMZONE"LETTRE"      2,  2"2");
             
ChargeUnPNJ (sNOMZONE"DANSEUR"     2,  1"3");
             
ChargeUnPNJ (sNOMZONE"DANSEUSE"    2,  1"3");
        }
        else {}
}

// ==============================================================
// PROCEDURE PERMETANT DE VIDER UNE ZONE AFIN DE LA REMPLIR AVEC
// DE NOUVEAUX ELEMENTS
// ==============================================================
void ViderZone(object oZONE)
{
    
object oObjetaDetruire GetFirstObjectInArea(oZONE);
    
object oFirstPC        GetNearestCreature(CREATURE_TYPE_PLAYER_CHARPLAYER_CHAR_IS_PC);
    
string sTag             ;

    while (
GetIsObjectValid(oObjetaDetruire)) {
       if ( (
GetObjectType(oObjetaDetruire) == OBJECT_TYPE_CREATURE) ||
            (
GetObjectType(oObjetaDetruire) == OBJECT_TYPE_ITEM)      ) {
             
AssignCommand(oObjetaDetruireClearAllActions()); // pour initialisation des actions PNJ
             
if (!GetPlotFlag(oObjetaDetruire)) {
                    if (
GetName(GetMaster(oObjetaDetruire))==""){
                        
sTag GetTag(oObjetaDetruire);
                        
sTag GetStringLeft(sTag,4);
                        if (! (
sTag == "PRM_"))
                            
DestroyObject (oObjetaDetruire);
                    }
             }  
// fin de IF
       
}  // fin de IF
       
oObjetaDetruire=GetNextObjectInArea();
    }  
// fin de while
    // ===============================================================
    // et maintenant j'initialise les valeurs indiquant si on est jour
    // ou nuit
    // ===============================================================

    
SetLocalInt(oZONE,"NuitActive",0);
    
SetLocalInt(oZONE,"JourActif",0);

Suite aqu prochain thread
Il faudra créer des personnages ayant pour Reference :
MARIN
CAPITAINE
et ayant même TAG.

Dans la zone il faut créer des points de passage ayant le tag suivant
WP_[tag aera]_x0i
x étant une différenciation des personnages (car il sont posé aléatoirement suivant les 0i. les 0i étant le nombre de TAG
exemple WP_A07_001, WP_A07_002, WP_A07_003... WP_A07_010, WP_A07_101, WP_A07_102

Alors on met dans onenter le script suivant :
Code PHP:

//**********************************
// SCRIPT POUR LA MAISON ANIMEE
//**********************************
// ************************************************************
// la commence le script de l'action il permet juste de charger
// le nombre personnage se trouvant dans la zone
// ************************************************************
#include "zinclude_area"
void main()
{
    
// oZONE est la zone dans laquelle se trouve le personnage entrant
    
object oZONE    =   OBJECT_SELF;
    
object oPJ      =   GetEnteringObject();
    
// c'est bien un personnage connect qui entre (PJ ou maitre)
    
if (GetIsPC(oPJ)) {
        
SetLocalInt(oZONE"li_NbrPJ"GetLocalInt(oZONE"li_NbrPJ") + 1);
        if (
GetLocalInt(oZONE"li_NbrPJ") == 1)
        {
            if (
GetIsNight())
            {
                
SetLocalInt(oZONE,"NuitActive",2);
                
SetLocalInt(oZONE,"JourActif",1);
                
ChargementPNJaeraNUIT(oZONE);
            }
            else
            {
                
SetLocalInt(oZONE,"NuitActive",1);
                
SetLocalInt(oZONE,"JourActif",2);
                
ChargementPNJaera(oZONE);
            }
        }
    }

On met dans le onExit le script suivant :
Code PHP:

 //**********************************
// SCRIPT DE SORTIE DE ZONE
//**********************************
#include "zinclude_area"
void main()
    {
    
//DECLARATION DES VARIABLES
    
object oPJ             GetExitingObject();
    
object oModule         GetModule();
    
object oZONE           OBJECT_SELF;

    
int nNBdePC GetLocalInt(oZONE,"li_NbrPJ"); // remplacer la variable par celle utilise dans le OnEnter de la zone

    //Mise a jour du Compteur
    
if (GetIsPC(oPJ))
    {
        
nNBdePC nNBdePC 1;
        
SetLocalInt(oZONE,"li_NbrPJ",nNBdePC);// remplacer la variable par celle utilise dans le OnEnter de la zone
    
}

    
//TEST POUR VERIFIER SI IL RESTE DES PC DANS L'Area
    
if (nNBdePC == 0)  ViderZone(oZONE);

et enfin dans le onHeartBeat de la zone (le test permet que cela ne se fasse que deux fois par jours :

Code PHP:

#include "zinclude_area"
void main()
{
    
object oZONE   OBJECT_SELF;

    if (
GetIsNight() && GetLocalInt(oZONE,"NuitActive") == 1)
    {
        
SetLocalInt(oZONE,"NuitActive",2);
        
SetLocalInt(oZONE,"JourActif",1);
        
ViderZone(oZONE);
        
ChargementPNJaeraNUIT(oZONE);
    }
    if (
GetIsDay() && GetLocalInt(oZONE,"JourActif") == 1)
    {
        
SetLocalInt(oZONE,"NuitActive",1);
        
SetLocalInt(oZONE,"JourActif",2);
        
ViderZone(oZONE);
        
ChargementPNJaera(oZONE);
    }

Moui Après tu adaptes comme tu veux mon chou Mais c'est la même chose. Je cherche à créer un script éducatif est facile pour débutant, je ne suis pas sur que ce soit le même cahier des charges

Ton script est un script de PW pré-professionel (il manque pas mal de trucs, l'économie de CPU est assez relative, entre autres points). Des scripts de ce type, tous les PW en ont créé un pour eux... Disons alors que ton script est à mi-chemin entre les deux. Mais il aurait mieux valu créé un autre sujet, je pense. Enfin bref, je n'ai pas le temps de regarder ce soir, mais dans les prochains jours, si personne n'a corrigé avant moi...

Cela dit, c'est quand même un beau morceau
Répondre

Connectés sur ce fil

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