map — Carte & Déplacement¶
API carte et déplacement MoonBot Lua : se déplacer, changer de map, pathfinding, zaaps, cellules.
62 fonctions dans ce namespace.
Index¶
map.currentMapmap.currentMapId / idmap.x / ymap.dimensions / width / heightmap.currentCell / cellIdmap.currentArea / currentSubAreamap.onMapmap.changeMapmap.moveToCellmap.gathermap.gatherResourcemap.fightmap.moveTowardmap.moveTowardMapmap.worldDistancemap.waitForMapChangemap.monsterGroupsmap.fightGroupmap.playersmap.npcsmap.getActors / getActorByIdmap.getResourcesmap.interactiveObjectsmap.useInteractivemap.houseInstancesmap.enterHousemap.openHouseChestCoffre de maison : exempleCoffre de maison : resultatsEntree maison : exempleEntree maison : resultatsMaisons et coffres dans le MapViewerLimites des interactifs generiquesmap.isWalkable / getWalkableCellsmap.getX / getYmap.hasChangedmap.openZaap / openZaapimap.useZaap / useZaapiSequence zaap recommandeemap.getZaapDestinationsmap.saveZaapmap.getPrismsmap.openPrismmap.getPrismDestinationsmap.usePrismmap.closePrismExemple — se teleporter par prismemap.sendEmote / sitDeplacement et combat — aliasesInformations de zone et distanceUtilitaires de carteGroupe de jeumap.getPendingGroupInvitemap.waitForGroupInviteInfos groupe de jeuDefis entre joueursmap.aggressPlayermap.getPendingChallengemap.waitForChallengemap.joinableFightsmap.joinFightmap.exchangePlayer
Référence¶
map.currentMap¶
returns string
Coordonnees "x,y".
map.currentMapId / id¶
returns number
ID de la map.
map.x / y¶
returns number
Coordonnees x et y.
map.dimensions / width / height¶
returns table {width, height} / number / number
Dimensions de la map actuelle. dimensions() renvoie une table {width, height}. width()/height() renvoient directement le nombre. Standard Retro = 15x17, mais les maps non-standard sont gerees (valeurs lues depuis le SWF).
map.currentCell / cellId¶
returns number
Cellule actuelle.
map.currentArea / currentSubArea¶
returns string
Zone et sous-zone.
map.onMap¶
returns boolean
Verifie si sur la map ("x,y" ou ID).
map.changeMap¶
blocking · returns boolean
Change de map : "right", "left", "top", "bottom".
map.moveToCell¶
blocking · returns boolean
Deplace vers une cellule (attend l'arrivee).
map.gather¶
blocking · returns boolean
Recolte toutes les ressources.
map.gatherResource¶
blocking · returns boolean
Recolte la ressource de la cellule cible avec le sequenceur dedie (portee de l'outil, approche et confirmation serveur). Retourne true uniquement apres confirmation de la recolte ; false si la ressource est indisponible, refusee ou si aucune confirmation n'arrive sous 30 s.
map.fight¶
blocking · returns boolean
Attaque le groupe de monstres le plus proche.
map.moveToward¶
blocking · returns boolean
Un pas de map vers les coordonnees cibles.
map.moveTowardMap¶
blocking · returns boolean
Un pas de map vers la map cible.
map.worldDistance¶
returns number
Distance en maps vers les coordonnees (-1 si inaccessible).
map.waitForMapChange¶
blocking · returns boolean
Attend un changement de map.
map.monsterGroups¶
returns table of {id: number, cellId: number, name: string, level: number, count: number, monsters: table of {id: number, name: string, level: number}}
Groupes de monstres sur la map. name = noms des monstres, level = niveau du groupe, count = nombre de monstres, monsters = détail de chaque monstre (template ID, nom, niveau individuel).
map.fightGroup¶
blocking · returns boolean
Attaque un groupe de monstres spécifique par son ID (récupéré via map.monsterGroups()). Bloquant : attend la fin du combat. Retourne true si victoire, false si défaite ou groupe introuvable.
map.players¶
returns table of {id: number, cellId: number, name: string, level: number}
Joueurs visibles sur la map.
map.npcs¶
returns table of {id: number, cellId: number, name: string, templateId: number}
PNJ sur la map. id = ID acteur, templateId = ID du modele PNJ.
map.getActors / getActorById¶
returns table / table | nil
Tous les acteurs (monstres + joueurs + PNJ) : {id, cellId, name, type}. type = 'monster'/'player'/'npc'.
map.getResources¶
returns table of {cellId: number, gfxId: number, name: string}
Ressources recoltables sur la map.
map.interactiveObjects¶
returns table of {cellId: number, gfxId: number}
Objets interactifs (ateliers, portes, etc).
map.useInteractive¶
blocking · returns boolean
Utilise un objet interactif avec deplacement automatique. Le trajet cible la cellule exacte de l'objet ; le serveur peut confirmer un arret sur une cellule adjacente valide. skillIndex: 1=premier skill (defaut), 2=deuxieme, etc. Pour une recolte, utiliser de preference map.gatherResource(). Pour un menu (zaap, atelier, porte, enclos), l'action peut reussir sans evenement GatherComplete : le boolean generique ne confirme donc pas toujours l'ouverture et peut retourner false apres une attente allant jusqu'a 30 s. Preferer l'API specialisee lorsqu'elle existe.
map.houseInstances¶
returns table of {houseId: number, cellId: number, instanceId: number, owner: string, locked: boolean, price: number}
Maisons annoncees par le serveur sur la carte actuelle, avec leur porte et identifiant d'instance. Peut retourner une table vide avant reception des informations. Plusieurs entrees peuvent partager la meme cellule : choisir explicitement l'instance souhaitee. houseId et instanceId sont differents ; utiliser instanceId pour enterHouse. locked indique une serrure, sans garantir que votre personnage devra saisir un code.
map.enterHouse¶
blocking · returns boolean, reason: string
Entre dans une maison de la carte actuelle avec approche automatique de la porte et saisie du code seulement si le serveur le demande. code : chaine de 1 a 8 caracteres ASCII parmi 0-9 et _, avec au moins un chiffre, par exemple "001234" ; nil ou chaine vide pour tenter sans code. Les nombres Lua sont refuses pour ne pas perdre les zeros initiaux. Si le code comporte une case vide entre des chiffres, utiliser _ a cette position (par exemple "01_2") ; les tirets et les chaines composees uniquement de _ sont refuses. instanceId peut etre omis uniquement si une seule instance est annoncee pour cette porte ; sinon fournir celle de houseInstances(). Attente bornee a 30 s. true, "ok" signifie qu'une nouvelle carte a ete recue, chargee et que le personnage y est apparu, et que le serveur a confirme l'identite de la maison choisie. La fermeture de la fenetre de code ne suffit pas. false est accompagne d'une raison ; timeout signifie resultat non confirme, verifier la carte avant de reessayer. Aucun nouvel essai de code automatique. L'arret du script et la deconnexion interrompent l'attente.
map.openHouseChest¶
blocking · returns boolean, reason: string
Ouvre un coffre de maison sur la carte actuelle (competence 104), avec approche automatique et saisie du code seulement si le serveur le demande. Etre deja dans la maison, sur la carte du coffre ; aucun instanceId ni proprietaire n'est necessaire. code : chaine de 1 a 8 caracteres ASCII parmi 0-9 et _, avec au moins un chiffre ; nil ou chaine vide pour essayer sans code. Les zeros initiaux et les cases vides internes sont conserves, par exemple "001234" ou "01_2" ; les nombres Lua sont refuses. Attente bornee a 30 s. true, "ok" confirme que la fenetre de stockage a ete ouverte et son contenu charge, meme si le coffre est vide. La fermeture du dialogue de code seule ne suffit pas. false est accompagne d'une raison et n'entraine aucun nouvel essai automatique. L'arret du script, la deconnexion, un changement de carte ou de fenetre interrompent l'attente. Apres succes, utiliser exchange.storageItems(), storageKamas(), putItem/getItem et exchange.leave() pour le stockage courant. npc.openCoffre() concerne uniquement le donjon forgeron.
Coffre de maison : exemple¶
local chestCell = 120 -- remplacer par la cellule de votre coffre
local ok, reason = map.openHouseChest(chestCell, nil)
if not ok then error("Ouverture non confirmee : " .. reason) end
print("Contenu charge : " .. #exchange.storageItems() .. " piles")
-- Transferts possibles dans le coffre courant :
-- exchange.putItem(templateId, quantity)
-- exchange.getItem(templateId, quantity)
-- exchange.leave()
Executer sur la carte interieure du coffre, apres une entree confirmee avec map.enterHouse() et les deplacements interieurs eventuellement necessaires. La cellule 120 est un exemple, pas une valeur universelle. Remplacer nil par le code connu du coffre, sous forme de chaine ; il peut etre different de celui de la porte. Ne pas afficher ou publier ce code. Le succes confirme le chargement du coffre ; les transferts exchange gardent leurs propres regles de confirmation. En cas d'echec, arreter cette sequence et verifier le contexte avant de reessayer.
Coffre de maison : resultats¶
Raisons usuelles : code_required (code demande mais absent), wrong_code (code refuse), invalid_code / code_too_long (format/longueur), not_chest (pas de coffre sur cette cellule), no_path (coffre inaccessible), action_rejected (ouverture refusee), busy / not_ready (personnage indisponible), stale_map / map_changed (carte modifiee), unexpected_exchange (autre fenetre recue), exchange_closed (stockage ferme avant chargement), interrupted / cancelled / disconnected (tentative interrompue), timeout (ouverture ou contenu non confirme). Aucun nouvel essai de code automatique.
Entree maison : exemple¶
local doorCell = 123 -- remplacer par la cellule de votre porte
local selected = nil
for _, house in ipairs(map.houseInstances()) do
if house.cellId == doorCell then
if selected then error("Plusieurs maisons : choisir un instanceId") end
selected = house
end
end
if not selected then error("Informations de maison indisponibles") end
local ok, reason = map.enterHouse(doorCell, nil, selected.instanceId)
if not ok then error("Entree non confirmee : " .. reason) end
Exemple sans code. Pour une maison protegee dont vous connaissez le code, remplacer nil par une chaine telle que "001234". Ne pas afficher le code dans les logs ni le publier dans un script partage. Pour plusieurs instances, selectionner celle souhaitee dans houseInstances() ; ne pas choisir arbitrairement la premiere.
Entree maison : resultats¶
Raisons usuelles : code_required (code demande mais absent), wrong_code (code refuse), invalid_code / code_too_long (format/longueur), instances_unavailable (liste non recue), instance_required (plusieurs maisons), invalid_instance / not_house (cible incorrecte), no_path (porte inaccessible), action_rejected (entree refusee), unexpected_map (destination differente de la maison choisie), busy / not_ready (personnage indisponible), stale_map / interrupted / cancelled / disconnected (contexte interrompu), timeout (confirmation non recue). Ne pas enchainer automatiquement les tentatives apres un refus ou un timeout.
Maisons et coffres dans le MapViewer¶
-- Porte : clic droit ou appui long > Entrer dans la maison
-- Coffre : clic, ou clic droit / appui long > Ouvrir le coffre
Le panneau de porte affiche les instances, leur proprietaire et la serrure. Choisir une instance si necessaire, puis saisir le code optionnel pour entrer. Sur la carte interieure, cliquer sur le coffre ouvre un panneau avec son propre code optionnel, sans selection d'instance. Les codes sont masques et ne sont pas memorises par l'interface. Les erreurs et interruptions restent visibles ; la fenetre ne se ferme sur un succes qu'apres confirmation. Le contenu du coffre utilise ensuite le panneau Banque / coffre, avec les operations de stockage existantes.
Limites des interactifs generiques¶
Utiliser map.enterHouse() pour la porte et son instance, puis map.openHouseChest() pour un coffre sur la carte interieure. Ces appels gerent la demande de code et attendent la confirmation adaptee ; map.useInteractive() ne fournit pas ces garanties. Achat, vente et changement de serrure restent hors de cette API. Les enclos multi-instance ne sont pas couverts ; utiliser le Client natif pour ces variantes.
map.isWalkable / getWalkableCells¶
returns boolean / table
Verifie si une cellule est marchable / liste des cellules marchables.
map.getX / getY¶
returns number
Coordonnees d'une map depuis son ID (game data).
map.hasChanged¶
returns boolean
True si la map a change. Se remet a false automatiquement.
map.openZaap / openZaapi¶
blocking · returns boolean
Approche le zaap/zaapi avec le pathfinding officiel, ouvre son menu et attend la liste des destinations. Retourne true quand la liste est recue, false si aucune liste n'arrive sous 10 s.
map.useZaap / useZaapi¶
blocking · returns boolean
Selectionne une destination dans le menu deja ouvert (WU pour un zaap, Wu pour un zaapi) et attend le changement de carte. Ces fonctions n'approchent pas de l'objet et ne l'ouvrent pas : appeler openZaap()/openZaapi() juste avant. En cas de timeout de 10 s, useZaapi() retourne false tandis que useZaap() leve actuellement une erreur Lua ; utiliser pcall pour un script tolerant aux echecs.
Sequence zaap recommandee¶
if not map.openZaap() then return false end
local ok, result = pcall(map.useZaap, mapId)
return ok and result == true
blocking · returns boolean
Enchainement autonome et tolerant aux echecs recommande. Pour un zaapi, utiliser openZaapi() puis useZaapi(mapId).
map.getZaapDestinations¶
returns table of {map_id: number, cost: number, name: string, area: string, x: number, y: number}
Liste des destinations disponibles apres openZaap() ou openZaapi().
map.saveZaap¶
Sauvegarde le zaap actuel.
map.getPrisms¶
returns table of {id: number, cellId: number, level: number, name: string, alignment: number, alignmentName: string, usable: boolean, reason: string?}
Prismes d'alignement presents sur la carte (sprite -10). alignment : 1 = Bonta, 2 = Brakmar. usable applique la regle du client officiel : le menu « Utiliser » n'est actif que pour un personnage du meme alignement que le prisme, jamais pour un neutre ni sous forme de mutant, et hors combat. reason explique un refus.
map.openPrism¶
blocking · returns boolean, string?
Clique « Utiliser » sur le prisme (GA512) et attend sa fenetre de teleportation (Wp). Activer d'abord les ailes avec character.setWings(true) : le serveur peut refuser GA512 sans elles (Im1144). Sans actorId, prend le prisme de la carte. Comme dans le client officiel, aucun deplacement n'est necessaire. Retourne true quand la liste est recue, sinon false et la raison (alignement, combat, fenetre deja ouverte, pas de reponse en 10 s). Tant que la fenetre est ouverte, les deplacements sont refuses : appeler map.closePrism() si l'on ne se teleporte pas.
map.getPrismDestinations¶
returns table of {map_id: number, cost: number, attack_near: boolean, name: string, area: string, x: number, y: number} or nil
Destinations de la fenetre du prisme ouverte (nil si elle est fermee). attack_near vaut true quand le client affiche l'icone « prisme attaque a proximite ».
map.usePrism¶
blocking · returns boolean, string?
Teleportation complete par prisme : ouvre la fenetre si besoin, verifie que la carte est proposee et que les kamas suffisent (comme le client), envoie Wp
map.closePrism¶
returns boolean
Ferme la fenetre du prisme (Ww). Retourne false si aucune n'est ouverte.
Exemple — se teleporter par prisme¶
-- Prisme de la carte -> destination en (x, y), si le prisme la propose.
local function prismeVers(x, y)
local prisme = map.getPrisms()[1]
if not prisme then return false, "aucun prisme sur cette carte" end
if not prisme.usable then return false, prisme.reason end
local ailesOk, raisonAiles = character.setWings(true)
if not ailesOk then return false, raisonAiles end
local ok, raison = map.openPrism(prisme.id)
if not ok then return false, raison end
for _, d in ipairs(map.getPrismDestinations() or {}) do
if d.x == x and d.y == y then
return map.usePrism(d.map_id)
end
end
map.closePrism()
return false, "destination absente de la liste du prisme"
end
blocking · returns boolean, string?
Active les ailes et teleporte vers la carte (x, y) depuis le prisme de la carte courante, si l'alignement du personnage le permet.
map.sendEmote / sit¶
Envoie une emote. sit() = emote 1.
Deplacement et combat — aliases¶
returns boolean
moveTo est un alias de moveToCell. Les fonctions tryFight ne lancent le combat que si le groupe cible est toujours present.
Informations de zone et distance¶
returns table / number / number
zoneInfo decrit la zone courante et worldDistanceToMap calcule une distance de monde. neighbourId est un stub historique et retourne 0.
Utilitaires de carte¶
returns boolean
Ferme l'interface zaap/zaapi ou envoie l'emote texte historique de slap.
Groupe de jeu¶
returns boolean
Inviter un joueur au groupe, quitter, accepter/refuser l'invitation en attente. acceptGroupInvite et declineGroupInvite retournent true seulement si une invitation etait reellement en attente ; sinon rien n'est envoye et le retour est false.
map.getPendingGroupInvite¶
returns inviterId: number, inviterName: string | nil
Invitation de groupe recue et pas encore traitee. Retourne 0, nil s'il n'y en a pas. Le paquet du jeu ne porte que des noms : inviterId vaut l'ID du joueur s'il est visible sur la map courante, sinon -1 (l'invitation est bien en attente, testez ~= 0). Les invitations traitees automatiquement (chef de groupe MoonBot, mode prive) ne sont pas exposees. L'invitation disparait quand elle est acceptee/refusee, quand le bot rejoint un groupe ou quand l'inviteur l'annule.
map.waitForGroupInvite¶
blocking · returns inviterId: number, inviterName: string | nil
Attend une invitation de groupe (retour immediat si une est deja en attente). Retourne 0, nil au bout du timeout (defaut 60000 ms). Exemple : local id, name = map.waitForGroupInvite(30000) if id ~= 0 then delay(math.random(1500, 4000)) map.declineGroupInvite() end
Infos groupe de jeu¶
returns table / number / boolean / number / boolean
getPartyMembers()→table of {id: number, name: string, class_id: number, sex: boolean, level: number, life_percent: number}. getPartyCount()→number. isInParty()→boolean. getPartyLeaderId()→number. isPartyLeader()→boolean.
Defis entre joueurs¶
returns boolean
Proposer un defi amical, accepter/refuser le defi en attente, annuler son propre defi. acceptChallenge et declineChallenge visent le defi en attente (id optionnel pour ne repondre qu'a ce joueur) et retournent true seulement si un defi etait reellement en attente ; sinon rien n'est envoye et le retour est false.
map.aggressPlayer¶
returns boolean
Demande une agression PvP contre un autre joueur visible sur la carte courante. target est son ID positif ou son nom exact (sans distinction de casse). L'appel Lua lance directement la demande ; le bouton de la MapViewer demande une confirmation. Retourne false si la cible ou l'action est indisponible, true si la commande est mise en file (le serveur peut encore la refuser). Les restrictions d'agression, l'etat du personnage et la presence de la cible sont reverifies avant envoi ; une commande devenue perimee lors d'un changement de carte est abandonnee. Exemple : local queued = map.aggressPlayer(123456). Accepte aussi map:aggressPlayer(target).
map.getPendingChallenge¶
returns challengerId: number, challengerName: string | nil
Defi PvP recu et pas encore traite. Retourne 0, nil s'il n'y en a pas. Le defi disparait quand il est accepte/refuse/annule, au changement de map et au debut d'un combat. En mode prive le defi est refuse automatiquement et n'est pas expose.
map.waitForChallenge¶
blocking · returns challengerId: number, challengerName: string | nil
Attend un defi PvP (retour immediat si un defi est deja en attente). Retourne 0, nil au bout du timeout (defaut 60000 ms). Exemple : local id, name = map.waitForChallenge(30000) if id ~= 0 then delay(math.random(2000, 5000)) map.declineChallenge(id) end
map.joinableFights¶
returns table of {fightId: number, teamId: number, fighters: table of {id: number, name: string, level: number}}
Liste les combats joignables visibles sur la map (1 entree par equipe, teamId negatif). fightId est synthetique : plus petit |teamId| de la paire (les 2 equipes d'un meme combat partagent le meme fightId).
map.joinFight¶
returns boolean
Rejoint une equipe d'un combat en cours sur la map. teamId vient de joinableFights() (ex: -862).
map.exchangePlayer¶
Demande un echange avec un joueur.