[Résolu] Crash sur le FindUnit...
Salut à tous,

Je me remet un peu au C++ Trinity et à vrai dire... certaines fonctions sont assez bizarre.

But du script : Récupérer pour CHAQUE creature du jeu (répertoriées par guid), la ZONE et l'AREA dans laquelle elle évolue, chose dont on en dispose pas dans la base de données.

Voici le script script:
[code=cpp]
// On séléctione TOUS les mobs
QueryResult resultset = WorldDatabase.PQuery("SELECT guid, id FROM creature");

// Si table vide (ben... là c'est balot... mais ne devrait jamais arriver.)
if (!resultset)
{
handler->PSendSysMessage("La table aurora_creature_zones est VIDE.");
return true;
}
else
{
//----- on récupère la créature
do
{
Field* RSFIELDS = resultset->Fetch();

uint32 guid = RSFIELDS[0].GetUInt32();
uint32 id = RSFIELDS[1].GetUInt32();

Unit* tmpNpcUnit = sObjectAccessor->FindUnit(MAKE_NEW_GUID(guid, id, HIGHGUID_UNIT));

uint32 zone_id, area_id;

// on récupère la zoen & arez ID
tmpNpcUnit->GetZoneAndAreaId(zone_id, area_id);

WorldDatabase.PQuery("INSERT INTO aurora_creature_zones (guid, zone, area) VALUES(%u,%u,%u)", guid, zone_id, area_id);
count++;
}
while(resultset->NextRow());
}
[/code]

La fonction FinUnit n'est pas super appréciée par le core je pense.. mais cependant, la macro MAKE_NEW_GUID me laisse perplexe...

Quelqu'un a une idée ?
[code=cpp]QueryResult resultset = WorldDatabase.PQuery("SELECT guid, id FROM creature");[/code]

Erreurs n°1 c'est une Query qu'il faut faire pas une PQuery.

[code=cpp]Unit* tmpNpcUnit = sObjectAccessor->FindUnit(MAKE_NEW_GUID(guid, id, HIGHGUID_UNIT));[/code]

Erreurs n°2 : Je ne connait pas la fonction MAKE_NEW_GUID et FinUnit, mais je vois pas ce queMAKE_NEW_GUID viens faire là ? j'aurais fait un simple sObjectAccessor->FindUnit(guid);

Erreurs n°3 : un if(!tmpNpcUnit) continue; serait pas de refue.

Inconnus n°1 : tmpNpcUnit->GetZoneAndAreaId(zone_id, area_id); je te fait confiance que celà retourne bien deux const mais je sais pas trop tu ferait ptet mieux de décomposer.

Le reste je suis d'accord Smile
PQuery ou Query sont sensiblement pareils. PQuery permet juste de rajouter des paramètres comme pour printf. Mais ici, utiliser PQuery ou Query ne change rien. Query serait juste plus performant. Mais PQuery n'empêchera pas le script de fonctionner pour autant.

Ce qui me choque dans ton script, c'est que tu récupères des Creatures mais tu créer le guid avec un le high guid de unit. Les créatures n'ont pas un high guid à elles ?

De plus, si la créature n'existe pas dans le monde à ce moment la (eg. aucun joueur n'est dans la zone en question et donc le serveur n'a pas encore instancié la créature en question), je ne suis pas du tout sur du comportement de FindUnit (elle renvoie peut être tout simplement NULL, à vérifier).



@totomakers : Si FindUnit prend un uint64 en paramètre, alors c'est le guid complet qu'il faut lui donner, et non juste le guid low (c'est le guid low qui est stocké en base de données). Il faut donc construire le guid complet, et la macro MAKE_NEW_GUID est faite pour cela.
Ca marche là pourtant ; ) mais je n'ai accès qu'aux créatures de la zone.. je suis obligé de faire la commande dans chaque zone du jeu pour alimenter ma table Erf
(18-07-2011 09:31)Magus a écrit :  De plus, si la créature n'existe pas dans le monde à ce moment la (eg. aucun joueur n'est dans la zone en question et donc le serveur n'a pas encore instancié la créature en question), je ne suis pas du tout sur du comportement de FindUnit (elle renvoie peut être tout simplement NULL, à vérifier).


Je me quote moi-même.
C'est exactement ce que je t'ai dit.

Si aucun joueur n'est dans la zone, Trinity ne créer pas les créatures de cette zone (pour éviter de devoir gérer des créatures/gameobjects que de toutes façons personne ne peut voir).
Édition :
Par contre, je pense juste à un truc :
Tu veux juste avoir la zone et l'area ?

Parce que dans la base de données, tu as les coordonnées x, y et z de la créature (et l'identifiant de sa map). Je ne suis pas sur, mais je pense qu'avec ces informations tu peux trouver la zone et l'area sans être obligé de passer par la créature elle-même.

Regarde dans les fonctions de Map pour voir s'il n'y a pas ce que tu cherches.
C'est un peu con, car de base les mobs sont spawnés dans les zones au chargement du serveur non ?

Donc avec le guid complet je devrais être en mesure d'obtenir un pointeur sur la créature en question.
(relis mon message, j'ai fait un edit important)

Pour des soucis de performance, non.
Trinity créer les monstres/PNJs/GameObjects quand au moins un joueur entre dans la zone. Avant cela, ils ne sont tout simplement pas instanciés (mais ils existent dans la base de données).

Et lorsqu'il n'y a plus aucun joueur dans une zone, au bout d'un certain temps Trinity retire tous les montres/PNJs/GameObjects

C'est juste pour ne pas surcharger le serveur. S'il devait tout gérer en permanence le pauvre il aurait mal :/
Ouais je me doutais bien que un tel système était en place.

Je vais me tourner plutôt vers les Maps.

Mais oui en effet je veux récupérer pour chaque mob la zone et l'area dans laquelle il est, mais dans la DB je n'ai que ces coordonnées et la Map, ça m'est pas super utile pour ce que je veux faire.
Magus tu m'en apprend merci je comprend l'utilité maintenant Heureux !!!.

Donc ou tu peux récupérer toute c'est info

map->GetAreaId(x,y,z); récupére l'areaId a partir de ces coord.
map->GetZoneId(x,y,z); idem

pour prendre chacune des maps fait :
Map* map = const_cast<Map*>(sMapMgr->CreateBaseMap("id"));
Et pourtant dans map, tu as ces 2 fonctions :

[code=cpp]uint32 GetAreaId(float x, float y, float z);
uint32 GetZoneId(float x, float y, float z)[/code]

Donc pour ton script, dans l'ordre tu dois :

- Récupérer les coordonnées x, y et z d'une créature
- Récupérer l'identifiant de la map dans laquelle il est
- Avec l'identifiant tu récupères l'objet Map correspondant
- Et tu utiliser GetAreaId et GetZoneId pour avoir l'Area et la Zone de la créature.

Retourner en haut Accueil