Agriculture bio

Répondre
Partager Rechercher
Bon, après la chasse, et avant la pêche, je me lance dans l'agriculture. Welcome to Aurora's José Bové ! yaisssse !

Donc voilà, le pj entre sur un trigger entourant un champ (ouais, avec une jolie fermière à quatre pattes dedans !) et il se passe ceci :

Code PHP:

void main()
{

object oPC GetEnteringObject();

if (!
GetIsPC(oPC)) return;

if (
GetItemPossessedBy(oPC"IT_SERPE")== OBJECT_INVALID)
   return;

object oTarget;
object oSpawn;
oTarget GetWaypointByTag("wp_ble01");

oSpawn CreateObject(OBJECT_TYPE_PLACEABLE"grasstuft001"GetLocation(oTarget));

oTarget GetWaypointByTag("wp_ble02");

oSpawn CreateObject(OBJECT_TYPE_PLACEABLE"grasstuft001"GetLocation(oTarget));

oTarget GetWaypointByTag("wp_ble03");

oSpawn CreateObject(OBJECT_TYPE_PLACEABLE"grasstuft001"GetLocation(oTarget));

oTarget GetWaypointByTag("wp_ble04");

oSpawn CreateObject(OBJECT_TYPE_PLACEABLE"grasstuft001"GetLocation(oTarget));

oTarget GetWaypointByTag("wp_ble05");

oSpawn CreateObject(OBJECT_TYPE_PLACEABLE"grasstuft001"GetLocation(oTarget));

oTarget GetWaypointByTag("wp_ble06");

oSpawn CreateObject(OBJECT_TYPE_PLACEABLE"grasstuft001"GetLocation(oTarget));

oTarget GetWaypointByTag("wp_ble07");

oSpawn CreateObject(OBJECT_TYPE_PLACEABLE"grasstuft001"GetLocation(oTarget));

oTarget GetWaypointByTag("wp_ble08");

oSpawn CreateObject(OBJECT_TYPE_PLACEABLE"grasstuft001"GetLocation(oTarget));

oTarget GetWaypointByTag("wp_ble09");

oSpawn CreateObject(OBJECT_TYPE_PLACEABLE"grasstuft001"GetLocation(oTarget));


donc, 9 plans de Blé poussent dans le champs à différents endroits, et le pj doit ramasser les grains contenus dans l'inventaire des plans (après s'être au préalable muni de la serpe adéquate of course)

Lorsqu'il sort du champ pour aller vendre sa récolte au marché, il se passe ça :

Code PHP:

