Forum du MMorpg Evol Online
 
AccueilFAQS'enregistrerConnexion

Partagez | 
 

 [Tuto] Allez plus loin dans le codage

Aller en bas 
AuteurMessage
Valkyrion

avatar

Masculin Nombre de messages : 143
Age : 24
Affectation : [Admin]
Date d'inscription : 03/08/2009

MessageSujet: [Tuto] Allez plus loin dans le codage   Sam 8 Aoû - 18:06

Lien : http://www.eathena.ws/board/index.php?showtopic=203728&pid=1118072&st=0&#entry1118072


Introduction.

Pourquoi ce tutoriel ? Il en existe déjà des forts bons et très documentés...
D'ailleurs, dans ce tuto, vous ne trouverez pas de "trucs" pour programmer vos NPC, pas (ou peu) d'explication sur le langage ou sur les fonctions. Rien de "technique".
Les exemples seront datés, basiques, old school...
Alors que va-t-on trouver dans ce tuto ?
Et bien, j'ai constaté dans la communauté de scripteurs RO qu'il y avait 2 types de scripteurs.
Les "techniques" et les "rolistes".
Un scripteur "technique" prend son pied à "pisser du code", à coder des fonctions, des NPC d'un très haut niveau de complexité niveau code/effets produits ingame. Son niveau de connaissance du "langage" NPC, voire des sources eathena est très bon. Le scripteurs technique est généralement un "scientifique", un "ingénieur".
Exemple de script "technique" : les antibot.
Un scripteur "roliste" prend son pied à "fabriquer un histoire", à faire des quêtes, des events NPC. Pour lui le code n'est qu'un "moyen" et il s'en fiche s'il n'est pas super propre (tant qu'il n'y a pas d'abus possible ^^) ou super optimisé.
Exemple de script "roliste" : les "quêtes à xp" de Gravity.

Il existe plein de tuto qui abordent l'aspect "technique" du script de NPC.
Mais moi, je suis un scripteur "roliste" et mes joueurs jouent à un MMORPG. Je me dois de les immerger le plus possible dans mon monde.
Alors, je vais essayer de vous lister les manières d'y arriver aussi.

Pour en finir avec :
CODE
if (countitem(666666) > 99){goto L_hat;}
mes "[Hatmaker]";
mes "Rapporte moi 100 trukbidul et je te donnerais un hat Machintruk";
close;

L_hat:
delitem 666666, 100;
getitem 777777, 1;
mes "[Hatmaker]";
mes "Tiens, ton hat";
close;



I- J'apprends, j'apprends.

Tout d'abord, un minimum de "bases" sont nécessaires.
Référez-vous au tutoriel de Vince : http://www.roeathena.fr/index.php?showtopic=3780
Et y'en a un aussi sur eathena.ws
Référez-vous au /doc/script_commands.txt
Ayez un serveur local/de test et éclatez-vous à faire quelques scripts "bidons" ou des tutos, pour maîtriser la bête.
Avant de poursuivre, voilà ce que vous devez connaître impérativement :
- Déclarer un npc et le placer ingame
- Connaître la syntaxe d'affichages des textes et menu* (mes "..."; , next;, menu "choix1",-,"choix2",L_choix2;)
- Connaître le fonctionnement des label et goto*
- Connaître les différents types de variables et leur "portée".
- Connaître la syntaxe des boucles conditionnelles ( if{...}else{...} )
- Avoir de l'imagination
- Avoir le script_commands.txt d'ouvert en permanence.

*: ouais, menu, goto, label. J'suis vieux jeu et y'a rien de mieux pour commencer. Les switch, l'aegis et le code "propre", c'est pour plus tard/si vous voulez.

II- Planification

Malheureux, que faîtes-vous avec le blocnote++ déjà ouvert !?!
On se calme, on réfléchit avant de se lancer.
Déjà, savoir où l'on va.

1°) Pour qui ? Pourquoi ?

On veut faire une quête. Oui, mais de quel type ?
Si c'est une quête événementielle : elle ne restera pas. On note donc dans un coin : "Penser à nettoyer les variables à la fin".
La quête aura-t-elle un impact sur le jeu ? Débloque-t-elle/débloquera-t-elle d'autres quêtes ou d'autre NPC ? Si oui, une variable joueur/account permanente sera nécessaire.
La quête peut-elle être recommencée (exemple : quête de hat) ? Il faudra donc remettre une variable à 0.
La quête concerne-t-elle un joueur ou un account ? Le type de variable changera en fonction.
La quête sera-t-elle participative (exemple : dons pour ouvrir Rachel Sanctuary) ? Il faudra donc des variables serveurs.

2°)Sadisme lvl ?
Maintenant, il faut réfléchir à la "difficulté" et aux récompenses.
C'est assez difficile à évaluer et va dépendre de votre serveur (rates, % de nolife, de "prodeRO").
Les gens ont un certains masochisme et aime qu'on leur résiste. Mais attention de ne pas trop en faire ! Un quête où il faut ramener 10000 item MvP sur un lowrate sera trop frustrante.
Il faut adapter en fonction de la "récompense" (xp ou objet). Il est évident qu'une quête offrant des Sunglasse[1] ou des Victory Wings devra être plus difficile qu'une quête permettant d'obtenir un White Ribbon.
En gros, plus l'impact en jeu est grand (xp ou item "utile", surtout en PvP/WoE), plus la difficulté sera grande. Attention, certains hats/wings sont très beaux et très demandés par les joueurs même s'ils sont "inutiles". Il convient donc d'augmenter la difficulté en fonction de l'attente et de la "beauté" si ces items sont concernés.

3°) Scénario
Le type de quête, sa récompense et sa difficulté (approximative) ont été défini.
Maintenant, il convient d'imaginer le déroulement.
En général on a une petite idée.
La plupart du temps, une quête comprend les éléments suivant :
- Accroche de la quête (exemple : le début de la Gaebolg, où l'on "bump" dans un gosse).
- Exposé de la situation/quête. Où l'on expose le "problème", les difficultés (ex: liste d'item à ramener, énigme, ect).
- Rassemblements des éléments pour résoudre le problème (rassemblement d'item, résolution d'énigmes, recherche de NPC, killage de mobs,...)
- Résolution de problème
(facultatif : - Trahison, nouveau(x) problème(s), rebondissement(s))
- Récompense.

Un des "erreurs" qui est souvent commise est de négliger l'accroche. Bien souvent, un NPC nous expose de but en blanc ce qu'il veut.
C'est très artificiel et n'offre pas d'intérêt dans l'immersion.
Il faut titiller la curiosité des joueurs et les amener à s'intéresser à l'histoire, même pour fabriquer un banal hat.
Pourquoi ? Parce que c'est plus fun.

III- NPC

ça y est, on a une idée assez précise de ce qu'on veut faire, avec un scénario qui tient la route.
On peut donc commencer à coder les NPC.
C'est bon là, vous pouvez ouvrir le notepad++. On peut coder. Je vais par revenir sur "comment" (y'a les autres tuto pour ça).
On va maintenant essayer de rendre un peu plus "vivants" et "réalistes" les NPC.

1°) Vous êtes qui, vous ?

Je ne sais pas vous, mais quand je m'adresse à quelqu'un croisé dans une rue, à part s'il s'agit d'un marchand, il ne me connait pas, ne me doit rien et n'a rien à fiche de ce que je veux. Et il va pas pleurer sur ses problèmes devant un inconnu.
C'est pour ça que j'ai parlé "d'accroche" au début. Il faut que le NPC discute un peu avec le joueur, voir le "teste", avant de lui révéler la quête.
Vous pouvez très bien engager une discussion politique,militaire, générale, etc sur un sujet qui amènera à un "test" que doit réussir le joueur pour progresser.
Exemples :
- Un jeune garde trouve la politique du palais trop "molle". Vous êtes d'accord => Ils vous en dit plus sur un parti de "mécontents" => quête.
- Une vieille commère se plaint du temps tout détraqué à cause du nouveau mage installé non loin. Faudrait que quelqu'un aille voir, non ? => quête.
- Un futur-Sage a égaré ses notes pour sa thèse. En l'aidant, on gagne sa confiance et il devient bavard au sujet de son projet top-secret => quête.
- Une fillette faisant l'école buissonnière veut jouer avec vous. Si oui et que vous la battez, elle vous confie un secret => quête.
J'pense que vous avez compris le truc : faire en sorte que le NPC apprécie et/ou oriente le joueur vers le vrai début de la quête.

Le fait de devoir gagner la confiance/prouver sa valeur aux NPC doit se poursuivre tout au long de la quête.
Lors des aller-retour ou envoie vers d'autre NPC, n'hésitez pas à mettre des input @qui$; demandant "Et vous venez de la part de qui ?";

Lors des dialogues, utilisez strcharinfo(0) quand le NPC "accepte" le joueurs : cela montre plus d'intimité. De même, le ton peut changer une fois un "service" rendu.

2°) Tons et façons de "parler".

Tiens, parlons-en justement du ton.
C'est ce qui rend le NPC original et vivant. Le ton dépend de la "proximité" du NPC avec le joueur (cf ci-dessus) et de son "statut socio-culturel".
En effet, un gamin des rues de Morroc ne parle pas comme une Prêtresse de Freya ou comme une grand-mère acariâtre ou un vieux paysan méfiant.
C'est le ton qui rend vraiment le personnage vivant, qui permet de faire penser au joueur "Ouais, là je discute avec un vrai Paladin" ou "Je le sens pas, ce Jaffar Coeurnoir de Vilfélon..."

Pour faire varier le ton, il faut d'abord définir le registre(niveau) de langue à employer. Généralement, on en discerne trois :
- Le registre familier : c'est celui qu'on emploie entre 2 personne qui se connaissent bien et s'apprécie. Il n'est pas formel (pas de vouvoiement), les mots sont simples, le vocabulaire pauvre (répétitions), le langage est souvent imagé. Les phrases peuvent être "fausses" (ex : "J'ai pas fait ça !" au lieu de "Je n'ai pas fait ça !"). Idéal pour faire s'exprimer les gens du commun, de la rue, les pauvres...
- Le registre standard : c'est le ton neutre, poli mais sans fioriture. Employez par 2 personnes venant de se rencontrer (et de même niveau social), par exemple. Cela donne un ton très neutre (et donc, potentiellement moins "implicatif" pour le joueurs). Parfait pour les gens "moyens", pour donner des informations (panneau, livres pour non-spécialiste/érudit), pour les "fonctionnaires" (Gardes, par exemple).
- Le registre soutenu : c'est le plus haut "niveau" de langue. Les phrases sont complexes, avec un vocabulaire riche et de figures de style. Il est très précis. Le vouvoiement est généralement employé (mais pas forcement). La grammaire est rigoureuse. Idéal pour faire parler les gens "éduqués" (Sage, nobles, ...)

On peut "forcer le trait" dans les 2 sens pour ces registres de langue, pour plus d'effet (caricature, stéréotype, par exemple) :
- Le registre argotique : permet de pousser la familiarité, de caricaturer. Vocabulaire vulgaire ou agressif, phrases courtes et incisives. Idéal pour les Rogues et pour caser de belles insultes ^^
- Le registre ampoulé : permet de pousser le soutenu à fond, donnant des phrases bien lourdes et pompeuses. Idéal si vous voulez caricaturez un bourgeois précieux ou un noble hautain.

Vouvoiement ou tutoiement ? La langue française permet de faire cette distinction, il serait bête de s'en priver !
Dans un registre familier, le tutoiement semble de rigueur (mais pas toujours). Pour les autres registres, c'est en fonction des "relations" entre le joueurs et le NPC. Généralement, le vouvoiement convient le mieux (oui, on devient rarement super-pote avec un NPC).
Le vouvoiement peut être utilisé dans le registre familier, pour faire ressortir certains sentiments envers le joueur.
Exemples :
- "Si votre Grandeur veut bien s'donner la peine de bouger ses miches..." (mépris ironique)
- "Houlà, z'êtes vraiment un bourrin vous !" (admiration... ou moquerie ^^).
A l'inverse le tutoiement peut être utilisé en registre soutenu (ça fait très bobo):
- "Tu vois là, c'est à la finesse du marbre d'Aldebaran qu'on reconnait le génie du sculpteur..."
- strcharinfo(0)+" ! Je te fais la bise ! Que deviens-tu, mon choux ? Toujours à courir après la fortune et la gloire ?"

Il existe encore un autre ton possible : le registre "enfantin". Et oui, pour faire s'exprimer les gosses (c'est fou ce qu'on croise comme gosses dans RO).
Ce ton est difficile à décrire et change selon le sexe/personnalité à donner au NPC.
Le vocabulaire et la grammaire sont simples, avec des mots "enfantin".

2°)Apparence (aka le sprite)

Venons-en à l'apparence.
Oui, le sprite a de l'importance et doit être coordonnée au ton choisi (ou pas, voir plus loin).
C'est la première chose que voit un joueur, sa première impression du NPC et donc, c'est vital. Le joueur doit pouvoir identifier à qui il s'adresse: jeune, vieux, prêtre, voleur, riche, pauvre, ect.
Il existe beaucoup de sprites différents pour les NPC (sans parler des sprites mob et des custom), aussi il faut en choisir un qui "cadre" avec le personnage et non un "qui claque".
A noter qu'on peut jouer sur l'opposition apparence/style (c'est connu les apparences sont parfois trompeuses ^^).
Vous pouvez par exemple faire un orc érudit, qui parle de manière normale, voire maniérée et se plaint d'être persécuté par les joueurs et par ses congénères.
Bien sûr, ceci doit avoir un but (servir l'histoire, la quête).

3°)Emplacement

Cela peut sembler surprenant, mais l'emplacement d'un NPC peut être important.
Honnis soient les "capitales" custom où l'on regroupe tous les NPC en ligne/cercle pour être à porté immédiate de clics des feignasses. C'est tout sauf "réaliste", donc immersif.
Comme on peut aisément le constater, chaque ville de RO a une "ambiance". Chose qui est renforcée depuis peu par les quêtes "à histoire" et l'apparition de "factions" (République de Swarchzald, nation d'Azrunamachin, ...).
Ajoutons à cela que les "skins" des NPC sont souvent présentés par "lots", typés selon la ville/factions.
Donc si vous mettez un guerrier chinois/japonais hors de Louyang/Amatsu, une prêtresse de Freya en dehors de Rachel, il faut qu'il y ait une raison (autre que "le skin est joli").

Ne négligeons pas une autre importance de l'emplacement : la recherche du NPC. RO regorge d'endroits pittoresques/tordus/qu'ils faut faire visiter aux joueurs.
La recherche d'un NPC est l'occasion, et apporte une touche de difficulté à la quête. Voire cela peut même devenir l'objet de la quête (npc-event cache-cache, etc).

4°) Comment tu m'causes, toi !
Quand on fait un menu pour "discuter" avec un NPC, la tentation est grande de mettre au moins une option "à la con", qui normalement fâcherait n'importe quelle personne...
Or, le plus souvent, il suffit de fermer le dialogue et reparler au NPC pour qu'il oublie complètement vos insinuation sur sa mère... Pas très logique, non.
Allez, un peu de code, pour changer. Mettons un NPC en colère :
D'abord un petit menu qui renvoie vers une variable...
CODE
next;
menu "Je suis poli...",L_suite,"Ta gueule",L_malpoli;

L_malpoli:
set @malpoli, 5;
mes "[NPC]";
mes "Et bien, quelle impolitesse !";
mes "^FF0000Dehors !^000000";
close2;
percentheal -10,0;
warp "payon",100,100;
end;


Le NPC se met donc "en colère", frappe(percentheal) et jette (warp) le joueur.
Maintenant, voyons comment le faire réagir s'il revient... Un peu de code après la déclaration du NPC :
CODE
if (@malpoli > 0){
mes "[NPC]";
mes "Encore vous le malpoli !";
next;
menu "Pardon, pardon...",-,"Encore une fois, ta gueule!",L_malpoli;
set @malpoli, @malpoli - 1;
mes "[NPC]";
mes "Hummm... Des excuses...C'est déjà ça... Mais je ne sais pas si je peux vous pardonner...";
close;
}


Simple : le joueur devra parler au NPC 5 fois avant de se faire pardonner. Et s'il choisit d'être encore impoli, la variable est remise à fond et il est rebalancé ailleurs.
Ce n'est bien sûr qu'un exemple "basique". On peut imaginez des "miniquêtes" pour regagner les faveurs d'un NPC "fâché" (ramener un item, lui dire une phrase particulière, ect).
Dans ce cas, mieux vaut employer une variable joueurs (sans le @). Le NPC restera alors "en colère" jusqu'à la résolution de la miniquête.


_________________
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://valkyrion.tx.la
Valkyrion

avatar

Masculin Nombre de messages : 143
Age : 24
Affectation : [Admin]
Date d'inscription : 03/08/2009

MessageSujet: Re: [Tuto] Allez plus loin dans le codage   Sam 8 Aoû - 18:08

IV - Items

Tiens, une section entière pour les items ? Mais, mais... Pourquoi ?

Ne
nous leurrons pas, dans RO, la majorité des quêtes consistent à ramener
entre beaucoup et énormément d'items (ou un peu moins, mais des rares).
C'est assez basique/classique en MMORPG, voire en JdR.
Ce n'est donc pas négligeable et on va donc s'y attarder un peu.

1°)Tenez, voici ma liste de courses...
Toujours
dans notre soucis "d'immersion", il faut que quand un NPC demande une
liste d'item, ceux-ci soient "réalistes". Il doivent avoir un rapport
avec la quête/l'item à obtenir.
Quelques exemples seront plus parlant :
Supposons
que vous réalisiez une quête pour faire le Neko Mimi Hat. Cette quête
est en 2 étapes : réparer la machine à coudre d'une couturière, puis
lui apporter de quoi faire le hat.

Etape 1 : réparer la machine à coudre.
Machine à coudre... Faut donc des items en rapport avec les machines ou la couture.
On
database/google et on peut ainsi trouver : Broken Needle, Needle
Packet, Spool pour le coté couture, un peu de Steel pour réparer, voire
de Solid Iron Piece. Puis on a décidé de faire une quête dure car le
hat est mignon : Fragment , Cogwheel.

Etape 2 : fabriquer le hat.
Le chapeau est vaguement orangé, mignon, représentant un chat, surement en fourrure.
Soyons astucieux, de quoi aurait besoin une couturière pour fabriquer ça ?
Imagination/Database : Orange Dyestuff, Cat's Eye, Kitty Band et de la Sea-Otter Fur.

Spécial vicieux :
Rien ne vous oblige à demander un nombre explicite d'item. Ni en anglais (on est en francophonie, que diable !).
Vous
pouvez être vague (ex :"Une dizaine de pommes devraient suffire..."),
voire obliger le joueur à chercher (par exemple : "Pour ma tarte aux
pommes, il me faudrait des pommes et du miel". Et ailleurs, dans un
NPC-livre ou objet-livre de cuisine (voir le tuto sur les books ^^) :
"Recette tarte au pomme&miel : 10 pommes, 2 Miel").
Vous pouvez
aussi parler par énigme (ex: "Un main d'épice rouge dans la main du
Bouddha" => Apporter 5 Red Spice au NPC devant la statue...).

Et voilà, par la simple logique et par l'imagination, on a une liste d'items qui "collent" à la quête et à sa récompense.

Effet
bonus : pensez à utiliser des items qui "font voyager" (monstres
obscurs de donjons/fields peu fréquentés). Cela permet de faire
découvrir des maps à vos joueurs et de les sortir de leur train-train
mobtrain.

2°) Combien j'vous en mets ?

Bon, on a la liste d'item qui va bien pour faire la quête. Maintenant il faut doser la difficulté (voir II.2).
C'est
à qu'à l'inverse d'un Administrateur (voir le topic idoine ^^), un
Scripteur doit avoir un perso joueur et bien connaître son serveur.
Afin d'estimer la difficulté d'obtenir certains items.
Doser le
nombre d'item est difficile. Le "camping" n'est pas quelque-chose de
rigolo, mais c'est un mur assez efficace. Evitez de trop en faire.
Méfiez-vous de ce qui est achetable à quelque obscur marchand NPC.
Vous devrez bien évidemment adapté ce qui est demandé aux rates/difficulté du serveurs.
Une fois vos quantités choisies... rajoutez-en un peu ^^. On a toujours tendance à sous-estimer les no-life !

Attention : songez aux mage-class et autre lavettes avec str = 1 ! Méfiez-vous du poids de certains items !
Lors
du test de la quête, effectuez-là en mage-classe no str. Si les items
requis dépasse le poids max que peut porter un joueurs, faîtes-les
rapporter en plusieurs fois.

3°) Controle
Evidemment, il faut contrôler que le joueurs a rapporté les items.
Y'a plusieurs méthodes :
CODE
if (countitem(502)<10)||(countitem(518)<2){
goto L_PasAssez;
}
else{
delitem 502,10;
delitem 518,2
set tarte, 2;
mes "Ah, vous avez tout ce qu'il faut pour faire une tarte au pomme !";
next;
L_recompense:
mes "Tenez, votre tarte au pomme...";
getitem 66666, 1;
set tarte, 3;
close;
}

L_PasAssez:
mes "Désolé, vous n'avez pas ce que j'ai demandé";
close;



On peut aussi faire comme ça :
CODE
if (countitem(502)>=10)&&(countitem(518)>=2){
delitem 502,10;
delitem 518,2
set tarte, 2;
mes "Ah, vous avez tout ce qu'il faut pour faire une tarte au pomme !";
next;
L_recompense:
mes "Tenez, votre tarte au pomme...";
getitem 66666, 1;
set tarte, 3;
close;

}
else{
goto L_PasAssez;
}

L_PasAssez:
mes "Désolé, vous n'avez pas ce que j'ai demandé";
close;



Personnellement je préfère la première méthode, mais les deux fonctionnent.
Pourquoi
une variable set et un label "L_recompense:" après l'effacement des
items ? Juste pour les malheureux qui déconnecte au mauvais moment (ça
arrive, parfois volontairement).
Cela permet de renvoyer à la
récompense les gens ayant rapporté les item (variable à 2 ici), mais
pas reçu l'item. Cela peut être utile si vous placer un NPC dans un
endroit "qui craint" (joueur mourant durant les dialogues).

Jamais, jamais, par contre :
CODE
if (countitem(502)<10)||(countitem(518)<2){
goto L_PasAssez;
}
else{
set tarte, 2;
mes "Ah, vous avez tout ce qu'il faut pour faire une tarte au pomme !";
next;
delitem 502,10;
delitem 518,2
L_recompense:
mes "Tenez, votre tarte au pomme...";
getitem 66666, 1;
set tarte, 3;
close;
}


Ne
jamais set de variable avant un next. Dans cet exemple, si on
déconnecte à la phrase "Ah, vous avez tout ce qu'il faut pour faire une
tarte au pomme !", on aura la variable à 2, donc on sera renvoyer aux
récompenses sans se faire deleter les items.

4°) Encore vous !?!

Il
est toujours sympathique de prévoir un "rappel" des éléments à fournir
(tout le monde n'as pas la mémoire pour se souvenir de douzaine de
listes d'objets réclamés par les NPC).
CODE
L_ingredient:
mes "Je pourrais te faire une tarte aux pommes et au miel, si tu me rapportes une dizaine de pommes et deux pots de miel...";
next;
...
...
L_PasAssez:
mes "Désolé, vous n'avez pas ce que j'ai demandé...";
next;
goto L_ingredient;



Cependant,toujours
pour plus de réalisme, les NPC pourraient se "fâcher" (voir III.4) si
les joueurs reviennent sans cesse leur demander la liste des items.^^
Soyez cruel !


_________________
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://valkyrion.tx.la
Valkyrion

avatar

Masculin Nombre de messages : 143
Age : 24
Affectation : [Admin]
Date d'inscription : 03/08/2009

MessageSujet: Re: [Tuto] Allez plus loin dans le codage   Sam 8 Aoû - 18:08

V - Textes, énigmes et effets spéciaux.

Bon, j'ai déjà parlé du "ton" du NPC et tout ça. Là on va voir comment "décorer".

1°) Voir la vie en rose

