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

Panneau de contrôle

Recherche | Retour aux forums

JOL Archives

Pour des "VRAIS" Marchands...

Par Frolo Xeres le 10/11/2002 à 15:29:44 (#2524840)

Mes recherches sur le forum m'ont données l'impression qu'il existait un script pour faire stocker l'or des PNJ par les marchands. Bon je l'ai pas trouvé ! Si quelqu'un sait où il est çà m'interesse merci !

Sinon, mon but premier était de créer un marchand qui ai un stock limité d'or et qui y puise quand il achète des objets aux PCs.
Le petit marchand du village du coin est l'homme le plus riche du village certes mais qu'il m'achete les 10 épées +1 et toutes les babiolles que j'ai récupéré dans le donjon d'à côté çà paraît louche ! Tous le monde n'a pas 20.000 Po sous la main !

Ma seule idée pour l'instant est de créer une conversation interactive avec le marchand pour gérer les échanges par script mais çà promet d'être galère ! S'il y a moyen de travailler sur l'objet magasin directement... Ou si l'idée à déjà portée ses fruits...

Et pis en plus si les stocks été gérés çà serait cool mais çà c'est bon Jédaï nous a déjà sortit un script pas mal (mot clé de recherche : magasin )

Je suis ouvert à toute proposition...

Edit : Tout ceux qui me donnerons un début de piste auront droit au script une fois qu'il sera écrit !
Mais non je déconne !

Par sounéva le 12/11/2002 à 23:12:34 (#2548377)

c'est que tu raison un marchand dans un bled paumé qui peut acheter tes items a l'infini ca le fait pas trop.....
j'en profite pour up ton poste car la question m'intérésse aussi.
je me demande si sur les forums de bioware ils n'avaient pas parler de rajouter une case pour definir l'or que le marchand posséde.......??????

Par Twist le 13/11/2002 à 11:45:01 (#2550756)

Il y a peut-être une possibilité, à creuser. Réaliser un scan régulier de l'inventaire de l'objet magasin, grâce à des fonctions d'informations pour définir le montant en or du stock (et en admettant qu'aucun des items à la vente n'est en infini, mais cela devrait être dans la logique d'un concepteur qui souhaite limiter les échanges d'un marchand), ce qui permettrait de savoir combien le marchand a dépensé (GetNumItems et GetGoldPieceValue).

Sur le OnConversation du marchand, on définit la valeur du stock, on l'enregistre sur une variable locale. Puis on la compare à la valeur précédente, et on applique cette différence, positive ou négative au stock d'or du Pnj, sur ses fonds propres indépendants du magasin. On met à jour la variable stock, et si le Pnj n'a plus d'or, on bloque les rachats.

Exemple :

Le marchanf Pehainji dispose de 5.000 PO en liquidités. Le stock de son magasin initial a pour valeur 30.000 PO (items à la vente). Ce montant est initialement calculé par le concepteur du module, et stocké dans la variable locale nCapital.

Pehainji est interpellé par un PJ qui lui vend 1000 PO d'items et qui lui en rachète 500. Lorsque le PJ quitte le marchand, il sort d'un trigger qui entoure le marchand (ou tout autre condition à votre convenance), qui lance le calcul du nouveau stock, soit dans le cas présent, 5000+1000-500=5500. Le marchand a donc dépensé théoriquement 500 PO, puisque la valeur de son stock a augmenté.

Une fois cette différence calculée, on l'applique au stock d'or du marchand. Ca doit donner un truc du genre :

nNouveauCapital=(calcul du montant du stock de l'inventaire en Po)
if nCapital>nNouveauCapital;
{
nDifferencePO=nCapital-nNouveauCapital;
TakeGold(nDifference, GetObjectByTag(TagPehainji), TRUE));
}
else
{
nDifferencePO=nNouveauCapital-nCapital
GiveGoldToCreature(nDifference, GetObjectByTag(TagPenhainji));
}

nCapital=nNouveauCapital;

Il suffit par la suite de rajouter une condition dans le dialogue du marchand, avant l'ouverture du magasin, pour vérifier s'il a de l'or dans ses poches. S'il n'en a pas, on ouvre le magasin avec la valeur 0 au rachat d'items pour décourager les joueurs (OpenStore,oStore,oPc, 100,0), puisque les fonctions d'achats et de vente ne peuvent être désolidarisées.

Il doit y avoir une centaine de choses à revoir, en particulier le décalage entre les valeurs de vente et d'achat des items, et les portions de code que je viens de jeter en pâture.

Mais c'était histoire de donner quelques pistes.

Par Nylou le 13/11/2002 à 12:08:09 (#2550919)

Personnellement je verrai plutot un script qui se joue au moment de de l'achat/vente des objets.


J'ai pas en tete les evenement possible sur un magasin mais meme si on peut pas empecher la transaction.
Rien n'empeche de faire un rollback et de faire parler le marchand en fonction de celle-ci ("merci vous avez fait une fort belle affaire, vous ne le regreterrez pas.", "C'est un plaisir de faire affaire avec vous *petit rictus*" ... "désolé, ce que vous me vendez est trop honéreux, revenez plus tard" voire ... "ça ne m'intéresse pas. Allez vendre votre camelotte à d'autre couillon. Au revoir").

Le trigger c'est pas forcément la meilleure idée, il faudrait recalculer l'argent du marchand à chaque transaction et ceux indépendament du déplacement d'un joueur. Sinon en multi ça va poser pas mal de pb.

C'est quoi les evenement possible avec un shop ?

Par Jedaï le 13/11/2002 à 13:42:26 (#2551793)

Désolé, Nylou mais les Events d'un magasin sont ridiculeusement peu nombreux : OnOpenStore et... OnOpenStore, c'est tout !:(
Les possibilités de contrôle sont donc extrêmement limité...
A part la solution de Twist, qui est très incomplète (les données ne sont mises à jour que avant et après la transaction...), je ne vois pas ce qui peut être fait. :doute:

Par Jedaï le 13/11/2002 à 13:44:07 (#2551807)

On pourrait peut-être faire un "rollback" à la fin du marchandage mais ça fait pas très réaliste...

Par eMRaistlin le 13/11/2002 à 14:16:39 (#2552143)

Euh... je peux me tromper, mais pour quoi ne pas utiliser OnAquiredItem et OnUnaquirredItem ?

Par Nylou le 13/11/2002 à 14:34:43 (#2552328)

Provient du message de Jedaï
On pourrait peut-être faire un "rollback" à la fin du marchandage mais ça fait pas très réaliste...


Je me trompe peut etre mais dans nwn quand tu veux acheter un objet pour lequel tu n'as pas assez de Po tout se passe bien jusqu'au dernier moment.

Le nombre de fois ou je croyais avoir acheté des potions et que j'avais pas assez.


Quand tu parles au marchand on peut creer une variable flag et ensuite sur les event onAcquiredItem et onUnAcquired item on fait les controle adéquat pour valider la transaction ou faire le rollback.

Par Frolo Xeres le 13/11/2002 à 19:37:49 (#2555045)

Ben pour l'instant je l'ai fait avec un trigger sous mon marchand :
Pour ceux que çà interesse :
-> Un coffre indestructible avec la réserve du marchand enfin pas exactement. Mon coffre porte une variable qui défini les ressources du PNJ. J'ai trouvé que le onEnter et le onExit de mon trigger pour mettre à jour la variable de mon solde. Donc comme dit plus haut, différence (positive ou négative) sur les ressources. Quand y a plus de sou : condition sur le discours et le PNJ ne propose plus de magasin... "Désolé vous m'avez mis sur la paille !".
-> Un détail je met l'or dans le coffre que quand un PC le force (peut que le crocheter de tout façon il est indestructible) Ca évite de manipuler des objets a chaque transaction. Et comme j'ai pas trouvé comment augmenter le nombre de pièces dans l'item it_gold002 il fallait, supprimer et recreer !
-> J'ai rajouté une augmentation du solde toute les semaines de quelques GP (style, y a pas que les PC qui achetent mes joujoux ).
-> Et puis je pensais rajouter une mise à jour du stock.

Bon vous aurez peut-être l'impression de voir du déjà lu mais comment j'avais codé çà avant de lire vos remarques je tenais à le signaler... C'est un bon début et çà met de l'ambiance.
Si quelqu'un est interessé par le code qu'il le dise, je le posterais !

Par Jedaï le 13/11/2002 à 19:43:00 (#2555115)

Exact, j'avais pas pensé à OnAcquire et OnUnAcquire, ça doit être possible, à voir...

Je propose qu'on poste chacun ses scripts ici, ainsi on pourra faire une synthèse.
La première question, à part vérifier que On(Un)AcquireItem se déclenche bien durant les transactions, c'est de savoir ce qu'on souhaite faire lorsque les stocks d'or sont épuisés :
[list=1]
*on arrête la transaction et le marchand explique qu'il n'a plus d'or.
*on fait retourner l'objet dans l'inventaire du PC sans explication (éventuellement le joueur a été prévenu auparavant de cette particularité du module)
*on ne fait rien, jusqu'à la fin de la transaction, ainsi il faudra déterminer quels objets reparte au joueur et lesquels restent, ceci implique de prendre une transaction comme un tout, donc une gestion un peu particulière (peut-être un peu plus réaliste : on fait le total à la fin de tous les échanges)


Le 1 risque d'être frustrant pour le joueur, sauf si bien implanté (exposé forcé du montant du stock d'or du marchand avant le début du marchandage), sans doute assez simple à mettre en oeuvre, efficace et sans problème, la mise en place la plus prometteuse à mon avis.
Le 2 implique de trouver un moyen simple d'expliquer ça au joueurs et risque de passer inaperçu au yeux du joueur...
Le 3 me semble très difficile et peu intéressant, sauf si on laisse le choix au joueur de ce qu'il reprend : implémentation complexe à base de tokens personnalisé, faisable avec ma bibliothèque.

Avis, critiques, conseils ?:lit:

Par Frolo Xeres le 18/11/2002 à 16:11:02 (#2587166)

Juste un petit :

Par eMRaistlin le 18/11/2002 à 16:21:20 (#2587247)

Euh... je veux bien, moi, mais on doit scripter quoi ? la 1, la 2 ou la 3 ?

Pasque si le post etait en abandon, c'est pasque personne n'a fournit de "spec." (^^),...

Par Frolo Xeres le 19/11/2002 à 12:25:37 (#2593179)

Ben le mieux à mon avis est que chacun se penche sur la solution qui lui semble la plus appropriée... Ensuite on les mets toutes... et on les mets dans le permanent... Non ?
Je pense que je vais améliorer la mienne et proposer les scripts, mais comme j'ai pas une solution particulièrement efficace je me disais que ceux qui avaient de meilleurs idées pouvais en faire profiter les autres...
[hrp] Bon c'est pas tout çà mais faut que j'aille coder ! [/hrp]

Par eMRaistlin le 19/11/2002 à 13:30:39 (#2593687)

Le 1 risque d'être frustrant pour le joueur, sauf si bien implanté (exposé forcé du montant du stock d'or du marchand avant le début du marchandage), sans doute assez simple à mettre en oeuvre, efficace et sans problème, la mise en place la plus prometteuse à mon avis.


A mon avis la solution la moins compliquée, la plus rapide, et la plus realiste.


ATTENTION, je realise ce script sans le toolset, et de memeoire, la fonction GetGoldPieceValue() bugge. c'est a verifier.

On Spawn

void main()
{
int nMontantMax= 50000;

SetLocalInt(OBJECT_SELF,"bank", nMontantMax);
}


Jusque la, c'est simple ^^

OnUnaQuired

void main()
{
SetLocalObject(GetArea(GetModuleItemLostBy() , "ExHaveIt", GetModuleItemLostBy());
SetLocalObject(GetArea(GetModuleItemLostBy() , "ExItem", GetModuleItemLost());
}


OnDisturbed du Marchand

void main()
{
object oPc = GetLastDisturbed();
int nValeur = GetGoldPieceValue(oItem);
object oItem;
int bank = GetLocalInt(OBJECT_SELF,"bank");
object oItem = GetLocalObject(GetArea(oPc),"ExItem");

if (GetInventoryDisturbType() == INVENTORY_DISTURB_TYPE_ADDED)
{
int newbank = bank-nValeur
if (newbank > 0)
{
SetLocalInt(OBJECT_SELF,"bank",newbank)
}
else
{
SpeakString("Malheuresement, ce que vous me proposer est bien au dela de mes prix");
DestroyObject(oItem);
CreateItemOnObject(RESREF(oItem),oPc,1);
GiveGoldToCreature(OBJECT_SELF,nValeur);
}
}


En oubliant pas de faire en sorte que RESREF(oITEM) soit connu (avec une fonction referencielle ou en mettant toujours les tag comme les Resref sur tes items...Perso, meme si c'est plus contraignant, je prefere la solution d'une fonction Include qui traite le nom d'un item pour le transformer en RefRef.)


string RESREF(object oItem)
{
string resref = GetStringLowerCase(GetName(oItem));
resref = GetStringLeft(resref,16);
return resref;
}

bien entendu, ca necessite de ne pas mettre de caracteres speciaux dans le nom (*-/+), mais ca fait a peu pres le meme boulot que le createur de resref du toolset, donc on gere pas mal de cas.

Enfin, Dans le OnConversation

void main()
{
int bank = GetLocalInt(OBJECT_SELF,"bank");

if (bank <= 10)
{
SpeakString("je n'ai plus rien, revenez plus tard...");
}
else ActionStartConversation(GetPCSpeaker(),");
}


Bien entendu, et je le repete, ce n'est qu'une ebauche non testée... Si vous avez 2sec pour tester.

[EDIT]
JE VEUX BIEN SAVOIR SI CA MARCHE? AU FAIT ^^ si celui a qui ca va servir pouviait donne un ch'tit feedback... ;)

Par Jedaï le 20/11/2002 à 12:16:36 (#2600832)

Euhh, y a pas de OnDisturbed dans les Events d'un magasin, et assurément celui du marchand associé peut pas marcher...

Par eMRaistlin le 20/11/2002 à 15:19:56 (#2602607)

Euh... milles excuse, je sais pas ce qui m'a pris. Merci Jedai.
J'edite le post du dessus, et je propose celui-ci.

ATTENTION, je realise ce script sans le toolset, et de memeoire, la fonction GetGoldPieceValue() bugge. c'est a verifier.
De plus, je ne suis pas sur de l'endroit ou sont gérés les items lors du lancement du OnUnaquired.

On Spawn


void main()
{
int nMontantMax= 50000;

SetLocalInt(OBJECT_SELF,"bank", nMontantMax);
}


Jusque la, c'est simple ^^

OnUnaQuired

void main()
{
object oPlayer = GetModuleItemLostBy() ;
object oItem = GetModuleItemLost() ;
object oArea = GetArea(oPlayer) ;
object oStore = GetNearestObject(OBJECT_TYPE_STORE,oPC,1) ;
object oInventory = GetFirstObjectInInventory(oStore);
object oMarchand = GetObjectByTag(« Tag_Marchand ») ;
int nCurrentbank = GetLocalInt(oMarchand, « bank ») ;


SetLocalObject(oArea, "ExHaveIt",oPlayer);
SetLocalObject(oArea, "ExItem", oItem);

If ( GetNearestObject(OBJECT_TYPE_ITEM,oPlayer,1) != oItem)
{
while (GetIsObjectValid(oInventory))
{
if (oInventory == oItem)
{
if (GetGoldPieceValue(oItem)>nCurrentBank)
{
ActionGiveItem(oItem,oPC) ;
AssignCommand(oMarchand,SpeakString(« Je n'aurais jamais assez d'or pour vous payer un tel objet, messire ») ;
}
}
oInventory = GetNextItemInInventory(oStore) ;
}
}
}



Enfin, Dans le OnConversation

void main()
{
int bank = GetLocalInt(OBJECT_SELF,"bank");

if (bank <= 10)
{
SpeakString("je n'ai plus rien, revenez plus tard...");
}
else ActionStartConversation(GetPCSpeaker(),");
}


Voila. Je vois pas autre chose pour le moment.
Je me suis compliqué un peu la vie, mais c'est pour ceux qui veulent avoir des item ayant un tag different du resref.

Bien entendu, et je le repete, ce n'est qu'une ebauche non testée... Si vous avez 2sec pour tester.

JE VEUX BIEN SAVOIR SI CA MARCHE? AU FAIT ^^ si celui a qui ca va servir pouvi
ait donne un ch'tit feedback... ;)

JOL Archives 1.0.1
@ JOL / JeuxOnLine