Archives des forums MMO/MMORPG > Neverwinter Nights > NWN - Maskado > Incendie dynamique
Incendie dynamique
Par Ormus le 9/10/2002 à 13:52:47 (#2303978)
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)
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)
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()
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:
{
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.
}
}
Par Tyn' le 9/10/2002 à 20:27:31 (#2307052)
void main()
Je l'ai testé sur un OnUsed, suffit d'adapter, après :)
{
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.
}
}
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 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)
Par Ormus le 26/10/2002 à 17:31:29 (#2412936)
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)
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)
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)
Par mobidique le 26/10/2002 à 22:04:06 (#2414145)
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
Un executescript sur une area ou un module c'est un trou à CPU. Surtout en boucle.
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 LeProctophantasmiste le 27/10/2002 à 12:11:14 (#2416563)
JOL Archives 1.0.1
@ JOL / JeuxOnLine