Classique, efficace : la couleur.
CODE
mes "^FF0000Attention !^000000";
mes
"Pour ceux qui aime cliquer comme un ^FF0000bourrin^000000 sur
^CCCCCCnext^000000, vous pouvez ^0000FFcolorer les informations
essentielles^000000!";
next;


La couleur peut être utiliser pour différentes choses :
- Faire ressortir les informations vitales (liste d'item, phrase à retenir, code...). L'exemple ci-dessus est mauvais : il y a trop de couleurs en même temps ^^.
-
Renforcer un ton ou montrer une manière de s'exprimer particulière
(bleu = glacial, rouge = colère, rose = fillette, couleur passée/très
claire = chuchotement, ect).
- Marquer un dialogue entre différents interlocuteurs:
CODE
mes "[Boulet]";
mes "Eh ! Salut mon vieux !";
next;
mes "^0000CC["+strcharinfo(0)+"]";
mes "* Oh Non !*";
mes "* Encore ce pot de colle... Comment l'éviter ?*^000000";
next;
mes "^0000FF["+strcharinfo(0)+"]";
mes "Je...Je dois y aller. Y'a WoE, tout ça !^000000";
next;


Là,
on colore les "pensées" du joueur (j'ajoute un caractère * devant les
pensées. Chacun à son truc pour ça, y'en a qui mette rien, d'autre ~,
etc), puis ses "paroles".
Attention de ne pas abuser des couleurs, sinon ça fait "sapin de Noël".

2°) Typographie

Tiens, quel est la différence entre :
CODE
mes
"Vous trouverez le Vieux Sage sur la Montagne au sommet du Pic de
Moljnir. Attention aux araignées géantes et aux insectes piqueurs !";


et
CODE
mes "Vous trouverez le Vieux Sage sur la Montagne au sommet du Pic de Moljnir.";
mes "Attention aux araignées géantes et aux insectes piqueurs !";



C'est simple : un second "mes" force un retour à la ligne.
Normalement,
il n'y en a pas besoin, le retour à la ligne se fait de manière
automatique (méfiez des retour à la ligne impromptu d'éléments
typographies isolés : !,?,: ect)
Forcer un retour à la ligne peut être utile pour mettre en relief une phrase ou une partie de celle-ci.
N'oubliez pas de bien "aérer" vos textes en découpant avec "next;".

3°) Regardez-moi dans les yeux.
Il
est toujours plus sympa de savoir à quoi ressemble celui à qui on
s'adresse. On a déjà le sprite, mais on peut faire mieux : mettre un
portrait en pied, un cutin !
Bon, y'a déjà un tuto là : http://www.roeathena.fr/index.php?showtopic=311
Je vais donc pas y revenir dessus. La chose à ne pas oublier : "fermer" le cutin avec :
CODE
...
close2;
cutin "",255;
end;




4°) Variables de personnalisations

Un titre barbare, hein ?

Ne
vous affolez, pas, c'est juste une liste (non-exhaustive) des p'tits
bouts de code qui peuvent être utile pour rendre les dialogue plus
vivants, plus personnels.
C'est parti !

Classique : afficher le nom du joueur :
CODE
mes "Vous voilà de retour, "+strcharinfo(0)+" ?";

Notez la syntaxe, avec les + et le fait de "sortir" des guillemets du mes.
Notez également que ça fonctionne pour pas mal de chose :
CODE
mes "Quel est ton nom ?";
next;
input @ton_nom$
if (@ton_nom$ != strcharinfo(0)){
announce "La honte, "+strcharinfo(0)+" ne connait même pas son propre nom !",bc_all,0xFFFF00;
atcommand "@jail "+strcharinfo(0);
}



Ses informations personnelles...
CODE
mes "Vous êtes "+strcharinfo(0)+", le ^FF0000"+jobname(Class)+"^000000.";
mes
"Actuellement, vous êtes de niveau
^FF0000"+BaseLevel+"/"+JobLevel+"^000000. Vous passerez de niveau dans
"+NextBaseExp+" exp.";
if (Hp < MaxHp){mes "Et vous oser vous présenter devant nous blessé !";}


Vous trouverez la liste des variables prédéfinis pour les joueurs dans doc/script_commands.txt et surtout dans db/const.txt
Notez l'amusante fonction jobname() qui retourne le nom du job (en théorie : je ne m'en suis jamais servi ^^).

Ses amis...
CODE
set @id_character, getcharid(0);
set @id_guilde, getcharid(2);
set @id_groupe, getcharid(1);
getpartymember(@id_groupe);
set @partymembercount,$@partymembercount;
copyarray @partymembername$[0],$@partymembername$[0],@partymembercount;
if (@partymembercount > 1){
mes "Et voilà "+strcharinfo(0)+", membre de la célébre compagnie d'aventuriers connue sous le nom de "+getpartyname(@id_groupe);
mes "Il partage ce privilège avec "+@partymembercount+" aventuriers :";
for( set @i,0; @i<=@partymembercount; set @i,@i+1 ){
switch(Sex){
case 0:
mes "La vaillante ^FF66FF"+@partymembername$[@i]+"^000000.";
break;
case 1:
mes "Le brave ^0000FF"+@partymembername$[@i]+"^000000.";
break;
}
}
if (getpartyleader(@id_groupe,2) == @id_character){
mes "Dont il est d'ailleurs actuellement le chef.";
}
if (@id_guilde != 0){
set @guildmaster$, getguildmaster(@id_guilde);
if (@guildmaster$ == strcharinfo(0)){
mes strcharinfo(0)+" est d'ailleurs le Maître de la prestigieuse Guilde
^FF0000"+getguildname(@id_guilde)+"^000000.";
}
else{
mes strcharinfo(0)+" est d'ailleurs le membre de la prestigieuse Guilde ^FF0000"+getguildname(@id_guilde)+"^000000.";
}
}

}
else{
mes "Pas trop solitaire ?";
}


Sympathique,
non, l'oeil qui voit tout ? (Note : j'ai fait ce script "à main levée",
pour l'exemple, à vérifier s'il marche vraiment...).
Notez le @partymembercount > 1 (car on peut être seul dans un groupe...).

Je
pense que vous avez piger le truc, je vous épargne "Sa famille"
(facile, jetez un oeil aux fonctions getpartnerid(), getchildid(),
getmotherid() et getfatherid() ).

5°) Enigmes.

Tiens, pourquoi énigmes dans ce paragraphe ?
Et bien parce que c'est du texte, donc elles doivent être bien présentés.
D'abord, le joueur est un feignasse inattentif qui clique sur next trop vite : mettez votre énigme en couleurs.
Mettez là généralement seule dans un "bloc de texte" (entre deux next; quoi).
Un petit exemple :
CODE
mes "[Père Fouras]";
mes
"Voici maintenant mon énigme, qui vous permettra d'entrer par la porte
de service qui amène directement en bas de Thanatos Tower...";
next;
L_enigme:
mes "[Père Fouras]";
mes "^0000CCJe suis toujours à l'abris et pourtant toujours mouillée.^000000";
mes "^0000CCQue suis-je ?^000000";
next;
input @reponse$;
if
((@reponse$ == "langue")||(@reponse$ == "Langue")||(@reponse$ == "la
langue")||(@reponse$ == "La langue")||(@reponse$ ==
"LANGUE")||(@reponse$ == "LA LANGUE")){
mes "[Père Fouras]";
mes "Vous avez bien répondu...";
goto L_lasuite;
}
else{
mes "[Père Fouras]";
mes "Hélas, ce n'est pas cela...";
mes "Souhaitez-vous ré-écouter mon énigme ?";
next;
menu "Oui.",L_enigme,"Non,-;
}
close;



Rien de bien compliqué et une énigme textuelle fait toujours plaisir.
Notez le principal problème des énigmes textuelles : la multiplicité possible des "bonnes réponses".
Dans l'exemple, j'ai mis avec et sans article, en majuscule ou non
(pour les gens qui ont la manie de bloquer capslock). Notons qu'une
réponse "La Langue" est considérée comme fausse, mais bon, faut pas
pousser mémé dans les orties...

A noter également les 2 types d'input : ne vous trompez pas entre les input de texte (input @texte$clin oeil et de chiffres (input @chiffre;). Un seul $ d'oublié et vos tests ne marcheront pas...

6°) Son et Lumière !

Il
est toujours amusant de pouvoir déclencher quelques "effets spéciaux"
lors d'une quête, de pouvoir faire jouer un son ou "simuler" le
lancement d'un skill.
Voici quelques exemples de commandes permettant cela :
CODE
specialeffect 90;

Voilà
un bel effet (visuel, on ne subit rien). Regardez dans les quêtes de
Veins pour un exemple (un percentheal permet de blesser le joueur pour
plus de réalisme ^^).
Cet "effet" est centré sur le NPC. Pour en faire un centré sur le joueurs, il faut utiliser specialeffect2.
Vous pouvez également utiliser misceffect, qui peut selon le cas être centré sur le NPC ou sur le joueur.
La liste des effets est disponible dans /doc/effect_list.txt

Un autre truc sympa, c'est de faire lancer des skills. Un Prêtre de Freya pourrait vous bénir et vous soigner, par exemple.
CODE
skilleffect 28,2000; // Visuel de Heal, en montrant le 2000 vert flottant, comme un vrai
heal 2000,0; // Effet de Heal
skilleffect 34,0; // visuel de Bless
sc_start 10,240000,10; // Effet de Bless level 10


Ouais, c'est la honte, c'est qu'un copier-coller de la doc ^^
On
peut également centrer le visuel sur la map plutôt que sur le joueurs
avec npcskilleffect. Pratique si vous voulez montrer des "scènes"
(genre un Meteor Storm qui s'abat sur un pont, l'apparition d'un démon
avec son&lumière...)
La liste des différents skill est dans /db/skill_db.txt
Attention avec skilleffect : ce n'est que le visuel du skill,
pas son effet. Celui-ci peut être généralement "reproduit" avec
sc_start (voir db/const.txt pour la liste des effets/status) ou
d'autres commandes.

Pour les sons 2 possibilité :
- Pour jouer un son pour le joueur uniquement :
CODE
soundeffect "nomduson",0;

Le fichier son doit être au format .wav et se place dans /data/wav/

Plus rigolo, un effet de zone pour que tout le monde profite du concert de métal :
CODE
soundeffectall "mon_concert",0,"prontera",100,100,120,120;

Voilà, ça jouera le son dans un carré de la map de prontera (coordonnée au pif pour l'exemple).

Et pour qu'un NPC utilise une emoticon (un smiley), on utilise:
CODE
mes "Bisou !";
emotion 3,0;


Le premier chiffre est le code de l'emoticon (voir dans /db/const.txt c'est les truc commençant par e_ ).
Le second chiffre est la cible : 0 pour le NPC, 1 pour le joueur.


_________________
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://valkyrion.tx.la
Valkyrion

avatar

Masculin Nombre de messages : 143
Age : 24
Affectation : [Admin]
Date d'inscription : 03/08/2009

MessageSujet: Re: [Tuto] Allez plus loin dans le codage   Sam 8 Aoû - 18:09

VI-) Derrière le paravent du MJ...

1°) Tu me vois ? Tu me vois plus !

Voilà, vous avez créer votre quête/votre event/vos NPC. Vous pensez que tout va bien. Vous pensez avoir tout testé.
Il est grand temps de passer en production, comme on dit dans l'milieu.
Et
comment allez-vous faire ça ? Update et relance du serveur, rien de
plus facile me direz-vous (au pire, c'est l'Admin qui le fait ^^).
Mais
ne serez-t-il pas mieux de pouvoir contrôler à volonté
l'activation/désactivation de votre quête/votre event/vos NPC. C'est
particulièrement utile pour lancer un event à une date désirée et
éviter trop de reboot serveur (1 maintenance par semaine pour charger
les scripts et un activation ingame quand on en a besoin).

Voilà comment je procède. C'est du pur facultatif.
Dans
un de mes NPC (normalement actif), je balance un petit paragraphe
OnInit qui désactive tous mes NPC si une variable serveur n'est pas à 1.
CODE
OnInit:
if ($my_event17 == 0){
disablenpc "Mon_NPC01";
disablenpc "Mon_NPC02";
...
disablenpc "Mon_NPC35";
}
end;


Donc, en cas de reboot serveur (pour update/maintenance), mon script est loadé puis pouf, mes NPC sont désactivés.
Pour
les activer, j'utilise un NPC "GM" qui contrôle les quêtes et les
events custom du serveur. Il est donc placé sur une map GM et n'est
utilisable que par les GM ayant un certain niveau.
Voici un petit exemple :
CODE
L_choix:
if (getgmlevel()>50){
mes "Maître, que souhaitez-vous faire ?";
next;
menu "Controle de l'event n°1",L_e1,"Controle de la quête n°2",L_e2,"Controle de l'event n°17",Le17,"Rien",-;
mes "Au revoir alors";
close;

L_e17:
mes "Que voulez faire à propos de l'event n°17";
next;
menu "Activer event n°17",L_e17a,"Désactiver event n°17",L_e17d,"Rien",-;
goto L_choix;

L_e17a:
set $my_event17, 1;
enablenpc "Mon_NPC01";
enablenpc "Mon_NPC01";
...
enablenpc "Mon_NPC35";
mes "Event n°17 activé !";
next;
goto L_choix;

L_e17d:
set $my_event17, 0;
disablenpc "Mon_NPC01";
disablenpc "Mon_NPC02";
...
disablenpc "Mon_NPC35";
mes "Event n°17 désactivé !";
next;
goto L_choix;
}
else{
mes "Du balais, manant !";
close;
}



Voilà, comme ça, on peut "lancer" un event ou un quête depuis le jeu (si bien évidemment ça a été chargé au préalable ^^).
La variable permet de laisser la quête active même en cas de reboot.

Note
: rien n'empêche de mettre le OnInit dans ce NPC "de contrôle". Mettez
des commentaires pour vous y retrouver dans les event/quêtes/npc à
désactiver/activer.

2°) Halte ! Contrôle !

Voilà,
inspirer par ce guide et plein de fougue, vous avez réaliser une
méga-quête, 500ko, 200 variables diverses, The Sign à coté c'est de la
gnognotte.
Et paf ! Lors du test sur le serveur-test, ça merdoie
quelque-part... Mais où ? Le "chargement" (map_server) indique que tout
va bien...
Pour se mettre sur la piste, rien de tel qu'un petit NPC "contrôlateur de variables".
Le
but ? Afficher/Permettre de modifier toutes les variables de la quête.
Cela permet de voir(enfin, peut être...) à quelle étape ça "coince". Et
de s'éviter des requêtes SQL/fouiller les txt pour vérifier les
variables.
Bref, une petite aide sympathique et pour flemmards, mais qui ne fera pas de miracle.

Un petit exemple :
CODE
L_show:
mes "Les variables de l'event 17:";
mes "Variable joueur event17 : ^FF0000"+event17+"^000000.";
mes "Variable joueur event17_part2 : ^FF0000"+event17_part2+"^000000.";
mes "Variable event17_pass$ : ^FF0000"+event17_pass$+"^000000.";
mes "Variable server $event17_idwinner : ^FF0000"+$event17_idwinner+"^000000.";
mes "Que souhaitez-vous faire ?";
next;
menu "RAZ variables",L_raz,"Modifier les variables",L_modif,"Rien",-;
mes "Ok, salut alors;
close;

L_raz:
set event17,0;
set event17_part2,0;
set event17_pass$, "";
set $event17_idwinner, 0;
mes "Les variables ont été remise à zéro";
next;
goto L_show;

L_modif:
mes "Nouvelle valeur event17 ?";
input @nb;
set event17, @nb;
next;
mes "Nouvelle valeur event17 ?";
input @nb;
set event17_part2, @nb;
next;
mes "Nouvelle valeur event17_pass$ ?";
input @txt$;
set event17_pass$, @txt$;
next;
mes "Nouvelle valeur $event17_idwinner ?";
input @nb;
set $event17_idwinner, @nb;
goto L_show;



Voilà de quoi tester un peu vos quêtes. ça peut paraître un peu bête ou superflu, mais l'air de rien, à l'usage c'est utile.
Un
autre truc : comme vous avez le contrôle, vous savez toujours où vous
en êtes niveau variable. ça vous permet donc de faire des tests du
style : "Il se passe quoi si je reparle au NPC 14 alors que j'en suis à
l'étape 27 ?".

VII°) Être sympa avec les collégues

1°) Le "header".
Vous
l'avez surement remarqué, mais tous les fichiers de /npc/ (ou presque)
commence par un "header" composé de commentaires (lignes commençant par
// )
C'est pas pour rien.
Voyons un peu ça (ce n'est qu'un exemple, mais il est assez standard) :
CODE
//===== eAthena Script =======================================
//= Script Machin (nom/titre du script)
//===== By: ==================================================
//= MageGaHell, Myllena (Votre pseudo et ceux des autres contributeurs)
//===== Current Version: =====================================
//=
1.4 (La version du script. Perso : j'augmente de 0.1 à change
modification mineure et de 1 à chaque modification majeure. J'ajoute un
b si le script est en test, que j'enlève une fois le test effectué,
avant de passer en prod')
//===== Compatible With: =====================================
//= eAthena SVN (la version d'eAthena sur laquelle vous avez testé le script)
//===== Description: =========================================
//= Script Machin
//= Quête custom pour DoT. Permet d'obtenir un Machin Hat.
//= Part 1 : activation multijoueur. Non répétable.
//= Part 2 : hat making mono-joueur. Répétable.
//= (une description plus ou moins poussé du script, vous l'aurez compris)
//=
//===== Additional Comments: =================================
//= 1.0 Première version, par MageGaHell
//= 1.1 Correction orthographique, par Myllena
//= 1.2 Correction faille possible, par MageGaHell
//= 1.3 Complexification Part 1.
//= 1.4 Dernière modification. Mise en ligne.
//============================================================



J'espère que l'exemple est assez clair.
Vous pouvez aussi rajouter les lists des variables utilisés (toujours pratique) et une description sommaire de leur rôle.
J'ajoute parfois aussi dans mes quêtes, notamment de hat, la liste des items nécessaires.
Le
but de ce truc est de simplifier la vie de l'admin et des scripteurs
qui pourraient être amener à bosser sur/avec vos scripts.
Normalement,
si vous utilisez une SVN dans votre team, vous aurez pas trop de
soucis. Mais le header reste toujours utiles pour savoir qui a fait
quoi et pour pallier à d'éventuelle erreurs humaines ("Bordel, mais
t'as passé quoi comme version du script !" "La dernière...T'es sur
d'avoir commit ?" "...Euh..").

2°) Clear code

Afin
de faciliter le travail (éventuel) de correcteurs/scripteurs autres que
vous, il est sympathique de rendre ses scripts le plus lisible possible.
Pour cela, il est bienvenue de faire 2 choses :

- Commenter
: comme vu dans le header, une ligne débutant par // n'est pas exécuté.
Mettre des commentaires permet aux autres de savoir ce que fait le
script et où.
C'est aussi particulièrement utile pour vous si êtes amateurs de if/else et autre switch bien imbriqué...
Ne
tombez pas non plus dans l'accès à commenter chaque ligne : essayez de
commenter des "bloc-logiques" ("ça c'est la partie 1 de la quête", "ça
c'est les fonctions", "ici les tests sur les items/variables...")
N'en écrivez pas non plus des tartines, ça doit être informatif et bref.

- Organiser.
Cela veut dire regrouper les npc/fonction d'un fichier en
"bloc-logiques" là aussi (NPC pour la partie 1 de la quête, NPC pour la
partie 2, fonctions...).
Mais pas seulement : il est aussi bien de
produire un code clair et indenté. C'est certes une perte de temps à
taper, mais c'est plus facile à lire (pour vous aussi).
Exemple :
CODE
if ((machin01 > 17)||(truc04 < 4)){
switch(machin01){
case 23:
if ((truc04 == 1)||(truc04 == 2)){
mes "Et bien, vous êtes bien confus...";
set truc04, truc04 + 1;
close;
}
else{
mes "Pas encore assez ?";
close;
}
case 25:
if ((truc04 == 2)||(truc04 == 3)){
mes "Mais où en sommes-nous ?";
set truc04, truc04 + 1;
close;
}
else{
mes "Est bien clair ?";
close;
}
default:
if ((truc04 == 1)||(truc04 == 2)){
mes "Seriez vous un peu perdu ?";
set truc04, truc04 + 1;
if (machin01 > 25){
set machin01, machin01 - 1;
}
close;
}
else{
mes "Pas encore assez ?";
close;
}
}
}
else{
if (truc04 == 5){
mes "Mouaip, là ça va ?";
close;
}
}



Vous préférez pas ça ?
CODE
if ((machin01 > 17)||(truc04 < 4)){
switch(machin01){
case 23:
if ((truc04 == 1)||(truc04 == 2)){
mes "Et bien, vous êtes bien confus...";
set truc04, truc04 + 1;
close;
}
else{
mes "Pas encore assez ?";
close;
}
case 25:
if ((truc04 == 2)||(truc04 == 3)){
mes "Mais où en sommes-nous ?";
set truc04, truc04 + 1;
close;
}
else{
mes "Est bien clair ?";
close;
}
default:
if ((truc04 == 1)||(truc04 == 2)){
mes "Seriez vous un peu perdu ?";
set truc04, truc04 + 1;
if (machin01 > 25){
set machin01, machin01 - 1;
}
close;
}
else{
mes "Pas encore assez ?";
close;
}
}
}
else{
if (truc04 == 5){
mes "Mouaip, là ça va ?";
close;
}
}



ça fait plus "pro", non ?
Jeu interactif : dans mon premier exemple, me suis-je merdé dans l'ouverture/fermeture de parenthèse/accolades.
Jeu
interactif 2 : si machin01 vaut 22 et truc04 vaut 3, que m'affichera le
script ? Et quelles seront les valeurs de machin01 et truc04 au final
dans ce cas ?


VIII-) Conclusion

Voilà, vous pouvez scripter les npc et votre quête, une vraie, une originale et intéressante.
Vous avez du piger le principe : cohérence, réalisme, suprise, envoutement du joueur !^^
Vous trouverez les trucs "utiles", plus mécanique dans /doc/script_commands.txt et /doc/pccommand_list.txt
Méfiez-vous
en tout de même ! C'est pas graver dans le marbre et tout peu changer.
Donc tester, tester, tester. Mettez-vous dans la peau d'un joueurs
vicieux.
Testez votre quête avec des classes "à la con" qui ont des
limitations (Wizard sans force, TK sans arme, ect) et testez sans
item/commandes GM (bon, je vous autorise @item). Connaissez votre
serveur et vos joueurs.

Enfin, venez pas ouinouiner si un des
exemples que je cite plante. Je ne les ai pas tous tester, et ce n'est
que des exemples. On est dans un tuto pour vous faire comprendre
l'importance des lettres RPG de MMORPG, pas dans un tuto "technique".

En espérant que cela vous soit utile.

_________________
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://valkyrion.tx.la
Contenu sponsorisé




MessageSujet: Re: [Tuto] Allez plus loin dans le codage   

Revenir en haut Aller en bas
 
[Tuto] Allez plus loin dans le codage
Revenir en haut 
Page 1 sur 1

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Evol Online :: Communauté :: Tutoriaux/Aides-
Sauter vers: