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

Panneau de contrôle

Recherche | Retour aux forums

JOL Archives

Creation de parchemins

Par Anianka le 23/10/2002 à 18:18:27 (#2391637)

j'essaie de faire un script qui permet de fabriquer des parchemins si on a le sort en memoire
(on verra plus tard a tester si le pj a le feat de creation de parchemin)

pour cela, j'ai un item "encrier" qui qd on l'utilise lance une conversation
qui affiche tous les choix possible de sorts ( cad tous les sorts appris du pj)
qd on choisi le sort qu'on veut ecrire en parchemin, il doit creer un parchemin correspondant et enlever de l'or et des xp au pj ...

ca marche parfaitement mais vu les scriopt que j'ai pour tester si le pj a le sort et le script qui fabrique le parch, je vais devoir faire un script de chaque pour chaque sort ... je sais pas comment faire pour avoir un seul script generique qui pourrait etre utilisé pour la liste complete des sorts ...

Aufait,si quelqu'un pouvait me donner les regles exactes de creation d'objetx magiques :
combien d'xp ca coute (ca je sais plus du tout)
combien d'or (50 % du prix normal je crois)
et comment on calcul le prix d'un parchemin en fonction du niveau du sort ...


pour l'instant ca donne : dans le onActivateItem :



include# ygg_inc_act
//...
encrier_act_test(oPC,oItem);
//...



dans le script : ygg_inc_act


void encrier_act_test(object oPC,object oItem)
{
if(GetTag(oItem) == "encrier" && GetIsInCombat(oPC) != TRUE) // si c'est l'object encrier
{
AssignCommand(oPC,ActionStartConversation(oPC,"conv_encrier"));
}
}



dans la conversation s'il affiche la reponse concernant le sort


int StartingConditional()
{
if ( GetHasSpell(SPELL_ACID_FOG,GetPCSpeaker()) )
{
return 1;
}
else
{
return 0;
}
}



alors il cré le parchemin :


#include"ygg_cre"
void main()
{

object oPC = GetPCSpeaker();
parch_creation(oPC,"nw_it_sparscr603",6.0);

}



avec le ygg_cre :


void parch_creation(object oPC,string nom, float niveau)
{
if (GetGold(oPC) >= FloatToInt(pow(2.0,niveau - 1.0) * 10.0))
{
CreateItemOnObject(nom,oPC);
SetXP(oPC, GetXP(oPC) - (FloatToInt(pow(2.0,niveau + 1.0) /2.0)));
TakeGoldFromCreature(FloatToInt(pow(2.0,niveau - 1.0) * 10.0), oPC,TRUE);
}
else
{
SendMessageToPC(oPC,"vous n'avez pas assez d'or, il vous faut :" + IntToString(FloatToInt(pow(2.0,niveau - 1.0) * 10.0)) + "po");
}
}



désolé, y a pas de couleur mais c un copié collé du code ...

Par LeProctophantasmiste le 23/10/2002 à 20:31:39 (#2392533)

Jolis scripts! Ca je ne savait même pas que c'était possible:


AssignCommand(oPC,ActionStartConversation(oPC,"conv_encrier"));


Pour l'histoire d'unifier les scripts:
Pour le premier script, ma solution est lourde, pour le deuxième je ne vois pas.
Mais comme tu l'as demandé :D
Pour le premier script, un principe simple marche: tu construis un "pointeur" via un LocalInt, par exemple "TEMP_SPELL" et tu l'incrémente à chaque fois que le StartingConditional est appelé (le dialogue est parcourru de haut en bas par le moteur).

Bien sûr, cela te contraint à respecter un ordre prédéterminé pour le choix du sort dans ton dialogue:


int StartingConditional()
{
object oPC =GetPCSpeaker();
// retourne 0 si la variable n'existe pas, soit SPELL_ACID_FOG
int nSpell = GetLocalInt(oPC,"TEMP_SPELL");
// on incrémente que le PJ connaisse le sort ou non
SetLocalInt(oPC,"TEMP_SPELL", nSpell + 1);
if ( GetHasSpell(GetSpellTrueId(nSpell),oPC) )
{
return 1;
}
else
{
return 0;
}
}


Tu auras remarqué la présence d'une fonction GetTrueSpellId():
Malheureusement, les constantes SPELL_* sont énumérées dans l'ordre alphabétique, indifférement de la classe qui peut les utiliser. Si donc tu veux mettre en place ce truc il va falloir que tu construise ta propre énumération:


int GetSpellId(int nSpell)
{
//nspell est l'id que tu t'es donné pour le sort de magicien
switch(nSpell)
{
....
}
return "le SPELL_* correspondant";
}


Pour unifier les scripts de création de parchemins, à défaut d'une fonction qui retourne le numéro de la réplique choisie ou qqc du même ordre, je ne vois pas comment faire.

Si tu décide de faire ce machin, pense à effacer "TEMP_SPELL" en sortie de dialogue, ou sur le deuxième script par exemple.

Par Amaranthe le 23/10/2002 à 21:03:29 (#2392769)

Il ya deja dans les HCR ( kss kss ;) ) un pnj qui crée des parchemins pour les joueurs ;)

Par LeProctophantasmiste le 23/10/2002 à 22:22:58 (#2393172)

Amarante, intéressant, je ne connais pas bien (voir pas du tout) le HCR, ceci dit, je ne comprend pas bien ce que tu veux dire. Ce que fait Anianka est différent, non?
Ou alors le HCR utilise un seul script pour la création de tous les types de parchemins? Je dirais que c'est possible par reconnaissance de pattern, mais dans une conversation je ne vois pas trop. Si tu sais je veux bien que tu m'explique ;).

Par Jedaï le 23/10/2002 à 22:36:23 (#2393232)

Les scripts sont pas mal effectivement même si j'émettrais quelques remarques de pure forme : Par exemple je mettrais plutôt un simple


return GetHasSpell(...);


et

if(GetTag(oItem) == "encrier" && !GetIsInCombat(oPC))
{
AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC,ActionStartConversation(oPC,"conv_encrier"));
}


Mais bon c'est surtout du pinaillage ;) ...

Par contre, ça serait plutôt bien de tester les IDs des sorts : sont-ils vraiment successifs ? N'y a-t-il pas moyen d'en déduire le niveau ? etc... :confus:
On peut en effet constater que les scrolls ont comme blueprint it_sparscrABC, où A, B et C sont trois chiffres, le premier désignant le niveau et les deux autres ? (en tout cas pour B et C, l'ordre alphabétique n'intervient pas : Ray of Frost est le 003 alors que Daze 004 et Light 005). :confus:
Peut-être y a-t-il un rapport avec les IDs...
Si ces points étaient éclaircis ça aiderait sûrement.

Par LeProctophantasmiste le 23/10/2002 à 22:51:21 (#2393340)


Par contre, ça serait plutôt bien de tester les IDs des sorts : sont-ils vraiment successifs ? N'y a-t-il pas moyen d'en déduire le niveau ? etc...

Ils sont successifs, l'énumération continue même sur les SPELLABILITY_*.
Pour le niveau et autre, non, comme je le mentionnais ça m'a tous l'air d'être de l'ordre alphabétique (jusqu'aux SPELLABILITY qui sont définies après) , a moins qu'il n'y aie un algo particulièrement vicieux caché derrière :D.

au cas où:
Tu peux voir tout ça dans nwscript.nss dans le dossier NWN\override.

pour ton pinaillage, tu sais les goûts et les couleurs ... ;) .

Par Amaranthe le 24/10/2002 à 9:33:41 (#2395122)

Provient du message de LeProctophantasmiste
Amarante, intéressant, je ne connais pas bien (voir pas du tout) le HCR, ceci dit, je ne comprend pas bien ce que tu veux dire. Ce que fait Anianka est différent, non?
Ou alors le HCR utilise un seul script pour la création de tous les types de parchemins? Je dirais que c'est possible par reconnaissance de pattern, mais dans une conversation je ne vois pas trop. Si tu sais je veux bien que tu m'explique ;).


Effectivement, le scribe des HCRs travaille par reconnaissance de pattern... c'est plus simple a developper... meme si c'est plus chiant pour le joeur. Mais apres tout... faire un parchemin magique ne doit pas etre simple ;)

Par Anianka le 24/10/2002 à 12:34:13 (#2396280)

Je prefere ne pas utiliser le hcr, c bien mais y a trop de trucs dans tous les sens ...

Pour la reconnaissance du pattern, c peut etre plus simple, mais je prefere que les joueurs aient qq chose d'agreable et de facile a utiliser .... je script pas pour faire du script, je script pour que ce soit plus facile pour le pj ....

Merci des reponses, je penses savoir comment je vais faire maintenant ...

Par coolstar le 24/10/2002 à 13:34:11 (#2396751)

Hi!


Je croise souvent les termes récurrents HCR et Pattern... pouvez-vous m'éclairer à ce propos... genre, dans quel cas ça sert & comment... :D

Merci. :merci:


...

Par LeProctophantasmiste le 24/10/2002 à 14:33:36 (#2397222)

Alors le HCR "Hard Core Rules", c'est un gros machin, un ensemble de scripts, très bien fichus d'après le peu que j'en ai vu, qui tente de rapprocher NWN des règles de la 3E.
Pour l'adresse désolé je ne l'ai pas mais tu ne devrais pas avoir trop de ma à trouver (par google? sinon en passant par NWVault)
Pattern, ça veut dire motif en anglais. C'est lié à la capicité de crier/parler/murmurer des joueurs et PNJ, il s'agit de motifs de phrases (des expressions régulières super light) que tu peux mettre en place sur un PNJ. A chaque fois que le PNJ entendra une phrase correspondant à ce motif, son OnConversation sera lancé, et tu pourra récupérer le motif entendu.

les deux fonctions suivantes se mettent générallement dans le OnSpawn du PNJ sensé écouter:
SetListening(): pour activer l'écoute par le PNJ (ne fait rien par soi-même: il faut ensuite définir ce qu'il doit écouter)

SetListenPattern(): pour que le PNJ recherche un motif particulier, il faut appeler cette fonction pour chaque motif que l'on veut établir sur le PNJ.


Celle là (ainsi que les deux autre qui suivent) s'utilise dans le OnConversation:
GetListenPatternNumber(): Renvoie le numéro du pattern (fixé par l'appel correspondant de SetListenPattern) auquel la phrase entendue s'est unifiée.



un peu plus compliqué: quand tu mets des wildcards (**), pattern pouvant s'unifier avec n'importe quelle chaîne de caractère, dans une pattern, la chaîne de caractère que le PNJ reconnaîtra va être "découpée en morceaux":

pattern: "**foo**bar**"
phrase entendue: "le meilleur poste au foot c'est à côté du bar"


pattern ** foo ** bar **
chaîne de caractère le meilleur poste au foo t c'est à côté du bar

Passons sur la phrase en question (je sais pas pourquoi, foo et bar ça réveille mon côté beauf) donc le "but du jeu" c'est de faire correspondre le motif et la phrase entendu, ici étant donné qu'il y a des ** partout les seules contraintes sont de trouver un "foo" et un "bar" (dans cet ordre de gauche à droite) dans la phrase. Incroyable cela marche! On voit que notre phrase est découpée en morceaux:

GetMatchedSubstringCount() renvoie le nombre de morceaux.
GetMatchedSubstring(i) renvoie les morceaux en questions (indicés de 0 à GetMatchedSubstringCount() -1)

GetMatchedSubstringsCount() renverrait donc... 5, le fait que la dernière soit " ne devrait rien changer .

GetMatchedSubstring(0) == "le meilleur poste au "
GetMatchedSubstring(1) == "foo"
GetMatchedSubstring(2) == "t c'est à côté du "
GetMatchedSubstring(3) == "bar"
GetMatchedSubstring(4) == "

L'exemple que j'ai choisi est un peu particulier car l'unification se fait de façon unique, ce n'est générallement pas le cas, hors BIOWARE n'a pas donné, autant que je saches, l'algo d'unification.

Un truc que je n'ai pas précisé sur le OnConversation: cet événement est aussi lancé en cas de clic sur le PNJ par un joueur (si le curseur est l'icone de conversation). Dans ce cas, GetListenPatternNumber() renvoie -1.

voilà, je vais arreter d'éditer ce message maintenant.

Ouf! j'arrive après le dernier Edit...

Par coolstar le 24/10/2002 à 16:11:02 (#2397966)

Edifiant ! ;)

Par LeProctophantasmiste le 24/10/2002 à 17:05:53 (#2398351)

Maintenant que j'ai fait ça, autant que ça serve. Donc si vous trouvez que mon explication est à peu près claire, peut-être pourrais-je la compléter (test de l'algo d'unification notament, toutes les possibilités pour la construction de patterns, et développer un exemple tout du long), faire un nouveau sujet et mettre un lien dans les tutoriaux (je ne crois pas que ce sujet soit couvert)?

Par eMRaistlin le 24/10/2002 à 17:10:07 (#2398379)

J'achete !!!

Par LeProctophantasmiste le 24/10/2002 à 18:26:13 (#2398912)

Bon, ben je vais m'y mettre alors :D.

Désolé de me faire soliciter, mais comme ça demande un peu de boulot, j'aimerais savoir si ça intéresse quelqu'un (et si ça n'a pas déjà été fait). Je compte aussi faire un hakpack de démonstration: deux implémentations d'objets qui change de forme (genre couteau suisse) grace à une propriété: ie l'objet original est détruit et remplacé par un autre. Ce serait surtout pour montrer comment on peut le faire.

première implémentation par reconnaissance de pattern, on utilise l'objet, on dit une phrase et zou... à la place d'une hache on se retrouve avec une cape des ombres, ou une lampe de poche (enfin... une amulette). Je pense qu'il y a des trucs à faire avec propriété d'objet + reconnaissance de pattern, donc ça pourrait avoir une valeur comme exemple. Ca marche mais j'ai encore un ou deux soucis: les modèles invisibles disponibles sont beaucoup trop gros à mon goût, et il y a un temps de latence entre la création d'une créature invisible et le moment ou elle entend le PC.

Deuxième implémentation en rajoutant une propriété à l'objet via les .2da. La propriété s'appelle "type d'objet" (je fais de la récup des chaînes definie par BiOWARE :D ) on clique dessus, un menu radial apparaît (type polimorphe self) et on choisi hache d'arme, amulette, cape (5 en tout).

voilà, voilà, dîtes moi si vous êtes intéressés, je vais avoir moins de temps (les études...) mais j'essaierais d'expliquer comment ça marche pour que ce soit facilement réutilisable pour faire autre chose.

Par coolstar le 24/10/2002 à 20:17:31 (#2399859)

t'excuse pas! ;)

:merci:

Par Mastokk le 25/10/2002 à 21:05:49 (#2408424)

Oui, il existe déjà un hack pack avec un .erf trouvable sur le net qui fait la même chose. Le fonctionnement est le suivant: On pose le personnage importé avec le .erf, quand un Pj lui parle, il lui demande si il veut faire un parchemin. le PJ n'a alors plus qu'a ecrire le nom du sort qu'il veut mettre en parchemin et celui ci est créé en contrepartie d'un montant d'or et d'expérience.

Par coolstar le 25/10/2002 à 23:11:11 (#2409303)

cool

Par Anianka le 26/10/2002 à 12:23:20 (#2411449)

Oui mais je veux pas que ce soit un pnj qui le fabrique mais le pj ...
donc je me fais mon code a moi qui marche ou que soir le pj ... ca donne vraiment l'impression de fabriquer, pas d'acheter au rabais en perdant des xp ...

Par Mastokk le 28/10/2002 à 12:47:25 (#2423442)

Et bien alors ton script m'interesse ;). Par contre, je sais pas si tu l'a fais, il vaut mieux mettre un coût de création (en exp et en or), comme dans les règles D&D3.

Par Anianka le 28/10/2002 à 15:34:11 (#2424792)

c compris dans le script ...
faut juste que je recupere les valeurs des parch de niveau 0-9 et les pourcentage
(50% en or, peut etre 10% en xp, je sais plus)

Par Mastokk le 28/10/2002 à 16:19:15 (#2425128)

Ha oui désolé tu l'avais marqué dans ton premier sujet :rolleyes:.

Par Mastokk le 28/10/2002 à 17:00:37 (#2425502)

Alors, je sais pas si on t'a répondu en PM mais comme je n'ai pas vu la réponse dans les posts précédent, je te met les coûts:

Coût en or : Niveau du sort * Niveau du lanceur de sort * 12,5

Coût en expérience : (tirés de la table 8_44 du guide du maître 3eme ed, p.244)

Niveau 0 :
- Druide, Magicien et Prêtre : 1 PX
- Ensorceleur : 1 PX
- Barde : 1 PX

Niveau 1 :
- Druide, Magicien et Prêtre : 1 PX
- Ensorceleur : 1 PX
- Barde : 2 PX
- Paladin, Rodeur : 2 PX

Niveau 2 :
- Druide, Magicien et Prêtre : 6 PX
- Ensorceleur : 8 PX
- Barde : 8 PX
- Paladin, Rodeur : 8 PX

Niveau 3 :
- Druide, Magicien et Prêtre : 15 PX
- Ensorceleur : 18 PX
- Barde : 21 PX
- Paladin, Rodeur : 15 PX

Niveau 4 :
- Druide, Magicien et Prêtre : 28 PX
- Ensorceleur : 32 PX
- Barde : 40 PX
- Paladin, Rodeur : 28 PX

Niveau 5 :
- Druide, Magicien et Prêtre : 45 PX
- Ensorceleur : 50 PX
- Barde : 65 PX

Niveau 6 :
- Druide, Magicien et Prêtre : 66 PX
- Ensorceleur : 72 PX
- Barde : 96 PX

Niveau 7 :
- Druide, Magicien et Prêtre : 91 PX
- Ensorceleur : 98 PX

Niveau 8 :
- Druide, Magicien et Prêtre : 120 PX
- Ensorceleur : 128 PX

Niveau 9 :
- Druide, Magicien et Prêtre : 153 PX
- Ensorceleur : 162 PX

Par Anianka le 28/10/2002 à 17:09:53 (#2425596)

merci bcp, je vais pouvoir faire mon code maintenant ...
une fois fini, j'en mettrais une partie ici

Par Mastokk le 28/10/2002 à 18:56:52 (#2426525)

Si le coeur t'en dis, il est possible de faire le même genre de chose avec les potions ;). La formule pour le cout en or et les PX à dépenser changent mais si ca t'interesse, je te les mettrais ;).

Par Anianka le 28/10/2002 à 19:49:54 (#2426929)

je comptais le faire, mais d'abord, faut que je finisse les parch ....
de toute maniere, ca va etre en grande parite la meme chose ...

Par Mastokk le 28/10/2002 à 20:08:23 (#2427078)

Oui ce sera quasiment la même chose mais en bouteille ;). Je t'aiderai bien à le faire mais... je suis .... comment dire..... une super mega grosse quiche en script... Mis à part quelques bidouilles, je sais rien faire :rolleyes:

Par Anianka le 28/10/2002 à 20:33:47 (#2427297)

Je vous dis, pour l'instant, mes scripts ne sont pas optimisés du tt car j'ai pas reussi a faire un script general qui teste le niveau de chaque classe, ni pour creer les parch ...

en plus, je sais pas la structure du switch case ni du for (c pas comme en c et j'ai pas trop cherché a vrai dire ...)

donc du coup, j'ai un paquet de scripts ....

Par LeProctophantasmiste le 28/10/2002 à 23:41:32 (#2428465)


en plus, je sais pas la structure du switch case ni du for (c pas comme en c et j'ai pas trop cherché a vrai dire ...)

:confus: Euh... C'est là même qu'en C.
Presque,

for(int i;...)

est interdit, pas de déclaration de variable, il faut la faire avant.
Pourtant les variables locales marchent, un petit oublie donc.

Par Anianka le 29/10/2002 à 0:23:55 (#2428641)

ca devait etre ca alors, j'avais pas cherché a savoir ...
et le i++, il prend ?

Par LeProctophantasmiste le 29/10/2002 à 14:14:20 (#2431816)

Mis à part ce qui n'y est pas, tout y est :D (i++, i+= en particulier, i+= marchant aussi pour les chaînes).

Pour être un peu plus précis la plupart des choses qui manquent sont prévisibles:
pas de tableau.
pas de type char.
pas de cast.
rien de ce qui touche à "l'accès direct" à la mémoire (pointeurs, alloc dynamique, passage par ref...).
Instruction pré processeur: #include uniquement.
...
Rien de ce qui foutrait le bordel, ni de ce qui est lié à quelque chose foutant le bordel...

A noter que les structures sont là

Par coolstar le 30/10/2002 à 4:41:40 (#2437492)

Allo, allo ! Vous avez un décodeur ?? Allo ! :maboule:

Par Frolo Xeres le 5/11/2002 à 13:38:14 (#2485576)

Ah ben là pour comprendre, focement faut connaitre un peu la prog !

M'enfin là je pense que tu veux pas savoir !

-> Pour la structure vu qu'y en a :
En gros, cela permet de regrouper plusieurs variables sous un même nom.
Cela rejoint le concept de classe ( où là je m'égard )

En clair :
Une variable de type 'struct' ou structure contient d'autre(s) variable(s), si c'est comme dans les autres langage il suffit de les récupérer par le point :

struct vecteur {
int iAbscisse;
int iOrdonnee;
int iHauteur;
}

vecteur.iAbscisse désigne l'abscisse de ton vecteur...

M'enfin là c'est du C pas du script Bioware... Alors che pas si sa s'écrit comme çà, j'ai pas regardé !

Par coolstar le 5/11/2002 à 14:49:37 (#2486175)

thx!

Par LeProctophantasmiste le 5/11/2002 à 18:00:59 (#2487971)

Les étiquettes et les variables de structure se déclarent et se manipulent comme en C. Evidemment sans allocation dynamique de mémoire ni pointeur, l'intérêt est limité...

Par Jedaï le 5/11/2002 à 20:05:07 (#2489360)

De plus si ce n'a pas été résolu dans un patch récent (j'ai pas vérifié), on ne peut pas mettre plus d'une string dans une structure : la dernière string entrée écrase la première... génant !:D

JOL Archives 1.0.1
@ JOL / JeuxOnLine