Bienvenue sur JeuxOnLine - MMO, MMORPG et MOBA !
Les sites de JeuxOnLine...
 

Panneau de contrôle

Recherche | Retour aux forums

JOL Archives

Incendie dynamique

Par Ormus le 9/10/2002 à 13:52:47 (#2303978)

Bonjour à tous :merci:

Voilà en fait je voudrais essayer de simuler un incendie qui se propage avec la placeable "Flamme" (la plus grosse)...Donc au départ je suppose que je dois créer plusieurs placeables flammes donc mettons une activée pour le début et d'autres par défaut désactivées mais qui s'activeront ensuite...et j'aimerais savoir si c'était possible de créer un script pour que les flammes s'activent au fur et à mesure...

Deuxième point, je voudrais que l'on subisse des dommages quand on passe dessus (si c'était exponentiel en fonction du temps que l'on passe dedans ça serait le top :))...

Aussi un truc tout bête que je n'arrive pas à faire, c'est que les flammes s'activent (apparaissent) pas tout de suite mais quand on s'approche de l'endroit...Donc je suppose que je dois créer un trigger, puis aller dans le OnEnter...et ensuite ? :doute:

Une quiche majeure vous remercie d'avance :merci:

P.S.: Bon allez c'est décidé je vais me pencher sur les tutoriaux :D

Par mobidique le 9/10/2002 à 14:23:50 (#2304235)

Pour ce qui est de l'apparition des des flammes je ferais de la façon suivante ...

D'abord effectivement je ferais un trigger autour du truc qui doit bruler, ensuite je planterais une série de waypoint sur le site qui doit bruler et pour finir connaissant le nombre de mes WP je ferais une boucle "for i=" ou ce qui s'en approche le plus et je ferais une création de flamme sur chaque WP ... Genre ... tu appelles tes WP WP_flamme_0, WP_flamme_1 ... WP_flamme_n et aprés tu fais un boucle


for i=0 à n
location lspawn = GetLocation(getobjectbytag("WP_flamme" + intotstring(i));
CreatObject(blablablab, blabla, lspawn)



En gros quoi :D

Bonne chance.

Mob'.

EDIT : Ha oui ... ce code tu le colle sur le Onenter du trigger et si tu veux que le feux se propage alors il faut que tes création d'objet tu les décales dans le temps en utilisant delaycommand et comme delay tu réutilise ton compteur i. Comme ça en réfléchissant un peu avec ta tête c'est la séquence et la position de tes WP qui vont determiner la façon dont ton feu va se propager. A noter qu'en l'absence de structure for tu peux également utiliser une structure while en faisant kkchose comme while(i<n+1) et en incrémentant d'une unité ton compteur dans la boucle.

Par Tyn' le 9/10/2002 à 14:34:27 (#2304303)

Hm. Un incendie dynamique...

Une idée interessante ! Je te propose un script qui crée tout les X temps un nouvel objet à une position aléatoire près du précédent.

void main()
{
string sResRef = "flame002"; //Reference de l'objet a creer
float fDelay = 10.0f; //Creation d'une flamme chaque X seconde
int nMaxDistance = 2; //Distance maximale entre deux flammes
object oCurrentArea = GetArea(OBJECT_SELF);
if(GetLocalInt(oCurrentArea,"In_Flame") == 0) //On verifie si la zone est deja en train de bruler
{
//Si ce n'est pas le cas, on initialise le systeme et on cree la premiere flamme
location lStart = GetLocation(GetWaypointByTag("WP_Incendary_Start_Point")); //Point de depart de l'incendie
CreateObject(OBJECT_TYPE_PLACEABLE,sResRef,lStart,TRUE); //On cree le 1er objet
SetLocalInt(oCurrentArea,"In_Flame",1); //On defini la zone comme en feu
SetLocalLocation(oCurrentArea,"Current_Flame_Location",lStart); //On enregistre la position de la 1ere flamme
DelayCommand(fDelay,ExecuteScript("at_incendie",oCurrentArea));
}else{
//Si la zone est deja en train de bruler
float fOrientation = IntToFloat(Random(360)); //Rotation aleatoire de la flamme
float fXMove = IntToFloat(Random(nMaxDistance)); //Deplacement sur l'axe des X
float fYMove = IntToFloat(Random(nMaxDistance)); //Deplacement sur l'axe des Y
int nXMoveDirection = Random(1); //Deplacement sur l'axe des X positif ou negatif
int nYMoveDirection = Random(1); //Deplacement sur l'axe des Y positif ou negatif
if(nXMoveDirection == 1){ fXMove = 0 - fXMove; } //Enregistrement definitif des valeurs de decalage
if(nYMoveDirection == 1){ fYMove = 0 - fYMove; }
vector vFinalPosition = GetPositionFromLocation(GetLocalLocation(oCurrentArea,"Current_Flame_Location")) + Vector(fXMove,fYMove,0.0f); //Creation du vecteur
location lFinalLocation = Location(oCurrentArea,vFinalPosition,fOrientation); //Creation de la Location
CreateObject(OBJECT_TYPE_PLACEABLE,sResRef,lFinalLocation,TRUE); //Creation de la nouvelle flamme
SetLocalLocation(oCurrentArea,"Current_Flame_Location",lFinalLocation); //Enregistrement de la nouvelle flamme
DelayCommand(fDelay,ExecuteScript("at_incendie",oCurrentArea)); //La boucle continue.
}
}
Je n'ai absolument pas testé, et le ResRef est faux (j'avais la flemme de chercher le bon :p). Mais ça devrait marcher... :doute:

Par Tyn' le 9/10/2002 à 20:27:31 (#2307052)

Correction du script après tests (ces cochons de Bioware ont changés la fonction Random !!) :

void main()
{
string sResRef = "plc_flamelarge"; //Reference de l'objet a creer
float fDelay = 0.1f; //Creation d'une flamme chaque X seconde
int nMaxDistance = 2; //Distance maximale entre deux flammes
object oCurrentArea, oPC;
if(GetLocalObject(GetModule(),"Incendiary_Area") == OBJECT_INVALID)
{
SetLocalObject(GetModule(),"Incendiary_Area",GetArea(GetLastUsedBy()));
oCurrentArea = GetArea(GetLastUsedBy());
SetLocalObject(GetModule(),"Incendiary_PC",GetLastUsedBy());
}else{
oCurrentArea = GetLocalObject(GetModule(),"Incendiary_Area");
oPC = GetLocalObject(GetModule(),"Incendiary_PC");
}
if(GetLocalInt(oCurrentArea,"In_Flame") == 0) //On verifie si la zone est deja en train de bruler
{
//Si ce n'est pas le cas, on initialise le systeme et on cree la premiere flamme
object oCurrentArea = GetArea(GetLastUsedBy());
SetLocalObject(GetModule(),"Incendiary_Area",oCurrentArea);
SendMessageToPC(GetLastUsedBy(),"Incendie initialise");
location lStart = GetLocation(GetWaypointByTag("WP_Incendary_Start_Point")); //Point de depart de l'incendie
CreateObject(OBJECT_TYPE_PLACEABLE,sResRef,lStart,TRUE); //On cree le 1er objet
SetLocalInt(oCurrentArea,"In_Flame",1); //On defini la zone comme en feu
SetLocalLocation(oCurrentArea,"Current_Flame_Location",lStart); //On enregistre la position de la 1ere flamme
DelayCommand(fDelay,ExecuteScript("at_incendie",oCurrentArea));
}else{
//Si la zone est deja en train de bruler
float fOrientation = IntToFloat(Random(360)); //Rotation aleatoire de la flamme
float fXMove = IntToFloat(Random(nMaxDistance)); //Deplacement sur l'axe des X
float fYMove = IntToFloat(Random(nMaxDistance)); //Deplacement sur l'axe des Y
if(Random(2) == 1){ fXMove = -1.0f/*0.0f - fXMove*/; } //Enregistrement definitif des valeurs de decalage
if(Random(2) == 1){ fYMove = -1.0f/*0.0f - fYMove*/; }
vector vPreOperatingVector = GetPositionFromLocation(GetLocalLocation(oCurrentArea,"Current_Flame_Location"));
vector vFinalPosition;
if(Random(2) == 1){ vFinalPosition = vPreOperatingVector + Vector(fXMove,fYMove,0.0f); }else{ vFinalPosition = vPreOperatingVector - Vector(fXMove,fYMove,0.0f); }//Creation du vecteur
location lFinalLocation = Location(oCurrentArea,vFinalPosition,fOrientation); //Creation de la Location
CreateObject(OBJECT_TYPE_PLACEABLE,sResRef,lFinalLocation,TRUE); //Creation de la nouvelle flamme
SetLocalLocation(oCurrentArea,"Current_Flame_Location",lFinalLocation); //Enregistrement de la nouvelle flamme
DelayCommand(fDelay,ExecuteScript("at_incendie",oCurrentArea)); //La boucle continue.
}
}
Je l'ai testé sur un OnUsed, suffit d'adapter, après :)

Le problème principal de ce script est au niveau des foyers d'incendie. Il se propage un peu à la manière d'un serpent. Ce n'est pas vraiment réaliste, mais c'est mieux que rien. Je ferais (j'essayerais de faire) à l'occasion un script avec une matrice, ou plutot une émulation de matrice...

Ah aussi, la propagation n'est pas limitée actuellement. Ajoutez simplement un if sur la ligne de l'ExecuteScript. Je précise qu'il est aussi imaginable de le faire via des UserDefinedEvent :).

Merci à vous !

Par Ormus le 9/10/2002 à 20:58:25 (#2307258)

Je suis content de voir que la communauté NwN Fr possède de bons scripteurs :).

Je reviendrais poster ici si j'ai un problème là dessus (ce qui sera surement le cas d'ailleurs :p).

Par Tyn' le 9/10/2002 à 21:05:54 (#2307302)

Oula on me flatte là... :p

Par Ormus le 26/10/2002 à 17:31:29 (#2412936)

Ah le voilà cet incendie dynamique ! Il était déjà enfoui sous 10 pages ! ;)

Bon, il marche bien (re-merci) mais je n'arrive pas à limiter la propagation...

Admettons je veux qu'il n'y aie que 5 flammes qui apparaissent...je crée une variable nFlammes que j'incrémente de 1 à chaque fois qu'un flamme est créée...et la condition pour que le script se ré-exécute c'est nFlammes < 5 (ou != 5 ça devrait aussi marcher en théorie)...

Oui mais à chaque début de script j'ai marqué int nFlammes = 0 (donc 0 pour 0 flammes)...ce qui veut dire que comme le script se ré-exécute sans cesse la variable n'atteindra jamais 5 ! :maboule:

Donc question : Y-a-t'il une commande qui compte le nombre de fois que s'éxécute le script ou pour le faire revenir en boucle genre Repeat nFlammes=5 (ah oui au fait il y a des boucles en NwScript ?) ...

Je sais que je pourrais copier coller 5 fois à partir du 1er "if" mais je pense qu'il y a une meilleure solution ;).

:merci:

Par eMRaistlin le 26/10/2002 à 17:47:10 (#2413003)

bien sur...


tu fais un


while (nFlammes<6)
{
//"Je brule tout, je casse tout... et j'aime ca ^^"
nFlammes = nFlammes+1;
}


Attention : si tu commence a nFlammes=0, alors le script du dessus créera 6 flamme, puisqu'il va commencer avec nFlammes=0
(comme toi dans ton exemple...:))

Par Tyn' le 26/10/2002 à 17:52:55 (#2413032)

Faux, Raistlin, le script que j'ai proposé au dessus travail avec les executescript et pour limiter l'incendie tu dois donc faire un LocalInt.

Mais ce script est pourri, il faut travailler avec les UserDefinedEvent pour ce genre de choses.. Mea culpa, erreur de jeunesse

Par LeProctophantasmiste le 26/10/2002 à 18:54:55 (#2413328)

Je ne suis pas sûr de comprendre ce que tu veux dire Tyn. Un UserDefineEvent qui se signale lui-même? Incrémenter l'indice de l'event pour le contrôle du nombre d'execution? Pourquoi ExecuteScript te semble-t-elle pourrie?

Par mobidique le 26/10/2002 à 22:04:06 (#2414145)

Chuis sûr que ma crotte tout bète elle marche impec et tu mets le nombre de flammes que tu veux :D

Ha bien sûr avec mes soluces faut se creuser un peu pour les mettres en oeuvre mais on apprend des trucs ;)

Par Tyn' le 27/10/2002 à 0:12:17 (#2414550)

Provient du message de LeProctophantasmiste
Je ne suis pas sûr de comprendre ce que tu veux dire Tyn. Un UserDefineEvent qui se signale lui-même? Incrémenter l'indice de l'event pour le contrôle du nombre d'execution? Pourquoi ExecuteScript te semble-t-elle pourrie?
Un executescript sur une area ou un module c'est un trou à CPU. Surtout en boucle.

Par LeProctophantasmiste le 27/10/2002 à 12:11:14 (#2416563)

Il y a une différence intrinsèque de performance entre un appel de ExecuteScript et de SignalEvent? Je n'ai pas remarqué, mais étant donné le projet sur lequel tu es je te fais confiance, je suis un peu surpris quand même, la méthode pour désigner le script à exécuter est certes différente mais pourquoi cela engendre-t-il une perte de performance? Etrange...

JOL Archives 1.0.1
@ JOL / JeuxOnLine