void main()
{

object oPC GetExitingObject();

if (!
GetIsPC(oPC)) return;

object oTarget;
oTarget GetObjectByTag("PlantGrowthGrassTufts");

DestroyObject(oTarget0.0);


et là problème : seul le premier plan de blé disparaît, et les 8 autres restent là, comme des cons. Mais si le pj sort sans avoir récolté le blé de ce plan, alors le plan disparait mais laisse un sac avec les grains de blé dedans

Pouvez-vous m'aider à faire disparaître TOUS les plans de blé et à faire en sorte que si l'un n'a pas été récolté, son inventaire n'apparaisse pas sur le sol comme une grosse crotte ?

Enfin bref, faites un geste pour l'environnement, aidez l'agriculture bio ! (terreau généreusement arrosé de purin d'orc !)



Ben tu demande de détruire une occurence de ton placeable 'pousse de blé'. Alors NWN regarde le premier objet qu'il trouve et le supprime.
Rajoute une boucle comme suis pour les supprimer tous.

Code PHP:

void main()
{
  
object oPC GetExitingObject();
  
object oTarget;

  if (
GetIsPC(oPC))
  {
    
oTarget GetObjectByTag("PlantGrowthGrassTufts");
    while (
oTarget != OBJECT_INVALID)
    {
      
DestroyObject(oTarget0.0);
      
oTarget GetObjectByTag("PlantGrowthGrassTufts");
    }
  }

Le code ci dessus va pas marcher comme tu veux si 2 joueurs entre dans la zone, mais ca je te laisse gérer


Au fait, petite information : Evite les return et les break intempestif. C'est hautement déconseillé.
Le break ne doit servir que dans un switch case
Le return ne doit servir que pour une fonction renvoyant une valeur.
Je préfère comme ceci

Code PHP:

object oPC GetEnteringObject();
while(
GetIsPC(oPC) && GetItemPossessedBy(oPC"IT_SERPE")!= OBJECT_INVALID)
{
int nI;  //[Edit pour gros oubli, désolé encore]
for(nI 1nI 9nI++)
{
 
object oTarget GetWaypointByTag("wp_ble0" IntToString(nI));
 
object oSpawn CreateObject(OBJECT_TYPE_PLACEABLE"grasstuft001"GetLocation(oTarget));
}

Ah oui, j'aime bien, c'est plus court

Sinon, une idée pour qu'à la destruction des plans les inventaires potentiels (les grains donc ) ne "tombent" pas sur le sol mais soient détruits aussi ?
J'up le bidule parcequ'après essais, ben tout ça ne marche pas du tout, mais alors pas du tout !

Citation :
Ben tu demande de détruire une occurence de ton placeable 'pousse de blé'. Alors NWN regarde le premier objet qu'il trouve et le supprime.
Rajoute une boucle comme suis pour les supprimer tous.

Code PHP:

void main()
{
  
object oPC GetExitingObject();
  
object oTarget;

  if (
GetIsPC(oPC))
  {
    
oTarget GetObjectByTag("PlantGrowthGrassTufts");
    while (
oTarget != OBJECT_INVALID)
    {
      
DestroyObject(oTarget0.0);
      
oTarget GetObjectByTag("PlantGrowthGrassTufts");
    }
  }

Le code ci dessus va pas marcher comme tu veux si 2 joueurs entre dans la zone, mais ca je te laisse gérer

Au fait, petite information : Evite les return et les break intempestif. C'est hautement déconseillé.
Le break ne doit servir que dans un switch case
Le return ne doit servir que pour une fonction renvoyant une valeur.
Ce script là me fait planter le jeu : "too many instructions !"

Non seulement mon blé ne pousse plus, mais le temps s'arrête carrément !

Quant à celui de Delphinea, il ne compile pas : "unknown state in compiler" sur cette ligne :

Code PHP:

for(nI 1nI 9nI++) 

Mes villageois vont finir par crever de faim !

Va voir le sujet "comptage dans un inventaire" juste en-dessous, ma solution ne te donnera pas de Too many instructions, aucun risque .

(Pour info, la faute réside dans cette instruction :
Code PHP:

oTarget GetObjectByTag("PlantGrowthGrassTufts");
    while (
oTarget != OBJECT_INVALID)
    {
      
DestroyObject(oTarget0.0);
      
oTarget GetObjectByTag("PlantGrowthGrassTufts");
    } 
Je vous résume ce qui se passe : DestroyObject() n'a jamais un effet immédiat, l'objet n'est détruit qu'à la fin du script, donc ici, le GetObjectByTag() tourne à l'infini sur le même objet, Too Many Instructions garanti !! )
Oups je suis désolé d'avoir oublié la déclaration de l'entier avant la boucle for
J'ai écrit ce script en vitesse sur le forum et je n'avais aucun moyen de compiler, et par paresse je n'ai pas trop vérifié j'avoue :P . Il faudrait que JOL ajoute un petit compilateur à son forum pour Maskado
Arf, je ne doute pas un seul instant que ces solutions marchent parfaitement, mais même si j'ai fais les tutoriaux (du moins jusqu'à là où j'ai pu... ) je n'en reste pas moins une énorme quiche en la matière, et concrètement je suis bien incapable de mettre ces idées en forme...

Arrêtez d'être élitistes vouzotres les gens intelligents !
pensez à la JOL d'en bas, ceux qui ont les idées mais pas le pétrole !



***********

Après reflexion, je me suis dit : "pourquoi vouloir détruire tous les plans d'un coup à la sortie du trigger ?" Donc j'ai fais ça sur le on close de l'inventaire du plan :

Code PHP:

void main()
{

object oPC GetLastClosedBy();

if (!
GetIsPC(oPC)) return;

object oTarget;
oTarget GetObjectByTag("PlantGrowthGrassTufts");

DestroyObject(oTarget0.0);


Et là encore, ça fonctionne sur le premier, mais pas sur les suivants. (je viens d'essayer avec GetNearestObjectByTag, et logiquement ça devrait détruire celui que je viens d'ouvrir, mais non, il en choisit un autre ! -> )

Sérieux, ça me gave, je vais me mettre au transgénique si ça continu !

Citation :
Provient du message de Jedaï
Je vous résume ce qui se passe : DestroyObject() n'a jamais un effet immédiat, l'objet n'est détruit qu'à la fin du script, donc ici, le GetObjectByTag() tourne à l'infini sur le même objet, Too Many Instructions garanti !! ) [/i]
Ah tiens donc interessant ca. Décidement mal fichu ce language

Bon ben reste plus qu'a essayer d'assigner la commande de destruction à l'objet lui même.

Tiens essai ca :
Code PHP:

void main()
{
  
object oPC GetExitingObject();
  
object oTarget;

  if (
GetIsPC(oPC))
  {
    
oTarget GetObjectByTag("PlantGrowthGrassTufts");
    while (
oTarget != OBJECT_INVALID)
    {
      
ExecuteScript("destroyhimself"oTarget);
      
oTarget GetObjectByTag("PlantGrowthGrassTufts");
    }
  }


Code PHP:

void main()
{
  
DestroyObject(OBJECT_SELF0.0);

Et dis voir ce qu'il se passe
Oui, il me paraît bien plus logique de détruire lors de la "récolte", mais il faut alors utiliser OBJECT_SELF tout simplement. et non un GetObjectByTag().
(par ailleurs ma solution ne convient pas, j'avais mal compris le problème )

@ Eclipse > En fait le problème du Destroy() ne doit pas tellement être lié au langage, il est simplement lié à un souci de cohérence de Bioware : l'état du monde actuel ne se modifie pas avant la fin du script, plus exactement on peut rajouter des choses mais pas en enlever, également, on peut constater que les actions ne se déclenchent qu'après la fin du script, on n'obtiendra donc pas deux valeur différentes de CurrentAction dans un même script (mais là je m'avance un peu, j'ai pas fait les tests).
Par ailleurs, certains de ces choix ont été fait dans le but d'éviter des erreurs courantes, par exemple il est très courant qu'on demande à un objet de s'autodétruire, dans ce cas, il est indispensable que le DestroyObject() soit automatiquement reporté à la fin du script, pour éviter l'interruption de l'exécution (un OBJECT_INVALID ne peut exécuter de scripts, cf AssignCommand() ou DelayCommand() qui sont souvent la cause d'erreur à cause de cela).

Maintenant, ce sont mes théories, demande directement à Bioware si tu veux connaître la vraie raison.

[EDIT] Je pense que cette solution ne marchera pas mieux Eclipse, même si je n'en suis pas sûr, intéressant à tester.
OBJECT_SELF fonctionne parfaitement sur le OnClose de mon placeable. Rien à dire. Mais il y a quelque chose qui me chiffonne : rien n'empêche le pj de rerentrer dans le champ pour refaire une récolte illico. Par quel moyen empêcher mon premier script de refonctionner tout de suite ?

Une idée ?
Tout dépend de ce que tu veux faire exactement, veux tu empecher une récolte immédiate pour ce PJ uniquement ou pour tous ?

Pour une raison de simplicité, je te conseil le dernier choix. Il faut lié une valeur temps à ton trigger 'champ de blé' que tu test quand quelqu'un entre dedans. La prochaine fois qu'un PJ entre dans ce trigger et si le temps n'est pas écoulé rien ne se passe.
J'ai résolu le problème de la manière suivante : Dans le premier script, le spawn des plans de blé est conditionné par la possession par le pj de l'item IT_SERPE qui lui donne le droit de récolter. Donc, j'ai mis ça sur le OnExit du trigger, ce qui l'oblige à aller vendre sa production 3 zones plus loin au grenier de la ville, et récupérer une nouvelle serpe sans qui il ne peut plus rien récolter :

Code PHP:

void main()
{

object oPC GetExitingObject();

if (!
GetIsPC(oPC)) return;

if (
GetItemPossessedBy(oPC"IT_SERPE")== OBJECT_INVALID)
   return;

object oTarget;
oTarget GetObjectByTag("IT_SERPE");

DestroyObject(oTarget0.0);


Finalement, même avec des connaissance plus que limitées on peut toujours contourner les problèmes...

En tout cas, merci à tous pour vos idées et votre aide.

Bien, passons à la pêche maintenant...
**Préfère l'utilisation d'une boucle while plutot que des "return", comme ceci:

Code PHP:

void main()
{

object oPC GetExitingObject();
string sSerpe "IT_SERPE";

while (
GetIsPC(oPC) && GetItemPossessedBy(oPCsSerpe)!= OBJECT_INVALID)
{
 
DestroyObject(GetObjectByTag(sSerpe), 0.0);
}

Petit problème de ton script, si le joueur ne quitte jamais le trigger, il pourra récolter sans cesse. Si tu veux je te fais un script avec un timer que tu pourras régler à ta guise en début de script, ainsi que d'autres petits paramètres rendant le script modulable.
Je te fais ça vite fait
Voilà, je l'ai fait en vitesse, je ne l'ai pas testé en jeu, mais il compile c'est deja ça

Code PHP:

//Cree un placable "plante" pour chaque type de plante, auquel tu donneras le
//Tag/ResRef equivalent a sPlante (dans cet exemple: "ble")
//Fait de meme avec un objet pour chaque plante, et donne lui le Tag/ResRef
// P + sPlante (par exemple: "pble")

//Voici les constantes que tu peux regler a ta guise:
//***************************************************

//Temps necessaire a la recolte d'une plante (en secondes)
float fRecolte 2.0;
//Delai necessaire a la repousse des plantes (en minutes)
int nDelai 5;
//Tag de l'outil necessaire a la recolte
string sOutil "IT_SERPE";

//A Appeler dans le OnEnter du Trigger
void Planter(string sPlante)
{
 
object oPC GetEnteringObject();
 
int nTime GetLocalInt(oPCsTime);
 
int nMinute GetTimeMinute();
 if(
nTime == 0)
 {
  
int nTime nMinute;
 }
 
SetLocalInt(oPCsTimenMinute);
 while(
GetIsPC(oPC) && nTime+nDelai nMinute)
 {
  
int nI;
  for(
nI 1nI 9nI++)
  {
   
object oTarget GetWaypointByTag("wp_" sPlante "0" IntToString(nI));
   
object oSpawn CreateObject(OBJECT_TYPE_PLACEABLEsPlanteGetLocation(oTarget));
  }
 }
}
//Pour appeler la fonction, tu ecris ceci:
//Planter("ble");
//ou encore, si tu veux que ce soit un champ de tournesol:
//Planter("tournesol");
//Il te suffit juste de creer un placable avec le tag/resref "tournesol" dans la palette.


//A Appeler dans le OnUsed de toutes tes plantes
void Recolte()
{
 
object oPC GetLastUsedBy();
 while(
GetItemPossessedBy(oPCsOutil)!= OBJECT_INVALID)
 {
  
AssignCommand(oPCActionPlayAnimation(ANIMATION_FIREFORGET_STEAL1.0fRecolte));
  
CreateItemOnObject("p" sPlanteoPC);
  
DestroyObject(OBJECT_SELF);
 }
 
SendMessageToPC(oPC"Vous ne possedez pas le bon outil pour recolter cela.");
}
//Pour appeler cette fonction tu ecris simplement:
//Recolte();

//Tu nommes ce fichier comme tu veux (par exemple: Farmage)
//Dans chaque script ou tu veux utiliser une fonction (OnEnter du trigger et
//OnUsed de la plante et p-e d'autres si tu en as l'utilite), tu mets:
//##include "Farmage" 
Merci Delphinea. Je n'ai pas tout compris quant à l'utilisation de ton script, mais c'est promis je me pencherais dessus.

Bon, je doute que cela intéresse grand monde, mais après la chasse et l'agriculture, je me suis lancé dans la pêche. J'explique juste l'idée, et si besoin je mettrai les scripts qui sont vraiment tout simples, (normal, c'est les seuls que je sache faire )

Bref, le pj parle au capitaine qui lui refile un harpon et hop : téléport sur un bateau en pleine mer. Le pj s'approche du bord du bateau et rehop, spawn de 4 objets invisibles renommés "banc de poissons" posés sur l'eau à porté de harpon (un simple baton avec un bout pointu).

Le pj frappe les "banc de poisson" et sur le OnDeath du placeable un script fait apparaître un item "poisson" sur le pont du navire.

Lorsqu'il n'y a plus de poissons, le pj sort du trigger pour reparler au capitaine et rentrer au port, et sur le OnExit, je détruit l'objet "harpon" afin que le pj ne puisse pas faire une pêche miraculeuse (la possession du harpon étant nécessaire au spawn de poisson sur le OnEnter du trigger)

Le seul hic, c'est l'effet que j'utilise pour le spawn des bancs de poisson : Spell Mantle. Si vous avez plus réaliste à proposer, je suis tout ouïes ()

Je sais, expliqué comme ça ça fait trés quiquiche, mais c'est la manière dont j'aimerais lire les explications en générale. C'est la seule qui me permet de tout comprendre d'un coup sans faire chauffer mon pitit cerveau outre mesure...
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés