Oyez, oyez !

Les résultats du vote sur les meilleurs RPG de tous les temps sont désormais dévoilés dans ce message !

Merci à toutes et à tous pour votre participation !

N'hésitez pas à aller commenter, ajouter des jeux auxquels vous n'auriez pas pensé...

[SCRIPT] Comment fonctionne un script de génération aléatoire de créatures ?

Répondre
Avatar du membre
DrAzTiK
Ours des cavernes
Messages : 1180
Enregistré le : ven. 19 sept. 2003, 03:20
Localisation : Bordeaux
Contact :
Statut : Hors ligne

[SCRIPT] Comment fonctionne un script de génération aléatoire de créatures ?

.

Message par DrAzTiK »

J'ai du mal à comprendre un script de génération de creature du mod BGspawns. C'est un script super interessant étant donné qu'il permet de créer des créatures en fonction du nombre des membres de l'équipe et de de leur niveau. C'est vraiment la révolution et c'est dommage que ce genre de script soient si rares dans BG. Vous êtes de cet avis, n'est ce pas ? :)

Voilà une partie du script :

Code : Tout sélectionner

IF
  Range([PC],35)
  OR(2)
  TimeOfDay(0)
  TimeOfDay(3)
  NumInParty(2)
  OR(3)
  CheckStat(StrongestOf(Myself),2,LEVEL)
  CheckStat(StrongestOf(Myself),2,LEVEL2)
  CheckStat(StrongestOf(Myself),2,LEVEL3)
  !CheckStatGT(StrongestOf(Myself),2,LEVEL)
  !CheckStatGT(StrongestOf(Myself),2,LEVEL2)
  !CheckStatGT(StrongestOf(Myself),2,LEVEL3)
  Global("SpawnReset25861956","AR7223",0)
  Global("RandomSet25861956_3","AR7223",1)
THEN
  RESPONSE #80
    SetGlobal("SpawnReset25861956","AR7223",1)
    CreateCreature("ZOMBIE",[2586.1956],0)  // Zombie
    SetGlobalTimer("012325861956","AR7223",2400)
  RESPONSE #20
    SetGlobal("SpawnReset25861956","AR7223",1)
    CreateCreature("GHOUL",[2586.1956],0)  // Ghoul
    SetGlobalTimer("012325861956","AR7223",2400)
END

Les lignes que je ne comprends pas sont les suivantes :

Code : Tout sélectionner

OR(3)
  CheckStat(StrongestOf(Myself),2,LEVEL)
  CheckStat(StrongestOf(Myself),2,LEVEL2)
  CheckStat(StrongestOf(Myself),2,LEVEL3)
  !CheckStatGT(StrongestOf(Myself),2,LEVEL)
  !CheckStatGT(StrongestOf(Myself),2,LEVEL2)
  !CheckStatGT(StrongestOf(Myself),2,LEVEL3)
  Global("SpawnReset25861956","AR7223",0)
  Global("RandomSet25861956_3","AR7223",1)
Içi le script check le niveau, mais le niveau de qui ? Si je comprends bien la signification de "OR(3), il faut que au moins une des 3 premiers lignes soient vraies pour que l'action se déclenche. Est ce bien çela ?
Mais je ne comprends pas trop le sens exact de ces lignes. :gign:
Faites comme moi, jouez FP :cool:

Mon Mod : BuTcHeRY

Ma châine Youtube
Avatar du membre
Haplo74
Minotaure
Messages : 1737
Enregistré le : dim. 08 avr. 2012, 20:20
Localisation : Paris
Statut : Hors ligne
.

Message par Haplo74 »

Bonjour DrAzTiK,

Etonnant que le créateur de BuTcHeRy ne comprenne pas ce morceau de code ?!
Je vais essayer de te répondre dans la limite de ma compréhension du code (en autodidacte, je procède par analogie)...

Dans un script, la structure est IF THEN END.
Les instructions après le IF sont "assemblées" en et logique.
Pour mixer avec des ou logique, il faut utiliser la commande OR, avec entre parenthèse le nombre d'arguments.
Exemple:
A et (B ou C) et D se code

Code : Tout sélectionner

 A
 OR(2)
  B
  C
 D
A et (B ou C ou D) se code

Code : Tout sélectionner

 A
 OR(3)
  B
  C
  D
C'est sûr, respecter les indentations permet de mieux décrypter le code (ce que ne fait pas le script BGSpawn).

Myself correspond à ton groupe.
StrongestOf(Myself) correspond au plus "fort" de ton groupe, en terme de niveau.
CheckStat est une fonction qui renvoie vraisemblablement un booléen (vrai ou faux) si la condition indiquée est remplie.
donc
CheckStat(StrongestOf(Myself),2,LEVEL) teste si le plus fort est de niveau 2 dans sa classe principale.
CheckStat(StrongestOf(Myself),2,LEVEL2) teste si le plus fort est de niveau 2 dans sa deuxième classe (test sur bi-classé ou jumelé).
CheckStat(StrongestOf(Myself),2,LEVEL3) teste si le plus fort est de niveau 2 dans sa troisième classe (test tri-classé seulement).

CheckStatGT est une fonction qui renvoie vraisemblablement un booléen (vrai ou faux) si la condition indiquée est dépassée (GT comme "greater than").
donc
!CheckStatGT(StrongestOf(Myself),2,LEVEL) indique qu'il ne faut pas (le signe ! est une négation) que le plus fort du groupe soit plus de niveau 2...

Bref si on décortique ton bout de code (ce que je comprends, ça ne veut pas dire que c'est bon) :

IF
Range([PC],35)

tu rentres dans la "zone" de spawn ! Je ne sais pas ce que c'est que 35, des mètres ou des pieds probablement (une distance en tout cas) ?

OR(2)
TimeOfDay(0)
TimeOfDay(3)

minuit ou 3 heures du mat ?

NumInParty(2)

équipe composée de deux membres uniquement

OR(3)
CheckStat(StrongestOf(Myself),2,LEVEL)
CheckStat(StrongestOf(Myself),2,LEVEL2)
CheckStat(StrongestOf(Myself),2,LEVEL3)

niveau 2 dans première, deuxième ou troisième classe

!CheckStatGT(StrongestOf(Myself),2,LEVEL)

pas plus de niveau 2 dans classe principale

!CheckStatGT(StrongestOf(Myself),2,LEVEL2)

pas plus de niveau 2 dans seconde classe

!CheckStatGT(StrongestOf(Myself),2,LEVEL3)

pas plus de niveau 2 dans troisième classe

Global("SpawnReset25861956","AR7223",0)

variable trucmuche vaut 0

Global("RandomSet25861956_3","AR7223",1)

autre variable à la mord-moi-le-noeud vaut 1

...

Voilà.
J'espère que d'autres te répondront de manière plus détaillée (et peut-être plus juste).

Haplo74
Modérateur des sections "le bazar de l'aventurier", "la taverne de Château-Suif", "la taverne d'Amkethran" et "le comptoir d'Amn".
Avatar du membre
Isaya
Adepte de Grondemarteau
Planaire
Messages : 6990
Enregistré le : mar. 22 juil. 2003, 21:03
Localisation : Plaisir
Contact :
Statut : Hors ligne
.

Message par Isaya »

A première vue, comme le script teste la proximité avec le PJ avec Range([PC]), je dirais que c'est plutôt un script de monstre ou de trigger. Si tu pouvais préciser d'où vient ce code (c'est à dire de quel script il s'agit et où il est implanté par le mod), ce serait plus simple de le vérifier.
Et dans ce cas, Myself, c'est la créature qui a ce script. Ou alors c'est affecté au spawn point, mais je ne savais pas que c'était possible, auquel cas le Myself pourrait peut-être concerner l'ensemble des créatures définies dans le spawn point, pour déterminer s'il faut du renfort parce que le groupe de créatures est de trop faible niveau, ici 2 maximum.
:!: Peu disponible
Guide d'installation (et FAQ) de Baldur's Gate, Baldur's Gate II, Baldur's Gate Trilogy (BGT), BG1Tutu, Widescreen, BGEE
Pensez à utiliser à la fonction Recherche pour trouver une réponse à votre question !
Avatar du membre
DrAzTiK
Ours des cavernes
Messages : 1180
Enregistré le : ven. 19 sept. 2003, 03:20
Localisation : Bordeaux
Contact :
Statut : Hors ligne
.

Message par DrAzTiK »

CheckStat(StrongestOf(Myself),2,LEVEL) teste si le plus fort est de niveau 2 dans sa classe principale.
CheckStat(StrongestOf(Myself),2,LEVEL2) teste si le plus fort est de niveau 2 dans sa deuxième classe (test sur bi-classé ou jumelé).
CheckStat(StrongestOf(Myself),2,LEVEL3) teste si le plus fort est de niveau 2 dans sa troisième classe (test tri-classé seulement).
Merçi beaucoup Haplo74, je n'arrivais pas à comprendre que le script "checkait" le niveau des autres classes ( bi-classé /jumelé/tri-classé)
OR(2)
TimeOfDay(0)
TimeOfDay(3)

minuit ou 3 heures du mat ?
Oui la je comprends pas trop , surement une erreur.

Etonnant que le créateur de BuTcHeRy ne comprenne pas ce morceau de code ?!
Tu l'as testé? Tu en penses quoi ? Je l'ai codé quasiement sans aucune connaissance de weidu. ha ha. J'avais un désir assez fort de faire une belle bataille à l'époque..


Isaya, Le mod est disponible içi :
http://www.shsforums.net/topic/39639-re ... rsion-111/


Je pense que tous les scripts de BGSPAWN sont des scripts de triggers. Tous les scripts ont la même architecture,il n'y a que les CRE qui changent.
Par exemple, pour la map AR8900 , on a plusieurs triggers dont le FW24000 qui contient le script du même nom et qui est le suivant :


(Cf, piece jointe)


Le Myself dans ce script fait t-il alors référençe au piège (un piège est-il uen créature?) ou bien au groupe de Charname ??


Par ailleurs, à quoi sert la première ligne du code : IF
RandomNum(1,1)

see you soon ;)
Fichiers joints
FW24000.txt
(269 Kio) Téléchargé 242 fois
Faites comme moi, jouez FP :cool:

Mon Mod : BuTcHeRY

Ma châine Youtube
Avatar du membre
Haplo74
Minotaure
Messages : 1737
Enregistré le : dim. 08 avr. 2012, 20:20
Localisation : Paris
Statut : Hors ligne
.

Message par Haplo74 »

Hello,
Isaya a écrit : A première vue, comme le script teste la proximité avec le PJ avec Range([PC]), je dirais que c'est plutôt un script de monstre ou de trigger. Si tu pouvais préciser d'où vient ce code (c'est à dire de quel script il s'agit et où il est implanté par le mod), ce serait plus simple de le vérifier.
Ce script est implanté dans tous les fichiers baf des zones modifiées par BGSpawn.
En effet (c'est le principe du mod), il adapte les créatures alétoirement générées au niveau de l'équipe.
J'y ai jeté un oeil hier soir et le morceau de code proposé traite du niveau 2. Mais il y a un équivalent pour les niveaux 1, 3, 4, 5, 6 et 7+, et ceci pour des groupes de 1, 2, 3, 4, 5, 6 membres (donc au minimum 42 blocs de code).
Isaya a écrit : Et dans ce cas, Myself, c'est la créature qui a ce script. Ou alors c'est affecté au spawn point, mais je ne savais pas que c'était possible, auquel cas le Myself pourrait peut-être concerner l'ensemble des créatures définies dans le spawn point, pour déterminer s'il faut du renfort parce que le groupe de créatures est de trop faible niveau, ici 2 maximum.
Oui c'est un spawn point (voir commentaire ci-dessus). Myself apparement définit le groupe complet.
DrAzTiK a écrit : "
A propos de :

OR(2)
TimeOfDay(0)
TimeOfDay(3)

minuit ou 3 heures du mat ?
"

Oui la je comprends pas trop , surement une erreur.
Non, je ne crois pas que ce soit une erreur. Dans le readme du mod, il est bien précisé que les monstres générés aléatoirement peuvent être différents selon que l'on voyage de jour ou de nuit.
Et d'expérience, si je vais par exemple dans la zone sous Beregost de jour (au niveau 2), je croise des araignées colossales, des hobgobelins, ..., lorsque j'y vais de nuit, je rencontre des goules et autres blèmes (et au niveau 2, je préfère éviter car l'attaque paralysante de ces cochonneries est quasi-sûre de fonctionner avec les JS merdiques qu'on a à ce moment du jeu)
DrAzTiK a écrit : "
A propos de:

Etonnant que le créateur de BuTcHeRy ne comprenne pas ce morceau de code ?!
"

Tu l'as testé? Tu en penses quoi ? Je l'ai codé quasiement sans aucune connaissance de weidu. ha ha. J'avais un désir assez fort de faire une belle bataille à l'époque..
Oui, je l'ai testé.
Tout d'abord je tiens à préciser que je l'ai testé avec une installation qui comprenait Revised Battles (j'ai rédigé un avis à ce sujet) et que j'arrivais à saturation de ce mod pénible à souhait.
J'ai d'ailleurs réglé son compte à Firkraag au Ctrl-Y sans même prendre la peine d'essayer et j'ai ensuite refait une installation...

Sur les animations, rien à redire (je me souviens d'un "t'es moche, toi") de Tazok qui s'adressait à un orque qui m'a bien fait rire...
Sur le combat, c'est vrai que ce groupe peut être un peu difficile, mais comme je fais les collines de Lancevent en dernier avant de partir pour Spellhold, j'ai normalement au moins un mage d'assez haut niveau pour lancer un sort de mort et éliminer les "troufions". Restait Tazok et les quelques autres brutes dont je ne souviens pas du nom (je crois que qu'il y a un Groumf, à ne pas confondre avec Graoumf, le coordinateur des d'Oghms :D ), mais en groupe ce n'est pas bien compliqué.

Il y a trois raisons pour lesquelles je ne l'ai pas réinstallé :
1/ Des combats de groupes contre des orques / orogs et autres bestioles de ce type, on en a dans les rencontres intercartes (avec SCSii et/ou BP) et là on est même au centre du groupe (avec difficulté de lancer le sort de mort car on se fait frapper avant la fin de l'incantation qui échoue) !!

2/ Il me paraît plus cohérent que Tazok et ses sbires gardent le prisonnier (donc dans la salle des cellules) et que Firkraag jouisse de son antre tout seul

3/ Rajoutait à Tazok et ses collègues des objets magiques qui faisaient doublons (ceci-dit, cet argument est mineur, puisque je peux les rendre non récupérable et non volable par script, le faisant déjà sur des créatures d'autres mods)
DrAzTiK a écrit : Par ailleurs, à quoi sert la première ligne du code : IF
RandomNum(1,1)

see you soon ;)
Alors là, aucune idée. Il faudrait voir le reste du bloc. Il génère un nombre aléatoire visiblement mais dans quel but ? (peut-être moduler légèrement le nombre d'ennemis qui apparaissent, ou leur type)

Ceci dit j'ai compris que les chiffres après RESPONSE correspondait déjà à un pourcentage de chance que les lignes qui suivent soient évaluées.

RESPONSE #100
CreatureCreature ... // Goule
=> une goule est générée systématiquement

par opposition à :

RESPONSE #80
CreatureCreature ... // Goule

RESPONSE #20
CreatureCreature ... // Vampire
=> une goule est générée dans 80% des cas, les 20% restant, c'est un vampire (eh, pas de bol, quoi ?!).

Haplo74
Modérateur des sections "le bazar de l'aventurier", "la taverne de Château-Suif", "la taverne d'Amkethran" et "le comptoir d'Amn".
Avatar du membre
Freddy_Gwendo
Adepte de Grondemarteau
Orbe ancien
Messages : 5877
Enregistré le : sam. 23 avr. 2011, 00:26
Localisation : Égaré dans un vortex entre Féérune et le Royaume de Diamant Éternel
Statut : Hors ligne
.

Message par Freddy_Gwendo »

Je confirme à peu près tout ce qui a déjà été dit, à quelques nuances près. ;)
Haplo74 a écrit : Alors là, aucune idée. Il faudrait voir le reste du bloc. Il génère un nombre aléatoire visiblement mais dans quel but ? (peut-être moduler légèrement le nombre d'ennemis qui apparaissent, ou leur type)

Ceci dit j'ai compris que les chiffres après RESPONSE correspondait déjà à un pourcentage de chance que les lignes qui suivent soient évaluées.

RESPONSE #100
CreatureCreature ... // Goule
=> une goule est générée systématiquement

par opposition à :

RESPONSE #80
CreatureCreature ... // Goule

RESPONSE #20
CreatureCreature ... // Vampire
=> une goule est générée dans 80% des cas, les 20% restant, c'est un vampire (eh, pas de bol, quoi ?!).
Contrairement à une idée reçue, les RESPONSE #nn ne correspondent pas à une répartition des % de tirage. J'avais lu un topic là-dessus il y a très longtemps.

Pour faire simple, si tu souhaites utiliser un % pour l'apparition des monstres, le seul moyen efficace est la fonction RandomNum(n,m).
Après plusieurs tests pour les rencontres aléatoires, j'ai définitivement abandonné les RESPONSE par ce code qui fonctionne à 100 % :

Code : Tout sélectionner

IF
  OnCreation()
  Global("GWRandom","GW0227",0)
THEN
  RESPONSE #100
    Explore()
    SetGlobal("GWRandom","GW0227",1)
    SetGlobalTimer("GWRdT227","GW0227",2400)
    Continue()
END

// Nuit
/////////
IF
  Global("GWRandom","GW0227",1)
  GlobalLT("GWFeuEnf","GLOBAL",5)
  GlobalTimerExpired("GWRdT227","GW0227")
  [color="#FFFF00"]RandomNum(2,1) // 50 % de chances[/color]
  TimeGT(21) // DUSK_START
  TimeLT(6)  // DAWN_START
THEN
  RESPONSE #100
    SetGlobalTimer("GWRdT227","GW0227",2400)
    CreateCreature("GWDrakPo",[1100.380],7) // ~Drake pourpre~
    CreateCreature("GWTrlDe1",[840.200],10) // ~Troll du Désert~
    CreateCreature("GWMistEl",[780.620],9)  // ~Brume électrique~
    CreateCreature("GWTrlFa1",[490.220],11) // ~Troll Fantôme~
    CreateCreature("MistVa01",[200.560],10) // ~Brume vampirique~
    CreateCreature("HGMis01",[390.390],10)  // ~Vampire en peine~
    CreateCreature("GWTrlSp1",[460.700],9)  // ~Troll spectral~
    CreateCreature("GWTrlEl1",[750.390],10) // ~Troll électrique~
    CreateCreature("GWTrlEl1",[130.160],13)
    Continue()
END

IF
  Global("GWRandom","GW0227",1)
  GlobalLT("GWFeuEnf","GLOBAL",5)
  GlobalTimerExpired("GWRdT227","GW0227")
  [color="#FFFF00"]RandomNum(2,2) // 50 % de chances[/color]
  TimeGT(21)
  TimeLT(6)
THEN
  RESPONSE #100
    SetGlobalTimer("GWRdT227","GW0227",2400)
    CreateCreature("GWDgnPo1",[525.570],12) // ~Dragon pourpre~
    CreateCreature("GWDrakPo",[1100.380],7)
    Continue()
END

// Jour
/////////
IF
  Global("GWRandom","GW0227",1)
  GlobalLT("GWFeuEnf","GLOBAL",5)
  GlobalTimerExpired("GWRdT227","GW0227")
  TimeLT(22)
  TimeGT(5)
  [color="#FFFF00"]RandomNum(3,1) // 33 % de chances[/color]
THEN
  RESPONSE #100
    SetGlobalTimer("GWRdT227","GW0227",2400)
    CreateCreature("GWDrakPo",[1100.380],7)
    CreateCreature("GWTrlDe1",[840.200],10)
    CreateCreature("GWTrlDe1",[780.620],9)
    CreateCreature("GWTrlDe1",[490.220],11)
    CreateCreature("GWTrlDe1",[200.560],10)
    CreateCreature("GWTrlEl1",[750.390],10)
    CreateCreature("GWTrlEl1",[390.390],10)
    CreateCreature("GWTrlEl1",[460.700],9)
    CreateCreature("GWTrlEl1",[130.160],13)
    Continue()
END

IF
  Global("GWRandom","GW0227",1)
  GlobalLT("GWFeuEnf","GLOBAL",5)
  GlobalTimerExpired("GWRdT227","GW0227")
  TimeLT(22)
  TimeGT(5)
  [color="#FFFF00"]RandomNum(3,2) // 33 % de chances[/color]
THEN
  RESPONSE #100
    SetGlobalTimer("GWRdT227","GW0227",2400)
    CreateCreature("GWDgnPo1",[525.570],12)
    CreateCreature("GWDrakPo",[1100.380],7)
    Continue()
END

IF
  Global("GWRandom","GW0227",1)
  GlobalLT("GWFeuEnf","GLOBAL",5)
  GlobalTimerExpired("GWRdT227","GW0227")
  TimeLT(22)
  TimeGT(5)
  [color="#FFFF00"]RandomNum(3,3) // 33 % de chances[/color]
THEN
  RESPONSE #100
    SetGlobalTimer("GWRdT227","GW0227",2400)
    Continue()
END
On peut aussi y ajouter des conditions sur le niveau du groupe.

Haplo74 a écrit : Oui c'est un spawn point (voir commentaire ci-dessus). Myself apparement définit le groupe complet.

Moi aussi j'ai été très sceptique en allant vérifier les fichiers .baf dans le mod : je ne savais pas que la variable Myself pouvait fonctionner ailleurs que dans des scripts ou des dialogues de créatures.
Je ferai des tests ce week end en l'utilisant dans des scripts de Triggers, ce qui me permettra d'alléger mes scripts de cartes et donc de fluidifier le jeu.

Je vous tiendrai au courant des résultats des tests.
CARPE DIEM...Co-modérateur de La Forge et de La Chambre des Scribes
Moddeur qui s'arrache les cheveux...
Avatar du membre
DrAzTiK
Ours des cavernes
Messages : 1180
Enregistré le : ven. 19 sept. 2003, 03:20
Localisation : Bordeaux
Contact :
Statut : Hors ligne
.

Message par DrAzTiK »

Dsl Freddy mais je ne comprends pas du tout comment fonctionne la fonction RandomNum(n,m). ???

Déjà elle se situe dans un trigger. A quoi s'applique t'elle ? aux lignes juste en dessous, dans le bloc trigger ?

Dans le script que j'ai posté, cette fonction n'est utilisé qu'une seule fois d'ailleurs, en tout début du script. Comment diantre peut elle agir sur le % d'aparition des monstres ??
Faites comme moi, jouez FP :cool:

Mon Mod : BuTcHeRY

Ma châine Youtube
Avatar du membre
Freddy_Gwendo
Adepte de Grondemarteau
Orbe ancien
Messages : 5877
Enregistré le : sam. 23 avr. 2011, 00:26
Localisation : Égaré dans un vortex entre Féérune et le Royaume de Diamant Éternel
Statut : Hors ligne
.

Message par Freddy_Gwendo »

La bible, c'est IESDP :
0x4047 RandomNum(I:Range*,I:Value*)
Generates a random number between 1 and Range. Returns true only if the random number equals the 2nd parameter.

0x4048 RandomNumGT(I:Range*,I:Value*)
NT As above except returns true only if the random number is greater than the 2nd parameter.

0x4049 RandomNumLT(I:Range*,I:Value*)
NT As above except returns true only if the random number is less than the 2nd parameter.

Le principe est assez simple : C'est un peu comme si tu tirais un dé à "Range" faces et que tu notais le résultat ("Value").

Tu choisis une gamme de pourcentage que tu souhaites utiliser : tous les 10 %, une fois sur 4, une fois sur 3, une fois sur 2, etc...

Admettons que tu ais trois possibilités. Dans ce cas, Range = 3 et tu joues avec la variable Value, ce qui donne ceci :

Code : Tout sélectionner

IF
  [BLOC de Conditions]
  [color="#FFFF00"]RandomNum(3,1) // si le pourcentage tiré est inférieur à 33,33 %[/color]
THEN
  RESPONSE #100
    [BLOC d'Actions 1]
END

IF
  [BLOC de Conditions]
  [color="#FFFF00"]RandomNum(3,2) // si le pourcentage tiré est compris entre 33,33 et 66,66 %[/color]
THEN
  RESPONSE #100
    [BLOC d'Actions 2]
END

IF
  [BLOC de Conditions]
  [color="#FFFF00"]RandomNum(3,3) // si le pourcentage tiré est supérieur à 66,66 %[/color]
THEN
  RESPONSE #100
    [BLOC d'Actions 3]
END
Ainsi, chaque fois que [BLOC de Conditions] sera rencontré, tu auras une chance sur 3 pour que Actions 1, Actions 2 ou Actions 3 soient lancées.


Mais tu peux aussi jongler avec des RandomNumGT et RandomNumLT :

Code : Tout sélectionner

IF
  [BLOC de Conditions]
  [color="#FFFF00"]RandomNumLT(10,4) // si le pourcentage tiré est inférieur à 40 % (tirages 1,2,3 sur un dé à 10 faces)[/color]
THEN
  RESPONSE #100
    [BLOC d'Actions 1]
END

IF
  [BLOC de Conditions]
  [color="#FFFF00"]RandomNumGT(10,8) // si le pourcentage tiré est supérieur à 80 % (tirages 9 et 10 sur un dé à 10 faces)[/color]
THEN
  RESPONSE #100
    [BLOC d'Actions 2]
END

IF
  [BLOC de Conditions]
  OR (2)
    [color="#FFFF00"]RandomNum(10,5) // si le pourcentage tiré est égal à 10 % (tirage 5 sur un dé à 10 faces)
    RandomNum(10,6) // si le pourcentage tiré est égal à 10 % (tirage 6 sur un dé à 10 faces)
                                 ==> 20 % de chances[/color]
THEN
  RESPONSE #100
    [BLOC d'Actions 3]
END

etc...

De même tu pourrais aussi utiliser la condition suivante

Code : Tout sélectionner

IF
  [BLOC de Conditions]
  OR(2)
    [color="#FFFF00"]RandomNumLT(10,3) // si le pourcentage tiré est inférieur à 30 %
    RandomNumGT(10,8) // si le pourcentage tiré est supérieur à 80 %
             --->  (tirages 1,2,9 et 10 sur un dé à 10 faces)[/color]

Voilà, j'espère avoir été clair.

Mais il est le vrai que je n'ai pas trop compris la syntaxe du code que tu as présenté car RandomNum(1,1) = 100 %, donc je ne vois pas son intérêt puisque manifestement la fonction RandomNum ne prend pas en compte la variable 0 ! ;)

Edit :

Je te confirme que dans ce cas

Code : Tout sélectionner

IF
  RandomNum(1,1)
  Global("RandomSet1297529_3","AR8900",0)
  Global("RandomBeenSet1297529","AR8900",0)
THEN
  RESPONSE #100
    SetGlobal("RandomSet1297529_3","AR8900",1)
    SetGlobal("RandomBeenSet1297529","AR8900",1)
le RandomNum(1,1) ne sert à rien. Peut-être est-ce une scorie d'une version beta qui envisageait de ne pas lancer systématiquement les compteurs de temps, histoire de rendre l'implantation des rencontres encore plus aléatoires...
CARPE DIEM...Co-modérateur de La Forge et de La Chambre des Scribes
Moddeur qui s'arrache les cheveux...
Avatar du membre
Haplo74
Minotaure
Messages : 1737
Enregistré le : dim. 08 avr. 2012, 20:20
Localisation : Paris
Statut : Hors ligne
.

Message par Haplo74 »

Bonjour Freddy_Gwendo,

Mais dans ton premier exemple tu effectues:

Code : Tout sélectionner

IF
  [BLOC de Conditions]
  RandomNum(3,1) // si le pourcentage tiré est inférieur à 33,33 %
THEN
  RESPONSE #100
    [BLOC d'Actions 1]
END

IF
  [BLOC de Conditions]
  RandomNum(3,2) // si le pourcentage tiré est compris entre 33,33 et 66,66 %
THEN
  RESPONSE #100
    [BLOC d'Actions 2]
END

IF
  [BLOC de Conditions]
  RandomNum(3,3) // si le pourcentage tiré est supérieur à 66,66 %
THEN
  RESPONSE #100
    [BLOC d'Actions 3]
END
Tu pars du principe que RandomNum n'évalue qu'un seul nombre aléatoire, pourtant la fonction est appelée trois fois, non ? Une fois par bloc.

Pourquoi n'est-il pas possible que RandomNum (3,1) renvoie false (nombre tiré = 2) puis RandomNum (3,2) renvoie false ("nouveau" nombre tiré = 1) puis RandomNum (3,3) renvoie false ("nouveau" nombre tiré = 1) à la suite ?

De même je ne comprends pas bien ton troisième exemple :

Code : Tout sélectionner

IF
  [BLOC de Conditions]
  RandomNumLT(10,3) // si le pourcentage tiré est inférieur à 30 %
  RandomNumGT(10,8) // si le pourcentage tiré est supérieur à 80 %
             --->  (tirages 1,2,9 et 10 sur un dé à 10 faces
Si on part toujours du principe que le nombre aléatoire de RandomNum n'est évalué qu'une fois (ou RandomNumGT ou RandomNumLT), ne faudrait-il pas mettre un OR(2) devant les deux RandomNum ? Sinon je vois mal comment on peut être à la fois < 30% et > 80%...

Haplo74
Modérateur des sections "le bazar de l'aventurier", "la taverne de Château-Suif", "la taverne d'Amkethran" et "le comptoir d'Amn".
Avatar du membre
Freddy_Gwendo
Adepte de Grondemarteau
Orbe ancien
Messages : 5877
Enregistré le : sam. 23 avr. 2011, 00:26
Localisation : Égaré dans un vortex entre Féérune et le Royaume de Diamant Éternel
Statut : Hors ligne
.

Message par Freddy_Gwendo »

Alors...
Haplo74 a écrit :Bonjour Freddy_Gwendo,

Mais dans ton premier exemple tu effectues:

Code : Tout sélectionner

IF
  [BLOC de Conditions]
  RandomNum(3,1) // si le pourcentage tiré est inférieur à 33,33 %
THEN
  RESPONSE #100
    [BLOC d'Actions 1]
END

IF
  [BLOC de Conditions]
  RandomNum(3,2) // si le pourcentage tiré est compris entre 33,33 et 66,66 %
THEN
  RESPONSE #100
    [BLOC d'Actions 2]
END

IF
  [BLOC de Conditions]
  RandomNum(3,3) // si le pourcentage tiré est supérieur à 66,66 %
THEN
  RESPONSE #100
    [BLOC d'Actions 3]
END
Tu pars du principe que RandomNum n'évalue qu'un seul nombre aléatoire, pourtant la fonction est appelée trois fois, non ? Une fois par bloc.

Pourquoi n'est-il pas possible que RandomNum (3,1) renvoie false (nombre tiré = 2) puis RandomNum (3,2) renvoie false ("nouveau" nombre tiré = 1) puis RandomNum (3,3) renvoie false ("nouveau" nombre tiré = 1) à la suite ?

Tout provient du fameux topic que je mentionnais. J'ai essayé de le rechercher mais comme il date de plus de 6 ans, je ne me souviens plus où il se trouve (en fait quelque part sur SHS, G3, PPG, ou bien les ex TeamBG et Mystra...).

Bref, les conclusions étaient qu'un pourcentage aléatoire unique (RandomNum) est tiré au début de chaque round. Donc la valeur prise en compte pour chaque bloc est la même. Du coup le code fonctionne.


De même je ne comprends pas bien ton troisième exemple :

Code : Tout sélectionner

IF
  [BLOC de Conditions]
  RandomNumLT(10,3) // si le pourcentage tiré est inférieur à 30 %
  RandomNumGT(10,8) // si le pourcentage tiré est supérieur à 80 %
             --->  (tirages 1,2,9 et 10 sur un dé à 10 faces
Si on part toujours du principe que le nombre aléatoire de RandomNum n'est évalué qu'une fois (ou RandomNumGT ou RandomNumLT), ne faudrait-il pas mettre un OR(2) devant les deux RandomNum ? Sinon je vois mal comment on peut être à la fois < 30% et > 80%...
Oups ! :$

Bonne lecture. C'est une erreur de frappe que je vais m'empresser de corriger.
Bravo pour ton oeil de lynx ! ;)
CARPE DIEM...Co-modérateur de La Forge et de La Chambre des Scribes
Moddeur qui s'arrache les cheveux...
Avatar du membre
DrAzTiK
Ours des cavernes
Messages : 1180
Enregistré le : ven. 19 sept. 2003, 03:20
Localisation : Bordeaux
Contact :
Statut : Hors ligne
.

Message par DrAzTiK »

A priori, utiliser la fonction RandomNum rallonge quand même les scripts vu qu'on doit réecrire tout le bloc trigger à chaque fois.
Contrairement à une idée reçue, les RESPONSE #nn ne correspondent pas à une répartition des % de tirage. J'avais lu un topic là-dessus il y a très longtemps.
Peux tu le confirmer ? La plupart des mods utilisent les RESPONSE #nn et ça semble marcher correctement..


Sinon j'ai trouvé un autre moyen qui permettrait au joueur de switcher la diffitulé d'un combat facilement. Il suffit d'utiliser la variable Global ("RTWMyDifficulty","global",x). C'"est la variable associé au curseur de difficulté dans les options. Donc on peut faire apparaitre plus ou moins davantage de monstre suivant le niveau de difficulté que le joueur aura lui même selectionné.
Le mod Rogue rebalancing utilise ce moyen et SCS veut aussi l'employer davantage.

Je trouve que c'est notamment intéressant pour les gros combats. Pour de simple spawns, un check de l'experience et du nombre de joueurs est surement plus adapaté.

C'est tout un art d'instaurer une difficulté dynamique !
petit doc interessant à ce propos : http://www.youtube.com/watch?v=YxfqP8yFE5U
Faites comme moi, jouez FP :cool:

Mon Mod : BuTcHeRY

Ma châine Youtube
Avatar du membre
Haplo74
Minotaure
Messages : 1737
Enregistré le : dim. 08 avr. 2012, 20:20
Localisation : Paris
Statut : Hors ligne
.

Message par Haplo74 »

Bonjour DrAzTiK
DrAzTiK a écrit : ...
Sinon j'ai trouvé un autre moyen qui permettrait au joueur de switcher la diffitulé d'un combat facilement. Il suffit d'utiliser la variable Global ("RTWMyDifficulty","global",x). C'"est la variable associé au curseur de difficulté dans les options.
Donc on peut faire apparaitre plus ou moins davantage de monstre suivant le niveau de difficulté que le joueur aura lui même selectionné.
Le mod Rogue rebalancing utilise ce moyen et SCS veut aussi l'employer davantage.
...
Cette histoire de monstres qui apparaissent suivant le niveau de difficulté me rappelle certains composants de Tactics et/ou Big Picture.
Notamment la passe du petit croc, qui dans le jeu de base fait apparaître quelques ankhegs ou quelques loup-garous (au chapitre 6 de SoA !! et encore je me demande même s'il n'y a pas des gnolls...) a été revue et tu tombes au milieu de dragons (déjà c'est plus conforme au nom du lieu). Ca peut aller jusqu'à 8 si tu joues en très difficile (personnellement, c'est uniquement pour cette raison que je joue dans cette configuration, et en arrivant dans la passe du petit croc, donc après voyage et sans pré-buff, tu croises direct 3 dragons hostiles...).

La "liche sur les docks" et les "gardes de Kangaxx" sont également présents ou non en fonction du curseur de difficulté. Tous ces composants me semblent être l'oeuvre originelle d'un certain Kensai Ryu.

J'ai retrouvé une discussion que j'avais consultée il y a longtemps sur le site de Spellhold (je croyais que c'était dans le forum Big Picture mais en fait non, c'est dans Big World Project):

http://www.shsforums.net/topic/54061-bw ... ues/page-2 (post de Suslik "Posted 29 March 2012 - 11:37 AM")



A priori il utilise autre chose (Difficulty(HARDEST), DifficultyGT(EASY)...) mais il faudrait éplucher le code BP pour en être tout à fait sûr (que Difficulty ne soit pas une fonction définie par le mod avec ton RTWMyDifficulty).

Haplo74
Modérateur des sections "le bazar de l'aventurier", "la taverne de Château-Suif", "la taverne d'Amkethran" et "le comptoir d'Amn".
Avatar du membre
Freddy_Gwendo
Adepte de Grondemarteau
Orbe ancien
Messages : 5877
Enregistré le : sam. 23 avr. 2011, 00:26
Localisation : Égaré dans un vortex entre Féérune et le Royaume de Diamant Éternel
Statut : Hors ligne
.

Message par Freddy_Gwendo »

DrAzTiK a écrit : Peux tu le confirmer ? La plupart des mods utilisent les RESPONSE #nn et ça semble marcher correctement..
En farfouillant dans mes archives, j'ai fini par retrouver ceci :
Multiple responses:

You are not limited to simply using a single RESPONSE #100 in scripts. You can have numerous responses. The actual response #s only matter relative to each other (they do not need to total 100), as they act as a weighting.
So, you could have, for example:

Code : Tout sélectionner

IF
    // Triggers
THEN
    RESPONSE #100
        // Action 1
    RESPONSE #100
        // Action 2
END
This will theoretically execute either action 1 or action 2 with equal chance of each when the block is executed. However, in practice, there is a bias towards the first response (see this post). Truly random responses, if essential, can be achieved using the RandomNum trigger.
Malheureusement, le lien indiqué - sans doute celui que je cherchais - ne mène à rien : c'est l'ancien site de TeamBG.


Quant à la gestion du niveau de difficulté, je suis d'accord avec Haplo : le plus simple est d'utiliser le trigger Difficulty() sans rajouter de variables. Je l'utilise plusieurs fois pour gérer le nombre de dragons rencontrés (4 ou 5, ce n'est pas la même chanson qu'un seul !).
CARPE DIEM...Co-modérateur de La Forge et de La Chambre des Scribes
Moddeur qui s'arrache les cheveux...
Avatar du membre
DrAzTiK
Ours des cavernes
Messages : 1180
Enregistré le : ven. 19 sept. 2003, 03:20
Localisation : Bordeaux
Contact :
Statut : Hors ligne
.

Message par DrAzTiK »

Quant à la gestion du niveau de difficulté, je suis d'accord avec Haplo : le plus simple est d'utiliser le trigger Difficulty() sans rajouter de variables. Je l'utilise plusieurs fois pour gérer le nombre de dragons rencontrés (4 ou 5, ce n'est pas la même chanson qu'un seul !).
Oui mais si le joueur modifie le curseur de difficulté dans les options, il change aussi les régles du jeux non ? (les ennemis dont 2x damage en mode très difficile par exemple)

C'est pour ça que j'installe toujours les composant Improved Difficulty System de The Bigg Tweak Pack :

This component has no effect on an unmodded game, it only makes sense with mods that add smarter enemies according to the difficulty level (EG Ding0's Quest Pack, Oversight).
This component (based on an idea originally contained in the RtW mod) allows you to set the difficulty level to be different from the one set in the slider. This allows you to get more intelligent enemies, while not getting 200% damage.
The difficulty is set via a dialogue with Ggib Eht; if you later want to change your difficulty level, you can either activate the AI, choose your character, and press the 'k' key, or use directly the "RTWMyDifficulty","Global" variable (1=easiest, 5=hardest).


En modifiant la variable "RTWMyDifficulty" in game par l'intermediare d'une boite de dialogue, on change le niveau de difficulté sans changer les régles de dégâts.

Mas comment marche le curseur de difficulté exactement ? Je suppose qu'il influe aussi sur la variable RTWMyDifficulty mais en augmentant les dégats (mod difficile) par la même occasion.
Faites comme moi, jouez FP :cool:

Mon Mod : BuTcHeRY

Ma châine Youtube
Répondre

Retourner vers « Scripts »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 0 invité