// ==UserScript==
// @name Tout_MZ
// @namespace MH
// @description Client MountyZilla
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAAUDBQwKBxQKBBwKEBkTBBwaJCQUBCQcCS4cBzASBDwWBDIeGCQGJDweLCwjETQkDjQqFDw0HDQqNDw2NEAeFEAlCkIsCkElF0EsFkwpEUwuHEQzFkw0ElwtH1w6BFQ1EVM8FVw5F14+GEEqLEwiNEE1J0wzLE88LFgsNFQzKV40Jl88KWw+HGQzN2E7N2w2NEQ+THA+QFRDIFZELFxCIFxKJFxNMl9VP2dEGmRLGXRLF2dEKWhMJ2ZENGdNOmJSLmxUK2xXP3RKLHdMP3BeKHdaL3pUInRfOnhVMWRaRGheSH9FR3dVQ3ZaQHReRnRmTHxhRn9pV39xZ4A8RIRMOIRXKYxWJIxfJ4xaPIBgKYFgNoNnNY9oMY1pPoRwNJBhNpFvPZxvPpxwMpx3P6RsOKRyPKR4O4RNSIxGVJBSRJZYT4NnRo9gRIRiVIxiXIRwR45wToRwVIR2WJBnTpxnRJR4QJx+RJJ4U5R+VJxwVpx9UIxqYIxyZI94YZJ+YJx+YpR+cKluSad6T6d+T6l+Qax6QLRuTLR+QLR6XKR4YKR+bJ+FObCEO52DXYyCZJCEbJyKfKOESqGNX6yFWK+MXbKER7GMSbyDRryNR7SFXLyLWbyTT7SUXbyaVKGDcayUYK6QbqSRda+YeLSaZLyWYbyZb7efd7ySfLqgZrymcMSRQcSRT8SXTcyXTMufU8maXMeVY9ShW9imX8agbcugYMyqbMSmfsimccqsf9ambNSrZdytZtSseNyybNyweOC3dey+f4yOnJSGiKyKhKyYiLSSlLCgiLSmjLylibSqlLasnryskLyyqLy2xMSihMWskc+0gceyl8i2mNS4k9S+mNy5ksi5psq+ptS8qNy+tOS+gOC+lNzClMzCrNTEp9TKrN/Eo9jFt9rMtuTEjOzDi/DLlPzKnPTVmuDLqO7NqOTOtuzSoePTuvDVsPvdtPzevPzisOTaw+zUwe/cwu3dzeTa1Pbjw/TmzPzmzvzuxPvr1Pzy2fz35/z+9AAAAEG26sQAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7CAAAOwgEVKEqAAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4wLjOM5pdQAAAGpElEQVRIS3WVD1wT5xnHwdUVWjacW9XQ4Ay6mipqV4MYyRlgeJBVtGrrXBKoiXRxBWxo1WXEqRXoulbSDUkiGqZAhVlJAiFX/oSYuI6mTLryJzUytTQ5SE0woHAsSd9j7EISTJT9Pnef5O6e7+d9nz/v80TMzKcJ4vZ6/f8f0byA2+QBAJsMPIVrPgC4unFsEP0POgoCb+YEwHyAt6fO9hWGT0+jk48QwNUzD4D3J4lu251O5323wxN45xcY+jP2OIBbSBKjpvl8/Q3tLac1ZAkAHNwB/DEAR2lS7YEDfHaaBBbobwQIL/EzeYNXiz/qNHCPMivfTaGvjIshQXACz9DqIqJLhMxhba/IvEDsMAwAU66b74jY8fE02s6XxLxqmCI3mKe9k6OD7cPVXHqWi1gnDJhAMeeO5zZGXXca9H36yuqa+N9ViD4UVUjlytPbIFENRtiEAhiKtZftQKVv3Ws8myNuq79YKTpDid4k5qZx2XDq7z/q9cUsFEBd7Tnxe77LO26WSYUFJ0XaUvFRFpmzS1TfWl8i7euz+QIQCngGoGcXbn5Qmd4ugeITV1MvZm08mgtxahrqilrtw87BKZ9RuA806o+//3bq5peTf/LzPSTG0qjVUAJLUl0vhaX3xlB0NsJhgGtVDHUXPTryiU//9feXYkm7agqfYRZIeq3adgxDv/HbhAL48Zi64Za9UYvWrGEyIRhyOHjiHSdQYL73wG2Z8GcwFAA26pC9hU1axjiULhR1s3giWFtd5PgcM1swy1zhhgKmz+82yzctJtcWFTR0pwspDL09Ncssue29iWFB+1AAN7VpK7kbY6Ph9LdS02tEsUkNPTRR20AtioGHp+8hgHc9ly7kMVY9sWzFy5bS/SIJZ8ni2B9JHA6LryLmNAeAgRN1EmHiD3+wujY5Op7COipnc5PJ5LQTJhBqPwcAy8d3jTr51lXH+h4c/+lpYZ4MptRB2hK4ogEPO0UBALi67C1NVQJ+cycy3MC+XCfN48HiZO5eurTPn7CggoBpuFOlbGxENE2I/njMSs4+saQoOyq1Gkq73D7PCvjN1hG1SqVSNjUXM0kLnqSXCugwi0rKkm6BOdqw5uEHQJdV5wNapBsWREZGbuTw8pI4/ByYDlfwc5tNjwHeyW57CwF0Nq+JjFwYtZDGgOvTuI1yAb/k/JH89485QohZAPx70K5TqzsNGd9bsGjRCgqtIO6AXNGmVZz9Y/5vX3yzuAaftZ1VALDZr3Yavn1/2ZMMiJ7CyTpDl6k62trUZ0/lv5KRnlHY+7DR+oH+HvzuvfG/rSdlCtj7c3icPq5cqdFfrpadyj+YuPPF7X/qm8u2H3Blf2azntwaBwnKeILSbtbFitN/RZDLFysOH8zftfXgkcYRR7D8ZoEZ0Lth/dq1MYvS+GV5PGl3Lixmy5s6Pvm44kj+YeHWQuSWEwumzw98d/PCH06KukzUndvgJEkuFyqAfoMYblsr39jOpK4vREbGgCuQPj/g6f3HByezPzicben5cHMydSmZxeLpjE5n9ivPpzNfKOkYGQdfYziOE67PAtO2C8UU8tIV8UuSsk7Umfp3xybmZiLG+wOJr65//mcZMt3I2HQtaefuWsIRHzBt2XMoDuKWyWT8fSkUyqYzPe8sZaXIDO6eTH7hwe2vNiFGO/72U8uXr81GfQMFdJGfSYK1ROY0KqWy/LUt8TuOQfp1ZYZxS+6l+uJzJUqdcWScxsjPf2P5bgIAJg68hDncqfQVn1KtuVKembghtyRFph9zceq1JeebEN1Ve83KPNmpvUUOEOEZ7dX/KmHgLqJUNaqUGm0rckWw8hfbEnhKg9OTxZFfamrp0F2tZu2vUr7OHyJ88Ixixl8Lh+7riNNwRYm0tSLKqn3wFnY5MuL97y9JcJ5coZALeLz3zr5e4psuEa5Dfbc4wtfM9mvGlsYqRUcH0qQSHJCX6+xW9PpiMo2Tk1dWXi57793SL2eTHdHPWsfJTYQozALxJY1GTVxqZXl5y1V9EZVMToI4ZQo1olYotOZAbUTMuBrERQlLoqOfejqOUXyuqpHYgEDxyY3eAfQbq9V6x2y+fcfhwnxDLgAAAMa+6v4L81wZn7WOkcFicY5+dAfz4tM4Tnxye9xTYX1mNtNegIOucWOnRrY/Ey6oG5xwT019gdps6KjLHdYBCPlricjeP4fG7deuIdKGUa9vcExd//QLFO1/2FODCgJet8VC7Hhg0BM0mQDA65uCjygIENuasKFE2w08/h/NzPwPOHaIyvrbq40AAAAASUVORK5CYII=
// @match http://games.mountyhall.com/*
// @match https://games.mountyhall.com/*
// @exclude *trolls.ratibus.net*
// @exclude *it.mh.raistlin.fr*
// @exclude *mh2.mh.raistlin.fr*
// @exclude *mhp.mh.raistlin.fr*
// @exclude *mzdev.mh.raistlin.fr*
// @version 1.5.17
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_setValue
// ==/UserScript==
// vérif UTF-8 ş
/** *****************************************************************************
* This file is part of Mountyzilla. *
* *
* Mountyzilla is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* Mountyzilla is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Mountyzilla; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
*******************************************************************************/
var MZ_latest = '1.5.17';
var MZ_changeLog = [
"V1.5.x \t\t 23/09/2024",
" - Multiples correctifs suites aux mises à jours MH",
"V1.4.11 \t\t 06/05/2024",
" - Remise en route des Jubilaires",
"V1.4.10 \t\t 05/05/2024",
" - Compte à rebours aussi pour la DLA suivante",
"V1.4.8 \t\t 02/05/2024",
" - remise en route de l'avertissement pour les DE et TP près d'un trou",
"V1.4.7 \t\t 28/04/2024",
" - Possibilité d'afficher le compte à rebours dans le titre (voir dans les options)",
"V1.4.4 \t\t 25/04/2024",
" - Affiche les infos MZ dans la page profil mobile",
"V1.4.3 \t\t 14/04/2024",
" - Corrige l'affichage des trolls hors-vue",
" - Permet le scroll des options Mountyzilla en affichage vertical (et accel pour les kastars)",
" - N'essaie plus d'afficher les infos trolls en vue spécifique (monstre, trésors, etc.)",
" - Affiche directement les derniers changements sur la page de nouvelles",
"V1.4.2 \t\t 10/04/2024",
" - Ajoute la possibilité d'afficher les rapports d'erreurs directement en jeu",
"V1.4.1 \t\t 09/04/2024",
" - Affichage de version hors Greasemonkey",
" - Meilleur gestion des popup et diverses insertions en version smartphone",
"V1.4.0 \t\t 05/04/2024",
" - Refonte générale du script tout MZ",
" - Meilleur support de MH en mode smartphone",
"V1.3.1.41 \t 27/03/2024",
" - Meilleur affichage des trolls hors-vue (interface tactique)",
"V1.3.1.40 \t 26/03/2024",
" - Affichage des fatigues optimales dans le profil",
"V1.3.1.27 \t 07/12/2023",
" - Adaptation don de PX",
"V1.3.1.24 \t 04/11/2023",
" - Fix effet armure de pierre",
"V1.3.1.23 \t 21/10/2023",
" - Fix vue externe avec emoticone dans un nom de Gowap",
"V1.3.1.20 \t 17/08/2023",
" - NOM_TROLL en LocalStorage",
"V1.3.1.19 \t 13/08/2023",
" - NOM_TROLL en LocalStorage",
"V1.3.1.18 \t 18/06/2023",
" - modif ID HTML titre2",
"V1.3.1.17 \t 18/04/2023",
" - Fix le N de sortie de TP",
"V1.3.1.16 \t 16/04/2023",
" - Ajustement modif MH",
"V1.3.1.15 \t 28/03/2023",
" - Remise en route analyse résultat CdM",
"V1.3.1.14 \t 26/03/2023",
" - Correction attaque Rotobaffe",
"V1.3.1.11 \t 03/03/2023",
" - Préparation pour l'affichage des couleurs du pogo'",
"V1.3.1.10 \t 06/02/2023",
" - Adaptation à un changement de présentation MH (recherche de compo en tanière)",
"V1.3.1.9 \t 19/12/2022",
" - Ajout de l'affichage des compos sur l'équipement d'un suivant et traitement de la limitation à 100 réponses",
"V1.3.1.7 \t 17/12/2022",
" - Ajout de l'affichage des compos en tanière à l'historique d'un compo",
"V1.3.1.6 \t 28/11/2022",
" - Nouvelles caractéristiques de l'équipement",
"V1.3.1.5 \t 16/11/2022",
" - Correction vue externe, troll manquant",
"V1.3.1.4 \t 07/11/2022",
" - Correction appel Anatrolliseur si DLA nombre exact d'heures",
"V1.3.1.3 \t 20/08/2022",
" - Pilotage externe de certaines options",
"V1.3.1.2 \t 18/08/2022",
" - Enrichissement de la page des suivants",
"V1.3.0.99 \t 23/07/2022",
" - Mémorise si on veut la vue SCIZ ou pas dans les Events",
"V1.3.0.98 \t 28/06/2022",
" - Fix pb suite à changement de présentation de la vue",
"V1.3.0.97 \t 18/06/2022",
" - Fix tableau de Fatigue et AM dans certains cas",
"V1.3.0.96 \t 18/04/2022",
" - Ajout de la gestion des portails pour SCIZ",
"V1.3.0.95 \t 16/04/2022",
" - Corrections du cas de soit-même dans la vue pour SCIZ",
"V1.3.0.94 \t 22/03/2022",
" - Fix message quand la réserve de temps de tour est exactement 0",
"V1.3.0.93 \t 20/02/2022",
" - Ajout guilde et mention 'HORS VUE' pour les trolls de la coterie SCIZ",
"V1.3.0.92 \t 29/01/2022",
" - modif suite à changement MH sur les CdM",
"V1.3.0.91 \t 16/01/2022",
" - Correction BM vue, PVMax en %",
"V1.3.0.89 \t 05/01/2022",
" - Corrections variées pour SCIZ",
"V1.3.0.88 \t 01/01/2022",
" - Fix cacher les gowaps au même niveau",
"V1.3.0.87 \t 01/01/2022",
" - Adaptation aux modifs MH pages des suivants",
"V1.3.0.86 \t 31/12/2021",
" - Corrections pour SCIZ",
"V1.3.0.85 \t 31/12/2021",
" - Amélioration du support SCIZ (trolls cachés ou hors-vue)",
"V1.3.0.84 \t 29/12/2021",
" - Corrections pour SCIZ",
"V1.3.0.83 \t 29/12/2021",
" - Amélioration du support SCIZ (bestiaire, champignons et pièges)",
"V1.3.0.82 \t 14/11/2021",
" - fix nom monstre marqué avec un nombre",
"V1.3.0.81 \t 14/11/2021",
" - fix CdM sans date dans les messages du bot",
"V1.3.0.80 \t 20/10/2021",
" - fix plantage à l'affichage du profil publique en cas de CSS avancé",
"V1.3.0.79 \t 14/07/2021",
" - Correction effet venin GdS",
"V1.3.0.78 \t 17/06/2021",
" - Correction affichage des trésors en vue externe",
"V1.3.0.77 \t 23/04/2021",
" - Ajout d'une icône pour les monstres qui volent (=lévitent)",
"V1.3.0.76 \t 23/03/2021",
" - Correction pour SCIZ (surcharge des événements)",
"V1.3.0.75 \t 11/03/2021",
" - Masquer en vue externe les monstres masqués dans la vue",
"V1.3.0.74 \t 18/01/2021",
" - Support ancien Firefox",
"V1.3.0.73 \t 15/01/2021",
" - Adaptation à Dist H/V MH",
"V1.3.0.72 \t 11/01/2021",
" - Correction de la vue des trolls avec SCIZ",
"V1.3.0.71 \t 11/01/2021",
" - Amélioration du support SCIZ (Vue trolls)",
"V1.3.0.70 \t 08/01/2021",
" - adaptation vue externe dist H/V",
"V1.3.0.69 \t 25/12/2020",
" - Fix (tentative) message d'erreur sur armM_phy dans la vue",
"V1.3.0.68 \t 10/12/2020",
" - Limitation vue externe",
"V1.3.0.66 \t 07/12/2020",
" - Options en mode smartphone",
"V1.3.0.65 \t 30/11/2020",
" - Fix mémorisation des missions (donc cibles plus affichées) + fix filtre en mode smartphone",
"V1.3.0.63 \t 20/11/2020",
" - Ajout du calcul de la marge de temps de tour dans le profil (nommé marge ou augmentation)",
"V1.3.0.60 \t 16/11/2020",
" - Vue externe en mode smartphone",
"V1.3.0.59 \t 08/11/2020",
" - Adaptation page Bonus-Malus",
"V1.3.0.58 \t 01/11/2020",
" - Remplacement CONST par VAR dans SCIZ",
"V1.3.0.57 \t 30/10/2020",
" - Fix mouches présentes",
"V1.3.0.56 \t 08/10/2020",
" - Retour de la carte des suivants",
"V1.3.0.55 \t 05/09/2020",
" - Ajout compte à rebours de DLA",
"V1.3.0.54 \t 28/08/2020",
" - Supprime le déplacement de la page de vue au survol de la souris du titre \"INFORMATIONS\"",
"V1.3.0.53 \t 20/07/2020",
" - Correction de la vue smartphone",
"V1.3.0.51 \t 23/06/2020",
" - Correction de la vue",
"V1.3.0.47 \t 23/06/2020",
" - Correction blessure",
"V1.3.0.46 \t 23/06/2020",
" - Adaptation réserve de temps",
"V1.3.0.45 \t 17/06/2020",
" - Pas de reset (erroné ?) fatigue en affichage profil",
"V1.3.0.44 \t 13/06/2020",
" - Remplacement CONST par VAR à cause de IOS (bug ?)", // voir https://stackoverflow.com/questions/37228892/why-is-my-javascript-not-working-correctly-in-strict-mode-on-safari
"V1.3.0.43 \t 11/06/2020",
" - Affichage callstack en erreur profil",
"V1.3.0.42 \t 18/05/2020",
" - Amélioration du support SCIZ (Mise en option des fonctionnalités)",
"V1.3.0.41 \t 15/05/2020",
" - Amélioration du support SCIZ (Vie des trolls de la coterie)",
"V1.3.0.40 \t 13/05/2020",
" - Correction ARM dans le cas d'un grosse perte pour le tour",
"V1.3.0.39 \t 08/05/2020",
" - Correction erreur sur le profil en mode smartphone",
"V1.3.0.38 \t 25/04/2020",
" - Amélioration du support SCIZ (Gestion des trésors cachés)",
"V1.3.0.37 \t 19/04/2020",
" - Suite travail sur l'envoi de CdM en mode smartphone",
"V1.3.0.36 \t 20/04/2020",
" - Amélioration du support SCIZ (Icônes pour les événements !)",
"V1.3.0.35 \t 19/04/2020",
" - Ignorer l'absence de date/heure des CdM et gestion smartphone",
"V1.3.0.33 \t 14/04/2020",
" - Correction fausse reconnaissance de CdM sur les autres compétences",
"V1.3.0.32 \t 14/04/2020",
" - Adaptation page des ordres des suivant + [état et callback] pour les",
" scripts tiers (voir doc sur le mot clef MZ_callback_init)",
"V1.3.0.31 \t 22/03/2020",
" - Envoi des CdM à partir du message du Bot",
"V1.3.0.30 \t 22/03/2020",
" - Amélioration du support SCIZ (Trésors dans la vue !)",
"V1.3.0.29 \t 14/03/2020",
" - Fix calcul PV après blessure en cas de maxPV inconnu",
"V1.3.0.28 \t 13/03/2020",
" - Fix la détection incohérence CdM et affichage en rouge",
"V1.3.0.27 \t 20/02/2020",
" - Ajout de la probabilité de toucher avec Lancer de Potion dans la Vue",
"V1.3.0.26 \t 08/02/2020",
" - Lisibilité CdM en mode smartphone",
"V1.3.0.25 \t 07/02/2020",
" - Adaptation basique au profil modifié",
"V1.3.0.23 \t 30/01/2020",
" - Correction affichage filtre monstre",
"V1.3.0.22 \t 23/01/2020",
" - Re-adaptation re-modif MH (affichage des durées négatives)",
"V1.3.0.21 \t 21/01/2020",
" - Adaptation à une modif MH dans la page des suivants",
"V1.3.0.20 \t 21/01/2020",
" - Adaptation modif MH (affichage des durées négatives)",
"V1.3.0.19 \t 19/01/2020",
" - Centralisation des éléments tactiques",
"V1.3.0.18 \t 19/01/2020",
" - Correctif pour les icônes d'action à distance dans la vue",
"V1.3.0.17 \t 16/01/2020",
" - Correctif pour le recall du filtre des Monstres",
"V1.3.0.16 \t 10/01/2020",
" - Amélioration du support SCIZ (Fix sur le prettyprint)",
"V1.3.0.15 \t 10/01/2020",
" - Amélioration du support SCIZ (Fix sur les événements de zone)",
"V1.3.0.14 \t 06/01/2020",
" - Correction filtre par famille pour les monstres variables et sans cdm",
"V1.3.0.13 \t 06/01/2020",
" - Ajout du filtre sur la famille des monstres",
"V1.3.0.12 \t 28/12/2019",
" - Fixed bug fix pour SCIZ (JWT)",
"V1.3.0.11 \t 28/12/2019",
" - Bug fix pour SCIZ (JWT)",
"V1.3.0.10 \t 22/12/2019",
" - Corrections mineures pour SCIZ",
"V1.3.0.9 \t 19/12/2019",
" - Amélioration du support SCIZ (Fixes + AdvancedCSS + SwitchEvent)",
"V1.3.0.8 \t 16/12/2019",
" - Amélioration du support SCIZ (Fixes + Play_evenement + PJView_Events)",
"V1.3.0.7 \t 12/12/2019",
" - correction cibles des missions 'famille', 'pouvoir' et cas particulier de 'race'",
"V1.3.0.6 \t 11/12/2019",
" - suppression infobulle sur l'intervalle de confiance s'il n'y en a pas,",
" correction affiche de l'heure dernière CdM, plus de debug en profil de monstre",
"V1.3.0.5 \t 11/12/2019",
" - Première interconnexion avec SCIZ (Options + MonsterView)",
"V1.3.0.4 \t 29/11/2019",
" - Ajout des déciles",
"V1.3.0.3 \t 29/11/2019",
" - Affichage d'une icône pour les Phœnix dont la génération est connue",
"V1.3.0.2 \t 24/11/2019",
" - Réduction taille info CdM",
"V1.3.0.1 \t 22/11/2019",
" - Ajustements sur les infos tactiques",
"V1.3.0 \t\t 15/11/2019",
" - Refonte calculs tactiques de la vue - beta",
"V1.2.20.6 \t 09/11/2019",
" - Correction de la formule d'AdD dans le profil",
"V1.2.20.5 \t 16/10/2019",
" - Mutualisation analyse ordres suivants MZ_analyse_page_ordre_suivant",
"V1.2.20.4 \t 03/10/2019",
" - Adaptation modif MH de la page des suivants",
"V1.2.20.3 \t 02/09/2019",
" - Compétence golem vers l'anatroliseur",
"V1.2.20.2 \t 25/05/2019",
" - Gestion des Parasitus pour les missions",
"V1.2.20.1 \t 25/05/2019",
" - Correction de la cible en cas de mission demandant un kill de Crasc + message d'alerte en cas de fumeux",
"V1.2.20.0 \t 25/05/2019",
" - Adaptation aux modifications des CdM par MH",
"V1.2.19.2 \t 16/04/2019",
" - Correction majuscules dans les talents",
"V1.2.19.1 \t 14/04/2019",
" - Prise en compte des nouvelles AdX dans profil2",
"V1.2.18.15 \t 29/03/2019",
" - Correction simple quote dans toutes les missions",
"V1.2.18.14 \t 09/03/2019",
" - Correction affichage vues 2D externes suite à une modif MH",
"V1.2.18.13 \t 27/02/2019",
" - Correction simple quote dans les familles de monstre des missions",
"V1.2.18.12 \t 23/12/2018",
" - Message si \"Menu d'actions contextuelles\" est décoché",
"V1.2.18.11 \t 21/11/2018",
" - Correction it bricol'troll, login avec accent",
"V1.2.18.10 \t 08/08/2018",
" - Correction boulette sDiplo",
"V1.2.18.09 \t 04/08/2018",
" - Protection contre diplomatie mal initialisée",
"V1.2.18.08 \t 11/07/2018",
" - Correction pour fonctionnement hors GM",
"V1.2.18.07 \t 18/05/2018",
" - prise en compte bonus magique d'esquive dans le profil, correction",
" gestion de la souris dans la page d'équipement [Dabihul, welcome back]",
"V1.2.18.06 \t 28/01/2018",
" - Protection malus Crasc sans durée",
"V1.2.18.05 \t 18/11/2017",
" - Désactivation MZ V2 en mode dev pour les tests d'adaptation violentmonkey",
"V1.2.18.04 \t 04/09/2017",
" - retour version 1.2.18.02 avec GM 3.17",
"V1.2.18.03 \t 01/09/2017",
" - Désactivation de GM_setValue/getValue à cause d'une lenteur sur GM 3.16",
"V1.2.18.02 \t 26/08/2017",
" - correction boulette sur le compos d'enchantement",
"V1.2.18.01 \t 25/08/2017",
" - Suppression des messages sur les certificats en https",
" - Protection contre des erreurs dans le stockage des compos d'enchantement",
"V1.2.17.19 \t 23/08/2017",
" - Possibilité de plusieurs IT Bricol'Troll",
"V1.2.17.18 \t 22/08/2017",
" - Adaptation compétence 'travail de la pierre' (dont anatrolliseur)",
" - Accélération de l'affichage des niveaux si plus de 500 monstres",
"V1.2.17.17 \t 16/07/2017",
" - modification du mécanisme de filtrage pour contourner un pb",
"V1.2.17.16 \t 16/07/2017",
" - Ajout de messages de debug sur les retours AJAX",
"V1.2.17.15 \t 15/07/2017",
" - modification du mécanisme de filtrage pour contourner un pb",
"V1.2.17.14 \t 14/07/2017",
" - correction dans la gestion des étapes de mission",
"V1.2.17.13 \t 12/07/2017",
" - Adaptation au déplacement des colonnes dans la vue des Trõlls",
"V1.2.17.12 \t 16/06/2017",
" - Correction mauvais compte de PX quand on change de Trõll",
"V1.2.17.11 \t 01/05/2017",
" - Travail sur le fonctionnement hors Greasemonkey",
"V1.2.17.10 \t 30/04/2017",
" - Protection dans la récupération d'erreur",
"V1.2.17.9 \t 30/04/2017",
" - Correction récupération d'erreur IT Bricol'Troll",
"V1.2.17.8 \t 29/04/2017",
" - Correction Bonus/Malus cas +0\+10 (AE)",
" - Correction portée IdC",
" - Prise en compte du bonus de portée PM dans le calcul tactique",
"V1.2.17.7 \t 26/04/2017",
" - Version compatible hors GreaseMonkey",
"V1.2.17.6 \t 23/04/2017",
" - Correction gestion des missions en cas de réinstallation",
"V1.2.17.5 \t 20/04/2017",
" - Correction de la récupération du niveau du Trõll pour le calcul des PX",
"V1.2.17.4 \t 08/04/2017",
" - Affichage triangle camou/invi pour les Trõlls de l'IT vus (sous VlC)",
" - Adaptation de la diplomatie à une modification de la page MH",
"V1.2.17.3 \t 04/04/2017",
" - Messages console en cas de cadre d'erreur",
" - Trolls de l'IT mais pas dans le vue en orange",
"V1.2.17.2 \t 20/03/2017",
" - Correction des PV restants",
"V1.2.17.1 \t 20/03/2017",
" - Blocage des PV restants en attendant résolution de bug",
"V1.2.17 \t 19/03/2017",
" - Refonte de l'envoi des CdM",
" - Modification de l'analyse de la frame de gauche (suite modification MH)",
"V1.2.16.4 \t 08/03/2017",
" - correction ID de troll en envoi de PX/MP",
"V1.2.16.3 \t 27/02/2017",
" - correction bonus/malus FP",
"V1.2.16.2 \t 24/02/2017",
" - corrige bug des cases à cocher qui n'étaient plus mémorisées",
"V1.2.16.1 \t 21/02/2017",
" - corrige bug sur Fx 38.8 ESR",
"V1.2.16 \t 21/02/2017",
" - double stockage GM + localStorage version Vapulabehemot en préparation du passage HTTPS",
" - possibilité de masquer les Gowaps Sauvages dans la vue",
" - calcul des caractéristiques du siphon des âmes",
"V1.2.15.2 \t 02/02/2017",
" - adaptation décumul VlC (page des bonus/malus)",
"V1.2.15.1 \t 29/01/2017",
" - carte sur la page de description du lieu TP",
"V1.2.15 \t 25/01/2017",
" - mise en place des nouvelles cartes (suivants, TP)",
"V1.2.14.3 \t 25/01/2017",
" - résumé dans l'export des données Trõlligion",
"V1.2.14.2 \t 20/01/2017",
" - forcer filtrage après le chargement des niveaux des monstres dans la vue",
"V1.2.14.1 \t 20/01/2017",
" - réécriture filtrage des monstres par niveau dans la vue",
" - Changelog dans la page des news MZ",
"V1.2.14 \t 20/01/2017",
" - Ajout de l'export des données Trõlligion",
"V1.2.13.7 \t 10/01/2017",
" - Exclusion Bricoll'troll dans l'entête GM",
"V1.2.13.6 \t 08/01/2017",
" - Réécriture analyse des étapes de mission sur monstre de niveau...",
"V1.2.13.5 \t 07/01/2017",
" - Correction bug qui se manisfestait sous LINUX",
"V1.2.13.4 \t 07/01/2017",
" - Plus de traces en mode debug pour l'analyse des étapes de mission",
"V1.2.13.3 \t 07/01/2017",
" - Correction erreur sur un commentaire qui bloquait la compilation javascript",
"V1.2.13.2 \t 07/01/2017",
" - Correction missions, recherche troogle (familles et types de monstres)",
"V1.2.13.1 \t 06/01/2017",
" - Suppression oldSchoolProfile qui n'existe plus",
" - Ajout du 'refresh' du cadre de gauche",
"V1.2.13 \t 01/01/2017",
" - homogénéisation des messages d'erreur",
" - Ajout du lien Troogle sur les étapes de mission monstre",
"V1.2.12.2 \t 30/12/2016",
" - retour en mode normal (http si jeu en http)",
"V1.2.12.1 \t 27/12/2016",
" - Correction mode IP",
" - Version patch pour forcer https sur /mz.mh.raistlin.fr (http en panne)",
"V1.2.12 \t 24/12/2016",
" - Nettoyage des URL",
" - Mode dev (Shift+Click sur le mot 'Crédits' dans Options/Pack Graphique) qui se branche sur le site de dev",
" - Interface bricoll'Troll en https",
" - Remise en marche des cartes des trajets des gowaps",
"V1.2.11.5 à 7 20 \t 21/12/2016",
" - Trace et protection sur plantage remonté par Marsak (lié à la diplo dans la vue)",
"V1.2.11.4 \t 19/12/2016",
" - Changement des couleurs de la barre de vie Interface Bricol'Troll",
"V1.2.11.3 \t 19/12/2016",
" - Correction de la récupération des PI totaux (du coup la portée de TP était NaN)",
" - Interface Bricol'Troll : suppression Trõlls pas mis à jour depuis plus d'un mois et grisé ceux depuis plus de 7 jours",
"V1.2.11.2 \t 18/12/2016",
" - Correction bug interface Bricoll'Troll, n n'était pas affiché pour les Potrolls au soleil",
"V1.2.11.1 \t 17/12/2016",
" - Correction bug interface Bricoll'Troll, les potrolls n'étaient pas affichés s'il n'y en avait pas au moins un",
"V1.2.11 \t 13/12/2016",
" - Passage sur BdD Raistlin \\o/",
"V1.2.10.4 \t 12/12/2016",
" - Correction bug à la récupération d'une erreur interface Bricoll'Troll",
"V1.2.10.3 \t 09/12/2016",
" - Adaptation à une modification du HTML MH (voir set2DViewSystem)",
"V1.2.10.2 \t 09/12/2016",
" - positionnement des Trõlls camou/invi à la bonne position par rapport à la distance",
"V1.2.10.1 \t 08/12/2016",
" - option pour affichage des Trõlls {invi/camou/hors vue} avec Bricol'Troll + peaufinage affichage",
"V1.2.10 \t 07/12/2016",
" - correction décumul des bonus/malus",
" - affichage des Trõlls {invi/camou/hors vue} avec Bricol'Troll",
"V1.2.9 \t\t 16/11/2016",
" - adaptation Firefox 50 (comportement différent sur échec Ajax https)",
"V1.2.8 \t\t 10/11/2016",
" - gestion des messages d'erreur de l'interface avec l'IT bricol'Troll",
" - déplacement des images sur l'infra raistlin + meilleure gestion HTTPS",
"V1.2.7 \t\t 07/11/2016",
" - remise en route de l'interface avec l'IT bricol'Troll",
"V1.2.6 \t\t 19/10/2016",
" - affichage d'un message en cas de certificat raistlin non accepté pour la vue sous https",
" - stockage idguilde et nomguilde",
"V1.2.5 \t\t 17/10/2016",
" - correction doublon do_cdm qui bloquait l'envoi des CdMs lors de la compétence",
" - remise en route de la gestion des options avec intégration md5 dans ce script",
"V1.2.4 \t\t 14/10/2016",
" - utilisation du relai raistlin pour l'envoi des CdM",
"V1.2.3",
" - suppression ancien profil",
" - nettoyage doublon sur getPortee",
" - adaptation portee TP basée sur les PI",
" - repository sur greasyfork.org (pour être en https et avoir la mise à jour automatique active par défaut)",
"V1.2.2",
" - correction bug sur les 2 URL raistlin qui avaient été confondues",
"V1.2.1",
" - include des URLs MH alternatives",
" - regroupement des URLs externes en tête de fichier pour pouvoir contempler l'horreur de la diversité de la chose",
" - Ajout d'un message d'alerte en cas de HTTPS sans avoir débloqué le contenu mixte",
"V1.2",
" - toujours un gros paquet sale, passage sous Greasemonkey",
"V1.1",
" - regroupement en un gros paquet sale",
];
/** ********************************************************
À faire / propositions d'évolutions
H2P 08/07/2020
* dans la vue des minerais, ça devrait a priori afficher, sur base des formules de mountypedia, le nombre de carats de chaque pépite de minerai
Bireli-Gravos 08/12/2018
FAIT faire un warning si l'utilisateur a désactivé la case "Menu d'actions contextuelles" dans la fenêtre "limiter la vue"
breizhou13 20/12/2016
envoyer les données à l'IT (Bricol'Trolls) aussi
(Roule') Ça me semble difficile vis à vis de Bricol'Troll. Un bouton pour demander le rafraichissement ?
partage de l'identification des tresors au sol. Ca c'etait cool mais ca implique une BDD
partage des CDM avec seulement son groupe. Perso je prefere le partage general
Akkila le boeuf le 26-03-2017 à 15:56
- bouton pour rafraîchir les infos des trolls de son groupe
Roule'
FAIT corriger la façon dont les cibles de mission sont stockées (JSON très grosse table)
Réactiver les jubilaires
À supprimer : traces marquées [MZd] (mises pour analyser pb Tcherno Bill)
06/01/2017 toute la partie tabcompo ne fonctionne plus (sans doute suite à la modification de l'affichage des objets en tanière)
- voir l'intérêt de refaire fonctionner
- gestion des compos d'enchantement, EM (!), mois des champignons, autre (?)
FAIT : ambiguité sur le nom de monstres de mission : Shai, Ombre, Geck'oo et Boujd'la
Sans doute à corriger, la compétence Baroufle pour le lien vers l'anatroliseur
Prévision des DLA de monstre
FAIT Niveau des monstres à la méthode Roule'
Raistlin
* et si la popup des compétences s'affichait aussi au survol des raccourcis ?
FAIT? pages des Bonus/malus, erreur sur l'effet total, tours suivants, attaque
FAIT Les cibles de mission ont disparu dans la vue (remonté par Hera)
80117 - Héra
* Il semble que l'icône de LdP n'apparait que pour les Tom
FAIT l'infobulle de sacrifice donne des info erronées maintenant (dues aux changement d'affichage des gains/bm de temps probablement). pour moi, ça me dit "vous ne pouvez pas compenser de blessures dues à un sacrifice" alors que clairement, je peux
Ajout dans le vue d'un pseudo-lieu pour la caverne où le meneur d'un mission doit se rendre
FAIT Pour la portée IdC, l'arrondi est par défaut et MZ le fait par excès (1 fois en horizontal + 1 fois en vertical)
FAIT Possibilité de plusieurs systèmes Bricol'troll
en 1.2.17.18 SyntaxError: expected expression, got end of script[En savoir plus] Tout_MZ.user.js:12731:6
?
FAIT Tenir compte de la distance pour le PM (calculatrice de combat)
Alanae/Gnu/Pen-Hiss
* l'infobulle du lancer de potion pourrait donner le % du jet de toucher en fonction de la distance
* popup d'erreur js en mode smartphone sur un TP (pb trajet_canvas)
Dans https://mhp.mh.raistlin.fr/mountyhall/View/View_closed.php, le lien pour se connecter à son troll est games.mountyhall.com Est-ce que ça peut être modifié par MZ ?
a de temps en temps un popup "Error: Permission denied to access property Symbol:toPrimitive"
est-ce que l'infobulle de charger pourrait calculer la portée pour les tours suivants en fonction de la diminution de fatigue (ce serait plus compliqué d'estimer quand on est blessé en fonction de la reg)
Kali
MASQUÉ "TyperError: InfoComposant[4] is undefined" à l'affichage de la vue
**********************************************************/
/** ********************************************************
Doc État et Callback pour l'utilisation par les scripts tiers
MZ met à jour la propriété document.body.dataset.MZ_Etat
1 à la fin de l'initialisation (tout le code MZ s'est déroulé mais il peut y avoir des appels AJAX en cours)
2 (uniquement sur l'onglet de la vue) quand l'onglet a été mis à jour avec les niveaux, etc.
ATTENTION, l'utilisateur peut demander un complément de CdM s'il voit plus de 500 monstres
MZ appelle les callback définies dans les tableaux suivants, si ces tableaux existent
document.body.MZ_Callback_init: fonctions que MZ appellera quand MZ aura fini sont initialisation
ATTENTION, si MZ est chargé avant le script tiers, cette fonction ne sera jamais appelée. Le script tiers doit donc tester l'état document.body.dataset.MZ_Etat et faire l'appel à la callback lui-même si l'état est déjà défini, ce qui signifie que MZ est déjà initialisé.
document.body.MZ_Callback_fin_vue: fonctions que MZ appellera quand MZ aura fini son premier traitement des CdM dans la vue
ATTENTION document.body.MZ_Callback_init et document.body.MZ_Callback_fin_vue sont des tableaux.
Vous n'êtes pas seuls au monde. Un autre script externe peut s'être déjà enregistré en callback
Voici un exemple de code pour enregistrer une callback
if (document.body.MZ_Callback_init === undefined) {
document.body.MZ_Callback_init = [myCallback];
} else {
document.body.MZ_Callback_init.push(myCallback);
}
**********************************************************/
/** x~x Logging/debugging MZ ------------------------------------------- */
var MY_DEBUG = false, MY_LOG = true;
function printMZ(print, check, obj, exc = undefined) {
// Wrapper logging MZ avec injection d'exception pour les devs.
// Utiliser : logMZ(..), warnMZ(..), debugMZ(..), avertissement(..)
if (!check) {
return;
}
let msg = typeof obj === "object" ? JSON.stringify(obj) : obj;
let lv = GM_info && GM_info.script && GM_info.script.version ? `|${GM_info.script.version}` : '';
if (exc) {
// Source l'exception directement dans le logger.
// Les navigateurs modernes injectent directement
// une stacktrace interactive (support large cf MDN) :
// https://developer.mozilla.org/fr/docs/Web/API/console/error_static
print(`[MZ${lv}] ${msg}\n---\n`, exc);
return;
}
print(`[MZ${lv}] ${msg}`);
}
function logMZ(obj, exc = undefined) {
if (exc) {
// Comme logMZ est le logger "par défaut"
// -> upgrade en _error_ si exception présente.
printMZ(window.console.error, MY_LOG, obj, exc);
return;
}
printMZ(window.console.info, MY_LOG, obj);
}
function warnMZ(obj, exc = undefined) {
printMZ(window.console.warn, MY_LOG, obj, exc);
}
function debugMZ(obj, exc = undefined) {
if (exc) {
// Comme debugMZ est le debugger "par défaut"
// -> upgrade en _trace_ si exception présente.
printMZ(window.console.trace, MY_DEBUG, obj, exc);
return;
}
printMZ(window.console.log, MY_DEBUG, obj);
// printMZ(window.console.debug, MY_DEBUG, obj);
}
// WARNING (gath) - non utilisé (refonte logging) -> commenté
// function traceStack(e, sModule) {
// let version = '';
// if (GM_info && GM_info.script && GM_info.script.version) {
// version = `${GM_info.script.version}`;
// }
// let sRet = `[MZ_TRACE|${version}]`;
// if (sModule) {
// sRet = `${sRet} \{${sModule}\}`;
// }
// try {
// if (e.message) {
// sRet = `${sRet} ${e.message}`;
// }
// } catch (e2) {
// sRet = `${sRet} <exception acces message>`; // + e2.message;
// }
// try {
// if (e.stack) {
// let sStack = e.stack;
// // enlever les infos confidentielles
// sRet = `${sRet}\n${sStack.replace(/file\:\/\/.*gm_scripts/ig, '...')}`;
// }
// } catch (e2) {
// sRet = `${sRet} <exception acces stack>`; // + e2.message;
// }
// return sRet;
// }
/** ********************************************************
**** Début de zone à déplacer dans une bibli commune ******
**********************************************************/
// URL de base serveur MZ
var URL_MZ = 'http://mz.mh.raistlin.fr/mz';
// pour passer en mode IP, commenter la ligne précédente et décommenter la suivante
// let URL_MZ = 'http://192.99.225.92/mz';
// URLs externes images (pas de souci CORS mais pas de HTTPS)
// On dirait qu'il n'y en a plus...
// URLs externes redirection (pas de souci CORS)
var URL_pageNiv = 'http://mountypedia.ratibus.net/mz/niveau_monstre_combat.php';
var URL_AnatrolDispas = 'http://mountyhall.dispas.net/dynamic/';
var URL_vue_CCM = 'http://clancentremonde.free.fr/Vue2/RecupVue.php';
var URL_vue_Gloumfs2D = 'http://gloumf.free.fr/vue2d.php';
var URL_vue_Gloumfs3D = 'http://gloumf.free.fr/vue3d.php';
var URL_vue_Grouky = 'http://mh.ythogtha.org/grouky.py/grouky';
var URL_vue_cube = 'vueCube/vueCube.html';
// URLs de test HTTPS
var URL_CertifRaistlin1 = `${URL_MZ.replace(/http:\/\//, 'https://')}/img/1.gif`; // s'adapte si mode IP
var URL_CertifRaistlin2 = 'https://it.mh.raistlin.fr/vilya/mz_json.php';
// ceux-ci rendent bien les 2 entêtes CORS (mais pas de HTTPS)
var URL_bricol = 'http://trolls.ratibus.net/'; // recupération des infos des trolls dans l'IT bricol'troll
var URL_bricol_https = 'https://it.mh.raistlin.fr/'; // IT bricol'troll en https via relai Raistlin
/** x~x marque pour s'y retrouver sous l'éditeur (longueur: 80 chars) -- */
/** x~x Libs ----------------------------------------------------------- */
/* ancien TODO
* - revoir la gestion des CdM --> nott armure magique
* - revoir tout ce qui est lié à la vue (estimateurs dég nott)
* - vérfier la gestion des enchants
*/
// Roule 04/09/2016 switch extern URLs to https if available
var isHTTPS = false;
if (window.location.protocol.indexOf('https') === 0) {
URL_MZ = URL_MZ.replace(/http:\/\//, 'https://');
URL_bricol = URL_bricol_https;
isHTTPS = true;
}
// Roule 23/12/2016 mode dev
var isDEV = false;
if (window.localStorage.getItem('MZ_dev') ||
window.location.href.indexOf('rouletabille.mh.free.fr') > 0 ||
window.location.href.indexOf('mzdev.mh') >= 0) {
URL_MZ = URL_MZ.replace(/$/, 'dev');
isDEV = true;
}
// Images (pas de souci CORS)
var URL_MZimg = `${URL_MZ}/img/`;
// URLs externes ajax (CORS OK)
var URL_MZinfoMonstre = `${URL_MZ}/monstres_0.9_FF.php`;
var URL_MZgetCaracMonstre = `${URL_MZ}/getCaracMonstre.php`;
var URL_pageDispatcherV2 = `${URL_MZ}/cdmdispatcherV2.php`;
// liens externes déduits
var URL_bricol_mountyhall = `${URL_bricol}mountyhall/`;
var MHicons = '/mountyhall/Images/Icones/';
/** x~x Compatibilité Greasemonkey/ViolentMonkey ----------------------- */
try { // à partir du 11/07/2018, (GM_getValue === undefined) provoque une exception
GM_getValue === undefined;
logMZ('Fonctionnement dans Greasemonkey');
} catch (exc) {
GM_getValue = function (key) { };
GM_setValue = function (key, val) { };
GM_deleteValue = function (key) { };
GM_info = { script: { version: MZ_latest } }; // GM_info.script.version
if (typeof MH_mountyzilla_json !== "undefined")
logMZ('Fonctionnement intégré MH');
else
logMZ('Fonctionnement hors Greasemonkey');
}
/* Utilisation de la gestion de l'enregistrement des données de
GreaseMonkey, avec partage entre scripts via le localStorage, par
Vapulabehemot (82169) 07/02/2017 */
// Correction Roule' pour les boolean, le JSON decode pose problème car MZ utilise JSON
// Nécessite la présence de @grant GM_getValue, @grant GM_deleteValue et @grant GM_setValue
function MY_getValue(key) {
let v = window.localStorage.getItem(key);
let vGM = GM_getValue(key);
if (vGM == null || v != null && v != vGM) {
GM_setValue(key, v);
} else if (v == null && vGM != null) {
v = vGM;
window.localStorage[key] = vGM;
}
return v;
}
function MY_removeValue(key) {
GM_deleteValue(key);
window.localStorage.removeItem(key);
}
function MY_setValue(key, val) {
// conversion des booléens en 0 ou 1 à cause du localStorage infoutu de gérer les booléens
if (val === true) {
val = 1;
} else if (val === false) {
val = 0;
}
try {
GM_setValue(key, val);
} catch (exc) {
logMZ(`MY_setValue echec GM_setValue(${key}, ${val})`, exc);
}
try {
window.localStorage[key] = val;
} catch (exc) {
logMZ(`MY_setValue echec localStorage[${key}] = ${val}]`, exc);
}
}
function MZ_setOrRemoveValue(key, val) {
if (val === true) {
val = 'true';
} else if (val === false || val === undefined || val === '') {
val = null;
}
if (val === null) {
MY_removeValue(key);
} else {
MY_setValue(key, val);
}
}
function MZ_getValueBoolean(key) {
let val = MY_getValue(key);
if (val == 'true' || val == 1) {
return true;
}
return false;
}
/** x~x Variables globales utiles -------------------------------------- */
// utilisé pour accès bdd (un peu partout) :
var numTroll = MY_getValue('NUM_TROLL');
// utilisé dans vue pour PX :
// Roule 16/06/2017 on ne peut pas prendre le dernier niveau vu ! on a peut-être changé de Troll
var nivTroll; // = MY_getValue('NIV_TROLL');
// Roule 20/04/2017 le niveau n'est plus dans la frame de gauche, on récupère dans <numtroll>.niveau
if (nivTroll == undefined) {
nivTroll = MY_getValue(`${numTroll}.niveau`);
}
// utilisés dans actions et vue (calculs SR) :
var mmTroll = MY_getValue(`${numTroll}.caracs.mm`);
var rmTroll = MY_getValue(`${numTroll}.caracs.rm`);
var currentURL = window.location.href;
/** x~x Durée script --------------------------------------------------- */
var date_debut = null;
var jour_en_ms = 864e5;
function start_script(nbJours_exp, texte) {
debugMZ(`Script ${texte} début sur ${window.location.pathname}`);
if (date_debut) {
return;
}
date_debut = new Date();
// Créé la variable expdate si demandé
if (!nbJours_exp) {
return;
}
let expdate = new Date();
expdate.setTime(expdate.getTime() + nbJours_exp * jour_en_ms);
}
function displayScriptTime(duree, texte) {
debugMZ(`Script ${texte} fin sur ${window.location.pathname}`);
let footerNode = getFooter();
if (!footerNode) {
return;
}
let node;
try {
node = document.evaluate(".//text()[contains(.,'Page générée en')]/../br", footerNode, null, 9, null).singleNodeValue;
} catch (e) {
return;
}
if (!node) {
return;
}
if (duree) {
insertText(node, ` - [${texte} en ${duree / 1000} sec.]`);
return;
}
insertText(node, ` - [Script MZ exécuté en ${(new Date().getTime() - date_debut.getTime()) / 1000} sec.]`);
}
/** x~x Communication serveurs ----------------------------------------- */
function FF_XMLHttpRequest(MY_XHR_Ob) {
let request = new XMLHttpRequest();
request.open(MY_XHR_Ob.method, MY_XHR_Ob.url);
for (let head in MY_XHR_Ob.headers) {
request.setRequestHeader(head, MY_XHR_Ob.headers[head]);
}
request.onreadystatechange = function () {
if (request.readyState != 4) {
return;
}
if (request.error) {
if (MY_XHR_Ob.onerror) {
MY_XHR_Ob.onerror(request);
}
return;
}
if (request.status == 0) {
if (isDEV) {
let grandCadre = createOrGetGrandCadre();
let sousCadre = document.createElement('div');
sousCadre.innerHTML = 'AJAX status = 0, voir console';
sousCadre.style.width = 'auto';
sousCadre.style.fontSize = 'large';
sousCadre.style.border = 'solid 1px black';
grandCadre.appendChild(sousCadre);
}
if (MY_XHR_Ob.onerror) {
MY_XHR_Ob.onerror(request);
}
// showHttpsErrorContenuMixte();
return;
}
if (MY_XHR_Ob.onload) {
if (MY_XHR_Ob.trace) {
logMZ(`XMLHttp.onload ${MZ_formatDateMS()} début traitement retour AJAX ${MY_XHR_Ob.trace}`);
}
/* DEBUG: Ajouter à request les pptés de MY_XHR_Ob à transmettre */
MY_XHR_Ob.onload(request);
if (MY_XHR_Ob.trace) {
logMZ(`XMLHttp.onload ${MZ_formatDateMS()} fin traitement retour AJAX ${MY_XHR_Ob.trace}`);
}
}
};
if (MY_XHR_Ob.HTML) {
request.responseType = 'document';
}
request.send(MY_XHR_Ob.data);
}
// rend une chaine affichant date et heure et milliseconds (maintenant si le paramètre est absent)
function MZ_formatDateMS(d = new Date(), avec_ms = true) {
let date_fmt = d.toLocaleString('fr-FR');
if (avec_ms) {
date_fmt = `${date_fmt}.${d.getMilliseconds()}`;
}
return date_fmt;
}
/** x~x Interface utilisateur ------------------------------------------ */
function isDesktopView() {
return document.getElementsByClassName('ui-mobile').length == 0;
}
function replaceLinkMHtoMZ() {
let aList = document.getElementsByTagName('a');
for (let i = 0; i < aList.length; i++) {
if (aList[i].href.includes('games.mountyhall')) {
aList[i].href = 'https://mhp.mh.raistlin.fr/mountyhall/MH_Play/PlayStart2.php';
return;
} else if (aList[i].href.includes('smartphone.mountyhall')) {
aList[i].href = 'https://szp.mh.raistlin.fr/mountyhall/MH_Play/PlayStart2.php';
return;
}
}
}
// http://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
function copyTextToClipboard(text) {
let textArea = document.createElement('textarea');
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a flash,
// so some of these are just precautions. However in IE the element
// is visible whilst the popup box asking the user for permission for
// the web page to copy to the clipboard.
//
// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = 0;
textArea.style.left = 0;
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = 0;
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
let successful = document.execCommand('copy');
document.body.removeChild(textArea);
return successful;
}
function avertissement(txt, duree, bBloque, exc = undefined) {
let d = duree ? ` pour (${duree} ms)` : '';
let print_stack = MY_getValue('PRINTSTACK') == 'true';
let excDetails = (exc && !print_stack) ? ' - Plus de détails en console (F12)' : '';
logMZ(`Avertissement: ${txt}${d}`, exc);
if (!duree) {
duree = 15000;
}
let div = document.createElement('div');
// On numérote les avertissements pour destruction sélective
let num = document.getElementsByName('avertissement').length;
div.num = num;
// Numéro enregistré dans le DOM pour récupération sur getElementsByName()
div.setAttribute('name', 'avertissement');
div.className = 'mh_textbox ui-content';
div.style.position = 'fixed';
div.style.top = `${10 + 45 * num}px`;
div.style.left = `${10 + 0 * num}px`;
div.style.border = '4px solid red';
div.style.borderRadius = '4px';
div.style.backgroundColor = 'rgb(229, 222, 203)';
div.style.zIndex = 2 + num;
div.style.cursor = 'pointer';
div.style.fontSize = 'large';
div.innerHTML = `${txt}${excDetails}`;
if (!bBloque) {
div.onclick = function () {
tueAvertissement(this.num);
};
}
if (exc && print_stack) {
let pre = document.createElement('pre');
appendText(pre, `---\n${exc.message}\n${exc.stack}`);
pre.style.whiteSpace = "pre-wrap";
div.appendChild(pre);
}
// un croix en haut à droite pour signifier à l'utilisateur qu'il peut cliquer pour fermer ce popup
let divcroix = document.createElement('div');
divcroix.style.position = 'absolute';
divcroix.style.top = 0;
divcroix.style.right = 0;
divcroix.style.color = 'black';
divcroix.style.fontSize = 'inherit';
divcroix.style.cursor = 'pointer';
divcroix.style.zIndex = 2 + num;
divcroix.innerHTML = 'X';
div.appendChild(divcroix);
document.body.appendChild(div);
// Destruction automatique de l'avertissement après "un certain temps"
window.setTimeout(() => {
tueAvertissement(num);
}, duree);
}
function tueAvertissement(num) {
let divs = document.getElementsByName('avertissement');
for (let i = 0; i < divs.length; i++) {
if (divs[i].num == num) {
divs[i].parentNode.removeChild(divs[i]);
return;
}
}
}
/** x~x Modifications du DOM ------------------------------------------- */
function getFooter() {
// retourne le footer sur mobile ou non
return document.getElementById('footer') || document.getElementById('footer1') || document.getElementById('footer2');
}
function insertBefore(node, child) {
node.parentNode.insertBefore(child, node);
}
function appendTr(tbody, cls_name) {
let tr = document.createElement('tr');
if (cls_name) {
tr.className = cls_name;
}
tbody.appendChild(tr);
return tr;
}
function appendTrDetail(tr_node, th_txt, td_txt, pre = undefined) {
let tr = document.createElement('tr');
tr.className = 'detail';
let th = document.createElement('th');
appendText(th, th_txt);
tr.appendChild(th);
let td = document.createElement('td');
if (pre) {
let p = document.createElement('pre');
appendText(p, td_txt);
td.appendChild(p);
} else {
appendText(td, td_txt);
}
tr.appendChild(td);
insertAfter(tr_node, tr);
return tr;
}
function insertTr(node, cls_name) {
let tr = document.createElement('tr');
if (cls_name) {
tr.className = cls_name;
}
insertBefore(node, tr);
return tr;
}
function appendTd(tr, styles) {
let td = document.createElement('td');
if (styles)
for (s in styles) td.style[s] = styles[s];
if (tr) {
tr.appendChild(td);
}
return td;
}
function insertTd(node) {
let td = document.createElement('td');
insertBefore(node, td);
return td;
}
function insertTh(node) {
let th = document.createElement('th');
insertBefore(node, th);
return th;
}
// handle when eTd is the last (in this case eTd.nextSibling is null, which is fine for insertBefore)
function insertAfterTd(eTd) {
let newTd = document.createElement('td');
eTd.parentNode.insertBefore(newTd, eTd.nextSibling);
return newTd;
}
function appendTdCenter(tr, colspan) {
let td = appendTd(tr);
td.align = 'center'; // WARNING - Obsolete
if (colspan) {
td.colSpan = colspan;
}
return td;
}
function insertTdElement(node, child) {
let td = insertTd(node);
if (child) {
td.appendChild(child);
}
return td;
}
function appendA(node, href, cssClass, text) {
let a = document.createElement('a');
if (href) {
a.href = href;
}
if (cssClass) {
a.className = cssClass;
}
if (text) {
a.appendChild(document.createTextNode(text));
}
node.appendChild(a);
return a;
}
function appendText(node, text, bold, color = undefined) {
let t = document.createTextNode(text);
if (!bold) {
node.appendChild(t);
return t;
}
let b = document.createElement('b');
if (color) {
b.style.color = color;
}
b.appendChild(t);
node.appendChild(b);
return t;
}
function replaceContentByText(node, texte) {
while (node.firstChild) node.removeChild(node.firstChild);
node.appendChild(document.createTextNode(texte));
}
function insertText(node, text, bold) {
if (!bold) {
insertBefore(node, document.createTextNode(text));
return;
}
let b = document.createElement('span');
appendText(b, text, bold);
insertBefore(node, b);
return b;
}
function insertTextDiv(node, text, bold) {
let b = document.createElement('div');
appendText(b, text);
if (bold) b.style.fontWeight = 'bold';
insertBefore(node, b);
return b;
}
function appendTextDiv(node, text, bold) {
let b = document.createElement('div');
appendText(b, text);
if (bold) b.style.fontWeight = 'bold';
node.appendChild(b);
return b;
}
function appendThText(tr, text, bold) {
let th = document.createElement('th');
if (tr) {
tr.appendChild(th);
}
th.appendChild(document.createTextNode(text));
if (bold) {
th.style.fontWeight = 'bold';
}
return th;
}
function appendTdText(tr, text, bold, styles) {
let td = appendTd(tr, styles);
td.appendChild(document.createTextNode(text));
if (bold) {
td.style.fontWeight = 'bold';
}
return td;
}
function insertThText(node, text, bold) {
let th = insertTh(node);
appendText(th, text, bold);
return th;
}
function insertTdText(node, text, bold) {
let td = insertTd(node);
appendText(td, text, bold);
return td;
}
function appendHr(node) {
node.appendChild(document.createElement('hr'));
}
function appendBr(node) {
node.appendChild(document.createElement('br'));
}
function insertBr(node) {
insertBefore(node, document.createElement('br'));
}
function appendLi(ul, text) {
// uniquement utilisé dans les options (crédits)
let li = document.createElement('li');
appendText(li, text);
ul.appendChild(li);
return li;
}
function appendTextbox(node, type, name, size, maxlength, value, sId) {
let input = document.createElement('input');
input.className = 'TextboxV2';
input.type = type;
input.name = name;
input.id = sId === undefined ? name : sId;
input.size = size;
input.maxLength = maxlength;
if (value) {
input.value = value;
}
node.appendChild(input);
return input;
}
function appendTextboxBlock(node, type, name, text, size, maxlength, value, sId, bTextRight) {
let label = document.createElement('label');
label.style.display = 'inline-block';
label.style.marginRight = '10px';
if (!bTextRight) {
label.appendChild(document.createTextNode(text));
}
let i = appendTextbox(label, type, name, size, maxlength, value, sId);
i.style.marginRight = '5px';
if (bTextRight) {
label.appendChild(document.createTextNode(text));
}
node.appendChild(label);
return label;
}
function appendCheckBox(node, name, checked, onClick) {
let input = document.createElement('input');
input.type = 'checkbox';
input.name = name;
input.id = name;
if (checked) {
input.checked = true;
}
if (onClick) {
input.onclick = onClick;
}
node.appendChild(input);
return input;
}
function appendCheckBoxBlock(node, name, text, checked, onClick) {
let label = document.createElement('label');
label.style.display = 'inline-block';
label.style.marginRight = '10px';
let input = document.createElement('input');
input.type = 'checkbox';
input.name = name;
input.id = name;
if (checked) {
input.checked = true;
}
if (onClick) {
input.onclick = onClick;
}
input.style.marginRight = '5px;';
label.appendChild(input);
label.appendChild(document.createTextNode(text));
node.appendChild(label);
return label;
}
function appendCheckBoxSpan(node, id, onClick, text) {
let span = document.createElement('span');
span.style.whiteSpace = 'nowrap';
let chk = appendCheckBox(span, id, false, onClick);
chk.setAttribute('data-role', 'none'); // Dire à JQuery de le laisser tranquile, même en mode smartphone
let label = document.createElement('label');
appendText(label, text);
label.htmlFor = id;
label.style.marginLeft = '1px';
span.appendChild(label);
span.style.marginRight = '3px';
node.appendChild(span);
appendText(node, ' ');
return span;
}
function appendOption(select, value, text) {
let option = document.createElement('option');
option.value = value;
appendText(option, text);
select.appendChild(option);
return option;
}
function appendHidden(form, nam, value) {
let input = document.createElement('input');
input.type = 'hidden';
input.name = nam;
input.id = nam;
input.value = value;
form.appendChild(input);
}
function appendButton(node, value, onClick) {
let input = document.createElement('input');
input.type = 'button';
input.className = 'mh_form_submit';
input.value = value;
input.onmouseover = function () {
this.style.cursor = 'pointer';
};
if (onClick) {
input.onclick = onClick;
}
node.appendChild(input);
return input;
}
function insertButton(node, value, onClick) {
let input = document.createElement('input');
input.type = 'button';
input.className = 'mh_form_submit';
input.value = value;
input.onmouseover = function () {
this.style.cursor = 'pointer';
};
input.onclick = onClick;
insertBefore(node, input);
return input;
}
function appendSubmit(node, value, onClick) {
let input = document.createElement('input');
input.type = 'submit';
input.className = 'mh_form_submit';
input.value = value;
input.onmouseover = function () {
this.style.cursor = 'pointer';
};
if (onClick) {
input.onclick = onClick;
}
node.appendChild(input);
return input;
}
function createImage(url, title, style) {
let img = document.createElement('img');
img.src = url;
img.title = title;
img.alt = `[${title}]`;
img.align = 'absmiddle'; // WARNING - Obsolete in HTML5.0
if (style) {
img.style = style;
}
return img;
}
function createAltImage(url, alt, title) {
let img = document.createElement('img');
img.src = url;
img.alt = alt;
if (title) {
img.title = title;
}
img.align = 'absmiddle'; // WARNING - Obsolete in HTML5.0
return img;
}
function createImageSpan(url, alt, title, text, bold) {
let span = document.createElement('span');
span.title = title;
let img = document.createElement('img');
img.src = url;
img.alt = alt;
img.align = 'absmiddle'; // WARNING - Obsolete in HTML5.0
span.appendChild(img);
appendText(span, text, bold);
return span;
}
function getMyID(elt) {
let parent = elt.parentNode;
for (let i = 0; i < parent.childNodes.length; i++) {
if (elt == parent.childNodes[i]) {
return i;
}
}
return -1;
}
function insertAfter(elt, newElt) {
let id = getMyID(elt);
if (id == -1) {
return;
}
if (id < elt.parentNode.childNodes.length - 1) {
insertBefore(elt.nextSibling, newElt);
} else {
elt.parentNode.appendChild(newElt);
}
}
function addStyleSheet(cssText) {
let styleElt = document.createElement('style');
styleElt.type = 'text/css';
if (styleElt.styleSheet) {
styleElt.styleSheet.cssText = cssText;
} else {
styleElt.appendChild(document.createTextNode(cssText));
}
document.getElementsByTagName('head')[0].appendChild(styleElt);
}
/** x~x Fonctions de mise en forme du texte ---------------------------- */
function aff(nb) {
return nb >= 0 ? `+${nb}` : nb;
}
function getNumber(str) {
let nbr = str.match(/\d+/);
return nbr ? Number(nbr[0]) : Number.NaN;
}
function getNumbers(str) {
let nbrs = str.match(/\d+/g);
if (!nbrs) {
return [];
}
for (let i = 0; i < nbrs.length; i++) {
nbrs[i] = Number(nbrs[i]);
}
return nbrs;
}
function getIntegers(str) {
let nbrs = str.match(/-?\d+/g);
if (!nbrs) {
return [];
}
for (let i = 0; i < nbrs.length; i++) {
nbrs[i] = Number(nbrs[i]);
}
return nbrs;
}
function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, '');
}
if (typeof String.prototype.trim != 'function') {
// Intégré depuis ES5, pour rétrocompatibilité
String.prototype.trim = function () {
return this.replace(/^\s+/, '').replace(/\s+$/, '');
};
}
function epure(texte) {
return texte
.replace(/[àâä]/g, 'a')
.replace(/Â/g, 'A')
.replace(/[ç]/g, 'c')
.replace(/[éêèë]/g, 'e')
.replace(/[ïî]/g, 'i')
.replace(/[ôöõ]/g, 'o')
.replace(/[ùûü]/g, 'u');
}
// WARNING Modifier des constantes, c'est mal
String.prototype.epure = function () {
return this
.replace(/[àâä]/g, 'a').replace(/Â/g, 'A')
.replace(/[ç]/g, 'c')
.replace(/[éêèë]/g, 'e')
.replace(/[ïî]/g, 'i')
.replace(/[ôöõ]/g, 'o')
.replace(/[ùûü]/g, 'u');
};
function bbcode(texte) {
return texte
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/'/g, '’')
.replace(/\[b\](.*?)\[\/b\]/g, '<b>$1</b>')
.replace(/\[i\](.*?)\[\/i\]/g, '<i>$1</i>')
.replace(/\[img\]([^"]*?)\[\/img\]/g, '<img src="$1" />');
}
/** x~x Gestion/transformation des Dates ------------------------------- */
function addZero(i) {
return i < 10 ? `0${i}` : i;
}
// WARNING - remplacé par MZ_formatDateMS()
// function DateToString(date) {
// return addZero(date.getDate()) + '/' + addZero(date.getMonth() + 1)
// + '/' + date.getFullYear() + ' ' + addZero(date.getHours())
// + ':' + addZero(date.getMinutes()) + ':' + addZero(date.getSeconds());
// }
function StringToDate(str) {
return str.replace(/([0-9]+)\/([0-9]+)/, '$2/$1');
}
// fonctionne aussi avec datetime
function SQLDateToFrench(str) {
return str.replace(/([0-9]+)\-([0-9]+)\-([0-9]+)/, '$3/$2/$1');
}
// ... et ajoute un 'à' du plus bel effet
function SQLDateToFrenchTime(str) {
return str.replace(/([0-9]+)\-([0-9]+)\-([0-9]+) /, '$3/$2/$1 à ');
}
// SQLDate vers objet date Javascript
function SQLDateToObject(str) {
let t = str.split(/[- :]/);
return new Date(t[0], t[1] - 1, t[2], t[3], t[4], t[5]);
}
var mz_ie = Boolean(window.attachEvent);
if (typeof addEvent !== 'function') {
if (mz_ie) {
function addEvent(obj, typ, fn, sens) {
obj[`e${typ}${fn}`] = fn; obj[typ + fn] = function () {
obj[`e${typ}${fn}`](window.event);
};
obj.attachEvent(`on${typ}`, obj[typ + fn]);
}
} else {
function addEvent(obj, typ, fn, sens) {
obj.addEventListener(typ, fn, sens);
}
}
}
/** ********************
* glissière en mode objet
* Roule 29/12/2016 à partir du code des trajets gowap doCallback_glissiere et Vapulabehemot
* Une glissière est un curseur permettant, par exemple de changer le zoom des cartes
*
* Usage:
* gliss = new glissiere_MZ(ref, labelHTML, target, bDynamic);
* ref : utilisé pour diversifier les IDs HTML
* labelHTML : le label qui apparaît devant la glissière (peut contenir des balises HTML)
* target : peut être de 3 types
* - élément HTML : l'élément HTML à zoomer
* - string : l'ID de l'élément à zoomer (qui doit exister au moment de la création de la glissière
* - function : callback quand le curseur bouge
* bDynamic : par défaut, le fonctionnement n'est pas dynamique (la callback est appellé au click)
* dans le mode dynamique, la callback est appelée sur mouseMove
* valDef : valeur par défaut si l'outil n'a jamais été utilisé
* valMin, valMax : les valeurs entre lesquelles le curseur varie
* autres méthodes
* gliss.getElt(); // rend la div de la glissière (par exemple pour la positionner)
**********************/
function glissiere_MZ(ref, labelHTML, paramTarget, bDynamic, valDef, valMin, valMax) {
try {
let mouseDown = false;
let div_gliss = document.createElement('div'); // la DIV mère
div_gliss.id = `MZ_gliss_${ref}`;
let div_label = document.createElement('span'); // le label
div_label.innerHTML = labelHTML;
div_gliss.appendChild(div_label);
div_gliss.className = 'choix_zoom';
let dessin = document.createElement('canvas'); // le dessin lui-même
dessin.id = `MZ_gliss_dessin_${ref}`;
dessin.style.cursor = 'pointer';
dessin.width = 104;
dessin.height = 12;
dessin.style.marginLeft = '2px';
dessin.style.marginRight = '2px';
div_gliss.appendChild(dessin);
let pourcent = document.createElement('span'); // le pourcentage
pourcent.id = `MZ_gliss_pourcent_${ref}`;
let pourcent_text = document.createTextNode('');
let previousVal;
let flouPourCurseurDoubleFleche = (valMax - valMin) / 40;
// alignement vertical
dessin.style.verticalAlign = 'middle';
div_label.style.verticalAlign = 'middle';
pourcent.style.verticalAlign = 'middle';
pourcent.appendChild(pourcent_text);
div_gliss.appendChild(pourcent);
let bulle_pourcent = document.createElement('div'); // la bulle
bulle_pourcent.id = `MZ_gliss_bulle_${ref}`;
bulle_pourcent.style.display = 'block';
bulle_pourcent.style.visibility = 'hidden';
bulle_pourcent.style.position = 'absolute';
bulle_pourcent.style.zIndex = 3500;
bulle_pourcent.style.border = '1px solid #a1927f';
let bulle_pourcent_text = document.createTextNode('');
bulle_pourcent.appendChild(bulle_pourcent_text);
document.body.appendChild(bulle_pourcent);
this.getElt = function () {
return div_gliss;
};
// //////////////////////////////////
// dessine et redessine le curseur
// //////////////////////////////////
let dessine_glissiere = function (val) {
let pos_0_100 = (val - valMin) * 100 / (valMax - valMin);
let ctx = dessin.getContext('2d');
ctx.clearRect(0, 0, 104, 12);
ctx.fillStyle = 'rgb(0,0,0)';
ctx.fillRect(0, 0, 2, 12);
ctx.fillRect(102, 0, 2, 12);
ctx.fillRect(0, 5, 104, 2);
ctx.fillStyle = 'rgb(80,80,80)';
ctx.fillRect(pos_0_100, 0, 5, 12);
ctx.fillStyle = 'rgb(200,200,200)';
ctx.fillRect(pos_0_100 + 1, 1, 3, 10);
pourcent_text.nodeValue = `${val}%`;
previousVal = parseInt(val);
};
// //////////////////////////////////
// action sur mousedown et mousemove
// stocker la nouvelle valeur
// redessiner
// afficher la nouvelle valeur
// action selon ce qui a été demandé
// //////////////////////////////////
let doCallback_glissiere = function (evt) {
try {
let xsouris = evt.offsetX ? evt.offsetX : evt.layerX;
let xpos = evt.offsetX ? evt.clientX : evt.pageX;
let ypos = evt.offsetX ? evt.clientY + document.body.scrollTop : evt.pageY;
if (evt.type === 'mousedown') {
mouseDown = true;
}
let val = Math.floor(Math.min(valMax, Math.max(valMin, (xsouris - 1) * (valMax - valMin) / 100 + valMin)));
dessin.style.cursor = val <= previousVal + flouPourCurseurDoubleFleche && val >= previousVal - flouPourCurseurDoubleFleche ? 'e-resize' : 'pointer';
// afficher la nouvelle valeur dans la bulle
bulle_pourcent_text.nodeValue = `${val}%`;
bulle_pourcent.style.top = `${ypos + 3}px`;
bulle_pourcent.style.left = `${xpos + 16}px`;
if (evt.buttons === undefined) {
// mode utilisant les evt mouseup/down (mauvaise méthode, utilisé si on ne peut pas faire autrement)
if (!mouseDown) {
return;
} // simple survol, on ne fait rien de plus
} else {
if (!(evt.buttons & 1)) {
return;
} // simple survol, on ne fait rien de plus
}
// stocker la nouvelle valeur
MY_setValue(`MZ_glissiere_${ref}`, val);
// redessiner la glissière avec le curseur où il faut
dessine_glissiere(val);
// action selon ce qui a été demandé
// for(let key in evt) logMZ(`evt key ${key} => ${evt[key]}`);
if (!bDynamic && evt.type !== 'mousedown') {
return;
}
let elt;
if (typeof paramTarget === 'object') {
elt = paramTarget;
} else if (typeof paramTarget === 'string') {
elt = document.getElementById(paramTarget);
} else if (typeof paramTarget === 'function') {
paramTarget(val);
return;
}
if (elt && elt.setZoom != undefined) {
elt.setZoom(val);
}
} catch (exc) {
logMZ('glissiere_MZ.doCallback', exc);
}
};
// //////////////////////////////////
// event mousedown et mousemove : redessiner et callback
// //////////////////////////////////
addEvent(dessin, 'mousedown', doCallback_glissiere, true);
addEvent(dessin, 'mousemove', doCallback_glissiere, true);
// //////////////////////////////////
// event mouseup : mémoriser mouseup (utile seulement si le navigateur ne supporte pas evt.buttons
// //////////////////////////////////
addEvent(dessin, 'mouseup', () => {
mouseDown = false;
}, true);
// //////////////////////////////////
// event mouseout & mouseover : afficher/cacher la bulle
// //////////////////////////////////
addEvent(dessin, 'mouseout', () => {
bulle_pourcent.style.visibility = 'hidden';
}, true);
addEvent(dessin, 'mouseover', () => {
bulle_pourcent.style.visibility = 'visible';
}, true);
// //////////////////////////////////
// dessiner la première fois
// //////////////////////////////////
let val_init = MY_getValue(`MZ_glissiere_${ref}`);
if (val_init === undefined) {
val_init = valDef;
}
dessine_glissiere(val_init);
} catch (exc) {
logMZ('glissiere_MZ', exc);
}
}
// calcul du point intermédiaire de déplacement gowap (x et y uniquement)
// reçoit 2 objets avec des propriétés x et y
// rend un objet avec x et y (rend undefined si le trajet est direct)
function pointIntermediaireMonstre2D(locDepart, locArrivee) {
let deltaX = locArrivee.x - locDepart.x;
if (deltaX == 0) {
return;
} // pas de point intermédiaire
let deltaY = locArrivee.y - locDepart.y;
if (deltaY == 0) {
return;
} // pas de point intermédiaire
let absDeltaX = Math.abs(deltaX), absDeltaY = Math.abs(deltaY);
if (absDeltaX > absDeltaY) {
return { x: locDepart.x + Math.sign(deltaX) * Math.sign(deltaY) * deltaY, y: locArrivee.y };
} else if (absDeltaY > absDeltaX) {
return { x: locArrivee.x, y: locDepart.y + Math.sign(deltaX) * Math.sign(deltaY) * deltaX };
}
return; // égalité, pas de point intermédiaire
}
/** ********************
* carte en mode objet
* Roule 14/01/2017 à partir du code des trajets gowap de Vapulabehemot
*
* Usage:
* carte = new carte_MZ(ref, tabDepl);
* ref : utilisé pour diversifier les IDs HTML
* tabDepl : table de tables d'objets contenant x, y et n (positions successives des différents suivants)
* pour l'affichage, le premier objet doit contenir nom et id (et typ pour des cibles particulières)
* autres méthodes
* carte.getElt(); // rend la div de la carte (par exemple pour la positioner dans la page)
**********************/
function carte_MZ(ref, tabDepl) {
try {
let div1_carte = document.createElement('div'); // la DIV mère. Elle prend toute la largeur
div1_carte.id = `MZ_carte_${ref}`;
div1_carte.className = 'mh_tdpage'; // le mh_tdpage sert à faire cacher la carte par les scripts trajet_gowap
div1_carte.style.backgroundImage = 'none';
div1_carte.style.backgroundColor = 'transparent';
let div2_carte = document.createElement('div'); // la DIV mère. Elle prend toute la largeur
div2_carte.className = 'carte_MZ';
div2_carte.style.display = 'inline-block'; // pour que la div ait la taille du contenu
let dessin = document.createElement('canvas'); // le dessin lui-même
dessin.id = `MZ_carte_dessin_${ref}`;
dessin.style.backgroundImage = "url('/mountyhall/MH_Packs/packMH_parchemin/tableau/tableau1.jpg')";
div1_carte.appendChild(div2_carte);
div2_carte.appendChild(dessin);
let position_trous_MZ = [
[-70.5, -7.5, 2, 1.5, -69], // x, y, ?, rayon du cercle, profondeur
[-66.5, -37.5, 2, 1.5, -69],
[-63.5, 8.5, 2, 1.5, -69],
[-59.5, -32.5, 2, 1.5, -69],
[-52, 57, 0.25, 0.8, -59],
[-50.5, -22.5, 2, 1.5, -69],
[-35.5, -51.5, 2, 1.5, -69],
[-34.5, 14.5, 2, 1.5, -69],
[-34.5, 64.5, 2, 1.5, -69],
[-11.5, 72.5, 2, 1.5, -69],
[5.5, -49.5, 2, 1.5, -69],
[5.5, 31.5, 2, 1.5, -69],
[10.5, 63.5, 2, 1.5, -69],
[12, -15, 0.25, 0.8, -59],
[21.5, 35.5, 2, 1.5, -69],
[30, -52, 0.25, 0.8, -59],
[46.5, 51.5, 2, 1.5, -69],
[48, -39, 0.25, 0.8, -59],
[55, 70, 0.25, 0.8, -59], // correction Roule 10/10/2016 -59 au lieu de -69
[56.5, 23.5, 75, 8.7, -99],
[64, 70, 0.25, 0.8, -59],
[74.5, 31.5, 2, 1.5, -69]];
let couleur_depl_normal = 'rgba(0,0,200,0.5)';
let couleur_cible = 'rgba(0,0,0,0.5)';
let couleur_depl_collision_trou = 'rgba(150,0,0, 0.5)';
let couleur_trou = 'rgb(200,0,0)';
let coord_x = function (val) {
return decalh + coeff * (val + 100);
};
let coord_y = function (val) {
return decalv + coeff * (100 - val);
};
let ctx = dessin.getContext('2d');
let coeff = MY_getValue(`MZ_glissiere_${ref}`); // ce qui a été sauvé précédement par la glissiere
if (coeff) {
coeff = coeff / 50;
} else {
coeff = 2;
}
let decalv = 30, decalh = 30;
let detecteCollisionTrou = function (pos0, pos1) { // fonction volée à feldspath et Vapulabehemot, merci à eux (voir calc_inter dans Trajet_Gowap)
// let res = false
let x0 = pos0.x, y0 = pos0.x;
let tmax = Math.max(Math.abs(pos1.x - pos0.x), Math.abs(pos1.y - pos0.y));
let px = Math.sign(pos1.x - pos0.x), py = Math.sign(pos1.y - pos0.y);
let a = 0, b = 0, c = 0, delta = 0, t0 = 0, t1 = 0;
// logMZ(`verif collision gowap-trou [x0=${x0},y0=${y0}, px=${px}, py=${py}, tmax=${tmax}]`);
for (let k in position_trous_MZ) {
a = parseFloat(px * px + py * py);
b = parseFloat((x0 - position_trous_MZ[k][0]) * px + (y0 - position_trous_MZ[k][1]) * py);
c = parseFloat((x0 - position_trous_MZ[k][0]) * (x0 - position_trous_MZ[k][0]) + (y0 - position_trous_MZ[k][1]) * (y0 - position_trous_MZ[k][1]) - position_trous_MZ[k][2]);
delta = b * b - a * c;
if (delta >= 0) {
t0 = Math.ceil(-b / a - Math.sqrt(delta) / a);
t1 = Math.floor(-b / a + Math.sqrt(delta) / a);
if (t0 <= tmax && t1 >= 0) {
// Roule' 10/10/2016 J'ai déplacé le flag res=true à l'intérieur de la boucle for ci-dessous car il y avait de fausses détections
// res = true;
// logMZ(`***** collision gowap-trou [x0=${x0},y0=${y0}, px=${px}, py=${py}, tmax=${tmax}]`);
for (let l = Math.max(0, t0); l <= Math.min(tmax, t1); l++) {
// logMZ(`***** collision gowap-trou en ${(x0+l*px)}, ${(y0+l*py)}`);
// Roule : pas utile pour nous
// res = true;
// chute.push([x0+l*px, y0+l*py]);
return true;
}
}
}
}
return false;
};
let dessine_carte = function () {
dessin.width = 200 * coeff + 2 * decalh;
dessin.height = 200 * coeff + 2 * decalv;
// repere
ctx.beginPath();
ctx.moveTo(coord_x(0), coord_y(100));
ctx.lineTo(coord_x(0), coord_y(-100));
ctx.moveTo(coord_x(-100), coord_y(0));
ctx.lineTo(coord_x(100), coord_y(0));
ctx.stroke();
ctx.strokeRect(coord_x(-100), coord_y(100), coord_x(100) - coord_x(-100), coord_y(-100) - coord_y(100));
// trous
ctx.fillStyle = couleur_trou;
for (let i in position_trous_MZ) {
ctx.beginPath();
ctx.arc(coord_x(position_trous_MZ[i][0]), coord_y(position_trous_MZ[i][1]), coeff * position_trous_MZ[i][3], 0, Math.PI * 2, true);
ctx.fill();
}
// trajets
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
for (let iSuivant in tabDepl) {
// logMZ(`carte_MZ, suivant n°${iSuivant}`);
let tabDeplOneSuivant = tabDepl[iSuivant];
let x0 = coord_x(tabDeplOneSuivant[0].x), y0 = coord_y(tabDeplOneSuivant[0].y);
let typeDepart = tabDeplOneSuivant[0].typ; // La "cible" au départ
switch (typeDepart) {
case 'tp':
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = couleur_cible;
ctx.fillStyle = couleur_cible;
ctx.moveTo(x0 + coeff * 3, y0 + coeff * 3);
ctx.lineTo(x0 + coeff * 3, y0 - coeff * 3);
ctx.lineTo(x0 - coeff * 3, y0 - coeff * 3);
ctx.lineTo(x0 - coeff * 3, y0 + coeff * 3);
ctx.lineTo(x0 + coeff * 3, y0 + coeff * 3);
ctx.moveTo(x0 + coeff * 3, y0);
ctx.lineTo(x0 - coeff * 3, y0);
ctx.moveTo(x0, y0 + coeff * 3);
ctx.lineTo(x0, y0 - coeff * 3);
ctx.stroke();
break;
default:
ctx.beginPath();
ctx.lineWidth = 1;
ctx.strokeStyle = couleur_cible;
ctx.fillStyle = couleur_cible;
ctx.arc(x0, y0, coeff * 4, 0, Math.PI * 2, true);
ctx.moveTo(x0 + coeff * 4, y0);
ctx.lineTo(x0 - coeff * 4, y0);
ctx.moveTo(x0, y0 + coeff * 4);
ctx.lineTo(x0, y0 - coeff * 4);
ctx.stroke();
break;
}
// les segments
let nb_pts = tabDeplOneSuivant.length;
let pointPrecedent = tabDeplOneSuivant[0];
for (let i = 1; i < nb_pts; i++) {
ctx.beginPath();
ctx.lineWidth = coeff;
ctx.moveTo(coord_x(pointPrecedent.x), coord_y(pointPrecedent.y));
ctx.strokeStyle = couleur_depl_normal;
let pointIntermediaire = pointIntermediaireMonstre2D(pointPrecedent, tabDeplOneSuivant[i]);
if (pointIntermediaire === undefined) {
if (detecteCollisionTrou(pointPrecedent, tabDeplOneSuivant[i])) {
ctx.strokeStyle = couleur_depl_collision_trou;
} else {
ctx.strokeStyle = couleur_depl_normal;
}
ctx.lineTo(coord_x(tabDeplOneSuivant[i].x), coord_y(tabDeplOneSuivant[i].y));
} else {
if (detecteCollisionTrou(pointPrecedent, pointIntermediaire) ||
detecteCollisionTrou(pointIntermediaire, tabDeplOneSuivant[i])) {
ctx.strokeStyle = couleur_depl_collision_trou;
} else {
ctx.strokeStyle = couleur_depl_normal;
}
ctx.lineTo(coord_x(pointIntermediaire.x), coord_y(pointIntermediaire.y));
ctx.lineTo(coord_x(tabDeplOneSuivant[i].x), coord_y(tabDeplOneSuivant[i].y));
}
pointPrecedent = tabDeplOneSuivant[i];
ctx.stroke();
}
// Les points à chaque étape
ctx.fillStyle = couleur_depl_normal;
for (let i = 1; i < nb_pts; i++) {
ctx.beginPath();
let x = coord_x(tabDeplOneSuivant[i].x), y = coord_y(tabDeplOneSuivant[i].y);
ctx.arc(x, y, coeff, 0, Math.PI * 2, true);
ctx.fill();
}
}
};
this.setZoom = function (val) {
ctx.clearRect(0, 0, dessin.width, dessin.height);
coeff = val / 50;
dessine_carte();
};
// glissiere
let gliss = new glissiere_MZ(ref, 'Zoom\u00A0:', this, true, 100, 50, 200);
let eGliss = gliss.getElt();
eGliss.style.position = 'absolute';
eGliss.style.top = `${coeff * 2}px`;
eGliss.style.left = `${decalh}px`;
dessin.style.position = 'relative';
div2_carte.style.position = 'relative';
eGliss.style.zIndex = 9000;
div2_carte.appendChild(eGliss);
// affichage au survol de la souris
let bulle = document.createElement('div');
bulle.style.visibility = 'hidden';
bulle.style.position = 'absolute';
bulle.style.zIndex = 3100;
bulle.style.border = 'solid 1px #a1927f';
bulle.className = 'mh_tdpage';
bulle.style.display = 'block'; // ATTENTION, display doit être après className pour forcer le display
let bulleHaut = document.createElement('div');
bulleHaut.style.display = 'block';
bulleHaut.style.paddingRight = '3px';
bulleHaut.className = 'mh_tdtitre';
bulleHaut.appendChild(document.createTextNode(' ')); // prépare texte
bulle.appendChild(bulleHaut);
let bulleBas = document.createElement('div');
bulleBas.style.display = 'block';
bulleBas.style.whiteSpace = "nowrap";
bulleBas.style.paddingRight = '3px';
// bulleBas.appendChild(document.createTextNode(' ')); // prépare texte
bulle.appendChild(bulleBas);
div2_carte.appendChild(bulle);
let affichePosition = function (evt) {
let xsouris = evt.offsetX ? evt.offsetX : evt.layerX;
let ysouris = evt.offsetX ? evt.offsetY : evt.layerY;
let xpos = evt.offsetX ? evt.clientX : evt.pageX;
let ypos = evt.offsetX ? evt.clientY + document.body.scrollTop : evt.pageY;
let xUser = Math.round((xsouris - decalh) / coeff - 100); // l'inverse de decalh+coeff*(val+100);
let yUser = Math.round(100 - (ysouris - decalv) / coeff); // l'inverse de decalv+coeff*(100-val);
bulleHaut.firstChild.nodeValue = `x=${xUser}, y=${yUser}`;
let tabHTMLbas = []; // message pour les trous
for (let i in position_trous_MZ) {
let ceTrou = position_trous_MZ[i];
let dist = (xUser - ceTrou[0]) * (xUser - ceTrou[0]) + (yUser - ceTrou[1]) * (yUser - ceTrou[1]) - ceTrou[2];
if (dist <= 0) {
tabHTMLbas.push(`Trous de Météorite : n=-1 -> n=${ceTrou[4]}`);
break;
}
}
for (let i in tabDepl) { // messages pour les suivants
let ceGowap = tabDepl[i][0]; // position courante du suivant
if (Math.abs(xUser - ceGowap.x) < 3 && Math.abs(yUser - ceGowap.y) < 3) {
tabHTMLbas.push(`(${ceGowap.x}, ${ceGowap.y}, ${ceGowap.n}) ${ceGowap.id} ${ceGowap.nom}`);
}
}
bulleBas.innerHTML = tabHTMLbas.join('<br />');
bulle.style.top = `${ysouris + 8}px`;
bulle.style.left = `${xsouris + 16}px`;
};
addEvent(dessin, 'mousemove', affichePosition, true);
addEvent(dessin, 'mouseout', () => {
bulle.style.visibility = 'hidden';
}, true);
addEvent(dessin, 'mouseover', () => {
bulle.style.visibility = 'visible';
}, true);
dessine_carte(); // dessin initial
this.getElt = function () {
return div1_carte;
};
} catch (exc) {
logMZ('glissiere_MZ.carte_MZ', exc);
}
}
/** ********************
* analyse de la vue pour produire un objet
* Raistlin 25/09/2020, intégré par Roule
*
* en mode objet car ça permet d'isoler les noms
/**********************/
var MZ_AnalyseVue = { // ceci est un OBJET stocké comme une variable globale
sectionList: {
Monstre: "VueMONSTRE",
Troll: "VueTROLL",
Tresor: "VueTRESOR",
Champignon: "VueCHAMPIGNON",
Lieu: "VueLIEU",
Cenotaphe: "VueCADAVRE"
},
columnTranslation: {
"Dist.": "distance",
"Actions": "actions",
"Réf.": "Id",
"Nom": "nom",
"X": "x",
"Y": "y",
"N": "n",
"Niv.": "niveau",
"Type": "nom",
"Race": "race",
"Champignon": "nom",
},
getSectionVueColsHeader: function (section) {
let colList = [];
for (let col of document.getElementById(section).childNodes[0].childNodes[0].childNodes) {
if (typeof col.innerText !== 'undefined') {
colList.push(col.innerText);
}
}
return colList;
},
getSectionVueLines: function (section) {
let sectionArray = [];
for (let line of document.getElementById(section).childNodes[1].childNodes) {
let lineArray = [];
for (let field of line.childNodes) {
lineArray.push(field.innerText);
}
sectionArray.push(lineArray);
}
return sectionArray;
},
htmlToObj: function () {
this.oVue = {};
for (let section in this.sectionList) {
let sectionColList = this.getSectionVueColsHeader(this.sectionList[section]);
let sectionLineList = this.getSectionVueLines(this.sectionList[section]);
let oSection = [];
for (let line in sectionLineList) {
let oElement = {};
for (let col in sectionColList) {
let colTranslated = this.columnTranslation[sectionColList[col]];
if (!colTranslated) {
continue;
}
oElement[colTranslated] = sectionLineList[line][col];
}
oSection.push(oElement);
}
this.oVue[section] = oSection;
}
this.oVue.caseOrigine = { x: MY_getValue(`${numTroll}.position.X`), y: MY_getValue(`${numTroll}.position.Y`), n: MY_getValue(`${numTroll}.position.N`) };
},
messageHandler: function (event) {
debugMZ(`get event, origin=${event.origin}`);
debugMZ(`get event, data=${event.data}`);
debugMZ(`sendVueExterne, domaine=${MZ_AnalyseVue.domaine}`);
MZ_AnalyseVue.otherTab.postMessage(MZ_AnalyseVue.oVue, MZ_AnalyseVue.domaine);
},
openVueExterne: function (url) {
window.addEventListener("message", this.messageHandler);
let oURL = new URL(url); // extraire le hostname, on en aura besoin dans sendVueExterne
this.htmlToObj();
// debugMZ(JSON.stringify(this.oVue));
this.url = url;
this.domaine = `${oURL.protocol}//${oURL.hostname}`;
this.otherTab = window.open(url, 'vueExtnMZ');
// l'onglet (ou fenêtre) va envoyer un message quand il sera prêt et on lui enevrra la vue alors (fonction messageHandler)
},
};
/** ********************************************************
**** Fin de zone à déplacer dans une bibli commune ********
**********************************************************/
/* DEBUG: NETTOYAGE TAGS */
if (MY_getValue(`${numTroll}.TAGSURL`)) {
MY_removeValue(`${numTroll}.TAGSURL`);
}
// Alerte si mode dev
if (isDEV) {
let divpopup = document.createElement('div');
divpopup.id = 'divDEV';
divpopup.style =
'position: fixed;' +
'border: 15px solid red;' +
'top: 10px;right: 10px;' +
'background-color: white;' +
'color: black;' +
'font-size: large;' +
'padding: 5px' +
'z-index: 200;';
appendText(divpopup, '[MZ] Mode DEV');
divpopup.title = 'Pour revenir en mode normal, \nshift-click sur le mot "Crédits" dans Options/Pack Graphique';
document.body.appendChild(divpopup);
}
/** x~x regroupement des getPortee() ----------------------------------- */
function getPortee(param) {
let p = Math.max(0, Number(param));
return Math.ceil(Math.sqrt(2 * p + 10.75) - 3.5);
// ça devrait être floor, +10.25, -2.5
}
/** x~x Calculs expérience / niveau ------------------------------------ */
function isLetter(c) {
return c.toLowerCase() != c.toUpperCase();
}
function getPXKill(niv) {
if (nivTroll == undefined) {
return '? (visitez le profil privé)';
}
return Math.max(0, 10 + 3 * niv - 2 * nivTroll);
}
function getPXDeath(niv) {
if (nivTroll == undefined) {
return '? (visitez le profil privé)';
}
return Math.max(0, 10 + 3 * nivTroll - 2 * niv);
}
function analysePX(niv) {
niv = `${niv}`;
let i = niv.indexOf('+');
if (i != -1) { // si niv = 'XX+' ??
return ` \u2192 \u2265 <b>${getPXKill(niv.slice(0, i))}</b> PX`; // \u2192 = '→'
}
i = niv.slice(1).indexOf('-'); // si niv = 'XX-YY' ??
if (i != -1) {
let max = getPXKill(niv.slice(i + 2));
if (max == 0) {
return ' \u2192 <b>0</b> PX';
} // \u2192 = '→'
return ` \u2192 <b>${getPXKill(niv.slice(0, i + 1))}</b> \u2264 PX \u2264 <b>${max}</b>`;
}
i = niv.indexOf('='); // ???
if (i != -1) {
let max = getPXKill(niv.slice(i + 1));
return max == 0 ? ' \u2192 <b>0</b> PX' : ` \u2192 \u2264 <b>${max}</b> PX`;
}
return ` \u2192 <b>${getPXKill(niv)}</b> PX`;
}
function analysePXTroll(niv) {
let str = analysePX(niv);
str = `${str}<br/>Vous lui rapportez <b>${getPXDeath(niv)}</b> PX.`;
return str;
}
/** x~x Gestion compos / champis --------------------------------------- */
// Refonte totale du code de Zorya
// Elements à implémenter en dur dans MZ2.0
var numQualite = {
'Très Mauvaise': 1,
'Mauvaise': 2,
'Moyenne': 3,
'Bonne': 4,
'Très Bonne': 5
};
var qualiteNum = [
'_dummy_',
'Très Mauvaise',
'Mauvaise',
'Moyenne',
'Bonne',
'Très Bonne'
];
// WARNING (gath) - non utilisé -> commenté
// let nival = {
// 'Abishaii Bleu': 19,
// 'Abishaii Noir': 10,
// 'Abishaii Rouge': 23,
// 'Abishaii Vert': 15,
// 'Ame-en-peine': 8,
// 'Amibe Geante': 9,
// 'Anaconda des Catacombes': 8,
// 'Ankheg': 10,
// 'Anoploure Purpurin': 36,
// 'Araignee Geante': 2,
// 'Ashashin': 35,
// 'Balrog': 50,
// 'Banshee': 16,
// 'Barghest': 36,
// 'Basilisk': 11,
// 'Behemoth': 34,
// 'Behir': 14,
// 'Beholder': 50,
// 'Boggart': 3,
// 'Bondin': 9,
// "Bouj'Dla Placide": 37,
// "Bouj'Dla": 19,
// 'Bulette': 19,
// 'Caillouteux': 1,
// 'Capitan': 35,
// 'Carnosaure': 25,
// 'Champi-Glouton': 3,
// 'Chauve-Souris Geante': 4,
// 'Cheval a Dents de Sabre': 23,
// 'Chevalier du Chaos': 20,
// 'Chimere': 13,
// 'Chonchon': 24,
// 'Coccicruelle': 22,
// 'Cockatrice': 5,
// 'Crasc Medius': 17,
// 'Crasc Maexus': 25,
// 'Crasc': 10,
// 'Croquemitaine': 6,
// 'Cube Gelatineux': 32,
// 'Daemonite': 27,
// 'Diablotin': 5,
// 'Dindon du Chaos': 1,
// 'Djinn': 29,
// 'Ectoplasme': 18,
// 'Effrit': 27,
// "Elementaire d'Air": 23,
// "Elementaire d'Eau": 17,
// 'Elementaire de Feu': 21,
// 'Elementaire de Terre': 21,
// 'Elementaire du Chaos': 26,
// 'Erinyes': 7,
// 'Esprit-Follet': 16,
// 'Essaim Craterien': 30,
// 'Essaim Sanguinaire': 25,
// 'Ettin': 8,
// 'Familier': 1,
// 'Fantome': 24,
// 'Feu Follet': 20,
// 'Flagelleur Mental': 33,
// 'Foudroyeur': 38,
// 'Fumeux': 22,
// 'Fungus Geant': 9,
// 'Fungus Violet': 4,
// 'Furgolin': 10,
// 'Gargouille': 3,
// 'Geant de Pierre': 13,
// 'Geant des Gouffres': 22,
// "Geck'oo Majestueux": 40,
// "Geck'oo": 15,
// 'Glouton': 20,
// 'Gnoll': 5,
// 'Gnu Domestique': 1,
// 'Gnu Sauvage': 1,
// 'Goblin': 4,
// 'Goblours': 4,
// "Golem d'Argile": 15,
// 'Golem de cuir': 1,
// 'Golem de Chair': 8,
// 'Golem de Fer': 31,
// 'Golem de mithril': 1,
// 'Golem de metal': 1,
// 'Golem de papier': 1,
// 'Golem de Pierre': 23,
// 'Gorgone': 11,
// 'Goule': 4,
// 'Gowap Apprivoise': 1,
// 'Gowap Sauvage': 1,
// 'Gremlins': 3,
// 'Gritche': 39,
// 'Grouilleux': 4,
// 'Grylle': 31,
// 'Harpie': 4,
// 'Hellrot': 18,
// 'Homme-Lezard': 4,
// 'Hurleur': 8,
// 'Hydre': 50,
// 'Incube': 13,
// 'Kobold': 2,
// 'Labeilleux': 26,
// 'Lezard Geant': 5,
// 'Liche': 50,
// 'Limace Geante': 10,
// 'Loup-Garou': 8,
// 'Lutin': 4,
// 'Mante Fulcreuse': 30,
// 'Manticore': 9,
// 'Marilith': 33,
// 'Meduse': 6,
// 'Megacephale': 38,
// 'Mille-Pattes Geant': 14,
// 'Mimique': 6,
// 'Minotaure': 7,
// 'Molosse Satanique': 8,
// 'Momie': 4,
// 'Monstre Rouilleur': 3,
// "Mouch'oo Domestique": 14,
// "Mouch'oo Majestueux Sauvage": 33,
// "Mouch'oo Sauvage": 14,
// 'Na-Haniym-Heee': 0,
// 'Necrochore': 37,
// 'Necromant': 39,
// 'Necrophage': 8,
// 'Naga': 10,
// 'Nuee de Vermine': 13,
// "Nuage d'Insectes": 7,
// 'Ogre': 7,
// 'Ombre de Roches': 13,
// 'Ombre': 2,
// 'Orque': 3,
// 'Ours-Garou': 18,
// 'Palefroi Infernal': 29,
// 'Phoenix': 32,
// 'Pititabeille': 0,
// 'Plante Carnivore': 4,
// 'Pseudo-Dragon': 5,
// 'Rat Geant': 2,
// 'Rat-Garou': 3,
// 'Rocketeux': 5,
// 'Sagouin': 3,
// 'Scarabee Geant': 4,
// 'Scorpion Geant': 10,
// 'Shai': 28,
// 'Sirene': 8,
// 'Slaad': 5,
// 'Sorciere': 17,
// 'Spectre': 14,
// 'Sphinx': 30,
// 'Squelette': 1,
// 'Strige': 2,
// 'Succube': 13,
// 'Tertre Errant': 20,
// 'Thri-kreen': 10,
// 'Tigre-Garou': 12,
// 'Titan': 26,
// 'Trancheur': 35,
// 'Tubercule Tueur': 14,
// 'Tutoki': 4,
// 'Vampire': 29,
// 'Ver Carnivore Geant': 12,
// 'Ver Carnivore': 11,
// 'Veskan Du Chaos': 14,
// 'Vouivre': 33,
// 'Worg': 5,
// 'Xorn': 14,
// 'Yeti': 8,
// 'Yuan-ti': 15,
// 'Zombie': 2
// }
var tabEM = {
// Monstre: [Compo exact, Sort, Position, Localisation]
// AA
'Basilisk': ["Œil d'un ", "Analyse Anatomique", 3, "Tête"],
// AE
'Ankheg': ["Carapace d'un", "Armure Ethérée", 3, "Spécial"],
'Rocketeux': ["Tripes d'un", "Armure Ethérée", 4, "Corps"],
// AdA
'Loup-Garou': ["Bras d'un", "Augmentation de l'Attaque", 3, "Membre"],
'Titan': ["Griffe d'un", "Augmentation de l'Attaque", 4, "Membre"],
// AdE
'Erinyes': ["Plume d'une", "Augmentation de l'Esquive", 3, "Membre"],
'Palefroi Infernal': ["Sabot d'un", "Augmentation de l'Esquive", 4, "Membre"],
// AdD
'Manticore': ["Patte d'une", "Augmentation des Dégâts", 3, "Membre"],
'Trancheur': ["Griffe d'un", "Augmentation des Dégâts", 4, "Membre"],
// BAM
'Banshee': ["Peau d'une", "Bulle Anti-Magie", 3, "Corps"],
// BuM
'Essaim Sanguinaire': ["Pattes d'un", "Bulle Magique", 3, "Membre"],
'Sagouin': ["Patte d'un", "Bulle Magique", 4, "Membre"],
'Effrit': ["Cervelle d'un", "Bulle Magique", 5, "Tête"],
// Explo
'Diablotin': ["Cœur d'un", "Explosion", 3, "Corps"],
'Chimère': ["Sang d'une", "Explosion", 4, "Corps"],
'Barghest': ["Bave d'un", "Explosion", 5, "Spécial"],
// FP
'Nécrophage': ["Tête d'un", "Faiblesse Passagère", 3, "Tête"],
'Vampire': ["Canine d'un", "Faiblesse Passagère", 4, "Spécial"],
// FA
'Gorgone': ["Chevelure d'une", "Flash Aveuglant", 3, "Tête"],
'Géant des Gouffres': ["Cervelle d'un", "Flash Aveuglant", 4, "Tête"],
// Glue
'Limace Géante': ["Mucus d'une", "Glue", 3, "Spécial"],
'Grylle': ["Gueule d'un", "Glue", 4, "Tête"],
// GdS
'Abishaii Noir': ["Serre d'un", "Griffe du Sorcier", 3, "Membre"],
'Vouivre': ["Venin d'une", "Griffe du Sorcier", 4, "Spécial"],
'Araignée Géante': ["Mandibule d'une", "Griffe du Sorcier", 5, "Spécial"],
// Invi
"Nuage d'Insectes": ["Chitine d'un", "Invisibilité", 3, "Spécial"],
'Yuan-ti': ["Cervelle d'un", "Invisibilité", 4, "Tête"],
'Gritche': ["Epine d'un", "Invisibilité", 5, "Spécial"],
// Lévitation
// ???
// PréM :
'Ashashin': ["Œil d'un ", "Précision Magique", 3, "Tête"],
'Crasc': ["Œil Rougeoyant d'un ", "Précision Magique", 4, "Tête"],
// Proj
'Yéti': ["Jambe d'un", "Projection", 3, "Membre"],
'Djinn': ["Tête d'un", "Projection", 4, "Tête"],
// PuM :
'Incube': ["Épaule musclée d'un", "Puissance Magique", 3, "Membre"],
'Capitan': ["Tripes Puantes d'un", "Puissance Magique", 4, "Corps"],
// Sacro
'Sorcière': ["Verrue d'une", "Sacrifice", 3, "Spécial"],
// Télék
'Plante Carnivore': ["Racine d'une", "Télékinésie", 3, "Spécial"],
'Tertre Errant': ["Cervelle d'un", "Télékinésie", 4, "Tête"],
// TP
'Boggart': ["Main d'un", "Téléportation", 3, "Membre"],
'Succube': ["Téton Aguicheur d'une", "Téléportation", 4, "Corps"],
'Nécrochore': ["Os d'un", "Téléportation", 5, "Corps"],
// VA
'Abishaii Vert': ["Œil d'un", "Vision Accrue", 3, "Tête"],
// VL
'Fungus Géant': ["Spore d'un", "Vision Lointaine", 3, "Spécial"],
'Abishaii Rouge': ["Aile d'un", "Vision Lointaine", 4, "Membre"],
// VlC
'Zombie': ["Cervelle Putréfiée d'un", "Voir le Caché", 3, "Tête"],
'Shai': ["Tripes d'un", "Voir le Caché", 4, "Corps"],
'Phoenix': ["Œil d'un", "Voir le Caché", 5, "Tête"],
// VT
'Naga': ["Ecaille d'un", "Vue Troublée", 3, "Corps"],
'Marilith': ["Ecaille d'une", "Vue Troublée", 4, "Membre"],
// Variables
'Rat': ["d'un"],
'Rat Géant': ["d'un"],
'Dindon': ["d'un"],
'Goblin': ["d'un"],
'Limace': ["d'une"],
'Limace Géante': ["d'une"],
'Ver': ["d'un"],
'Ver Carnivore': ["d'un"],
'Ver Carnivore Géant': ["d'un"],
'Fungus': ["d'un"],
'Vouivre': ["d'une"],
'Gnu': ["d'un"],
'Scarabée': ["d'un"]
};
var mundiChampi = {
'Préscientus Reguis': 'du Phoenix',
'Amanite Trolloïde': 'de la Mouche',
'Girolle Sanglante': 'du Dindon',
'Horreur Des Prés': 'du Gobelin',
'Bolet Péteur': 'du Démon',
'Pied Jaune': 'de la Limace',
'Agaric Sous-Terrain': 'du Rat',
'Suinte Cadavre': "de l'Hydre",
'Cèpe Lumineux': 'du Ver',
'Fungus Rampant': 'du Fungus',
'Nez Noir': 'de la Vouivre',
'Pleurote Pleureuse': 'du Gnu',
'Phytomassus Xilénique': 'du Scarabée'
};
// WARNING (gath) - non utilisé -> commenté
// function addInfoMM(node, mob, niv, qualite, effetQ) {
// appendText(node, ' ');
// let urlImg = URL_MZimg + 'Competences/melangeMagique.png';
// let text = ' [-' + (niv + effetQ) + ' %]';
// let str = '';
// switch (mob[0]) {
// case 'A':
// case 'E':
// case 'I':
// case 'O':
// case 'U':
// str = "Compo d'";
// break;
// default:
// str = 'Compo de ';
// }
// let title = str + mob + ' : -' + niv + '\nQualité ' + qualite + ' : -' + effetQ;
// let span = createImageSpan(urlImg, 'MM:', title, text);
// node.appendChild(span);
// }
function addInfoEM(node, mob, compo, qualite, localisation) {
if (!tabEM[mob]) {
return;
}
let title = 'Composant variable', texte = 'Variable', bold = false;
if (tabEM[mob].length > 1) {
let pc = 5 * (numQualite[qualite] - tabEM[mob][2]);
if (tabEM[mob][0].indexOf(compo) == -1) {
pc = pc - 20;
}
if (localisation.indexOf(tabEM[mob][3]) == -1) {
pc = pc - 5;
}
if (pc < -20) {
return;
}
if (pc >= 0) {
bold = true;
}
texte = `${aff(pc)}%`;
title = `${texte} pour l'écriture de ${tabEM[mob][1]}`;
}
let urlImg = `${URL_MZimg}Competences/ecritureMagique.png`;
let span = createImageSpan(urlImg, 'EM:', title, ` [${texte}]`, bold);
node.appendChild(span);
}
function insererInfosEM(tbody) {
// lancé par equip, equipgowap
let trCompos = document.evaluate("./tr[not(starts-with(td[2]/img/@alt,'Pas'))]", tbody, null, 7, null);
// let strCompos = '';
for (let i = 0; i < trCompos.snapshotLength; i++) {
let node = trCompos.snapshotItem(i).childNodes[7];
let str = node.firstChild.textContent;
let compo = trim(str.slice(0, str.indexOf(" d'un")));
let mob = trim(str.slice(str.indexOf("d'un") + 5));
// Si non-EM on stoppe le traitement
if (!tabEM[mob]) {
continue;
}
str = trCompos.snapshotItem(i).childNodes[9].textContent;
let qualite = trim(str.slice(str.indexOf('Qualit') + 9));
let localisation = trim(str.slice(0, str.indexOf(' |')));
addInfoEM(node, mob, compo, qualite, localisation);
}
}
function getQualite(qualite) {
let nb = numQualite[qualite];
return nb ? nb - 1 : -1;
}
function getEM(nom) {
if (nom.indexOf('[') != -1) {
nom = trim(nom.substring(0, nom.indexOf('[')));
}
if (tabEM[nom]) {
return nom;
}
return '';
}
// DEBUG ex-fonction composantEM
function compoMobEM(mob) {
if (!tabEM[mob]) {
return '';
}
if (tabEM[mob].length == 1) {
return `Divers composants ${tabEM[mob][0]} ${mob} (Composant Variable)`;
}
return `${tabEM[mob][0]} ${mob} (Qualité ${qualiteNum[tabEM[mob][2]]}) pour l'écriture de ${mob}`;
}
// DEBUG ex-fonction compoEM
function titreCompoEM(mob, compo, localisation, qualite) {
if (!tabEM[mob]) {
return '';
}
if (tabEM[mob].length == 1) {
return 'Composant variable';
}
let pc = 5 * (tabEM[mob][2] - numQualite[qualite]);
if (compo.indexOf(tabEM[mob][0]) == -1) {
pc = pc - 20;
}
if (localisation.indexOf(tabEM[mob][3]) == -1) {
pc = pc - 5;
}
if (pc >= -20) {
return `${pc}% pour l'écriture de ${tabEM[mob][2]}`;
}
return '';
}
// DEBUG - rétrocompatibilité
function compoEM(mob) {
// appelé dans libs, vue
return compoMobEM(mob);
}
function composantEM(mob, compo, localisation, qualite) {
// appelé dans libs, tancompo
return titreCompoEM(mob, compo, localisation, qualite);
}
/** x~x Stockage des Talents ------------------------------------------- */
var arrayTalents = {
/* Compétences */
'Acceleration du Metabolisme': 'AM',
'Attaque Precise': 'AP',
'Balayage': 'Balayage',
// 'Balluchonnage':'Ballu',
'Baroufle': 'Baroufle',
'Bidouille': 'Bidouille',
'Botte Secrete': 'BS',
'Camouflage': 'Camou',
'Charger': 'Charger',
'Connaissance des Monstres': 'CdM',
'Construire un Piege': 'Piege',
'Piege a Feu': 'PiegeFeu',
'Piege a Glue': 'PiegeGlue',
'Contre-Attaquer': 'CA',
'Coup de Butoir': 'CdB',
'Course': 'Course',
'Deplacement Eclair': 'DE',
'Dressage': 'Dressage',
'Ecriture Magique': 'EM',
'Frenesie': 'Frenesie',
'Golemologie': 'Golemo',
'Golem de cuir': 'GolemCuir',
'Golem de metal': 'GolemMetal',
'Golem de mithril': 'GolemMithril',
'Golem de papier': 'GolemPapier',
'Grattage': 'Grattage',
'Hurlement Effrayant': 'HE',
'Identification des Champignons': 'IdC',
'Insultes': 'Insultes',
'Lancer de Potions': 'LdP',
'Marquage': 'Marquage',
'Melange Magique': 'Melange',
'Miner': 'Miner',
'Travail de la Pierre': 'Pierre',
'Necromancie': 'Necro',
'Painthure de Guerre': 'PG',
'Parer': 'Parer',
'Pistage': 'Pistage',
'Planter un Champignon': 'PuC',
'Regeneration Accrue': 'RA',
'Reparation': 'Reparation',
'Retraite': 'Retraite',
'RotoBaffe': 'RB',
'Shamaner': 'Shamaner',
"S'interposer": 'SInterposer',
'Tailler': 'Tailler',
// 'Vol':'Vol',
/* Sortilèges */
'Analyse Anatomique': 'AA',
'Armure Etheree': 'AE',
'Augmentation de l´Attaque': 'AdA', // obsolète?
"Augmentation de l'Attaque": 'AdA',
'Augmentation de l´Esquive': 'AdE',
'Augmentation des Degats': 'AdD',
'Bulle Anti-Magie': 'BAM',
'Bulle Magique': 'BuM',
'Explosion': 'Explo',
'Faiblesse Passagere': 'FP',
'Flash Aveuglant': 'FA',
'Glue': 'Glue',
'Griffe du Sorcier': 'GdS',
'Hypnotisme': 'Hypno',
'Identification des Tresors': 'IdT',
'Invisibilite': 'Invi',
'Levitation': 'Levitation',
'Precision Magique': 'PreM',
'Projectile Magique': 'Projo',
'Projection': 'Proj',
'Puissance Magique': 'PuM',
'Rafale Psychique': 'Rafale',
'Sacrifice': 'Sacro',
'Siphon des ames': 'Siphon',
'Telekinesie': 'Telek',
'Teleportation': 'TP',
'Vampirisme': 'Vampi',
'Vision Accrue': 'VA',
'Vision lointaine': 'VL',
'Voir le Cache': 'VlC',
'Vue Troublee': 'VT'
// '':''
};
// DEBUG - Pour rétrocompatibilité
function getSortComp(nom, niveau) {
return getTalent(nom, niveau);
}
function getTalent(nom, niveau = '') {
if (nom === true) {
return true;
}
let nomEnBase = arrayTalents[epure(nom)];
if (!nomEnBase) {
nomEnBase = nom;
}
if (MY_getValue(`${numTroll}.talent.${nomEnBase}${niveau}`)) {
return Number(MY_getValue(`${numTroll}.talent.${nomEnBase}${niveau}`));
}
return 0;
}
function removeAllTalents() {
for (let talent in arrayTalents) {
let nomEnBase = arrayTalents[talent];
if (MY_getValue(`${numTroll}.talent.${nomEnBase}`)) {
MY_removeValue(`${numTroll}.talent.${nomEnBase}`);
continue;
}
let niveau = 1;
while (MY_getValue(`${numTroll}.talent.${nomEnBase}${niveau}`)) {
MY_removeValue(`${numTroll}.talent.${nomEnBase}${niveau}`);
niveau++;
}
}
}
function isProfilActif() { // DEBUG: Réfléchir à l'utilité de cette fonction
try { // Roule 07/06/2017 protection, ça plante si on est dans une callback de XMLHTTPREQUEST
let att = MY_getValue(`${numTroll}.caracs.attaque`);
let attbmp = MY_getValue(`${numTroll}.caracs.attaque.bmp`);
let attbmm = MY_getValue(`${numTroll}.caracs.attaque.bmm`);
let mm = MY_getValue(`${numTroll}.caracs.mm`);
let deg = MY_getValue(`${numTroll}.caracs.degats`);
let degbmp = MY_getValue(`${numTroll}.caracs.degats.bmp`);
let degbmm = MY_getValue(`${numTroll}.caracs.degats.bmm`);
let vue = parseInt(MY_getValue(`${numTroll}.caracs.vue`));
let bmvue = parseInt(MY_getValue(`${numTroll}.caracs.vue.bm`));
if (att == null || attbmp == null || attbmm == null || mm == null || deg == null ||
degbmp == null || degbmm == null || vue == null || bmvue == null) {
return false;
}
return true;
} catch (e) {
return false;
}
}
/** x~x Gestion des CDMs ----------------------------------------------- */
function getPVsRestants(pv, bless, vue) {
bless = Number(bless.match(/\d+/)[0]);
if (bless == 0) {
return null;
}
let pvminmax = pv.match(/\d+/g);
let oMinMaxPV = { min: pvminmax[0], max: pvminmax[1] };
let oMinMaxPVRestant = MZ_getPVsRestants(oMinMaxPV, bless);
if (vue) {
if (!oMinMaxPVRestant.min) {
return oMinMaxPVRestant.max ? ` (\u2A7D${oMinMaxPVRestant.max})` : ''; // U+2A7D 'LESS-THAN OR SLANTED EQUAL TO'
}
return oMinMaxPVRestant.max ? ` (${oMinMaxPVRestant.min}-${oMinMaxPVRestant.max})` : ` (\u2A7E${oMinMaxPVRestant.min})`; // U+2A7E 'GREATER-THAN OR SLANTED EQUAL TO'
}
let oRet = ['Points de Vie restants : '];
if (oMinMaxPVRestant.min) {
oRet[1] = oMinMaxPVRestant.max ? `Entre ${oMinMaxPVRestant.min} et ${oMinMaxPVRestant.max}` : `\u2A7E${oMinMaxPVRestant.min}`; // U+2A7E 'GREATER-THAN OR SLANTED EQUAL TO'
} else {
oRet[1] = oMinMaxPVRestant.max ? `\u2A7D${oMinMaxPVRestant.max}` : 'inconnu'; // U+2A7D 'LESS-THAN OR SLANTED EQUAL TO'
}
return oRet;
}
function MZ_getPVsRestants(oMinMaxPV, bless) { // rend un objet minmax
if (bless == 95) {
return { min: 1, max: Math.floor(oMinMaxPV.max / 20) };
}
if (bless == 5) {
return { min: Math.floor(oMinMaxPV.min * 19 / 20), max: oMinMaxPV.max };
}
return { min: Math.ceil(oMinMaxPV.min * (95 - bless) / 100), max: Math.floor(oMinMaxPV.max * (105 - bless) / 100) };
}
function insertButtonCdmSmartphone(nextName, onClick, texte) {
let tabInput = document.getElementsByName(nextName);
if (!tabInput) {
return false;
}
let eInput = tabInput[0];
if (!eInput) {
return false;
}
let eDiv = eInput.parentNode;
if (!eDiv) {
return false;
}
let eNewDiv = eDiv.cloneNode(true);
let tabNewSpan = eNewDiv.getElementsByTagName('span');
if (!tabNewSpan || tabNewSpan.length == 0) {
return false;
}
Array.from(tabNewSpan).forEach((pSpan) => {
if (pSpan.getElementsByTagName('span').length > 0) {
return false;
}
replaceContentByText(pSpan, texte);
});
let tabNewInput = eNewDiv.getElementsByTagName('input');
if (!tabNewInput) {
return false;
}
let eNewInput = tabNewInput[0];
if (!eNewInput) {
return false;
}
eNewInput.onclick = onClick;
eNewInput.value = texte;
eNewInput.type = "button";
insertBefore(eDiv, eNewDiv);
return true;
}
function insertButtonCdm(nextName, onClick, texte) {
if (texte == null) {
texte = 'Participer au bestiaire';
}
if (insertButtonCdmSmartphone(nextName, onClick, texte)) {
return;
}
let nextNode = document.getElementsByName(nextName)[0];
if (!nextNode) nextNode = document.getElementById(nextName);
/* version input/button
let button = document.createElement('input');
button.type = 'button';
button.className = 'mh_form_submit';
button.value = texte;
button.onmouseover = function () {
this.style.cursor = 'pointer';
};
if (onClick) {
button.onclick = onClick;
}
*/
/* version <a> */
let button = document.createElement('a');
button.href = '#';
button.classList.add('submit');
button.classList.add('ui-btn');
button.style.marginLeft = '3px';
button.appendChild(document.createTextNode(texte));
if (onClick) {
button.onclick = onClick;
}
insertBefore(nextNode, button);
return button;
}
function createCDMTable(id, nom, donneesMonstre, closeFunct) { // rend un Élément Table
try {
let table = document.createElement('table');
let profilActif = isProfilActif();
let desk_classes = isPage("MH_Play/Play_vue") ? 'mh_textbox ' : '';
let ui_classes = isDesktopView() ? `${desk_classes}mh_tdborder` : 'ui-body-a ui-corner-all';
table.className = ui_classes;
table.border = 0;
table.cellSpacing = 1;
table.cellPadding = 4;
if (!isDesktopView() && isPage("MH_Play/Play_vue")) {
table.style.fontSize = 'smaller';
}
let thead = document.createElement('thead');
let tr = appendTr(thead, 'mh_tdtitre ui-bar-b');
let td = appendTdText(tr, `CDM de ${nom} (N° ${id})`, false);
td.style.fontWeight = 'bold';
if (closeFunct) {
td.colSpan = 2;
td.style.borderRight = 'none';
td = appendTdText(tr, 'X', false);
td.style.cursor = 'pointer';
td.style.textAlign = 'right';
td.style.fontWeight = 'bold';
td.style.width = '1%';
td.style.borderLeft = 'none';
td.onclick = closeFunct;
} else {
td.colSpan = 3;
}
table.appendChild(thead);
let tbody = document.createElement('tbody');
table.appendChild(tbody);
// calcul des PX gagnés
let ominmaxPX = {};
if (donneesMonstre.niv) {
if (donneesMonstre.niv.min) {
ominmaxPX.min = getPXKill(donneesMonstre.niv.min);
}
if (donneesMonstre.niv.max) {
ominmaxPX.max = getPXKill(donneesMonstre.niv.max);
}
}
MZ_tab_carac_add_tr_minmax2(tbody, 'Niveau', donneesMonstre.niv, 'PX', ominmaxPX);
MZ_tab_carac_add_tr_texte(tbody, 'Famille', donneesMonstre.fam, '');
// MZ_tab_carac_add_tr_texte(tbody, 'Génération', donneesMonstre.gen == 23 ? '2 ou 3' : donneesMonstre.gen, ''); // remplacé par une icône
MZ_tab_carac_add_tr_texte(tbody, 'Blessure', MZ_tab_carac_mkBlessureTexte(donneesMonstre), '');
MZ_tab_carac_add_tr_minmax(tbody, 'Points de Vie', donneesMonstre.pv, 'PV');
MZ_tab_carac_add_tr_minmax(tbody, 'Attaque', donneesMonstre.att, 'D6');
MZ_tab_carac_add_tr_minmax(tbody, 'Esquive', donneesMonstre.esq, 'D6');
MZ_tab_carac_add_tr_minmax(tbody, 'Dégâts', donneesMonstre.deg, 'D3');
MZ_tab_carac_add_tr_minmax(tbody, 'Régénération', donneesMonstre.reg, 'D3');
MZ_tab_carac_add_tr_minmax(tbody, 'Armure physique', donneesMonstre.armP, '');
MZ_tab_carac_add_tr_minmax(tbody, 'Armure magique', donneesMonstre.armM, '');
MZ_tab_carac_add_tr_minmax(tbody, 'Armure totale', donneesMonstre.arm, '');
MZ_tab_carac_add_tr_minmax(tbody, 'Vue', donneesMonstre.vue, 'Case(s)');
MZ_tab_carac_add_tr_minmax(tbody, 'MM', donneesMonstre.MM, '');
MZ_tab_carac_add_tr_minmax(tbody, 'RM', donneesMonstre.RM, '');
MZ_tab_carac_add_tr_minmax(tbody, 'Durée du tour', donneesMonstre.duree, ' heures');
MZ_tab_carac_add_tr_pouvoir(tbody, donneesMonstre);
MZ_tab_carac_add_tr_autres(tbody, donneesMonstre, id, nom);
/* à supprimer, remplacé par un "title" sur le 3e td de "autres"
let msgInfo = MZ_carac_build_nb_cmd_msg(donneesMonstre);
if (msgInfo) MZ_tab_carac_add_tr_sansTitre(tbody, msgInfo, 0, true);
*/
return table;
} catch (exc) {
avertissement('Une erreur est survenue (createCDMTable)', null, null, exc);
}
}
function MZ_tab_carac_mkBlessureTexte(donneesMonstre) {
if (donneesMonstre.bless === undefined) {
return;
}
let texte = `${donneesMonstre.bless}%`;
if (donneesMonstre.bless > 0 && donneesMonstre.pv && donneesMonstre.pv.min && donneesMonstre.pv.max) {
let ominmax = MZ_getPVsRestants(donneesMonstre.pv, donneesMonstre.bless);
texte = `${texte} (${ominmax.min}-${ominmax.max})`;
}
if (donneesMonstre.timegmt) {
texte = `${texte} le ${MZ_formatDateMS(new Date(donneesMonstre.timegmt * 1000), false)}`;
}
return texte;
}
// function MZ_tab_carac_add_tr_sansTitre(table, msg, bItalic) {
// if (!msg) { return; }
// let tr = appendTr(table, 'mh_tdpage');
// td = appendTdText(tr, msg);
// td.colSpan = 3;
// if (bItalic) { td.style.fontStyle = 'italic'; }
// td.className = 'mh_tdpage';
// return td;
// }
function MZ_tab_carac_add_tr_pouvoir(tbody, donneesMonstre) {
if (!donneesMonstre.pouv) {
return;
}
let td = MZ_tab_carac_add_tr_texte(tbody, 'Pouvoir', `${donneesMonstre.pouv} `, '', 0);
let tabImg = [];
MZ_tab_carac_add_tr_one_img(tabImg, donneesMonstre.portpouv, {
'de zone': ["zone.gif", "Pouvoir de zone"],
'automatique': ["automatique.gif", "Pouvoir automatique"],
'au toucher': ["toucher.gif", "Pouvoir au toucher"]
});
for (let iImg = 0; iImg < tabImg.length; iImg++) {
let thisImg = tabImg[iImg];
td.appendChild(createImage(URL_MZimg + thisImg[0], thisImg[1]));
}
}
function MZ_tab_carac_add_tr_autres(table, donneesMonstre, id, nom) {
let tabImg = [];
MZ_tab_carac_add_tr_one_img(tabImg, donneesMonstre.attd, {
'1': ['distance.gif', 'Attaque à distance'],
'~': ['cac.gif', 'Corps à corps']
}); // si absent
MZ_tab_carac_add_tr_one_img(tabImg, donneesMonstre.nb_att, {
1: ['1.gif', '1 attaque par tour'],
2: ['2.gif', '2 attaques par tour'],
3: ['3.gif', '3 attaques par tour'],
4: ['4.gif', '4 attaques par tour'],
5: ['5.gif', '5 attaques par tour'],
6: ['6.gif', '6 attaques par tour'],
999: ['plus.gif', "Beaucoup d'attaques par tour"]
});
MZ_tab_carac_add_tr_one_img(tabImg, donneesMonstre.attm, {
1: ['magic-wand.png', 'Attaque magique']
});
MZ_tab_carac_add_tr_one_img(tabImg, donneesMonstre.vole, {
1: ['levite.png', 'Lévite']
});
MZ_tab_carac_add_tr_one_img(tabImg, donneesMonstre.vit, {
lente: ['lent.gif', 'Lent à se déplacer'],
normale: ['normal.gif', 'Vitesse normale de déplacement'],
rapide: ['rapide.gif', 'Déplacement rapide']
});
MZ_tab_carac_add_tr_one_img(tabImg, donneesMonstre.charg, {
'vide': [null, null],
'~': ['charge2.gif', `Possède de l'équipement (${donneesMonstre.charg})`]
});
MZ_tab_carac_add_tr_one_img(tabImg, donneesMonstre.vlc, {
1: ['oeil.gif', 'Voit le caché']
});
MZ_tab_carac_add_tr_one_img(tabImg, donneesMonstre.gen, {
1: ['Phoenix1.png', 'Phœnix de première génération'],
2: ['Phoenix2.png', 'Phœnix de deuxième génération'],
3: ['Phoenix3.png', 'Phœnix de troisième génération'],
23: ['Phoenix23.png', 'Phœnix de deuxième ou troisième génération'],
});
let tr = appendTr(table, 'mh_tdpage');
let td = appendTdText(tr, 'Autres', true);
td.className = 'mh_tdtitre';
td.width = MZ_EtatCdMs.tdWitdh;
td = appendTd(tr);
td.className = 'mh_tdpage';
for (let iImg = 0; iImg < tabImg.length; iImg++) {
let thisImg = tabImg[iImg];
td.appendChild(createImage(URL_MZimg + thisImg[0], thisImg[1]));
}
if (donneesMonstre.esq != undefined) {
td.appendChild(MZ_Tactique.createImage(id, nom));
}
let txt = String.fromCharCode(160); // blanc insécable
if (donneesMonstre.nCdM) {
txt = donneesMonstre.nCdM;
}
let td2 = appendTdText(tr, txt);
td2.title = MZ_carac_build_nb_cmd_msg(donneesMonstre);
td2.style.width = '1%';
let myColor = MZ_CdMColorFromMode(donneesMonstre);
if (myColor) {
td2.style.backgroundColor = myColor;
td2.style.color = 'white';
}
return td;
}
function MZ_tab_carac_add_tr_one_img(tabImg, val, listCas) {
if (val == undefined) {
return;
}
// logMZ('MZ_tab_carac_add_tr_one_img: val=' + val);
let lVal = `${val}`.toLowerCase(); // astuce : transformer le nombre en string (beurk !)
if (listCas[lVal]) {
let t = listCas[lVal];
if (t[0] == null) {
return;
}
tabImg.push(t);
} else if (listCas['~']) {
tabImg.push(listCas['~']);
}
}
function MZ_tab_carac_add_tr_texte(table, titre, msg, unit) {
if (!msg) {
return;
}
let tr = appendTr(table, 'mh_tdpage');
let td = appendTdText(tr, titre, true);
td.className = 'mh_tdtitre';
td.width = MZ_EtatCdMs.tdWitdh;
let texte = msg;
if (unit) {
texte = `${texte} ${unit}`;
}
td = appendTdText(tr, texte);
td.colSpan = 2;
td.className = 'mh_tdpage';
return td;
}
function MZ_tab_carac_add_tr_minmax(table, titre, ominmax, unit) {
if (!ominmax) {
return;
}
if (!(ominmax.min || ominmax.max)) {
return;
}
let tr = appendTr(table, 'mh_tdpage');
let td = appendTdText(tr, titre, true);
td.className = 'mh_tdtitre';
td.width = MZ_EtatCdMs.tdWitdh;
let texte = '';
if (!ominmax.min || ominmax.min == 0) {
texte = `\u2A7D${ominmax.max}\u00A0${unit}`; // <= (mais plus beau)
} else if (!ominmax.max) {
texte = `\u2A7E${ominmax.min}\u00A0${unit}`; // >=
} else {
if (ominmax.min != ominmax.max) {
texte = `${ominmax.min}-${ominmax.max}\u00A0→\u00A0`;
if (ominmax.min > ominmax.max) {
td.style.color = 'red';
unit = `${unit} *** erreur ***`;
}
}
texte = `${texte}${(ominmax.min + ominmax.max) / 2}\u00A0${unit}`;
}
td = appendTdText(tr, texte);
let texte2 = '';
if (ominmax.min2 || ominmax.max2) { // affichage de l'intervalle de confiance à 80%
if (!ominmax.min2) {
texte2 = `\u2A7D${ominmax.max2}`; // <= (mais plus beau)
} else if (!ominmax.max2) {
texte2 = `\u2A7E${ominmax.min2}`; // >=
} else {
texte2 = `${ominmax.min2}-${ominmax.max2}`;
}
let span = document.createElement('span');
span.appendChild(document.createTextNode(texte2));
span.style.float = 'right';
span.style.textAlign = 'right';
span.style.background = 'yellow';
td.insertBefore(span, td.firstChild);
table.title = 'En jaune : intervalle de confiance à 80%';
}
td.colSpan = 2;
td.className = 'mh_tdpage';
return td;
}
function MZ_tab_carac_add_tr_minmax2(table, titre, ominmax, unit, ominmaxUnit) {
if (!ominmax) {
return;
}
if (!(ominmax.min || ominmax.max)) {
return;
}
let tr = appendTr(table, 'mh_tdpage');
let td = appendTdText(tr, titre, true);
td.className = 'mh_tdtitre';
td.width = MZ_EtatCdMs.tdWitdh;
let texte = '';
if (!ominmax.min || ominmax.min == 0) {
texte = `\u2A7D${ominmax.max}`;
} else if (!ominmax.max) {
texte = `\u2A7E${ominmax.min}`;
} else if (ominmax.min != ominmax.max) {
texte = `${ominmax.min}-${ominmax.max}`;
if (ominmax.min > ominmax.max) {
td.style.color = 'red';
texte = `${texte} *** erreur ***`;
}
} else {
texte = ominmax.min;
}
if (ominmaxUnit.min === undefined) {
if (ominmaxUnit.max === undefined) {
// ignore (ne devrait pas arriver)
} else {
texte = `${texte} \u2192 ${unit}\u2A7D${ominmaxUnit.max}`;
}
} else if (ominmaxUnit.max === undefined) {
texte = `${texte} \u2192 ${unit}\u2A7E${ominmaxUnit.min}`;
} else if (ominmaxUnit.min != ominmaxUnit.max) {
texte = `${texte} \u2192 ${ominmaxUnit.min}\u2A7D${unit}\u2A7D${ominmaxUnit.max}`;
if (ominmaxUnit.min > ominmaxUnit.max) {
td.style.color = 'red';
texte = `${texte} *** erreur ***`;
}
} else if (isNaN(ominmaxUnit.min)) {
texte = `${texte} \u2192 ${ominmaxUnit.min}`;
} else {
texte = `${texte} \u2192 ${ominmaxUnit.max}\u00A0${unit}`;
}
td = appendTdText(tr, texte);
td.colSpan = 2;
td.className = 'mh_tdpage';
return td;
}
/** x~x Gestion des enchantements -------------------------------------- */
var listeMonstreEnchantement = null,
listeEquipementEnchantement = null,
listeInfoEnchantement = null;
function computeCompoEnchantement() {
listeMonstreEnchantement = new Array();
listeInfoEnchantement = new Array();
listeEquipementEnchantement = new Array();
let liste = MY_getValue(`${numTroll}.enchantement.liste`).split(';');
for (let i = 0; i < liste.length; i++) {
let idEquipement = Number(liste[i]);
let nomEquipement = MY_getValue(`${numTroll}.enchantement.${idEquipement}.objet`);
let infoEnchanteur = MY_getValue(`${numTroll}.enchantement.${idEquipement}.enchanteur`);
if (nomEquipement == null || infoEnchanteur == null) {
continue;
}
infoEnchanteur = infoEnchanteur.split(';');
let texteGlobal = '';
for (let j = 0; j < 3; j++) {
let k = `${numTroll}.enchantement.${idEquipement}.composant.${j}`;
let v = MY_getValue(k);
let infoComposant = v.split(';');
if (infoComposant.length < 5) { // protection Roule 25/08/2017
logMZ(`err infoComposant k=${k}, v=${v}`);
continue;
}
listeMonstreEnchantement[infoComposant[2]] = 1;
let array = new Array();
array[0] = infoComposant[0].replace("Ril", "Œil");
array[1] = infoComposant[1];
array[2] = infoComposant[2];
array[3] = getQualite(infoComposant[3]);
let texte = infoComposant[4].replace("Ril", "Œil");
for (let jj = 5; jj < infoComposant.length; jj++) {
texte = `${texte};${infoComposant[jj].replace("Ril", "Œil")}`;
}
texteGlobal = `${texteGlobal}${texte}\n`;
texte = `${texte} pour l'enchantement d'un(e) ${nomEquipement} chez l'enchanteur n°${infoEnchanteur[0]} (${infoEnchanteur[1]}|${infoEnchanteur[2]}|${infoEnchanteur[3]})`;
array[4] = texte;
listeInfoEnchantement.push(array);
}
texteGlobal = `${texteGlobal}chez l'enchanteur n°${infoEnchanteur[0]} (${infoEnchanteur[1]}|${infoEnchanteur[2]}|${infoEnchanteur[3]})`;
listeEquipementEnchantement[idEquipement] = texteGlobal;
}
}
function isEnchant(nom) {
let monstreEnchant = '';
for (let j in listeInfoEnchantement) {
let monstre = listeInfoEnchantement[j][2].toLowerCase();
if (`${nom} `.toLowerCase().indexOf(`${monstre} `) >= 0) {
monstreEnchant = monstre;
break; // ça permet d'arreter de chercher dans le tableau des EM -> on gagne du temps
}
}
return trim(monstreEnchant);
}
function getInfoEnchantementFromMonstre(nom) {
try {
if (!listeMonstreEnchantement) {
computeCompoEnchantement();
}
let infosEnchant = '';
for (let j in listeInfoEnchantement) {
let monstre = listeInfoEnchantement[j][2].toLowerCase();
if (`${nom} `.toLowerCase().indexOf(`${monstre} `) < 0) {
continue;
}
if (infosEnchant == '') {
infosEnchant = listeInfoEnchantement[j][4];
} else {
infosEnchant = `${infosEnchant}\n${listeInfoEnchantement[j][4]}`;
}
}
return trim(infosEnchant);
} catch (exc) {
avertissement('Une erreur est survenue (getInfoEnchantementFromMonstre)', null, null, exc);
}
}
function composantEnchant(Monstre, composant, localisation, qualite) {
let compo = '';
for (let i = 0; i < listeInfoEnchantement.length; i++) {
if (listeInfoEnchantement[i][2].toLowerCase() == Monstre.toLowerCase() &&
listeInfoEnchantement[i][0].toLowerCase() == composant.toLowerCase() &&
listeInfoEnchantement[i][1].toLowerCase() == localisation.toLowerCase() &&
listeInfoEnchantement[i][3] <= qualite
) {
return listeInfoEnchantement[i][4];
}
}
return compo;
}
function insertEnchantInfos(tbody) {
try {
if (!listeMonstreEnchantement) {
computeCompoEnchantement();
}
let nodes = document.evaluate("descendant::img[@alt = 'Composant - Spécial']", tbody, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (nodes.snapshotLength == 0) {
return false;
}
let urlImg = `${URL_MZimg}enchant.png`;
for (let i = 0; i < nodes.snapshotLength; i++) {
let link = nodes.snapshotItem(i).nextSibling.nextSibling;
let nomCompoTotal = link.firstChild.nodeValue.replace(/\240/g, ' ');
let nomCompo = nomCompoTotal.substring(0, nomCompoTotal.indexOf(" d'un"));
nomCompoTotal = nomCompoTotal.substring(nomCompoTotal.indexOf("d'un"), nomCompoTotal.length);
nomCompoTotal = nomCompoTotal.substring(nomCompoTotal.indexOf(' ') + 1, nomCompoTotal.length);
let nomMonstre = nomCompoTotal.substring(0, nomCompoTotal.indexOf(" de Qualité"));
let qualite = nomCompoTotal.substring(nomCompoTotal.indexOf("de Qualité") + 11, nomCompoTotal.indexOf(' ['));
let localisation = nomCompoTotal.substring(nomCompoTotal.indexOf('[') + 1, nomCompoTotal.indexOf(']'));
if (isEnchant(nomMonstre).length <= 0) {
continue;
}
let infos = composantEnchant(nomMonstre, nomCompo, localisation, getQualite(qualite));
if (infos.length <= 0) {
continue;
}
if (link.parentNode == link.nextSibling.parentNode) {
link.parentNode.insertBefore(createImage(urlImg, infos), link.nextSibling);
} else {
link.parentNode.appendChild(createImage(urlImg, infos));
}
}
} catch (exc) {
avertissement('Une erreur est survenue (insertEnchantInfos)', null, null, exc);
}
}
function computeEnchantementEquipement(fontionTexte, fontionFormateTexte) {
try {
if (!listeMonstreEnchantement) {
computeCompoEnchantement();
}
let nodes = document.evaluate("//a[@class='AllLinks' and contains(@href,'TresorHistory.php')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (nodes.snapshotLength == 0) {
return false;
}
let urlImg = `${URL_MZimg}enchant.png`;
for (let i = 0; i < nodes.snapshotLength; i++) {
let link = nodes.snapshotItem(i);
let idEquipement = link.getAttribute('href');
idEquipement = idEquipement.substring(idEquipement.indexOf('ai_IDTresor=') + 12);
idEquipement = parseInt(idEquipement.substring(0, idEquipement.indexOf("'")));
let nomEquipement = trim(link.firstChild.nodeValue);
let enchanteur = MY_getValue(`${numTroll}.enchantement.${idEquipement}.enchanteur`);
if (!enchanteur || enchanteur == '') {
continue;
}
let infos = listeEquipementEnchantement[idEquipement];
infos = fontionFormateTexte(infos);
if (infos.length <= 0) {
continue;
}
if (link.parentNode == link.nextSibling.parentNode) {
link.parentNode.insertBefore(fontionTexte(urlImg, infos), link.nextSibling);
} else {
link.parentNode.appendChild(fontionTexte(urlImg, infos));
}
MY_setValue(`${numTroll}.enchantement.${idEquipement}.objet`, `${nomEquipement} (${idEquipement})`);
}
} catch (exc) {
avertissement('Une erreur est survenue (computeEnchantementEquipement)', null, null, exc);
}
}
/** x~x Analyse Tactique ----------------------------------------------- */
if (typeof isPage != "function") {
function isPage(url) {
return window.location.pathname.indexOf(`/mountyhall/${url}`) == 0;
}
}
function isPageWithParam(filters) {
if (filters.url && window.location.pathname.indexOf(`/mountyhall/${filters.url}`) != 0) return false;
if (filters.body_id && document.body.id != filters.body_id) return false;
if (filters.params) {
let paramsGET = new URLSearchParams(window.location.search);
for (let param in filters.params)
if (paramsGET.get(param) != filters.params[param]) return false;
}
if (filters.ids)
for (let id of filters.ids)
if (!document.getElementById(id)) return false
if (filters.names)
for (let name of filters.names)
if (document.getElementsByName(name).length == 0) return false
return true;
}
// Cette section est commune à InfoMonstre et Vue
var MZ_Tactique = {
// --- Variables
popup: null,
// --- Méthodes
// Création de l'image portant le popup tactique
createImage: function (id, nom) {
let img = document.createElement('img');
img.src = URL_MZimg + (isPage('View/MonsterView') ? 'calc.png' : 'calc2.png');
img.id = id;
img.nom = nom;
img.style.verticalAlign = 'middle';
img.onmouseover = MZ_Tactique.showPopup;
img.onmouseout = MZ_Tactique.hidePopup;
return img;
},
// Masquage du popup tactique
hidePopup: function () {
MZ_Tactique.popup.style.display = 'none';
},
initPopup: function () {
/** @mandatory Initialisation du popup tactique */
MZ_Tactique.popup = document.createElement('div');
MZ_Tactique.popup.id = 'MZ_Tactique.popup';
MZ_Tactique.popup.className = 'mh_textbox';
MZ_Tactique.popup.style =
'position: absolute;' +
'display: none;' +
'z-index: 3;' +
'max-width: 400px;';
document.body.appendChild(MZ_Tactique.popup);
},
// Affichage du popup tactique
showPopup: function (evt) {
let id, nom;
try {
id = this.id;
nom = this.nom;
let texte = getAnalyseTactique(id, nom);
if (texte == undefined || texte == '') {
return;
}
MZ_Tactique.popup.innerHTML = texte;
// roule 16/03/2016 déclage horizontal différent suivant la page qu'on traite
if (isPage('View/MonsterView')) {
MZ_Tactique.popup.style.left = `${Math.min(evt.pageX - 120, window.innerWidth - 300)}px`;
} else {
MZ_Tactique.popup.style.left = `${Math.min(evt.pageX + 15, window.innerWidth - 400)}px`;
}
MZ_Tactique.popup.style.top = `${evt.pageY + 15}px`;
MZ_Tactique.popup.style.display = 'block';
} catch (exc) {
logMZ(`showPopup() exception pour id=${id}, nom=${nom}`, exc);
}
}
};
var g_cnp = new Array(); // Les % de toucher
// coefficients binomiaux
function cnp(n, k) {
if (g_cnp[n] != null && g_cnp[n][k] != null) {
return g_cnp[n][k];
}
if (g_cnp[n] == null) {
g_cnp[n] = new Array();
}
if (k == 0) {
g_cnp[n][k] = 1;
return 1;
}
let result = cnp(n - 1, k - 1) * n / k; // mouais... k mul+k div
g_cnp[n][k] = result;
// logMZ('cnp(' + n + ',' + k + ')=' + result); // Roule debug
return result;
}
// by Dab, à comparer
function binom(n, p) {
if (p < 0 || p > n) {
return 0;
}
if (g_cnp[n]) {
if (g_cnp[n][p]) {
return g_cnp[n][p];
}
g_cnp[n] = [1];
g_cnp[n][n] = 1;
if (p == 0 || p == n) {
return 1;
}
}
if (2 * p > n) {
g_cnp[n][p] = binom(n, n - p);
} else {
g_cnp[n][p] = binom(n - 1, p - 1) + binom(n - 1, p);
} // k(k-1)/2 additions
return g_cnp[n][p];
}
var g_coeff = new Array();
function coef_np(n, p) {
if (n == 0 && p == 0) {
return 1;
}
if (p > n * 3.5) {
p = 7 * n - p;
}
// roule désactive cache
if (g_coeff[n] != null && g_coeff[n][p] != null) {
return g_coeff[n][p];
}
if (g_coeff[n] == null) {
g_coeff[n] = new Array();
}
let kmax = Math.floor((p - n) / 6);
let x = 0;
for (let k = 0; k <= kmax; k++) {
x = x + (1 - 2 * (k % 2)) * cnp(n, k) * cnp(p - 6 * k - 1, n - 1);
}
g_coeff[n][p] = x;
// logMZ('cnk(' + n + ',' + p + ')=' + x); // Roule debug
return x;
}
function chanceEsquiveParfaite(a, d, ba = 0, bd = 0) {
let win = 0, los = 0;
// if(6*a+ba<2*(d+bd)) { return 100; }
// if(a+ba>2*(6*d+bd)) { return 0; }
for (let dd = d; dd <= 6 * d; dd++) {
let cd = coef_np(d, dd);
for (let aa = a; aa <= 6 * a; aa++) {
if (2 * Math.max(aa + ba, 0) < Math.max(dd + bd, 0)) {
win = win + cd * coef_np(a, aa);
} else {
los = los + cd * coef_np(a, aa);
}
}
}
// logMZ('chanceEsquiveParfaite, att=' + a + ', esq=' + d + ', ba=' + ba + ', bd=' + bd + ', win=' + win + ', los=' + los); // roule debug
return Math.round(100 * win / (win + los));
}
function chanceTouche(a, d, ba = 0, bd = 0) {
let win = 0, los = 0;
if (a + ba > 6 * d + bd) {
return 100;
}
if (6 * a + ba < d + bd) {
return 0;
}
for (let dd = d; dd <= 6 * d; dd++) {
let cd = coef_np(d, dd);
for (let aa = a; aa <= 6 * a; aa++) {
if (Math.max(aa + ba, 0) > Math.max(dd + bd, 0)) {
win = win + cd * coef_np(a, aa);
} else {
los = los + cd * coef_np(a, aa);
}
}
}
return Math.round(100 * win / (win + los));
}
function chanceCritique(a, d, ba = 0, bd = 0) {
let win = 0, los = 0;
if (a + ba > 2 * (6 * d + bd)) {
return 100;
}
if (6 * a + ba < 2 * (d + bd)) {
return 0;
}
for (let dd = d; dd <= 6 * d; dd++) {
let cd = coef_np(d, dd);
for (let aa = a; aa <= 6 * a; aa++) {
if (Math.max(aa + ba, 0) > 2 * Math.max(dd + bd, 0)) {
win = win + cd * coef_np(a, aa);
} else {
los = los + cd * coef_np(a, aa);
}
}
}
return Math.round(100 * win / (win + los));
}
/** *********************************************
Analyse tactique
***********************************************/
function getTexteAnalyse(modificateur, chiffre) {
if (chiffre == 0) {
return chiffre;
}
return modificateur + chiffre;
}
// rend le HTML pour le tableau de la "calculette"
function getAnalyseTactique(id, nom) {
let donneesMonstre = MZ_EtatCdMs.listeCDM[id];
let needAutres = false;
if (donneesMonstre == null) {
return;
}
let array = analyseTactique(donneesMonstre, nom); // rend tableau de tableaux avec NomAttaque,chanceDEsquiveParfaite,chanceDeTouche,chanceDeCritique,degats,modificateurEsquive,modificateurArmure
// logMZ('getAnalyseTactique ' + JSON.stringify(array));
if (array == null) {
return "";
}
let ui_table = isDesktopView() ? 'mh_tdborder' : 'ui-body-a ui-corner-all';
let ui_tr = isDesktopView() ? 'mh_tdtitre' : ' ui-bar-b';
let ui_size = isDesktopView() ? '' : ' font-size: smaller;';
let str = `<table class='${ui_table}' border='0' cellspacing='1' cellpadding='4' style='background-color:rgb(229, 222, 203);${ui_size}'><tr class='${ui_tr}'><td>Attaque</td><td>Esq. Parfaite</td><td>Touché</td><td>Critique</td><td>Dégâts</td></tr>`;
let i;
for (i = 0; i < array.length; i++) {
if (array[i][1] == 100 && i > 0) { // si esquive parfaite du Trõll sur le Monstre est assurée pour cette frappe
needAutres = true;
break;
}
if (i == 1 && array[i][4] > 0) { // l'attaque normale du Trõll sur le monstre fait des dégâts => gras
str = `${str}<tr class=mh_tdpage><td><b>${array[i][0]}</b></td><td><b>${getTexteAnalyse(array[i][5], array[i][1])}%</b></td><td><b>${getTexteAnalyse(array[i][5], array[i][2])}%</b></td><td><b>${getTexteAnalyse(array[i][5], array[i][3])}%</b></td><td><b>${getTexteAnalyse(array[i][6], array[i][4])}</b></td></tr>`;
} else if (i == 0) { // attaque du monstre sur le Trõll => italique
str = `${str}<tr class=mh_tdpage><td><i>${array[i][0]}</i></td><td><i>${getTexteAnalyse(array[i][5], array[i][1])}%</i></td><td><i>${getTexteAnalyse(array[i][5], array[i][2])}%</i></td><td><i>${getTexteAnalyse(array[i][5], array[i][3])}%<i></td><td><b><i>${getTexteAnalyse(array[i][6], array[i][4])}<i></b></td></tr>`;
} else { // autre, pas de décoration
str = `${str}<tr class=mh_tdpage><td>${array[i][0]}</td><td>${getTexteAnalyse(array[i][5], array[i][1])}%</td><td>${getTexteAnalyse(array[i][5], array[i][2])}%</td><td>${getTexteAnalyse(array[i][5], array[i][3])}%</td><td><b>${getTexteAnalyse(array[i][6], array[i][4])}</b></td></tr>`;
}
}
if (needAutres) {
if (i == array.length - 1) {
str = `${str}<tr class=mh_tdpage><td>${array[i][0]}</td><td>${getTexteAnalyse(array[i][5], array[i][1])}%</td><td>${getTexteAnalyse(array[i][5], array[i][2])}%</td><td>${getTexteAnalyse(array[i][5], array[i][3])}%</td><td><b>${getTexteAnalyse(array[i][6], array[i][4])}</b></td></tr>`;
} else if (i == 1) {
str = `${str}<tr class=mh_tdpage><td><b>Toutes attaques</b></td><td>100%</td><td>0%</td><td>0%</td><td>0</td></tr>`;
} else {
str = `${str}<tr class=mh_tdpage><td>Autres attaques</td><td>100%</td><td>0%</td><td>0%</td><td>0</td></tr>`;
}
}
let txtCdM = MZ_carac_build_nb_cmd_msg(donneesMonstre);
if (txtCdM) {
str = `${str}<tr class="mh_tdpage"><td colspan="5" style="font-style: italic;">${txtCdM}</td></tr>`;
}
return `${str}</table>`;
}
function MZ_carac_build_nb_cmd_msg(donneesMonstre) {
if (!donneesMonstre) {
return;
}
if (!donneesMonstre.Mode) {
return;
}
switch (donneesMonstre.Mode) {
case 'cdm':
return `fondé sur ${Number(donneesMonstre.nCdM)} CdM${donneesMonstre.nCdM > 1 ? 's' : ''} de ce monstre à cet âge`;
case 'stat':
return `fondé sur les statistiques de ${Number(donneesMonstre.nCdM)} CdM${donneesMonstre.nCdM > 1 ? 's' : ''} de ce type de monstre (même type, même âge, même template)`;
case 'statV1':
return 'fondé sur les statistiques anciennes (MZ V1)';
case 'nom':
return 'fondé sur le nom du monstre, pas de CdM';
}
return `Mode ${donneesMonstre.Mode}`;
}
// rend un tableau (un par attaque du Trõll ou du monstre) de tableaux contenant:
// NomAttaque,chanceDEsquiveParfaite,chanceDeTouche,chanceDeCritique,degats,modificateurEsquive,modificateurArmure
function analyseTactique(donneesMonstre, nom) {
try {
let listeAttaques = [];
// Roule 16/03/2016 ajout des ParseInt car je récupérais parfois une chaine non numérique :(
let att = parseInt(MY_getValue(`${numTroll}.caracs.attaque`), 10);
let reg = parseInt(MY_getValue(`${numTroll}.caracs.regeneration`), 10);
let attbmp = parseInt(MY_getValue(`${numTroll}.caracs.attaque.bmp`), 10);
let attbmm = parseInt(MY_getValue(`${numTroll}.caracs.attaque.bmm`), 10);
let mm = parseInt(MY_getValue(`${numTroll}.caracs.mm`), 10);
let deg = parseInt(MY_getValue(`${numTroll}.caracs.degats`), 10);
let degbmp = parseInt(MY_getValue(`${numTroll}.caracs.degats.bmp`), 10);
let degbmm = parseInt(MY_getValue(`${numTroll}.caracs.degats.bmm`), 10);
let vue = parseInt(MY_getValue(`${numTroll}.caracs.vue`), 10);
let pv = parseInt(MY_getValue(`${numTroll}.caracs.pv`), 10);
let pvbase = parseInt(MY_getValue(`${numTroll}.caracs.pv.base`), 10);
let esq = parseInt(Math.max(MY_getValue(`${numTroll}.caracs.esquive`), 10) - parseInt(MY_getValue(`${numTroll}.caracs.esquive.nbattaques`), 0), 10);
let esqbonus = parseInt(MY_getValue(`${numTroll}.caracs.esquive.bm`), 10);
let arm = parseInt(MY_getValue(`${numTroll}.caracs.armure`), 10);
let armbmp = parseInt(MY_getValue(`${numTroll}.caracs.armure.bmp`), 10);
let armbmm = parseInt(MY_getValue(`${numTroll}.caracs.armure.bmm`), 10);
let modificateurEsquive = '';
let modificateurArmure = '';
let modificateurMagie = '';
let modificateurEsquiveM = '';
let modificateurArmureM = '';
let pasDeSR = false;
let esqM = 0, attM = 0, armM_mag = 0, armM_phy = 0, armM_tot = 0, degM = 0;
if (donneesMonstre == null || att == null || attbmp == null || attbmm == null || mm == null || deg == null || degbmp == null || degbmm == null || vue == null || pv == null || esq == null || arm == null) {
return null;
}
debugMZ(`analyseTactique nom=${nom} ${JSON.stringify(donneesMonstre)}`);
let coeffSeuil = 0.95;
if (donneesMonstre.index == undefined) {
// à supprimer
let td = document.createElement('td');
td.innerHTML = bbcode(donneesMonstre[4]); // sans déconner ? C'est quoi cette histoire ?
esqM = 0;
try {
esqM = Math.ceil(td.getElementsByTagName('b')[0].firstChild.nodeValue);
} catch (exc) {
debugMZ(`analyseTactique, exception calcul esqM`, exc);
esqM = Math.ceil(parseInt(td.firstChild.nodeValue));
modificateurEsquive = '<';
modificateurArmure = '<';
modificateurMagie = '<';
}
td.innerHTML = bbcode(donneesMonstre[3]);
attM = 0;
try {
attM = Math.ceil(td.getElementsByTagName('b')[0].firstChild.nodeValue);
} catch (exc) {
debugMZ(`analyseTactique, exeception calcul attM`, exc);
attM = Math.ceil(parseInt(td.firstChild.nodeValue));
modificateurEsquiveM = '>';
modificateurArmureM = '>';
}
td.innerHTML = bbcode(donneesMonstre[5]);
degM = 0;
try {
degM = Math.ceil(td.getElementsByTagName('b')[0].firstChild.nodeValue);
} catch (exc) {
debugMZ(`analyseTactique, exeception calcul degM`, exc);
degM = Math.ceil(parseInt(td.firstChild.nodeValue));
modificateurArmureM = '>';
}
td.innerHTML = bbcode(donneesMonstre[7]);
try {
armM_tot = Math.ceil(td.getElementsByTagName('b')[0].firstChild.nodeValue);
armM_mag = armM_tot; // compatibilité avec ancien calcul
} catch (exc) {
debugMZ(`analyseTactique, exeception calcul armM`, exc);
armM_tot = Math.ceil(parseInt(td.firstChild.nodeValue));
armM_mag = armM_tot;
modificateurArmure = '<';
}
try {
td.innerHTML = bbcode(donneesMonstre[9]);
// debugMZ('analyseTactique, calcul SR, donnessMonstre=' + donneesMonstre[9] + ', bbcode=' + bbcode(donneesMonstre[9]));
let rm = parseInt(td.getElementsByTagName('b')[0].firstChild.nodeValue);
let v = rm / mm;
let seuil = rm < mm ? Math.max(10, Math.floor(v * 50)) : Math.min(90, Math.floor(100 - 50 / v));
coeffSeuil = (200 - seuil) / 200;
} catch (exc) {
debugMZ(`analyseTactique, exeception calcul SR`, exc);
modificateurMagie = '<';
pasDeSR = true;
}
} else {
// calcul de modificateurEsquive, modificateurArmure, modificateurMagie, modificateurEsquiveM, modificateurArmureM, pasDeSR, esqM, attM, armM_mag, armM_tot, degM;
if (donneesMonstre.esq) {
if (donneesMonstre.esq.min && donneesMonstre.esq.max) {
esqM = Math.ceil((donneesMonstre.esq.min + donneesMonstre.esq.max) / 2);
} else if (donneesMonstre.esq.max) {
esqM = donneesMonstre.esq.max;
modificateurEsquive = '<';
modificateurArmure = '<';
modificateurMagie = '<';
}
}
if (donneesMonstre.att) {
if (donneesMonstre.att.min && donneesMonstre.att.max) {
attM = Math.ceil((donneesMonstre.att.min + donneesMonstre.att.max) / 2);
} else if (donneesMonstre.att.max) {
attM = donneesMonstre.att.max;
modificateurEsquiveM = '>';
modificateurArmureM = '>';
}
}
if (donneesMonstre.armM) {
if (donneesMonstre.armM.min && donneesMonstre.armM.max) {
armM_mag = Math.ceil((donneesMonstre.armM.min + donneesMonstre.armM.max) / 2);
} else if (donneesMonstre.armM.max) {
armM_mag = donneesMonstre.armM.max;
modificateurArmure = '<';
}
if (donneesMonstre.armP) {
if (donneesMonstre.armP.min && donneesMonstre.armP.max) {
armM_phy = Math.ceil((donneesMonstre.armP.min + donneesMonstre.armP.max) / 2);
} else if (donneesMonstre.armP.max) {
armM_phy = donneesMonstre.armP.max;
modificateurArmure = '<';
}
armM_tot = armM_mag + armM_phy;
} else { // ça ne devrait pas arriver
armM_tot = armM_mag;
}
} else if (donneesMonstre.arm) {
if (donneesMonstre.arm.min && donneesMonstre.arm.max) {
armM_tot = Math.ceil((donneesMonstre.arm.min + donneesMonstre.arm.max) / 2);
armM_mag = armM_tot; // worst case
} else if (donneesMonstre.arm.max) {
armM_tot = donneesMonstre.arm.max;
armM_mag = armM_tot;
modificateurArmure = '<';
}
}
if (donneesMonstre.deg) {
if (donneesMonstre.deg.min && donneesMonstre.deg.max) {
degM = Math.ceil((donneesMonstre.deg.min + donneesMonstre.deg.max) / 2);
} else if (donneesMonstre.deg.max) {
degM = donneesMonstre.deg.max;
modificateurArmureM = '>';
}
}
if (donneesMonstre.RM) {
if (donneesMonstre.RM.min && donneesMonstre.RM.max) {
let rmM = Math.ceil((donneesMonstre.RM.min + donneesMonstre.RM.max) / 2);
let v = rmM / mm;
let seuil = rmM < mm ? Math.max(10, Math.floor(v * 50)) : Math.min(90, Math.floor(100 - 50 / v));
coeffSeuil = (200 - seuil) / 200;
} else if (donneesMonstre.deg.max) {
// gath: vide ici, rien a faire ?
}
modificateurMagie = '<';
pasDeSR = true;
}
}
debugMZ(`modificateurEsquive=${modificateurEsquive}, modificateurArmure=${modificateurArmure}, modificateurMagie=${modificateurMagie}, modificateurEsquiveM=${modificateurEsquiveM}, modificateurArmureM=${modificateurArmureM}, pasDeSR=${pasDeSR}, esqM=${esqM}, attM=${attM}, armM_tot=${armM_tot}, armM_mag=${armM_mag}, degM=${degM}, coeffSeuil=${coeffSeuil}`);
let chanceDEsquiveParfaite = chanceEsquiveParfaite(att, esqM, attbmp + attbmm, 0);
let chanceDeTouche = chanceTouche(att, esqM, attbmp + attbmm, 0);
let chanceDeCritique = chanceCritique(att, esqM, attbmp + attbmm, 0);
// roule debug
// logMZ('Attaque normale troll sur monstre, att=' + att + ', esqM=' + esqM + ', attbmp=' + attbmp + ', attbmm=' + attbmm
// + ', chanceDEsquiveParfaite=' + chanceDEsquiveParfaite + ', chanceDeTouche=' + chanceDeTouche + ', chanceDeCritique=' + chanceDeCritique);
let degats = ((chanceDeTouche - chanceDeCritique) * Math.max(deg * 2 + degbmp + degbmm - armM_tot, 1) + chanceDeCritique * Math.max(Math.floor(deg * 1.5) * 2 + degbmp + degbmm - armM_tot, 1)) / 100;
// str += "Attaque normale : Touché "+chanceDeTouche+"% Critique "+chanceDeCritique+"% Dégâts "+(((chanceDeTouche-chanceDeCritique)*Math.max(deg*2+degbmp+degbmm-arm,1)+chanceDeCritique*Math.max(Math.floor(deg*1.5)*2+degbmp+degbmm-arm,1))/100);
listeAttaques.push(new Array("Attaque normale", chanceDEsquiveParfaite, chanceDeTouche, chanceDeCritique, degats, modificateurEsquive, modificateurArmure));
if (getSortComp("Vampirisme") > 0) {
let pour = getSortComp("Vampirisme");
chanceDEsquiveParfaite = Math.round(chanceEsquiveParfaite(Math.floor(deg * 2 / 3), esqM, attbmm, 0) * pour / 100);
chanceDeTouche = Math.round(chanceTouche(Math.floor(deg * 2 / 3), esqM, attbmm, 0) * pour / 100);
chanceDeCritique = Math.round(chanceCritique(Math.floor(deg * 2 / 3), esqM, attbmm, 0) * pour / 100);
degats = Math.round(coeffSeuil * ((chanceDeTouche - chanceDeCritique) * Math.max(deg * 2 + degbmm, 1) + chanceDeCritique * Math.max(Math.floor(deg * 1.5) * 2 + degbmm - armM_mag, 1))) / 100;
// str += "\nVampirisme : Touché "+chanceDeTouche+"% Critique "+chanceDeCritique+"% Dégâts "+(degats);
listeAttaques.push(new Array("Vampirisme", chanceDEsquiveParfaite, chanceDeTouche, chanceDeCritique, degats, modificateurEsquive, modificateurMagie));
}
if (getSortComp("Siphon des âmes") > 0) {
let pour = getSortComp("Siphon des âmes");
chanceDEsquiveParfaite = Math.round(chanceEsquiveParfaite(att, esqM, attbmm, 0) * pour / 100);
chanceDeTouche = Math.round(chanceTouche(att, esqM, attbmm, 0) * pour / 100);
chanceDeCritique = Math.round(chanceCritique(att, esqM, attbmm, 0) * pour / 100);
degats = ((chanceDeTouche - chanceDeCritique) * Math.max(reg * 2 + degbmm, 1) + chanceDeCritique * Math.max(Math.floor(reg * 1.5) * 2 + degbmm - armM_mag, 1)) / 100;
listeAttaques.push(new Array("Siphon des âmes", chanceDEsquiveParfaite, chanceDeTouche, chanceDeCritique, degats, modificateurEsquive, modificateurMagie));
}
if (getSortComp("Botte Secrète") > 0) {
let pour = getSortComp("Botte Secrète");
chanceDEsquiveParfaite = Math.round(chanceEsquiveParfaite(Math.floor(2 * att / 3), esqM, Math.floor((attbmp + attbmm) / 2), 0) * pour / 100);
chanceDeTouche = Math.round(chanceTouche(Math.floor(2 * att / 3), esqM, Math.floor((attbmp + attbmm) / 2), 0) * pour / 100);
chanceDeCritique = Math.round(chanceCritique(Math.floor(2 * att / 3), esqM, Math.floor((attbmp + attbmm) / 2), 0) * pour / 100);
degats = Math.round((chanceDeTouche - chanceDeCritique) * Math.max(Math.floor(deg / 2) * 2 + Math.floor((degbmp + degbmm) / 2) - Math.floor(armM_tot / 2), 1) + chanceDeCritique * Math.max(Math.floor(deg * 1.5 / 2) * 2 + Math.floor((degbmp + degbmm) / 2) - Math.floor(armM_tot / 2), 1)) / 100;
// str += "\nBotte Secrète : Touché "+chanceDeTouche+"% Critique "+chanceDeCritique+"% Dégâts "+(degats);
listeAttaques.push(new Array("Botte Secrète", chanceDEsquiveParfaite, chanceDeTouche, chanceDeCritique, degats, modificateurEsquive, modificateurArmure));
}
if (getSortComp("Rafale Psychique") > 0) {
let pour = getSortComp("Rafale Psychique");
chanceDEsquiveParfaite = 0;
chanceDeTouche = Math.round(100 * pour / 100);
chanceDeCritique = Math.round(0 * pour / 100);
degats = Math.round(coeffSeuil * ((chanceDeTouche - chanceDeCritique) * Math.max(deg * 2 + degbmm, 1) + chanceDeCritique * Math.max(Math.floor(deg * 1.5) * 2 + degbmm - armM_mag, 1))) / 100;
// str += "\nRafale Psychique : Touché "+chanceDeTouche+"% Critique "+chanceDeCritique+"% Dégâts "+(degats);
listeAttaques.push(new Array("Rafale Psychique", chanceDEsquiveParfaite, chanceDeTouche, chanceDeCritique, degats, '', pasDeSR ? modificateurMagie : ''));
}
if (getSortComp("Explosion") > 0) {
let pour = getSortComp("Explosion");
chanceDEsquiveParfaite = 0;
chanceDeTouche = Math.round(100 * pour / 100);
chanceDeCritique = Math.round(0 * pour / 100);
degats = Math.round(coeffSeuil * ((chanceDeTouche - chanceDeCritique) * Math.max(Math.floor(1 + deg / 2 + pvbase / 20) * 2, 1) + chanceDeCritique * Math.max(Math.floor(Math.floor(1 + deg / 2 + pvbase / 20) * 1.5) * 2, 1))) / 100;
// str += "\nRafale Psychique : Touché "+chanceDeTouche+"% Critique "+chanceDeCritique+"% Dégâts "+(degats);
listeAttaques.push(new Array("Explosion", chanceDEsquiveParfaite, chanceDeTouche, chanceDeCritique, degats, '', pasDeSR ? modificateurMagie : ''));
}
if (getSortComp("Projectile Magique") > 0) {
let pour = getSortComp("Projectile Magique");
chanceDEsquiveParfaite = Math.round(chanceEsquiveParfaite(vue, esqM, attbmm, 0) * pour / 100);
chanceDeTouche = Math.round(chanceTouche(vue, esqM, attbmm, 0) * pour / 100);
chanceDeCritique = Math.round(chanceCritique(vue, esqM, attbmm, 0) * pour / 100);
// distance troll - monstre
degats = Math.round(coeffSeuil * ((chanceDeTouche - chanceDeCritique) * Math.max(Math.floor(vue / 2) * 2 + degbmm, 1) + chanceDeCritique * Math.max(Math.floor(Math.floor(vue / 2) * 1.5) * 2 + degbmm - armM_mag, 1))) / 100;
// str += "\nProjectile Magique : Touché "+chanceDeTouche+"% Critique "+chanceDeCritique+"% Dégâts "+(degats);
if (donneesMonstre.index !== undefined && MZ_EtatCdMs.tr_monstres !== undefined && MZ_EtatCdMs.tr_monstres[donneesMonstre.index] !== undefined) {
let dist = getMonstreDistance(donneesMonstre.index);
// if (isDEV) log:W('Dist pour PM=' + dist);
let vue_bm = parseInt(MY_getValue(`${numTroll}.caracs.vue.bm`), 10);
let portee = getPortee(vue + vue_bm);
if (dist <= portee) {
degats = Math.round((degats + 2 * (portee - dist)) * 100) / 100;
} else {
degats = `${degats} (plus bonus de portée)`;
}
debugMZ(`analyseTactique, iTR= ${donneesMonstre.index}, dist=${dist}, porteePM=${portee}`);
} else {
degats = `${degats} (plus bonus de portée)`;
}
listeAttaques.push(new Array("Projectile Magique", chanceDEsquiveParfaite, chanceDeTouche, chanceDeCritique, degats, modificateurEsquive, modificateurMagie));
}
if (getSortComp("Frénésie") > 0) {
let pour = getSortComp("Frénésie");
chanceDEsquiveParfaite = Math.round(chanceEsquiveParfaite(att, esqM, attbmm + attbmp, 0) * pour / 100);
chanceDeTouche = Math.round(chanceTouche(att, esqM, attbmm + attbmp, 0) * pour / 100);
chanceDeCritique = Math.round(chanceCritique(att, esqM, attbmm + attbmp, 0) * pour / 100);
degats = Math.round((chanceDeTouche - chanceDeCritique) * 2 * Math.max(deg * 2 + degbmp + degbmm - armM_tot, 1) + chanceDeCritique * 2 * Math.max(Math.floor(deg * 1.5) * 2 + degbmm + degbmp - armM_tot, 1)) / 100;
// str += "\nFrénésie : Touché "+chanceDeTouche+"% Critique "+chanceDeCritique+"% Dégâts "+(degats);
listeAttaques.push(new Array("Frénésie", chanceDEsquiveParfaite, chanceDeTouche, chanceDeCritique, degats, modificateurEsquive, modificateurArmure));
}
if (getSortComp("Charger") > 0) {
let pour = getSortComp("Charger");
chanceDEsquiveParfaite = Math.round(chanceEsquiveParfaite(att, esqM, attbmm + attbmp, 0) * pour / 100);
chanceDeTouche = Math.round(chanceTouche(att, esqM, attbmm + attbmp, 0) * pour / 100);
chanceDeCritique = Math.round(chanceCritique(att, esqM, attbmm + attbmp, 0) * pour / 100);
degats = Math.round((chanceDeTouche - chanceDeCritique) * Math.max(deg * 2 + degbmp + degbmm - armM_tot, 1) + chanceDeCritique * Math.max(Math.floor(deg * 1.5) * 2 + degbmm + degbmp - armM_tot, 1)) / 100;
// str += "\nCharge : Touché "+chanceDeTouche+"% Critique "+chanceDeCritique+"% Dégâts "+(degats);
listeAttaques.push(new Array("Charger", chanceDEsquiveParfaite, chanceDeTouche, chanceDeCritique, degats, modificateurEsquive, modificateurArmure));
}
if (getSortComp("Griffe du Sorcier") > 0) {
let pour = getSortComp("Griffe du Sorcier");
chanceDEsquiveParfaite = Math.round(chanceEsquiveParfaite(att, esqM, attbmm, 0) * pour / 100);
chanceDeTouche = Math.round(chanceTouche(att, esqM, attbmm, 0) * pour / 100);
chanceDeCritique = Math.round(chanceCritique(att, esqM, attbmm, 0) * pour / 100);
degats = Math.round(coeffSeuil * ((chanceDeTouche - chanceDeCritique) * Math.max(Math.floor(deg / 2) * 2 + degbmm, 1) + chanceDeCritique * Math.max(Math.floor(Math.floor(deg / 2) * 1.5) * 2 + degbmm, 1))) / 100;
// str += "\nGriffe du Sorcier : Touché "+chanceDeTouche+"% Critique "+chanceDeCritique+"% Dégâts "+(degats);
listeAttaques.push(new Array("Griffe du Sorcier", chanceDEsquiveParfaite, chanceDeTouche, chanceDeCritique, degats, modificateurEsquive, modificateurMagie));
}
if (getSortComp("Attaque Précise", 1) > 0) {
let niveau = 5;
let oldPour = 0;
chanceDEsquiveParfaite = 0;
chanceDeTouche = 0;
chanceDeCritique = 0;
degats = 0;
while (niveau > 0) {
let pour = getSortComp("Attaque Précise", niveau);
if (pour > oldPour) {
let chanceDEsquiveParfaiteNiveau = chanceEsquiveParfaite(Math.min(att + 3 * niveau, Math.floor(att * 1.5)), esqM, attbmm + attbmp, 0) * (pour - oldPour) / 100;
let chanceDeToucheNiveau = chanceTouche(Math.min(att + 3 * niveau, Math.floor(att * 1.5)), esqM, attbmm + attbmp, 0) * (pour - oldPour) / 100;
let chanceDeCritiqueNiveau = chanceCritique(Math.min(att + 3 * niveau, Math.floor(att * 1.5)), esqM, attbmm + attbmp, 0) * (pour - oldPour) / 100;
chanceDEsquiveParfaite = chanceDEsquiveParfaite + chanceDEsquiveParfaiteNiveau;
chanceDeTouche = chanceDeTouche + chanceDeToucheNiveau;
chanceDeCritique = chanceDeCritique + chanceDeCritiqueNiveau;
degats = degats + ((chanceDeToucheNiveau - chanceDeCritiqueNiveau) * Math.max(deg * 2 + degbmp + degbmm - armM_tot, 1) + chanceDeCritiqueNiveau * Math.max(Math.floor(deg * 1.5) * 2 + degbmm + degbmp - armM_tot, 1)) / 100;
oldPour = pour;
}
niveau--;
}
// str += "\nAttaque Précise : Touché "+(Math.round(chanceDeTouche*100)/100)+"% Critique "+(Math.round(chanceDeCritique*100)/100)+"% Dégâts "+Math.round(degats*100)/100;
listeAttaques.push(new Array("Attaque Précise", chanceDEsquiveParfaite, Math.round(chanceDeTouche * 100) / 100, Math.round(chanceDeCritique * 100) / 100, Math.round(degats * 100) / 100, modificateurEsquive, modificateurArmure));
}
if (getSortComp("Coup de Butoir", 1) > 0) {
let niveau = 5;
let oldPour = 0;
chanceDEsquiveParfaite = 0;
chanceDeTouche = 0;
chanceDeCritique = 0;
degats = 0;
while (niveau > 0) {
let pour = getSortComp("Coup de Butoir", niveau);
if (pour > oldPour) {
let chanceDEsquiveParfaiteNiveau = chanceEsquiveParfaite(att, esqM, attbmm + attbmp, 0) * (pour - oldPour) / 100;
let chanceDeToucheNiveau = chanceTouche(att, esqM, attbmm + attbmp, 0) * (pour - oldPour) / 100;
let chanceDeCritiqueNiveau = chanceCritique(att, esqM, attbmm + attbmp, 0) * (pour - oldPour) / 100;
chanceDEsquiveParfaite = chanceDEsquiveParfaite + chanceDEsquiveParfaiteNiveau;
chanceDeTouche = chanceDeTouche + chanceDeToucheNiveau;
chanceDeCritique = chanceDeCritique + chanceDeCritiqueNiveau;
degats = degats + ((chanceDeToucheNiveau - chanceDeCritiqueNiveau) * Math.max(Math.min(Math.floor(deg * 1.5), deg + 3 * niveau) * 2 + degbmp + degbmm - armM_tot, 1) + chanceDeCritiqueNiveau * Math.max(Math.floor(Math.min(Math.floor(deg * 1.5), deg + 3 * niveau) * 1.5) * 2 + degbmm + degbmp - armM_tot, 1)) / 100;
oldPour = pour;
}
niveau--;
}
// str += "\nCoup de Butoir : Touché "+(Math.round(chanceDeTouche*100)/100)+"% Critique "+(Math.round(chanceDeCritique*100)/100)+"% Dégâts "+Math.round(degats*100)/100;
listeAttaques.push(new Array("Coup de Butoir", chanceDEsquiveParfaite, Math.round(chanceDeTouche * 100) / 100, Math.round(chanceDeCritique * 100) / 100, Math.round(degats * 100) / 100, modificateurEsquive, modificateurArmure));
}
listeAttaques.sort((a, b) => {
let diff = parseInt(100 * b[4]) - parseInt(100 * a[4]); if (diff == 0) {
return parseInt(b[1]) - parseInt(a[1]);
} return diff;
});
if (nom.toLowerCase().indexOf("mégacéphale") == -1) {
chanceDEsquiveParfaite = Math.round(chanceEsquiveParfaite(attM, esq, 0, esqbonus));
chanceDeTouche = Math.round(chanceTouche(attM, esq, 0, esqbonus));
chanceDeCritique = Math.round(chanceCritique(attM, esq, 0, esqbonus));
} else {
chanceDEsquiveParfaite = 0;
chanceDeTouche = 100;
chanceDeCritique = 0;
}
degats = Math.round((chanceDeTouche - chanceDeCritique) * Math.max(Math.floor(degM) * 2 - arm, 1) + chanceDeCritique * Math.max(Math.floor(Math.floor(degM) * 1.5) * 2 - arm * 2 - armbmm - armbmp, 1)) / 100;
listeAttaques.unshift(new Array("Monstre", Math.round(chanceDEsquiveParfaite * 100) / 100, Math.round(chanceDeTouche * 100) / 100, Math.round(chanceDeCritique * 100) / 100, Math.round(degats * 100) / 100, modificateurEsquive, modificateurArmure));
return listeAttaques;
} catch (exc) {
let msgid = '';
try {
msgid = ` du monstre ${donneesMonstre.id}`;
} catch (exc2) {
// pass
}
avertissement(`Échec de l'analyse tactique${msgid}`, null, null, exc);
}
}
/** x~x Gestion des missions ------------------------------------------- */
/*
* Patch :
* gestion des missions terminées
*/
function checkLesMimis() { // supprimer les missions finie de numTroll.MISSIONS
let titresMimis, obMissions;
try {
titresMimis = document.evaluate(
"//h3/a[contains(@href,'Mission_')]", document, null, 7, null
);
obMissions = JSON.parse(MY_getValue(`${numTroll}.MISSIONS`));
} catch (exc) {
logMZ('mission_liste initialisation', exc);
return;
}
let enCours = {};
debugMZ(`checkLesMimis nb=${titresMimis.snapshotLength}`);
for (let i = 0; i < titresMimis.snapshotLength; i++) {
debugMZ(`checkLesMimis text=${titresMimis.snapshotItem(i).textContent}`);
let num = titresMimis.snapshotItem(i).textContent.match(/\d+/)[0];
enCours[num] = true;
}
for (let numMimi in obMissions) {
if (!enCours[numMimi]) {
delete obMissions[numMimi];
}
}
MY_setValue(`${numTroll}.MISSIONS`, JSON.stringify(obMissions));
}
function do_mission_liste() {
checkLesMimis();
}
/** x~x Gestion des actions -------------------------------------------- */
/* TODO
* getLvl pour Explo, Rotobaffe et cie
*/
/* Page de combat */
function getLevel() {
let divList = document.getElementsByTagName('div');
if (divList.length <= 2) {
return;
}
// On essaie de voir si cette action était une attaque
let pList = document.getElementsByTagName('p');
let nomM = '';
// Modification pour Frénésie by TetDure
let numAtt = 0;
for (let i = 0; i < pList.length; i++) {
if (pList[i].firstChild) {
nomM = pList[i].firstChild.nodeValue;
if (nomM && nomM.indexOf('Vous avez attaqué un') == 0) {
numAtt++;
}
}
}
if (nomM == '') {
return;
}
// Si c'est une attaque normale, un seul PX
let comPX = 1;
if (divList[2].firstChild.nodeValue.indexOf('Attaque Normale') == -1 && numAtt != 2) {
comPX++;
}
// Extraction des infos du monstre attaqué
let idM, male;
if (nomM.slice(20, 21) == 'e') {
male = false;
idM = nomM.substring(nomM.indexOf('(') + 1, nomM.indexOf(')'));
nomM = nomM.slice(22, nomM.indexOf('(') - 1);
} else {
male = true;
idM = nomM.substring(nomM.indexOf('(') + 1, nomM.indexOf(')'));
nomM = nomM.slice(21, nomM.indexOf('(') - 1);
}
if (idM == '') {
return;
}
let bList = document.getElementsByTagName('b');
let niveau = '';
for (let i = 0; i < bList.length; i++) {
let b = bList[i];
if (b.childNodes[0].nodeValue != "TUÉ") {
continue;
}
let nbPX = "";
for (i++; i < bList.length; i++) {
// Si plusieurs monstres ont été tués (par ex. explo), on ne peut pas déduire leurs niveaux
if (bList[i].childNodes[0].nodeValue == "TUÉ") {
return;
}
if (bList[i].childNodes[0].nodeValue.indexOf("PX") != -1) {
nbPX = bList[i].childNodes[0].nodeValue;
break;
}
}
if (nbPX == '') {
return;
}
// Si on arrive ici c'est qu'on a trouvé un (et un seul) monstre tué et les PX gagnés
nbPX = parseInt(nbPX.slice(0, nbPX.indexOf("P") - 1));
if (!nbPX) {
nbPX = 0;
}
let chaine = `${male ? "Il" : "Elle"} était de niveau `;
niveau = (Number(nbPX) + 2 * nivTroll - 10 - comPX) / 3;
if (comPX > nbPX) {
chaine = `${chaine}inférieur ou égal à ${Math.floor(niveau)}.`;
niveau = "";
} else if (Math.floor(niveau) == niveau) {
chaine = `${chaine}${niveau}.`;
} else {
chaine = "Mountyzilla n'est pas arrivé à calculer le niveau du monstre.";
niveau = "";
}
insertBr(b.nextSibling.nextSibling.nextSibling);
insertText(b.nextSibling.nextSibling.nextSibling, chaine);
}
if (niveau != '') {
let button = insertButtonCdm('as_Action');
button.setAttribute("onClick", `window.open('${URL_pageNiv}?id=${Number(idM)}&monstre=${escape(nomM)}&niveau=${escape(niveau)
}', 'popupCdm', 'width=400, height=240, toolbar=no, status=no, location=no, resizable=yes'); ` +
`this.value = 'Merci de votre participation'; this.disabled = true;`);
}
}
/** x~x Messages du bot : MM/RM ---------------------------------------- */
function insertInfoMagie(node, intitule, magie) {
if (node.nextSibling) {
node = node.nextSibling;
insertBr(node);
insertText(node, intitule);
insertText(node, magie, true);
} else {
node = node.parentNode;
appendBr(node);
appendText(node, intitule);
appendText(node, magie, true);
}
}
function getMM(sr) {
if (rmTroll <= 0) {
return `Inconnue (quelle idée d'avoir une RM valant${rmTroll} !)`;
}
let nsr = Number(sr.match(/\d+/)[0]);
if (nsr == 10) {
return `\u2265 ${5 * rmTroll}`;
}
if (nsr <= 50) {
return Math.round(50 * rmTroll / nsr);
}
if (nsr < 90) {
return Math.round((100 - nsr) * rmTroll / 50);
}
return `\u2264 ${Math.round(rmTroll / 5)}`;
}
function traiteMM() {
let mm, node = document.evaluate(
"//b[contains(preceding::text()[1], 'Seuil de Résistance')]/text()[1]", document, null, 9, null
).singleNodeValue;
if (node) {
mm = getMM(node.nodeValue);
node = node.parentNode.nextSibling.nextSibling.nextSibling;
} else {
node = document.evaluate(
"//p/text()[contains(., 'Seuil de Résistance')]", document, null, 9, null
).singleNodeValue;
if (!node) {
return;
}
mm = getMM(node.nodeValue);
node = node.nextSibling.nextSibling;
}
insertInfoMagie(node, 'MM approximative de l\'Attaquant...: ', mm);
}
function getRM(sr) {
if (mmTroll <= 0) {
return `Inconnue (quelle idée d'avoir une MM valant ${mmTroll} !)`;
}
let nsr = Number(sr.match(/\d+/)[0]);
if (nsr == 10) {
return `\u2264 ${Math.round(mmTroll / 5)}`;
}
if (nsr <= 50) {
return Math.round(nsr * mmTroll / 50);
}
if (nsr < 90) {
return Math.round(50 * mmTroll / (100 - nsr));
}
return `\u2265 ${5 * mmTroll}`;
}
function traiteRM() {
let nodes = document.evaluate(
"//b[contains(preceding::text()[1],'Seuil de Résistance')]/text()[1]", document, null, 7, null
);
if (nodes.snapshotLength == 0) {
return;
}
for (let i = 0; i < nodes.snapshotLength; i++) {
let node = nodes.snapshotItem(i);
let rm = getRM(node.nodeValue);
node = node.parentNode.nextSibling.nextSibling.nextSibling;
insertInfoMagie(node, 'RM approximative de la Cible.......: ', rm);
}
}
/** x~x Stats IdT par Raistlin ----------------------------------------- */
/* function getIdt() {
if(MY_getValue("SEND_IDT") == "non")
return false;
let regExpBeginning = /^\s+/;
let regExpEnd = /\s+$/;
let nomIdt = document.evaluate(
"//tr/td[contains(p/text(),'identification a donné le résultat suivant : ')]/b/text()",
document, null, XPathResult.STRING_TYPE, null).stringValue;
if(!nomIdt)
return false;
let caracIdt;
if(nomIdt.indexOf("Malédiction !") != -1) {
caracIdt = "";
nomIdt = "Mission maudite";
} else {
caracIdt = nomIdt.slice(nomIdt.indexOf("(") + 1, nomIdt.indexOf(")"));
nomIdt = nomIdt.slice(nomIdt.indexOf(" - ")+3);
nomIdt = nomIdt.slice(0, nomIdt.indexOf("(") - 1);
nomIdt = nomIdt.replace(regExpBeginning, "").replace(regExpEnd, "");
}
FF_XMLHttpRequest({
method: 'GET',
url: idtURL + "?item=" + escape(nomIdt) + "&descr=" + escape(caracIdt),
headers : {
'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
'Accept': 'application/atom+xml,application/xml,text/xml',
}
});
return true;
}*/
/** x~x Décalage DLA --------------------------------------------------- */
var oldDLA;
function confirmeDecalage() {
// On vérifie que MH n'excluera pas déjà la demande (validNumeric)
let nbMinutes = document.getElementById('ai_NbMinutes').value;
if (!nbMinutes || isNaN(nbMinutes) || nbMinutes < 1) {
return false;
}
let newDLA = new Date(oldDLA);
newDLA.setMinutes(newDLA.getMinutes() + Number(nbMinutes));
return window.confirm(
`Votre DLA sera décalée au : ${MZ_formatDateMS(newDLA, false)
}\nConfirmez-vous ce décalage ?`
);
}
function newsubmitDLA(evt) {
evt.stopPropagation();
evt.preventDefault();
if (confirmeDecalage()) {
this.submit();
}
}
function changeActionDecalage() {
if (MY_getValue('CONFIRMEDECALAGE') != 'true') {
return;
}
try {
// On récupère le contenu du script JS MH de calcul du décalage
let scriptTxt = document.evaluate(
".//script[ not(@src) ]", document, null, 9, null
).singleNodeValue.textContent;
// On en extrait la DLA courante
scriptTxt = scriptTxt.slice(scriptTxt.indexOf('new Date(') + 9);
scriptTxt = scriptTxt.split('\n')[0];
let nbs = scriptTxt.match(/\d+/g);
oldDLA = new Date(nbs[0], nbs[1], nbs[2], nbs[3], nbs[4], nbs[5]);
} catch (exc) {
avertissement('Erreur de parsage : confirmation de décalage impossible', null, null, exc);
logMZ('changeActionDecalage DLA non trouvée');
return;
}
let form = document.getElementsByName('ActionForm')[0];
if (form) {
form.addEventListener('submit', newsubmitDLA, true);
} else {
avertissement('Erreur de parsage : confirmation de décalage impossible', null, null, '[changeActionDecalage] ActionForm non trouvé');
}
}
/** x~x Compte à rebours de DLA ---------------------------------------- */
function DMYHMSToDate(t) {
return new Date(t.replace(/(\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+)/, "$2/$1/$3 $4:$5:$6"));
}
/*
function DateDiff(d1, d2) {
let diff = {},
tmp = Math.floor((d2 - d1) / 1000); // on s'affranchit des 1000e de s
diff.sec = tmp % 60; tmp = Math.floor((tmp - diff.sec) / 60);
diff.min = tmp % 60; tmp = Math.floor((tmp - diff.min) / 60);
diff.hour = tmp % 24; tmp = Math.floor((tmp - diff.hour) / 24);
diff.day = tmp;
return diff.day > 5 ? "> 5j" : [
diff.day > 0 ? `${diff.day}j` : null,
diff.hour > 0 ? `${diff.hour}h` : null,
diff.min > 0 ? `${diff.min}m` : null,
diff.sec > 0 ? `${diff.sec}s` : null
].filter((o) => {
return o;
}).join(" ");
}
*/
function initCompteAreboursDLA() {
if (MY_getValue('COMPTEAREBOURSDLA') != 'true') {
return;
}
let mhTitle = window.top.document.body.mz_initial_title;
if (mhTitle === undefined) {
// mémoriser le titre initial dans le document lui-même
mhTitle = window.top.document.title;
window.top.document.body.mz_initial_title = mhTitle;
}
let inTitleAlso = (MY_getValue('COMPTEAREBOURSTITRE') == 'true');
let dlaFavicon = '/favicon.ico';
let div = document.getElementById('DLA_xyn');
div.style.marginTop = '10px';
let br = div.getElementsByTagName('br')[0];
// logMZ('initCompteAreboursDLA_log' + div.innerHTML);
let dlaDate = DMYHMSToDate((/DLA:\s+([^<]+)</).exec(div.innerHTML)[1]);
let cnt = document.createElement('div');
div.insertBefore(cnt, br);
div.removeChild(br);
let diff2color = function (diff) {
if (diff > 20 * 60 * 1000) return;
if (diff > 5 * 60 * 1000) return 'yellow';
else if (diff > 0) return 'orange';
else if (diff > -5 * 60 * 1000) return 'orangered';
else return;
}
let diff2icon = function (diff) {
if (diff > 20 * 60 * 1000) return dlaFavicon;
if (diff > 5 * 60 * 1000) return URL_MZimg + 'dangerJaune.ico';
else if (diff > 0) return URL_MZimg + 'dangerOrange.ico';
else if (diff > -6 * 60 * 1000) return URL_MZimg + 'dangerRouge.ico';
else return dlaFavicon;
}
let funcTimer = function () {
let mhDiff = MY_getValue('MZ_rebours_diff_time');
if (mhDiff == undefined) mhDiff = 0;
let dlaDiff = dlaDate.getTime() - (new Date()).getTime() - mhDiff;
//console.log('initCompteAreboursDLA_log : dlaDate=' + dlaDate + ', date=' + (new Date()) + ', mhDiff=' + mhDiff + ', dlaDiff=' + dlaDiff);
/*
let dlaTitleString = '';
let tabEltCnt = [];
let dlaColor = undefined;
*/
let paRestant = parseInt(MY_getValue(`${numTroll}.PA`), 10);
let showLienActiver = undefined; // 1 "vous pouvez réactiver", 2 "vous pouvez jouer"
let showCompteARebours = undefined; // 1 avec gestion couleur, 2 mode Over-DLA, 3 sans couleur
let showTitre = undefined; // 1 pour le mode compte à rebours, 2 pour le mode Over-DLA, 3 pour le mode avec compte à rebours sans icone
let clearInterval = false;
let dlaNext = undefined;
let showPAPerdus = false;
//debugMZ('initCompteAreboursDLA_log paRestant=' + paRestant);
if (dlaDiff > 0) {
if (paRestant === 0) {
// affichage compte à rebours sans couleur
// titre : compte à rebours sans icone
showCompteARebours = 3;
showTitre = 3;
} else {
// affichage compte à rebours avec couleur si besoin
// affichage "vous pouvez jouer"
showLienActiver = 2;
// titre : compte à rebours et icone d'alerte si besoin
showCompteARebours = 1;
showTitre = 1;
}
} else if (dlaDiff > -(5 * 60 * 1000) && paRestant !== 0) {
// over-dla
// affichage compte à rebours en rouge, texte "over-DLA"
// titre : (Over-DLA) + compte (minutes uniquement) et icone rouge
showCompteARebours = 2;
showTitre = 2;
} else {
showLienActiver = 1;
let dureeNext = parseInt(MY_getValue(`${numTroll}.caracs.dureeProchainTour`), 10);
dlaNext = new Date(dlaDate);
dlaNext.setMinutes(dlaDate.getMinutes() + dureeNext);
if (!isNaN(dureeNext)) {
dlaDiff = dlaDiff + dureeNext * 60 * 1000;
} else {
dlaDiff = undefined;
}
if (dlaDiff === undefined) {
// affichage lien activer
// titre : rien
// stop timer
clearInterval = true;
} else if (dlaDiff > 0) {
// on est avant la DLA suivante
// affichage compte à rebours avec couleur
// affichage lien activer
// titre : compte à rebours et icone d'alerte si besoin
showCompteARebours = 1;
showTitre = 1;
// arrêt du timer si au moins 20 min avant la DLA
if (dlaDiff > 20 * 60 * 1000) {
let d = new Date();
d.setSeconds(d.getSeconds() + dlaDiff / 1000 - 20 * 60);
//debugMZ('initCompteAreboursDLA_log reveil ' + MZ_formatDateMS(d));
window.setTimeout(funcTimer, dlaDiff - 20 * 60 * 1000);
}
} else {
// on est après la DLA suivante
// affichage lien activer
// titre : rien
// stop timer
clearInterval = true;
// bricoler dlaDiff pour forcer pas de couleur
dlaDiff += 3600 * 1000;
}
// et, dans tous les cas, on affiche les PA perdus
showPAPerdus = true;
}
if (timer && clearInterval) {
window.clearInterval(timer);
debugMZ('initCompteAreboursDLA_log kill timer');
timer = undefined;
}
while (cnt.firstChild) cnt.removeChild(cnt.lastChild);
if (dlaNext !== undefined) {
let newdiv = appendTextDiv(cnt, 'suiv. indicative : ' + dlaNext.toLocaleTimeString());
newdiv.title = 'Heure indicative qui peut avoir changé entre-temps';
}
let dlaTime, dlaHours, dlaMinutes, dlaSeconds, dlaCompteReboursTexte;
let tFmt = function (t, sfx, padding) { return (padding || t > 0) ? ` ${padding && t < 10 ? '0' : ''}${t}${sfx}` : ''; };
switch (showCompteARebours) { // 1 avec gestion couleur, 2 mode Over-DLA, 3 sans couleur
case 1:
case 3:
dlaTime = new Date(dlaDiff);
dlaHours = Math.floor(dlaDiff / 60 / 60 / 1000);
dlaMinutes = dlaTime.getUTCMinutes();
dlaSeconds = dlaTime.getUTCSeconds();
dlaCompteReboursTexte = tFmt(dlaHours, 'h') + tFmt(dlaMinutes, 'm', true) + tFmt(dlaSeconds, 's', true);
appendTextDiv(cnt, `DLA dans${dlaCompteReboursTexte}`);
break;
case 2:
dlaTime = new Date(- dlaDiff);
dlaMinutes = dlaTime.getUTCMinutes();
dlaSeconds = dlaTime.getUTCSeconds();
dlaCompteReboursTexte = tFmt(dlaMinutes, 'm') + tFmt(dlaSeconds, 's', true);
appendTextDiv(cnt, `Over-DLA :${dlaCompteReboursTexte}`);
break;
}
switch (showLienActiver) {
case 1: {
let ea = appendA(cnt, '/mountyhall/MH_Play/Activate_DLA.php', undefined, 'Vous pouvez réactiver');
ea.target = '_top';
ea.style.color = '#AEFFAE';
}
break;
case 2: {
let newdiv = appendTextDiv(cnt, 'Vous pouvez jouer');
newdiv.style.color = '#AEFFAE';
}
break;
}
let dlaColor = diff2color(dlaDiff);
//debugMZ('initCompteAreboursDLA_log dlaDiff=' + dlaDiff + ', color=' + dlaColor + ', showCompteARebours=' + showCompteARebours + ', paRestant=' + paRestant);
if (dlaColor === undefined || showCompteARebours == 3) {
cnt.style.removeProperty("color");
//debugMZ('initCompteAreboursDLA_log remove color');
} else {
cnt.style.color = dlaColor;
//debugMZ('initCompteAreboursDLA_log set color ' + dlaColor);
}
if (showPAPerdus && paRestant > 0) appendTextDiv(cnt, 'Vous pourez concentrer ' + paRestant + ' PA');
if (inTitleAlso) {
let dlaTitleString = '';
let icon = dlaFavicon;
switch (showTitre) { // 1 pour le mode compte à rebours, 2 pour le mode Over-DLA, 3 pour le mode avec compte à rebours sans icone
case 1:
icon = diff2icon(dlaDiff);
case 3:
dlaTitleString = `${dlaCompteReboursTexte} - `;
break;
case 2:
dlaTitleString = `Over-DLA:${dlaCompteReboursTexte} - `;
icon = diff2icon(dlaDiff);
break;
}
window.top.document.title = dlaTitleString + mhTitle;
let done = false;
for (let elt of window.top.document.head.children) {
if (elt.tagName != 'LINK' || elt.rel != 'icon') continue;
if (elt.href != icon) elt.href = icon;
done = true;
break;
}
if (!done) {
let elt = window.top.document.createElement('link');
elt.rel = 'icon';
elt.href = icon;
window.top.document.head.appendChild(elt);
}
}
};
let timer = setInterval(funcTimer, 1000);
}
/** x~x Alerte Mundi --------------------------------------------------- */
function prochainMundi() {
let node;
try {
node = document.evaluate(
"//div[@class='dateAction']/b", document, null, 9, null
).singleNodeValue;
if (!node) {
logMZ('skip mundi');
return;
}
} catch (exc) {
logMZ('prochainMundi Date introuvable', exc);
return;
}
let longueurMois = node.textContent.indexOf('Saison du Hum') == -1 ? 28 : 14;
let jour = longueurMois + 1 - getNumber(node.textContent);
if (node.textContent.indexOf('Mundidey') != -1) {
jour = longueurMois;
}
let txt = '[MZ : Prochain Mundidey ';
if (jour > 1) {
txt = `${txt}dans ${jour} jours]`;
} else {
txt = `${txt}demain]`;
}
let br = node.parentNode.nextSibling;
if (br.nodeName == '#text') br = br.nextSibling;
let div = insertTextDiv(br, txt, true);
div.style.textAlign = 'center';
div.style.marginBottom = '-5px';
if (br.nodeName == 'BR') br.parentNode.removeChild(br);
}
/* Fonction principale */
function dispatch() {
if (isPage('MH_Play/Play_action')) {
prochainMundi();
} else if (isPage('MH_Play/Play_a_Decaler.php')) {
changeActionDecalage();
} else if (isPage('MH_Play/Actions')) {
if (document.evaluate(
"//form/descendant::p/text()[contains(., 'Zone Piégée')]", document, null, 2, null
).stringValue) {
traiteMM();
} else if (document.evaluate(
"//tr/td/descendant::p/text()[contains(., 'identification a donné')]", document, null, 2, null
).stringValue) {
// getIdt();
traiteRM();
} /* else {
// Est censé se lancer sur quoi *précisément* ?
traiteRM();
getLevel();
}*/
} else {
/* Traitement des messages du bot */
let messageTitle = document.evaluate(
"//form/table/tbody/tr[1]/td[1]/descendant::text()[contains(.,'[MountyHall]')]", document, null, 2, null
).stringValue;
if (messageTitle.indexOf('Attaquant') != -1 && messageTitle.indexOf('sur') != -1) {
getLevel();
traiteRM();
} else if (messageTitle.indexOf('Résultat du pouvoir') != -1 || messageTitle.indexOf('Défenseur') != -1) {
traiteMM();
} else if (messageTitle.indexOf('Identification des trésors') != -1 ||
// à replacer avec Attaque après révision getLvl :
messageTitle.indexOf('Explosion') != -1 ||
messageTitle.indexOf('Insulte') != -1) {
traiteRM();
}
}
}
function do_actions() {
start_script(31, 'do_actions_log');
dispatch();
do_memoPA();
displayScriptTime(undefined, 'do_actions_log');
}
/** x~x Pré-enchantement ----------------------------------------------- */
/* 2013-08-19 : correction auto syntaxe alert */
var combobox = null;
function changeObject() {
if (!combobox) {
return;
}
let id = combobox.options[combobox.selectedIndex].value;
let texte = combobox.options[combobox.selectedIndex].firstChild.nodeValue;
if (!id || id == "") {
MY_removeValue(`${numTroll}.enchantement.lastEquipement`);
return;
}
MY_setValue(`${numTroll}.enchantement.lastEquipement`, `${id};${texte}`);
}
function treatePreEnchantement() {
let input = document.evaluate("//input[@name='ai_IDLI']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (!input || input.getAttribute("type") == "hidden") {
return false;
}
MY_setValue(`${numTroll}.enchantement.lastEnchanteur`, input.getAttribute("value"));
combobox = document.evaluate("//select[@name='ai_IDTE']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (!combobox) {
return true;
}
combobox.addEventListener('change', changeObject, true);
return true;
}
function treateEnchantement_pre() {
let input = document.evaluate("//input[@name='ai_IDTE']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (!input || input.getAttribute("type") != "hidden") {
return false;
}
let idEquipement = input.getAttribute("value");
let nomEquipement = `Equipement inconnu (${idEquipement})`;
let enchanteur = MY_getValue(`${numTroll}.enchantement.${idEquipement}.enchanteur`);
if (enchanteur && enchanteur != null) {
return true;
}
input = document.evaluate("//input[@name='ai_IDLI']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (!input || input.getAttribute("type") != "hidden") {
return false;
}
let idEnchanteur = input.getAttribute("value");
let nodes = document.evaluate("//p/img[@src='../Images/greenball.gif']/following-sibling::text()", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (nodes.snapshotLength != 3) {
return;
}
for (let i = 0; i < 3; i++) {
let {compo, monstre, qualite, localisation} = extractRequiredCompo(nodes.snapshotItem(i));
// avertissement(compo+" ["+localisation+"] "+monstre+" "+qualite);
MY_setValue(`${numTroll}.enchantement.${idEquipement}.composant.${i}`, `${compo};${localisation};${monstre.replace(/ Géante?/, "")};${qualite};${trim(nodes.snapshotItem(i).nodeValue)}`);
}
MY_setValue(`${numTroll}.enchantement.${idEquipement}.enchanteur`, `${idEnchanteur};${MY_getValue(`${numTroll}.position.X`)};${MY_getValue(`${numTroll}.position.Y`)};${MY_getValue(`${numTroll}.position.N`)}`);
MY_setValue(`${numTroll}.enchantement.${idEquipement}.objet`, nomEquipement);
let liste = MY_getValue(`${numTroll}.enchantement.liste`);
if (!liste || liste == "") {
MY_setValue(`${numTroll}.enchantement.liste`, idEquipement);
} else {
MY_setValue(`${numTroll}.enchantement.liste`, `${liste};${idEquipement}`);
}
}
function do_pre_enchant() {
start_script(60, 'do_pre_enchant_log');
if (!treatePreEnchantement()) {
treateEnchantement_pre();
}
displayScriptTime(undefined, 'do_pre_enchant_log');
}
function extractRequiredCompo(node) {
let texte = trim(node.textContent);
texte = texte.replace(" d'une ", " d'un ");
let compo = texte.substring(0, texte.indexOf(" d'un "));
let monstre = texte.substring(texte.indexOf(" d'un ") + 6, texte.indexOf(" d'au minimum"));
monstre = monstre.replace(/ Géante?/, "");
let qualite = texte.substring(texte.indexOf("Qualité ") + 8, texte.indexOf(" ["));
let localisation = texte.substring(texte.indexOf("[") + 1, texte.indexOf("]"));
return {compo, monstre, qualite, localisation};
}
function treateEnchantement() {
let idEnchanteur = MY_getValue(`${numTroll}.enchantement.lastEnchanteur`);
let infoEquipement = MY_getValue(`${numTroll}.enchantement.lastEquipement`);
if (!idEnchanteur || idEnchanteur == "" || !infoEquipement || infoEquipement == "") {
return;
}
let tab = infoEquipement.split(";");
if (tab.length < 2) {
return;
}
let idEquipement = tab[0];
let nomEquipement = tab[1];
for (let i = 2; i < tab.length; i++) {
nomEquipement = `${nomEquipement};${tab[i]}`;
}
let nodes = document.evaluate("//p/img[@src='../Images/greenball.gif']/following-sibling::text()", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (nodes.snapshotLength != 3) {
return;
}
for (let i = 0; i < 3; i++) {
let {compo, monstre, qualite, localisation} = extractRequiredCompo(nodes.snapshotItem(i));
MY_setValue(`${numTroll}.enchantement.${idEquipement}.composant.${i}`, `${compo};${localisation};${monstre.replace(/ Géante?/, "")};${qualite};${trim(nodes.snapshotItem(i).nodeValue)}`);
}
MY_setValue(`${numTroll}.enchantement.${idEquipement}.enchanteur`, `${idEnchanteur};${MY_getValue(`${numTroll}.position.X`)};${MY_getValue(`${numTroll}.position.Y`)};${MY_getValue(`${numTroll}.position.N`)}`);
MY_setValue(`${numTroll}.enchantement.${idEquipement}.objet`, nomEquipement);
let liste = MY_getValue(`${numTroll}.enchantement.liste`);
if (!liste || liste == "") {
MY_setValue(`${numTroll}.enchantement.liste`, idEquipement);
} else {
MY_setValue(`${numTroll}.enchantement.liste`, `${liste};${idEquipement}`);
}
}
function do_enchant() {
start_script(60, 'do_enchant_log');
treateEnchantement();
MY_removeValue(`${numTroll}.enchantement.lastEquipement`);
MY_removeValue(`${numTroll}.enchantement.lastEnchanteur`);
displayScriptTime(undefined, 'do_enchant_log');
}
function lireEnchantementEncours() {
let enCours = [];
let cells = document.querySelectorAll("td.mh_tdtitre");
for (let i = 0; i < cells.length; i++) {
let cell = cells[i];
let equipmentInfo = cell.querySelector("a").text.split(/[\[\]]/);
let idEquipement = equipmentInfo[1];
enCours.push(idEquipement);
let nomEquipement = trim(equipmentInfo[2]);
MY_setValue(`${numTroll}.enchantement.${idEquipement}.objet`, nomEquipement);
let components = cell.querySelectorAll("li");
for (let j = 0; j < components.length; j++) {
let {compo, monstre, qualite, localisation} = extractRequiredCompo(components[j]);
MY_setValue(`${numTroll}.enchantement.${idEquipement}.composant.${j}`, `${compo};${localisation};${monstre};${qualite};${trim(components[j].textContent)}`);
MZ_troogle.addTroogleLink(components[j], `${MZ_troogle.SEARCH_MONSTER} ${monstre}`);
MZ_troc.addTrocLink(components[j], monstre, compo, qualite);
}
let enchanteurText = cell.querySelectorAll("b")[2].textContent;
let enchanteurMatch = enchanteurText.match(/(\d+).*X= *([-\d]+).*Y= *([-\d]+).*N= *([-\d]+)/);
MY_setValue(`${numTroll}.enchantement.${idEquipement}.enchanteur`, `${enchanteurMatch[1]};${enchanteurMatch[2]};${enchanteurMatch[3]};${enchanteurMatch[4]}`);
}
let liste = MY_getValue(`${numTroll}.enchantement.liste`);
let listeEquipement = null == liste ? [] : liste.split(";");
MY_setValue(`${numTroll}.enchantement.liste`, enCours.join(';'));
for (const previous of listeEquipement) {
if (-1 == enCours.indexOf(previous)) {
debugMZ(`Suppression enchantement ${previous} du local storage`);
MY_removeValue(`${numTroll}.enchantement.${previous}.objet`);
MY_removeValue(`${numTroll}.enchantement.${previous}.enchanteur`);
MY_removeValue(`${numTroll}.enchantement.${previous}.composant.0`);
MY_removeValue(`${numTroll}.enchantement.${previous}.composant.1`);
MY_removeValue(`${numTroll}.enchantement.${previous}.composant.2`);
}
}
// TODO: isoler code lié aux enchantements dans un pseudo-module & purger code obsolète
}
function do_lire_enchant_en_cours() {
start_script(60, 'do_lire_enchant_en_cours_log');
lireEnchantementEncours();
displayScriptTime(undefined, 'do_lire_enchant_en_cours_log');
}
/** x~x MyEvent -------------------------------------------------------- */
// Script désactivé en attendant la màj vers le nouveau système de missions.
function do_myevent() { }
/** x~x Malus ---------------------------------------------------------- */
/* v1.4 - 2014-01-06
* - Gestion des sorts double composante
* v1.4.1 - 2014-01-22
* - Correction décumul
* TODO
* - Identifier la position de "PV" dans l'ordre MH
*/
var listeBM;
/** x~x Utilitaires ---------------------------------------------------- */
function decumul(bmt, nbr) {
let bmr;
if (!nbr || nbr < 2) {
bmr = bmt;
} else if (nbr == 2) {
bmr = parseInt(0.67 * bmt);
} else if (nbr == 3) {
bmr = parseInt(0.40 * bmt);
} else if (nbr == 4) {
bmr = parseInt(0.25 * bmt);
} else if (nbr == 5) {
bmr = parseInt(0.15 * bmt);
} else {
bmr = parseInt(0.1 * bmt);
}
if (bmt < 0) {
return Math.min(-1, bmr);
}
return Math.max(1, bmr);
}
function triecaracs(a, b) { // version Yoyor, mod by Dab
// Roule 23/11/2016 ajout PV
switch (a) {
case 'ATT':
return -1;
case 'ESQ':
if (b == 'ATT') {
return 1;
}
return -1;
case 'DEG':
switch (b) {
case 'ATT':
case 'ESQ':
return 1;
default:
return -1;
}
case 'REG':
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
return 1;
default:
return -1;
}
case 'Vue':
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
return 1;
default:
return -1;
}
case 'TOUR':
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
case 'Vue':
return 1;
default:
return -1;
}
case 'PV':
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
case 'Vue':
case 'TOUR':
return 1;
default:
return -1;
}
case 'Armure':
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
case 'Vue':
case 'TOUR':
case 'PV':
return 1;
default:
return -1;
}
case 'RM':
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
case 'Vue':
case 'TOUR':
case 'PV':
case 'Armure':
return 1;
default:
return -1;
}
case 'MM':
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
case 'Vue':
case 'TOUR':
case 'PV':
case 'Armure':
case 'RM':
return 1;
default:
return -1;
}
case 'Concentration':
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
case 'Vue':
case 'TOUR':
case 'PV':
case 'Armure':
case 'RM':
case 'MM':
return 1;
default:
return -1;
}
case 'Fatigue':
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
case 'Vue':
case 'TOUR':
case 'PV':
case 'Armure':
case 'RM':
case 'MM':
case 'Concentration':
return 1;
default:
return -1;
}
case "Dés d'attaque":
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
case 'Vue':
case 'TOUR':
case 'PV':
case 'Armure':
case 'RM':
case 'MM':
case 'Concentration':
case 'Fatigue':
return 1;
default:
return -1;
}
case 'Dés de dégâts':
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
case 'Vue':
case 'TOUR':
case 'PV':
case 'Armure':
case 'RM':
case 'MM':
case 'Concentration':
case 'Fatigue':
case "Dés d'attaque":
return 1;
default:
return -1;
}
default:
switch (b) {
case 'ATT':
case 'ESQ':
case 'DEG':
case 'REG':
case 'Vue':
case 'TOUR':
case 'PV':
case 'Armure':
case 'RM':
case 'MM':
case 'Concentration':
case 'Fatigue':
case "Dés d'attaque":
case 'Dés de dégâts':
return 1;
default:
return -1;
}
}
}
/** x~x Fonctions hide / display --------------------------------------- */
function toggleDetailsBM() {
if (MY_getValue('BMDETAIL') != 'false') {
MY_setValue('BMDETAIL', 'false');
let trlist = document.getElementsByClassName('mh_tdpage BilanDetail');
for (let i = 0; i < trlist.length; i++) {
trlist[i].style.display = 'none';
}
trlist = document.getElementsByClassName('mh_tdpage BilanSomme');
for (let i = 0; i < trlist.length; i++) {
trlist[i].style = '';
}
} else {
MY_setValue('BMDETAIL', 'true');
let trlist = document.getElementsByClassName('mh_tdpage BilanSomme');
for (let i = 0; i < trlist.length; i++) {
trlist[i].style.display = 'none';
}
trlist = document.getElementsByClassName('mh_tdpage BilanDetail');
for (let i = 0; i < trlist.length; i++) {
trlist[i].style = '';
}
}
}
function toggleBMList() {
if (MY_getValue('BMHIDELIST') == 'true') {
MY_setValue('BMHIDELIST', 'false');
for (let i = 0; i < listeBM.snapshotLength; i++) {
listeBM.snapshotItem(i).style = '';
}
document.getElementsByTagName('thead')[0].style = '';
document.getElementById('trhelp').style = '';
} else {
MY_setValue('BMHIDELIST', 'true');
for (let i = 0; i < listeBM.snapshotLength; i++) {
listeBM.snapshotItem(i).style.display = 'none';
}
document.getElementsByTagName('thead')[0].style.display = 'none';
document.getElementById('trhelp').style.display = 'none';
}
}
function setDisplayBM() {
if (!listeBM) {
return;
}
let titre = document.getElementById('MHTitreH2');
if (titre) {
titre.style.cursor = 'pointer';
titre.onclick = toggleBMList;
}
let tfoot = document.getElementsByTagName('tfoot')[0];
let tr = document.evaluate(
"./tr/td/text()[contains(.,'décumul')]/../..", tfoot, null, 9, null
).singleNodeValue;
tr.id = 'trhelp';
if (MY_getValue('BMHIDELIST') == 'true') {
for (let i = 0; i < listeBM.snapshotLength; i++) {
listeBM.snapshotItem(i).style.display = 'none';
}
document.getElementsByTagName('thead')[0].style.display = 'none';
tr.style.display = 'none';
}
}
/** x~x Traitement Malus --------------------------------------- */
function traiteMalus() {
let mainTab = document.getElementById('bmm');
if (!mainTab) {
logMZ('traiteMalus: pas de table bmm');
return;
}
let tbody = mainTab.tBodies[0];
if (!tbody) {
logMZ('traiteMalus: pas de BM (pas de tbody)');
return;
}
/* Suppression des BM de fatigue stockés */
if (MY_getValue(`${numTroll}.bm.fatigue`)) {
MY_removeValue(`${numTroll}.bm.fatigue`);
}
/* Extraction des données */
let uniListe = [], listeDurees = {}, listeDecumuls = {};
let nb = 0;
for (let tr of tbody.rows) {
nb++;
let effetsT = tr.cells[1].textContent.split(' | ');
let phymag = tr.cells[3].textContent;
let duree = tr.cells[4].textContent.match(/\d+/);
if (duree == null) { // Roule 28/01/2018 protection malus Crasc sans durée
duree = 1;
} else {
duree = Number(duree[0]);
}
// Roule 23/11/2016 tout semble être soumis à décumul (vérifié pour Charme, Drain de vie)
// si c'est un type à décumul
/*
let type = tr.childNodes[3].textContent;
switch(type) {
case 'Potion':
case 'Parchemin':
case 'Sortilège':
case 'Capacité Spéciale':
nom = tr.childNodes[1].textContent+phymag;
break;
default:
nom = 'pasdedecumul';
}
*/
let nom = tr.childNodes[1].textContent + phymag;
// !! Amnésie = Capa, mais pas décumulée
if (nom.indexOf('Amnésie') != -1) {
nom = 'pasdedecumul';
}
uniListe[nb] = {
duree: duree,
nom: nom, // permet de gérer le non décumul des sorts à double composante
caracs: {}
};
for (let i = 0; i < effetsT.length; i++) {
if (effetsT[i].indexOf(':') == -1) {
continue;
}
// structure : liste[nb]=[duree , nom , [type ,] Array[caracs] ]
// nom = 'pasdedecumul' si pas de décumul
let carac = trim(effetsT[i].substring(0, effetsT[i].indexOf(':')));
if (carac == 'ATT' || carac == 'DEG' || carac == 'Armure') {
uniListe[nb].type = phymag;
}
let tmatch = effetsT[i].match(/(-?\d+)(\\([+-]?\d+))?/); // un numérique et exceptionnellement un autre numérique précédé d'un antislash
let bm;
if (tmatch[2] == undefined) {
bm = Number(tmatch[1]);
} // cas DEG : -6
else {
bm = Number(tmatch[3]);
} // cas DEG : +0\-5
uniListe[nb].caracs[carac] = bm;
debugMZ(`effetsT[${i}]=${effetsT[i]}, uniListe[${nb}]['caracs'][${carac}] = ${bm}, durée=${duree} tmatch=${JSON.stringify(tmatch)}`);
listeDurees[duree] = true;
}
} // fin boucle sur les lignes de bonus/malus
/* Gestion des décumuls et cumuls des durées */
let toursGeres = [];
for (let d in listeDurees) {
toursGeres.push(d);
}
toursGeres.sort((a, b) => {
return b - a;
});
debugMZ(`toursGeres=${JSON.stringify(toursGeres)}\nuniListe=${JSON.stringify(uniListe)}`);
let strfat = ''; // pour sauvegarder les bm de fatigue
// Pour affichage & adpatation à footable.js (statique)
let thead = document.getElementsByTagName('thead')[0];
let nbHidden = document.evaluate(
"./tr/th[@style='display: none;']", thead, null, 7, null
).snapshotLength;
let tfoot = document.getElementsByTagName('tfoot')[0];
for (let i = 0; i < toursGeres.length; i++) {
let tour = toursGeres[i];
let effetsCeTour = {}, decumulsCeTour = {};
for (let nbb = 1; nbb < uniListe.length; nbb++) {
if (uniListe[nbb].duree < toursGeres[i]) {
continue;
} // si durée pvr < durée analysée, on passe
let nom = uniListe[nbb].nom;
if (nom != 'pasdedecumul') {
if (decumulsCeTour[nom] == null) {
decumulsCeTour[nom] = 0;
}
decumulsCeTour[nom]++;
}
for (let carac in uniListe[nbb].caracs) {
let bm = uniListe[nbb].caracs[carac];
if (carac == 'ATT' || carac == 'DEG' || carac == 'Armure') {
let type = uniListe[nbb].type;
if (!effetsCeTour[carac]) {
effetsCeTour[carac] = { Physique: 0, Magique: 0 };
}
let thisBm;
if (nom == 'pasdedecumul') {
thisBm = bm;
} else {
thisBm = decumul(bm, decumulsCeTour[nom]);
}
effetsCeTour[carac][type] += thisBm;
debugMZ(`calcul décumul tour=${tour}, nom=${nom}, carac=${carac}, bm=${bm}, type=${type}, decumulsCeTour[nom]=${decumulsCeTour[nom]} : ${thisBm} => ${effetsCeTour[carac][type]}`);
} else {
if (!effetsCeTour[carac]) {
effetsCeTour[carac] = 0;
}
let thisBm;
if (nom == 'pasdedecumul' || carac == 'Fatigue') {
thisBm = bm;
} else if (carac == 'TOUR') {
thisBm = decumul(2 * bm, decumulsCeTour[nom]) / 2;
} // les durees se comptent en demi-minutes dans MH
else {
thisBm = decumul(bm, decumulsCeTour[nom]);
}
effetsCeTour[carac] += thisBm;
debugMZ(`calcul décumul tour=${tour}, nom=${nom}, carac=${carac}, bm=${bm}, decumulsCeTour[nom]=${decumulsCeTour[nom]} : ${thisBm} => ${effetsCeTour[carac]}`);
}
} // fin boucle sur les caractéristiques
} // fin boucle sur les bonus/malus
/* Création du bilan du tour */
let texteD = '', texteS = '';
let caracGerees = [];
for (let k in effetsCeTour) {
caracGerees.push(k);
}
caracGerees.sort(triecaracs);
for (let j = 0; j < caracGerees.length; j++) {
let carac = caracGerees[j], str = '';
debugMZ(`traiteMalus, j=${j}, carac=${carac}, effetsCeTour=${effetsCeTour[carac]}, toursGeres=${toursGeres[i]}`);
switch (carac) {
case 'ATT':
case 'DEG':
case 'Armure':
let phy = effetsCeTour[carac].Physique;
let mag = effetsCeTour[carac].Magique;
texteD = texteD + (phy || mag ? ` | ${carac} : ${aff(phy)}\\${aff(mag)}` : '');
texteS = texteS + (phy + mag ? ` | ${carac} : ${aff(phy + mag)}` : '');
break;
case 'TOUR':
str = effetsCeTour[carac] ? ` | TOUR : ${aff(effetsCeTour[carac])} min` : '';
break;
case 'Fatigue':
strfat = `${strfat}${toursGeres[i]}-${effetsCeTour[carac]};`;
case 'PV':
case 'PVMax':
case 'ESQ':
case 'REG':
case 'Vue':
case 'VUE':
case 'Voir le Caché':
str = effetsCeTour[carac] ? ` | ${carac} : ${aff(effetsCeTour[carac])}` : '';
break;
default:
str = effetsCeTour[carac] ? ` | ${carac} : ${aff(effetsCeTour[carac])} %` : '';
}
if (str) {
texteD = texteD + str;
texteS = texteS + str;
}
debugMZ(`traiteMalus, j=${j}, strfat=${strfat}`);
} // fin boucle sur les caractéristiques
/* Affichage */
// Si rien à afficher on passe
if (!texteD) {
continue;
}
// Si BMM+BMP=0
texteS = texteS ? texteS.substring(3) : 'Aucun effet';
let tr = insertTr(tfoot.childNodes[2], 'mh_tdpage BilanDetail');
if (MY_getValue('BMDETAIL') == 'false') {
tr.style.display = 'none';
}
let td = appendTdText(tr, texteD.substring(3));
td.colSpan = 4 - nbHidden;
let txttour = `${toursGeres[i]} Tour`;
if (toursGeres[i] > 1) {
txttour = `${txttour}s`;
}
appendTdText(tr, txttour);
tr = insertTr(tfoot.childNodes[2], 'mh_tdpage BilanSomme');
if (MY_getValue('BMDETAIL') != 'false') {
tr.style.display = 'none';
}
td = appendTdText(tr, texteS);
td.colSpan = 4 - nbHidden;
appendTdText(tr, txttour);
} // fin boucle sur les tours générés
/* mise en place toggleDetails */
tfoot.style.cursor = 'pointer';
tfoot.onclick = toggleDetailsBM;
/* Stockage fatigue : tour-fatigue;tour-fatigue;... */
if (strfat) {
MY_setValue(`${numTroll}.bm.fatigue`, strfat);
}
}
function do_malus() {
try {
start_script(undefined, 'do_malus_log');
traiteMalus();
setDisplayBM();
displayScriptTime(undefined, 'do_malus_log');
} catch (exc) {
avertissement('Une erreur est survenue (do_malus)', null, null, exc);
}
}
/** x~x Mouches -------------------------------------------------------- */
var mainTab, tr_mouches;
function initialiseMouches() {
// Lanceur global
try {
mainTab = document.getElementById('mouches');
tr_mouches = document.evaluate('./tbody/tr', mainTab, null, 7, null);
} catch (exc) {
avertissement('Une erreur est survenue (mouches)', null, null, exc);
return;
}
if (mainTab === void 0 || tr_mouches.snapshotLength == 0) {
return;
}
setDisplayMouches();
traiteMouches();
}
function setDisplayMouches() {
// Initialise l'affichage / l'effacement du détail des mouches
let titre = document.getElementById('MHTitreH2');
if (titre) {
titre.style.cursor = 'pointer';
titre.onclick = toggleMouches;
}
let tfoot = document.getElementsByTagName('tfoot')[0];
if (tfoot) {
tfoot.style.cursor = 'pointer';
tfoot.onclick = toggleMouches;
}
if (MY_getValue('HIDEMOUCHES') == 'true') {
for (let i = 0; i < tr_mouches.snapshotLength; i++) {
tr_mouches.snapshotItem(i).style.display = 'none';
}
document.getElementsByTagName('thead')[0].style.display = 'none';
}
}
function toggleMouches() {
// Handler pour afficher / masquer les détails
if (MY_getValue('HIDEMOUCHES') == 'true') {
MY_setValue('HIDEMOUCHES', 'false');
for (let i = 0; i < tr_mouches.snapshotLength; i++) {
tr_mouches.snapshotItem(i).style.display = '';
}
document.getElementsByTagName('thead')[0].style.display = '';
} else {
MY_setValue('HIDEMOUCHES', 'true');
for (let i = 0; i < tr_mouches.snapshotLength; i++) {
tr_mouches.snapshotItem(i).style.display = 'none';
}
document.getElementsByTagName('thead')[0].style.display = 'none';
}
}
function traiteMouches() {
// Traitement complet: présence et effets des mouches
let listeTypes = {}, effetsActifs = {};
debugMZ(`traiteMouches, tr_mouches.length=${tr_mouches.snapshotLength}`);
for (let i = 0; i < tr_mouches.snapshotLength; i++) {
let tr = tr_mouches.snapshotItem(i);
// La mouche est-elle présente?
let etat = document.evaluate(
'./img', tr.cells[6], null, 9, null
).singleNodeValue.alt;
// debugMZ('traiteMouches, i=' + i + ', etat=' + etat + ', type=' + trim(tr.cells[3].textContent));
if (etat != 'La Mouche est là') {
continue;
}
// Extraction du type de mouche
let type = trim(tr.cells[3].textContent);
if (!listeTypes[type]) {
listeTypes[type] = 1;
} else {
listeTypes[type]++;
}
// debugMZ('traiteMouches, i=' + i + ', etat=' + etat + ', type=' + type + ', nb=' + listeTypes[type]);
// La mouche a-t-elle un effet?
let effet = trim(tr.cells[2].textContent);
if (etat != 'La Mouche est là' || !effet) {
continue;
}
// Si oui, extraction des effets (multiples pour pogées)
let caracs = effet.split(' | ');
for (let j = 0; j < caracs.length; j++) {
let carac = caracs[j].substring(0, caracs[j].indexOf(':') - 1);
let valeur = Number(caracs[j].match(/-?\d+/)[0]);
if (effetsActifs[carac] === void 0) {
effetsActifs[carac] = valeur;
} else {
effetsActifs[carac] += valeur;
}
}
}
// Extraction Effet total et affichage des différences à la normale
let tfoot = document.getElementsByTagName('tfoot')[0];
if (!tfoot) {
debugMZ('traiteMouches, pas de tfoot');
return;
}
let nodeTotal = document.evaluate(
".//b[contains(./text(),'Effet total')]", tfoot, null, 9, null
).singleNodeValue.nextSibling;
let effetsTheoriques = nodeTotal.nodeValue.split('|');
let texte = ' ';
for (let i = 0; i < effetsTheoriques.length; i++) {
if (texte.length > 1) {
texte = `${texte} | `;
}
let carac = trim(
effetsTheoriques[i].substring(0, effetsTheoriques[i].indexOf(':') - 1)
);
let valeur = effetsTheoriques[i].match(/-?\d+/)[0];
if (effetsActifs[carac] !== void 0 && effetsActifs[carac] == valeur) {
texte = texte + effetsTheoriques[i];
} else {
texte = `${texte}<b>${carac} : ${aff(effetsActifs[carac])}`;
if (carac == 'TOUR') {
texte = `${texte} min`;
}
texte = `${texte}</b>`;
}
}
let span = document.createElement('span');
span.innerHTML = texte;
nodeTotal.parentNode.replaceChild(span, nodeTotal);
// Affichage des différences du nombre de mouches de chaque type
let mouchesParType = document.evaluate("./tr/td/ul/li/text()", tfoot, null, 7, null);
for (let i = 0; i < mouchesParType.snapshotLength; i++) {
let node = mouchesParType.snapshotItem(i);
// let mots = node.nodeValue.split(' ');
// let type = mots.pop();
let tMatch = node.nodeValue.match(/([0-9]+) .*à *([^ ]+)/);
if (!tMatch) {
continue;
}
let nMouche = tMatch[1];
let type = tMatch[2];
debugMZ(`traiteMouches, texte=${node.nodeValue}, tMatch=${JSON.stringify(tMatch)}, type=${type}`);
if (!listeTypes[type]) {
node.nodeValue = `${node.nodeValue} (0 présente)`;
} else if (nMouche != listeTypes[type]) {
if (listeTypes[type] == 1) {
node.nodeValue = `${node.nodeValue} (1 présente)`;
} else {
node.nodeValue = `${node.nodeValue} (${listeTypes[type]} présentes)`;
}
}
}
}
function do_mouches() {
start_script(undefined, 'do_mouches_log');
initialiseMouches();
displayScriptTime(undefined, 'do_mouches_log');
}
/** x~x Equipement Gowap ----------------------------------------------- */
function initPopupEquipgowap() {
let popup = document.createElement('div');
popup.setAttribute('id', 'popupGwp');
popup.setAttribute('class', 'mh_textbox');
popup.setAttribute('style', 'position: absolute; visibility: hidden;' +
'display: inline; z-index: 3; max-width: 400px;');
document.body.appendChild(popup);
}
function showPopupGwp(evt) {
let texte = this.getAttribute("texteinfo");
let popup = document.getElementById('popupGwp');
popup.innerHTML = texte;
popup.style.left = `${evt.pageX + 15}px`;
popup.style.top = `${evt.pageY}px`;
popup.style.visibility = "visible";
}
function hidePopupGwp() {
let popup = document.getElementById('popupGwp');
popup.style.visibility = "hidden";
}
function createPopupImage(url, text) {
let img = document.createElement('img');
img.setAttribute('src', url);
img.setAttribute('align', 'ABSMIDDLE');
img.setAttribute("texteinfo", text);
img.addEventListener("mouseover", showPopupGwp, true);
img.addEventListener("mouseout", hidePopupGwp, true);
return img;
}
function formateTexte(texte) {
texte = texte.replace(/\n/g, "<br/>");
texte = texte.replace(/^([^<]*) d'un/g, "<b>$1</b> d'un");
texte = texte.replace(/<br\/>([^<]*) d'un/g, "<br/><b>$1</b> d'un");
texte = texte.replace(/(d'une? )([^<]*) d'au/g, "$1<b>$2</b> d'au");
texte = texte.replace(/(Qualité )([^<]*) \[/g, "$1<b>$2</b> [");
texte = texte.replace(/\[([^<]*)\]/g, "[<b>$1</b>]");
return texte;
}
function treateGowaps() {
// On récupère les gowaps possédants des composants
let tbodys = document.evaluate(
"//tr[@class='mh_tdpage_fo']/descendant::img[@alt = 'Composant - Spécial']/../../..",
document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (let j = 0; j < tbodys.snapshotLength; j++) {
let tbody = tbodys.snapshotItem(j);
// let id_gowap = currentURL.substring(currentURL.indexOf("?ai_IdFollower=") + 15) * 1;
// insertButtonComboDB(tbody, 'gowap', id_gowap,'mh_tdpage_fo');
// if (MY_getValue("NOINFOEM") != "true") { insertEMInfos(tbody); }
if (MY_getValue(`${numTroll}.enchantement.liste`) && MY_getValue(`${numTroll}.enchantement.liste`) != "") {
insertEnchantInfos(tbody);
}
}
}
function treateChampi() {
if (MY_getValue("NOINFOEM") == "true") {
return false;
}
let nodes = document.evaluate(
"//img[@alt = 'Champignon - Spécial']/../a/text()", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null
);
if (nodes.snapshotLength == 0) {
return false;
}
for (let i = 0; i < nodes.snapshotLength; i++) {
let node = nodes.snapshotItem(i);
let texte = trim(node.nodeValue.replace(/\240/g, " "));
if (texte.indexOf("*") != -1) {
texte = texte.substring(0, texte.lastIndexOf(" "));
}
let nomChampi = texte.substring(0, texte.lastIndexOf(" "));
if (moisChampi[nomChampi]) { // gath: 'moisChampi' is not defined
appendText(node.parentNode.parentNode, ` [Mois ${moisChampi[nomChampi]}]`);
}
}
}
function do_equipgowap() {
start_script(undefined, 'do_equipgowap');
treateGowaps();
treateChampi();
if (MY_getValue(`${numTroll}.enchantement.liste`) && MY_getValue(`${numTroll}.enchantement.liste`) != "") {
initPopupEquipgowap();
computeEnchantementEquipement(createPopupImage, formateTexte);
}
displayScriptTime(undefined, 'do_equipgowap');
}
/** *******************************************************************************
* This file is part of zoryazilla & mountyzilla, published under GNU License *
*********************************************************************************/
/** x~x Ordres Gowap --------------------------------------------------- */
var MZ_analyse_page_ordre_suivant;
var MZ_fo_ordres = isPageWithParam({ url: 'MH_Play/Play_a_Action', ids: ['t_fo_ordre'] });
if (MZ_analyse_page_ordre_suivant === undefined && MZ_fo_ordres) {
// objet réutilisé dans MZ, dans Trajet_canvas et dans une extension perso ☺
MZ_analyse_page_ordre_suivant = {
result: { ordres: [] },
init: function () {
// façon blindée de tester la variable MY_DEBUG
debugMZ('start MZ_analyse_page_ordre_suivant.init');
try {
let e_t_ordres = document.getElementById('t_fo_ordre');
for (let ligne of e_t_ordres.getElementsByTagName('caption')) {
//debugMZ('MZ_analyse_page_ordre_suivant_log ' + ligne.innerText);
for (let div of ligne.getElementsByTagName('div')) {
//debugMZ('MZ_analyse_page_ordre_suivant_log div ' + j + ' ' + div.innerText);
let tabmatch = div.innerText.match(/(\d+) *\.* *(.*\[.*\].*)$/);
if (tabmatch) {
// ID, Nom
this.result.id = tabmatch[1].trim();
this.result.nom = tabmatch[2].trim();
}
tabmatch = div.innerText.match(/(\d+) *PA.*X = (-?\d+).*Y = (-?\d+).*N = (-?\d+)/i);
if (tabmatch) {
// PA, x, y, n
this.result.PA = parseInt(tabmatch[1]);
this.result.x = parseInt(tabmatch[2]);
this.result.y = parseInt(tabmatch[3]);
this.result.n = parseInt(tabmatch[4]);
// Trajet_canvas a besoin d'un pointeur vers cette div
this.result.eltPos = div;
}
}
}
for (let ligne of e_t_ordres.rows) {
//debugMZ(`MZ_analyse_page_ordre_suivant td[0]=${ligne.textContent}`);
for (let td of ligne.getElementsByTagName('td')) {
let tabmatch = td.textContent.match(/^(.*)X=(-?\d+) \| Y=(-?\d+) \| N=(-?\d+)/i);
if (tabmatch) {
this.result.ordres.push({ ordre: tabmatch[1].trim(), x: parseInt(tabmatch[2]), y: parseInt(tabmatch[3]), n: parseInt(tabmatch[4]) });
} else {
tabmatch = td.textContent.match(/^\s*Aller\s*chercher\s*le\s*trésor\s*\[\s*(\d+)\s*\](.*)$/i);
if (tabmatch) {
this.result.ordres.push({ ordre: tabmatch[0].trim(), idtresor: parseInt(tabmatch[1]), nomtresor: trim(tabmatch[2]) });
} else {
this.result.ordres.push({ ordre: td.textContent.trim() });
}
}
}
}
debugMZ(`fin MZ_analyse_page_ordre_suivant ${JSON.stringify(this.result)}`);
} catch (exc) {
logMZ('Exception dans MZ_analyse_page_ordre_suivant.init', exc);
}
}
};
MZ_analyse_page_ordre_suivant.init();
}
var MZ_analyse_page_suivants;
if (isPage("MH_Play/Play_e_follo")) {
if (MZ_analyse_page_suivants === undefined) {
// Fonction réutilisée dans MZ, dans Trajet_canvas et dans une extension perso ☺
// rend un object, par exemple
MZ_analyse_page_suivants = {
suivants: [], // objet de type oMZ_TrSuivant
eTabSuivant: undefined, // la div qui contient tous les suivants
init: function () {
this.eTabSuivant = document.getElementById('suivants');
if (!this.eTabSuivant) {
logMZ("MZ_analyse_page_suivants : pas d'élément 'suivants' dans la page");
return;
}
let nbDiv = this.eTabSuivant.children.length;
for (let iDiv = 0; iDiv < nbDiv - 1; iDiv += 2) {
let oSuivant = new this.oMZ_TrSuivant(this.eTabSuivant.children[iDiv], this.eTabSuivant.children[iDiv + 1]);
if (oSuivant.oJSON) {
this.suivants.push(oSuivant);
} else {
// logMZ('MZ_analyse_page_suivants ignore ' + this.eTabSuivant.children[iDiv].innerText);
}
}
},
oMZ_TrSuivant: function (div1, div2) { // ceci est un objet
// .eTi : l'élément HTML de titre (div en ce moment qui qui sait quand ça changera ?)
// .eTr : l'élément HTML des trésors
// .oJSON : l'objet reçu en JSON dans le data-json
// .nom : le nom complet
// .loc : objet avec x, y, n
// les suivants sont chargés par la méthode initTresors()
// .categories : tableau d'objets de type oMZ_categorieSuivant
// .bVide : true si le suivant est vide
this.eTi = div1.getElementsByTagName('div')[0];
this.eTr = div2;
let elts = [];
for (let eDiv of this.eTi.getElementsByTagName('div')) elts.push(eDiv);
for (let eDiv of this.eTi.getElementsByTagName('h3')) elts.push(eDiv);
for (let eDiv of elts) {
let sTextDiv = eDiv.textContent.trim();
if ((!this.nom) && (eDiv.classList.contains('mh_titre3') || eDiv.tagName == 'H3')) {
this.nom = sTextDiv;
//logMZ('oMZ_TrSuivant nom=' + this.nom);
}
if (!this.loc) {
let m = sTextDiv.match(/(\d+) *PA *-* *X *= *(-?\d+) \| Y\n* *= *(-?\d+) \| N\n* *= *(-?\d+)/i);
if (m && m.length >= 5) {
this.loc = new Object();
this.loc.x = parseInt(m[2], 10);
this.loc.y = parseInt(m[3], 10);
this.loc.n = parseInt(m[4], 10);
//logMZ('oMZ_TrSuivant loc=' + JSON.stringify(this.loc));
}
}
if ((!this.oJSON) && eDiv.hasAttribute('data-json')) {
//logMZ('oMZ_TrSuivant json=' + eDiv.getAttribute('data-json'));
this.oJSON = JSON.parse(eDiv.getAttribute('data-json'));
}
}
this.oMZ_categorieSuivant = function (oSuivant, eTable, eDiv) { // object
this.oMZ_tresor = function (row) { // objet
this.id = parseInt(row.id.substring(3, 999));
};
this.eTableCategorie = eTable;
this.eDivTresors = eDiv;
this.eTableTresors = eDiv.getElementsByTagName('table')[0];
this.tresors = [];
if (this.eTableTresors) {
for (let row of this.eTableTresors.rows) {
let oTresor = new this.oMZ_tresor(row);
if (oTresor.id) this.tresors.push(oTresor);
}
}
};
// lecture des infos des trésors et valorisation de this.categories
this.initTresors = function () {
let eContenu = this.eTr.children[0];
if (!eContenu || eContenu.tagName == "DIV") { // no equipement
this.bVide = true;
return;
}
// énumération des catégories. 2 éléments pour chaque
this.categories = [];
for (let i = 0, l = this.eTr.children.length; i < l; i++) {
let eTable = this.eTr.children[i];
let sTag = eTable.tagName;
if (sTag == 'SCRIPT') {
continue;
} // c'est le cas pour le premier suivant qui porte du matos
if (sTag == 'STYLE') {
continue;
} // ça pourrait bien se produire aussi...
if (sTag != 'TABLE') { // ce n'est pas normal
logMZ(`oMZ_TrSuivant.initTresors id=${this.oJSON.id}, élément de type non attendu : ${sTag}`);
continue;
}
// le suivant doit être une DIV
if (++i >= l) {
logMZ(`oMZ_TrSuivant.initTresors id=${this.oJSON.id}, pas d'élément suivant`);
continue;
}
let eDiv = this.eTr.children[i];
if (eDiv.tagName != 'DIV') {
logMZ(`oMZ_TrSuivant.initTresors id=${this.oJSON.id}, élément suivant de type non attendu : ${eDiv.tagName}`);
continue;
}
let oCategorie = new this.oMZ_categorieSuivant(this, eTable, eDiv);
// logMZ('oMZ_TrSuivant.initTresors oCategorie=' + oCategorie);
this.categories.push(oCategorie);
}
//console.log('[MZ_analyse_page_suivants debug] iniTresor ' + this.nom + ' ' + JSON.stringify(this));
};
},
autoTest: function () {
logMZ(`MZ_analyse_page_suivants.autoTest : nb suivants=${this.suivants.length}`);
for (let oSuivant of this.suivants) {
logMZ(JSON.stringify(oSuivant));
}
},
};
MZ_analyse_page_suivants.init();
}
//MZ_analyse_page_suivants.autoTest();
}
// version Roule' janvier 2017
function MZ_setCarteUnGogoHTML5() {
// fabriquer la liste des positions successives
let listeDepl = []; // ce sera un tableau d'objets
listeDepl = MZ_analyse_page_ordre_suivant.result.ordres.slice(0); // clone array
listeDepl.unshift(MZ_analyse_page_ordre_suivant.result); // le result de MZ_analyse_page_ordre_suivant a déjà juste les bonne propriétés
MZ_showCarteBottom([listeDepl]); // L'arg est un tableau de tableaux d'objets
}
// L'arg est un tableau de tableaux d'objets (trajets des suivants)
function MZ_showCarteBottom(listeSuiv) {
// générer la carte
let carte = new carte_MZ('cartegogo', listeSuiv);
// positionner la carte
let eCarte = carte.getElt();
eCarte.style.textAlign = 'left';
eCarte.style.marginTop = '2px';
let footer = getFooter();
if (footer) {
insertBefore(footer, eCarte);
} else {
document.body.appendChild(eCarte);
}
}
function MZ_setCarteTousGogoHTML5() {
// partie récupérée de "trajet gowaps" de feldspath et Vapulabehemot
let ligne = document.getElementById('suivants').getElementsByTagName("tbody")[0].childNodes;
let suivants = [];
for (let i = 0; i < ligne.length; i++) {
if (ligne[i].nodeName != "TR" || !ligne[i].getElementsByTagName('a')[0]) {
continue;
}
let cas = ligne[i].getElementsByTagName("td")[0];
// if (cas.className == "mh_tdtitre") {
if (cas.className == "mh_tdtitre_fo") { // correction par Vapulabehemot (82169) le 10/07/2015
let oGogo = {};
if (cas.getElementsByTagName('a')[0].href) {
let m = cas.getElementsByTagName('a')[0].href.match(/id_target=(\d+)/);
if (m) oGogo.id = parseInt(m[1], 10);
}
oGogo.nom = trim(cas.getElementsByTagName('a')[0].firstChild.nodeValue);
let point = cas.innerHTML.match(/X[ \n\r]+=[ \n\r]+(-?\d+)[ \n\r]+\|[ \n\r]+Y[ \n\r]+=[ \n\r]+(-?\d+)[ \n\r]+\|[ \n\r]+N =[ \n\r]+(-?\d+)/); // Roule 21/01/2020 des espaces multiples et un saut de ligne sont apparus entre "Y" et "="
oGogo.x = parseInt(point[1]);
oGogo.y = parseInt(point[2]);
oGogo.n = parseInt(point[3]);
suivants.push([oGogo]); // un suivant ayant un trajet d'une seule étape
}
}
if (suivants.length == 0) {
return;
}
MZ_showCarteBottom(suivants); // L'arg est un tableau de tableaux d'objets
}
function MZ_setCarteTP() {
// regexp compliquée par le fait que MH met une rupture de ligne dans les coord dans la page Lieu_Description.php
let pos = window.document.getElementsByTagName("body")[0].innerHTML.match(/X[\n\r\t ]*=[\n\r\t ]*(-?\d+)[\n\r\t ]*\|[\n\r\t ]*Y[\n\r\t ]*=[\n\r\t ]*(-?\d+) *\|[\n\r\t ]*N[\n\r\t ]*=[\n\r\t ]*(-?\d+)/i);
let sortie = { x: parseInt(pos[1]), y: parseInt(pos[2]), n: parseInt(pos[3]), id: '', nom: 'Sortie TP', typ: 'tp' };
MZ_showCarteBottom([[sortie]]); // L'arg est un tableau de tableaux d'objets
}
function testeGlissiere() {
try {
let gliss = new glissiere_MZ('test', 'Test glissière', 'xxx', false, 100, 50, 250);
let footer = getFooter();
insertBefore(footer, gliss.getElt());
} catch (exc) {
logMZ('testeGlissiere', exc);
}
}
function MZ_testsUnitairesCalculIntermediaire(x0, y0, x1, y1) {
if (x0 !== undefined) {
// ouais, récursif une fois
let PtInterm = pointIntermediaireMonstre2D({ x: x0, y: y0 }, { x: x1, y: y1 });
if (PtInterm === undefined) {
logMZ(`pt interm(${x0},${y0})(${x1},${y1}) => rien`);
} else {
logMZ(`pt interm(${x0},${y0})(${x1},${y1}) => (${PtInterm.x},${PtInterm.y})`);
}
return;
}
// MZ_testsUnitairesCalculIntermediaire(10, 10, 100, 100);
// MZ_testsUnitairesCalculIntermediaire(10, 100, 100, 10);
// MZ_testsUnitairesCalculIntermediaire(100, 10, 10, 100);
// MZ_testsUnitairesCalculIntermediaire(100, 100, 10, 10);
MZ_testsUnitairesCalculIntermediaire(10, 10, 100, 80);
MZ_testsUnitairesCalculIntermediaire(10, 10, 80, 100);
MZ_testsUnitairesCalculIntermediaire(10, 100, 80, 10);
MZ_testsUnitairesCalculIntermediaire(10, 80, 100, 10);
MZ_testsUnitairesCalculIntermediaire(100, 10, 10, 80);
MZ_testsUnitairesCalculIntermediaire(80, 10, 10, 100);
MZ_testsUnitairesCalculIntermediaire(100, 80, 10, 10);
MZ_testsUnitairesCalculIntermediaire(80, 100, 10, 10);
MZ_testsUnitairesCalculIntermediaire(-80, 100, -10, 10);
MZ_testsUnitairesCalculIntermediaire(80, -100, 10, -10);
MZ_testsUnitairesCalculIntermediaire(-80, -100, -10, -10);
MZ_testsUnitairesCalculIntermediaire(35, -87, 45, -87);
MZ_testsUnitairesCalculIntermediaire(45, -87, 45, -77);
}
function do_ordresgowap() {
MZ_setCarteUnGogoHTML5(); // Version Roule janvier 2017
// testeGlissiere();
// MZ_testsUnitairesCalculIntermediaire();
}
function do_listegowap() {
if (MY_getValue('MZ_upgradeVueSuivants') !== undefined) {
MZ_upgradeVueSuivants();
}
MZ_setCarteTousGogoHTML5();
}
function MZ_upgradeVueSuivants() {
if (MZ_analyse_page_suivants == undefined) {
logMZ('MZ_upgradeVueSuivants impossible, pas de MZ_analyse_page_suivants');
return;
}
let bVueCompressee = MZ_getValueBoolean('MZ_SuivantsCompress');
let bTresorUnique = MZ_getValueBoolean('MZ_SuivantsTresUnique');
let nMaxOrdres = MY_getValue('MZ_SuivantsOrdres');
if (bVueCompressee && MZ_analyse_page_suivants.eTabSuivant) {
// reduce padding of all TD
let e = MZ_analyse_page_suivants.eTabSuivant.getElementsByTagName('TD');
for (let iRow = 0; iRow < e.length; iRow++) {
e[iRow].style.paddingTop = '0';
e[iRow].style.paddingBottom = '0';
}
for (let oSuivant of MZ_analyse_page_suivants.suivants) {
try {
oSuivant.eTi.parentNode.style.paddingTop = '0';
oSuivant.eTi.parentNode.style.paddingBottom = '0';
} catch (e) { console.error(e); }
try {
for (let h3 of oSuivant.eTi.getElementsByTagName('h3'))
h3.style.marginTop = '1px';
} catch (e) { console.error(e); }
}
}
for (let oSuivant of MZ_analyse_page_suivants.suivants) {
if (nMaxOrdres != undefined) {
let tabTxtOrdre = [];
let nDisplayOrdre = 0;
let lastSecouerAllerChercher = undefined;
if (oSuivant.oJSON.ordres) {
for (let oOrdre of oSuivant.oJSON.ordres) {
tabTxtOrdre.push(oOrdre.ordre);
if (nMaxOrdres > 0 && nDisplayOrdre >= nMaxOrdres - 1) {
break;
}
if (nMaxOrdres < 0) {
if (oOrdre.ordre.indexOf('rrêt') >= 0) {
break;
}
if (oOrdre.ordre.indexOf('ller chercher') >= 0) {
lastSecouerAllerChercher = nDisplayOrdre;
}
if (oOrdre.ordre.indexOf('secouer') >= 0) {
lastSecouerAllerChercher = nDisplayOrdre;
}
if (oOrdre.ordre.indexOf('uivre') >= 0) {
break;
}
}
nDisplayOrdre++;
}
}
if (lastSecouerAllerChercher != undefined) {
tabTxtOrdre = tabTxtOrdre.slice(0, lastSecouerAllerChercher + 1);
}
let eOuterDiv = document.createElement('div');
eOuterDiv.id = `MZ_suiv_outer_${oSuivant.oJSON.id}`;
eOuterDiv.style.width = "100%";
eOuterDiv.style.fontSize = '12px';
eOuterDiv.style.display = 'inline-block';
let eDLA = document.createElement('div');
eDLA.id = `MZ_suiv_dla_${oSuivant.oJSON.id}`;
eDLA.style.whiteSpace = 'nowrap';
let d = new Date(oSuivant.oJSON.dla);
eDLA.appendChild(document.createTextNode(`DLA : ${MZ_formatDateMS(d, false)}`));
eDLA.style.display = 'inline-block';
eOuterDiv.appendChild(eDLA);
if (tabTxtOrdre.length > 0) {
let eA = document.createElement('a');
eA.id = `MZ_suiv_ordres_${oSuivant.oJSON.id}`;
eA.style.display = 'inline-block';
eA.style.cssFloat = 'right';
eA.style.textAlign = 'right';
//eA.style.whiteSpace = 'nowrap';
eA.href = `/mountyhall/MH_Play/Play_a_Action.php?type=F&id=-4&sub=ordres&id_target=${oSuivant.oJSON.id}`;
eA.title = 'Accès direct aux ordres';
for (let ordre of tabTxtOrdre) {
let eDiv = document.createElement('div');
eDiv.style.whiteSpace = 'nowrap';
eDiv.style.display = 'inline-block';
eDiv.appendChild(document.createTextNode(ordre));
if (eA.firstChild) eA.appendChild(document.createTextNode(' / '));
eA.appendChild(eDiv);
}
//eA.appendChild(document.createTextNode(tabTxtOrdre.join(' / ')));
eOuterDiv.appendChild(eA);
} else {
eOuterDiv.style.display = 'none';
}
oSuivant.eTi.appendChild(eOuterDiv);
}
if (!bVueCompressee && !bTresorUnique) {
continue;
}
oSuivant.initTresors();
if (oSuivant.bVide) { // no equipement
if (bVueCompressee) {
oSuivant.eTr.style.display = 'none';
oSuivant.eTi.style.borderBottom = 'solid 1px #FFFFCC';
}
continue;
}
for (let oCategorie of oSuivant.categories) {
if (bVueCompressee && oCategorie.eTableTresors.tHead)
oCategorie.eTableTresors.tHead.style.display = 'none';
if (!bTresorUnique) {
continue;
} // la suite ne concerne que l'affichage des trésors uniques
//console.log('[MZ debug] categorie ' + oSuivant.nom + ', nb tr=' + oCategorie.eTableTresors.rows.length + ', nb tresor=' + oCategorie.tresors.length);
if (oCategorie.tresors.length != 1) {
continue;
}
oCategorie.eTableCategorie.style.display = 'none';
oCategorie.eDivTresors.style.display = '';
// copy weight from category to single trésor
try { // ignore error
let e = oCategorie.eTableCategorie.rows[0].cells[3]; // cell containing total weight
let s = e.textContent.match(/poids total *\u00A0*: *(.*)$/i)[1];
e = oCategorie.eTableTresors.rows[1].cells[4]; // cell for weight of first trésor
//console.log('[MZ debug] categorie ' + oSuivant.nom + ', remppace ' + e.innerHTML + ' par ' + s);
e.innerHTML = s;
oCategorie.eTableTresors.rows[0].cells[3].style.whiteSpace = 'nowrap';
} catch (exc) {
console.error(exc);
}
}
}
}
function do_lieuDescription() {
if (window.document.getElementsByTagName("body")[0].innerHTML.indexOf("Portail : Portail de T") != -1) {
MZ_setCarteTP();
}
}
function do_lieuTeleport() {
changeButtonValidate();
MZ_setCarteTP();
}
/** x~x Infomonstre ---------------------------------------------------- */
// DEBUG
var g_nomMonstre = '', g_idMonstre = -1;
// let tbody;
function traiteMonstre() {
let texte = "";
try {
let nodeTitre = document.evaluate(
"//div[@class='view']//thead//h2", document, null, 9, null
).singleNodeValue;
texte = (nodeTitre != null) ? nodeTitre.firstChild.nodeValue : texte;
if (texte == "" || texte.includes("existe pas")) {
let tabEventDescription = document.getElementsByClassName('monstre');
console.log(tabEventDescription);
if (tabEventDescription[0] != undefined) {
let eltNom = tabEventDescription[0];
texte = eltNom.textContent;
// logMZ('traiteMonstre, nom sans id=' + texte);
// find next textElement
let eCurrent = eltNom;
while (eCurrent = eCurrent.parentNode) {
// logMZ('traiteMonstre, eCurrent.nodeName=' + eCurrent.nodeName);
let eSibling = eCurrent.nextSibling;
if (!eSibling) {
// logMZ('traiteMonstre, pas de sibling');
continue;
}
// logMZ('traiteMonstre, eSibling.nodeName=' + eSibling.nodeName + ', texte=' + eSibling.textContent);
if (eSibling.nodeType != 3) {
continue;
}
texte = `${texte} ${eSibling.textContent.replace(/[ .]/g, '')}`;
break;
}
} else {
logMZ('traiteMonstre, impossible de trouver le nom du monstre');
return;
}
}
// logMZ('traiteMonstre, nom=' + texte);
} catch (exc) {
logMZ('traiteMonstre', exc);
return;
}
g_nomMonstre = texte.slice(0, texte.indexOf('(') - 1);
if (g_nomMonstre.indexOf(']') != -1) {
g_nomMonstre = g_nomMonstre.slice(0, g_nomMonstre.indexOf(']') + 1);
}
g_idMonstre = texte.match(/[^\]]\].*\((\d+)\)/)[1];
let tReq = [{ index: 1, id: Number(g_idMonstre), nom: g_nomMonstre }]; // "+" pour forcer du numérique
FF_XMLHttpRequest({
method: 'POST',
url: URL_MZgetCaracMonstre,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: `l=${JSON.stringify(tReq)}`,
trace: 'demande niveaux monstres V2, MonsterView',
onload: function (responseDetails) {
try {
// logMZ('retrieveCDMs readyState=' + responseDetails.readyState + ', error=' + responseDetails.error + ', status=' + responseDetails.status);
if (responseDetails.status == 0) {
return;
}
// logMZ('[MZd] ' + (+new Date) + ' ajax niv monstres début');
texte = responseDetails.responseText;
let infosRet = JSON.parse(texte);
if (infosRet.length == 0) {
return;
}
let info = infosRet[0];
// QUESTION Quelle est l'utilité de ceci?
// Roule 19/01/2020 Il doit y avoir un endroit "au fond du trou" où le code va chercher les infos à partir de l'ID. Est-ce que c'est propre ? : non
MZ_EtatCdMs.listeCDM[g_idMonstre] = info;
let nodeInsert;
try {
nodeInsert = document.evaluate(
"//div[@class='view']//h3", document, null, 9, null
).singleNodeValue;
} catch (exc) {
logMZ('recherche node pour info CdM', exc);
return;
}
let table = createCDMTable(g_idMonstre, g_nomMonstre, info);
table.align = 'center';
let tbody = table.childNodes[1];
let thead = table.childNodes[0];
let tdEntete = thead.firstChild.firstChild;
tdEntete.onclick = toggleTableau;
tdEntete.style.cursor = 'pointer';
thead.firstChild.style = 'mh_tdpage';
tbody.style.display = 'none';
table.style.width = '350px';
insertBefore(nodeInsert, table);
} catch (exc) {
logMZ('traiteMonstre onload', exc);
}
},
});
}
function toggleTableau() { // click sur un td de thead
let tbody = this.parentNode.parentNode.parentNode.childNodes[1];
tbody.style.display = tbody.style.display == 'none' ? '' : 'none';
}
function do_infomonstre() {
start_script(undefined, 'do_infomonstre_log');
try {
MZ_Tactique.initPopup();
traiteMonstre();
} catch (exc) {
avertissement(`Une erreur est survenue (do_infomonstre)`, null, null, exc);
}
displayScriptTime(undefined, 'do_infomonstre_log');
}
/** x~x Highlight same XYN --------------------------------------------- */
function do_highlightSameXYN() {
if (MY_getValue('HIGHLIGHTSAMEXYN') != 'true') return;
addStyleSheet("tr.xyn td, tr.xyn-sel td { background-color: beige; }");
// Vu que jQuery est disponible, il serait dommage de ne pas en tirer
// parti, même si les perfs ne sont pas miraculeuses...
// En pratique, ce serait vraiment beaucoup plus ch... de coder ça en
// vanilla, alors tant pis.
// Le principe: On marque chaque ligne de tableau avec un attribut
// calculé à partir de ses coordonnées, puis on associe à chaque case
// (ou uniquement à celles de coordonnées) un traitement de bascule de
// style sur survol ou click souris qui va s'appliquer à toutes les
// cellules (de tous les tableaux) comportant le même attribut.
let toggleFn = function (e) {
let tr = $(this).parent("tr");
$(`tr[data-xyn='${tr.attr("data-xyn")}']`).toggleClass(e.data.class);
};
$.each(MZ_AnalyseVue.sectionList, function (_, section) {
let tableSpec = `table#${section}`,
nthChild = $(`${tableSpec} tr.mh_tdtitre th:contains("X")`).index(),
xSel = `td:nth-child(${nthChild + 1})`,
ySel = `td:nth-child(${nthChild + 2})`,
nSel = `td:nth-child(${nthChild + 3})`;
$(`${tableSpec} tr.mh_tdpage`).each(function (i, e) {
let tr = $(e),
tdX = tr.find(xSel),
tdY = tr.find(ySel),
tdN = tr.find(nSel);
tr.attr("data-xyn", [tdX.text(), tdY.text(), tdN.text()].join(";"));
$.each(
(MY_getValue('HIGHLIGHTSAMEXYNCOORDSONLY') == 'true') ? [tdX, tdY, tdN] : tr.find("td"),
function (i, e) {
let td = $(e);
td.on("mouseenter mouseleave", { class: "xyn" }, toggleFn);
td.on("click", { class: "xyn-sel" }, toggleFn);
});
});
});
}
/** x~x SCIZ ----------------------------------------------------------- */
var scizSetup = {
eventsMaxMatchingInterval: 5000, // Maximum interval (seconds) for matching some events
viewMaxEnhancedTreasure: 100, // Maximum number of treasures to enhanced in the view
viewMaxEnhancedMushroom: 100 // Maximum number of treasures to enhanced in the view
};
var scizGlobal = {
events: [],
trolls: [],
treasures: [],
monsters: [],
traps: [],
mushrooms: [],
portals: []
};
function scizAddCSS() {
// SCIZ style
addStyleSheet(`
.sciz-progress-bar-wrapper {
width: 75px;
margin-right: 5px;
display: inline-block;
}
.sciz-progress-bar {
width: 100%;
background-color: #e0e0e0;
padding: 1px;
border-radius: 1px;
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);
}
.sciz-progress-bar-fill {
display: block;
height: 5px;
border-radius: 1px;
transition: width 500ms ease-in-out;
}
.sciz-troll-view-block {
display: inline-block;
padding-left: 10px;
margin-left: 10px;
border-left: 1px solid black;
white-space: pre-wrap;
}
`);
}
function scizCreateHoverable(height, display, callbackOnHover) {
let img = document.createElement('img');
img.src = 'https://www.sciz.fr/static/sciz-logo-quarter.png';
img.alt = 'SCIZ logo';
img.style = `height: ${height}px; cursor: pointer;`;
img.onmouseover = callbackOnHover;
let div = document.createElement('div');
div.style = `text-align: center;display: ${display}`;
div.appendChild(img);
return div;
}
function scizCreateClickable(height, display, callbackOnClick) {
let img = document.createElement('img');
img.src = 'https://www.sciz.fr/static/sciz-logo-quarter.png';
img.alt = 'SCIZ logo';
img.style = `height: ${height}px; cursor: pointer;`;
img.onclick = callbackOnClick;
let div = document.createElement('div');
div.style = `text-align: center;display: ${display}`;
div.appendChild(img);
return div;
}
function scizCreateIcon(height, display, icon) {
let img = document.createElement('img');
img.src = `https://www.sciz.fr/static/${icon}`;
img.alt = 'SCIZ icon';
img.style = `height: ${height}px;`;
let div = document.createElement('div');
div.style = `text-align: center;display: ${display}`;
div.appendChild(img);
return div;
}
/* SCIZ - View */
function scizPrettyPrintTroll(t) {
let res = '<div style="float:right;margin-right:10px">';
// Life progress bar
let pbPercent = t.pdv !== null && t.pdv_max !== null ? Math.min(100, t.pdv / t.pdv_max * 100) : -1;
let pbColor = pbPercent === -1 ? '#424242' : pbPercent < 40 ? '#ff5252' : pbPercent < 80 ? '#fb8c00' : '#4caf50';
t.pdv_max = t.pdv_max === null ? '?' : t.pdv_max;
res = `${res}<div class="sciz-progress-bar-wrapper"><div class="sciz-progress-bar"><span class="sciz-progress-bar-fill" style="background-color: ${pbColor};;width: ${pbPercent}%;"></span></div></div>`;
res = `${res}${t.pdv} / ${t.pdv_max}`;
res = `${res}<div class="sciz-troll-view-block">DLA ${t.dla}</div>`; // DLA
res = `${res}<div class="sciz-troll-view-block"><= ${t.pa} PA</div>`; // PA
res = `${res}<div class="sciz-troll-view-block">Fatigue ${` ${t.fatigue}`.slice(-3)}</div>`; // Fatigue
res = `${res}<div class="sciz-troll-view-block">Conc ${` ${t.concentration}`.slice(-2)}%</div>`; // Concentration
res = `${res}</div>`;
return res;
}
function scizPrettyPrintTreasure(t) {
let res = '';
res = res + /* t.type + ' - ' + */ t.nom;
if (t.templates) {
res = `${res} <b>${t.templates}</b>`;
}
if (t.mithril) {
res = `${res} <b>en Mithril</b>`;
}
if (t.effet) {
res = `${res} (${t.effet})`;
}
return res;
}
function scizPrettyPrintTrap(t) {
let res = '<span style="color:#990000">';
res = `${res}Piège à ${t.type} `;
if (t.mm) {
res = `${res}(MM ${t.mm}) `;
}
if (t.creation_datetime) {
res = `${res} - ${t.creation_datetime} `;
}
res = `${res}</span>`;
return res;
}
function scizPrettyPrintMushroom(m) {
let res = '';
res = res + m.nom;
if (m.qualite) {
res = `${res} <b>${m.qualite}</b>`;
}
return res;
}
function scizPrettyPrintPortal(p) {
let res = '';
let html_nom = `<a href="javascript:EPV(${p.owner_id})" class="mh_trolls_1">${p.owner_nom}</a>`;
res = `${res}Portail de Téléportaion de ${html_nom} vers X = ${p.pos_x_dst} | Y = ${p.pos_y_dst} | N = ${p.pos_n_dst}`;
return res;
}
function do_scizEnhanceView() {
scizGlobal.treasures = [];
// Ensure we have a JWT setup for the current user
let jwt = MY_getValue(`${numTroll}.SCIZJWT`);
if (jwt === null || jwt === undefined || jwt.trim() === '') {
return;
}
// Add our CSS
scizAddCSS();
// Retrieve position and view
let pos = document.body.innerHTML.match(/X\s*=\s*(-?\d+)\s*,\s*Y\s*=\s*(-?\d+)\s*,\s*N\s*=\s*(-?\d+)/);
let posX = parseInt(pos[1]);
let posY = parseInt(pos[2]);
let posN = parseInt(pos[3]);
let viewH = parseInt(document.body.innerHTML.match(/(\d+)\s*cases?\s*horizontalement/)[1]);
let viewV = parseInt(document.body.innerHTML.match(/(\d+)\s*verticalement/)[1]);
/* SCIZ View - TROLLS */
let cbx = MY_getValue(`${numTroll}.SCIZ_CB_VIEW_TROLLS`);
if (cbx !== '0') {
// Retrieve trolls
let xPathTrollQuery = "//*/table[@id='VueTROLL']/tbody/tr";
let xPathTrolls = document.evaluate(xPathTrollQuery, document, null, 0, null);
let xPathTroll;
while (xPathTroll = xPathTrolls.iterateNext()) {
if (xPathTroll.children[2]) scizGlobal.trolls.push({
id: parseInt(xPathTroll.children[2].innerHTML),
name: xPathTroll.children[3].innerHTML,
sciz_desc: null,
node: xPathTroll,
displayed: false,
caracs: null,
});
}
// Call SCIZ
let sciz_url = 'https://www.sciz.fr/api/hook/trolls';
FF_XMLHttpRequest({
method: 'POST',
url: sciz_url,
headers: { 'Authorization': jwt, 'Content-Type': 'application/json' },
onload: function (responseDetails) {
try {
if (responseDetails.status !== 200) {
logMZ('ERREUR - MZ/SCIZ - Appel à SCIZ en échec...', responseDetails);
return;
}
let trolls = JSON.parse(responseDetails.responseText);
if (trolls.trolls.length < 1) {
// logMZ('DEBUG - MZ/SCIZ - Aucun événement trouvé dans la base SCIZ...');
return;
}
// Look for trolls to enhanced
let found = false;
trolls.trolls.forEach((t) => {
for (let i = 0; i < scizGlobal.trolls.length; i++) {
found = false;
if (scizGlobal.trolls[i].id === t.id) {
// PrettyPrint
scizGlobal.trolls[i].sciz_desc = scizGlobal.trolls[i].node.children[3].innerHTML + scizPrettyPrintTroll(t);
// Store caracs
scizGlobal.trolls[i].caracs = t.caracs;
found = true;
break;
}
}
if (!found) {
// Special case of itself
let is_self = false;
if (parseInt(numTroll) === t.id) {
is_self = true;
t.pos_x = posX;
t.pos_y = posY;
t.pos_n = posN;
// Don't display the user itself if he does not want to
cbx = MY_getValue(`${numTroll}.SCIZ_CB_VIEW_USER`);
if (cbx === '0') {
return;
}
}
// Find the right index
let distance = Math.max(Math.abs(t.pos_x - posX), Math.abs(t.pos_y - posY), Math.abs(t.pos_n - posN));
xPathTrolls = document.evaluate(xPathTrollQuery, document, null, 0, null);
while (xPathTroll = xPathTrolls.iterateNext()) {
if (is_self) {
break;
}
if (parseInt(xPathTroll.children[0].innerHTML) > distance) {
break;
}
}
// Create the troll
let template = document.createElement('template');
let html_nom = `<a href="javascript:EPV(${t.id})" class="mh_trolls_1">${t.nom}</a>`;
if (!is_self) {
html_nom = `${html_nom} (HORS VUE)`;
}
let html_guilde = `<a href="javascript:EAV(${t.guilde_id},750,550)" class="mh_links">${t.guilde_nom}</a>`;
template.innerHTML = `<tr class="mh_tdpage"><td>${distance}</td><td></td><td>${t.id}</td><td title="">${html_nom}</td><td>${html_guilde}</td><td>${t.niv}</td><td>${t.race}</td><td>${t.pos_x}</td><td>${t.pos_y}</td><td>${t.pos_n}</td></tr>`;
let troll = template.content.firstChild;
// Add the troll
scizGlobal.trolls.push({
id: t.id, name: html_nom, sciz_desc: html_nom + scizPrettyPrintTroll(t), node: troll, displayed: false, caracs: t.caracs
});
if (xPathTroll !== null) {
xPathTroll.parentNode.insertBefore(troll, xPathTroll);
} else {
document.evaluate("//*/table[@id='VueTROLL']/tbody", document, null, 0, null).iterateNext().appendChild(troll);
}
//console.log(`MZ do_scizEnhanceView set tr_trolls[${nbTrolls+1}] `);
tr_trolls[++nbTrolls] = troll;
}
});
} catch (exc) {
logMZ('ERREUR - MZ/SCIZ - Stacktrace', exc);
}
// Do the display overwrite and add the switches
do_scizSwitchTrolls();
}
});
}
/* SCIZ View - TREASURES */
cbx = MY_getValue(`${numTroll}.SCIZ_CB_VIEW_TREASURES`);
if (cbx !== '0') {
// Retrieve treasures
let ids = [];
let xPathTreasureQuery = "//*/table[@id='VueTRESOR']/tbody/tr";
let xPathTreasures = document.evaluate(xPathTreasureQuery, document, null, 0, null);
let xPathTreasure;
while (xPathTreasure = xPathTreasures.iterateNext()) {
let xPathRef = document.evaluate("//td[@class='ref']", xPathTreasure, null, 0, null).iterateNext();
let xPathNom = document.evaluate("//td[@class='nom']", xPathTreasure, null, 0, null).iterateNext();
let oTres = {
id: parseInt(xPathRef.innerHTML),
type: xPathNom.innerHTML,
sciz_desc: null,
buried: xPathNom.innerHTML.includes('Enterré'),
node: xPathTreasure,
};
if (oTres.id === null || oTres.id == 0 || isNaN(oTres.id)) {
logMZ("do_scizEnhanceView recup des trésors, échec de l'analyse"
+ "\n" + xPathTreasure.children[0].innerHTML
+ "\n" + xPathTreasure.children[1].innerHTML
+ "\n" + xPathTreasure.children[2].innerHTML
+ "\n" + xPathTreasure.children[3].innerHTML
);
continue;
}
scizGlobal.treasures.push(oTres);
ids.push(oTres.id);
if (scizGlobal.treasures.length >= scizSetup.viewMaxEnhancedTreasure) {
break;
}
}
// Call SCIZ
let sciz_url = 'https://www.sciz.fr/api/hook/treasures';
if (ids.length > 0) FF_XMLHttpRequest({
method: 'POST',
url: sciz_url,
headers: { 'Authorization': jwt, 'Content-Type': 'application/json' },
data: JSON.stringify({ ids: ids }),
onload: function (responseDetails) {
try {
if (responseDetails.status !== 200) {
logMZ('ERREUR - MZ/SCIZ - Appel à SCIZ en échec...', responseDetails);
return;
}
let treasures;
try {
treasures = JSON.parse(responseDetails.responseText);
} catch (e) {
//logMZ('ERREUR - MZ/SCIZ - Appel à SCIZ trésors en échec', e);
return;
}
if (treasures.treasures.length < 1) {
// logMZ('DEBUG - MZ/SCIZ - Aucun trésor trouvé dans la base SCIZ...');
return;
}
// Look for treasures to enhanced
treasures.treasures.forEach((t) => {
for (let i = 0; i < scizGlobal.treasures.length; i++) {
if (scizGlobal.treasures[i].id === t.id) {
// PrettyPrint
t = scizPrettyPrintTreasure(t);
// Store the SCIZ treasure desc
scizGlobal.treasures[i].sciz_desc = t;
// Adapt the sciz type (delete the buried marker, the do_scizSwitchTreasures will handle it)
scizGlobal.treasures[i].type = scizGlobal.treasures[i].node.children[3].firstChild.textContent;
break;
}
}
});
} catch (exc) {
logMZ('ERREUR - MZ/SCIZ - Stacktrace', exc);
}
// Do the display overwrite and add the switches
do_scizSwitchTreasures();
}
});
}
/* SCIZ View - MUSHROOMS */
cbx = MY_getValue(`${numTroll}.SCIZ_CB_VIEW_MUSHROOMS`);
let xPathMushroomQuery = "//*/table[@id='VueCHAMPIGNON']/tbody/tr";
let xPathMushrooms = document.evaluate(xPathMushroomQuery, document, null, 0, null);
if (cbx !== '0' && !xPathMushrooms) {
// Retrieve mushrooms
let ids = [];
let xPathMushroom;
while (xPathMushroom = xPathMushrooms.iterateNext()) {
scizGlobal.mushrooms.push({
id: parseInt(xPathMushroom.children[2].innerHTML),
type: xPathMushroom.children[3].innerHTML,
sciz_desc: null,
node: xPathMushroom,
});
ids.push(xPathMushroom.children[2].innerHTML);
if (scizGlobal.mushrooms.length >= scizSetup.viewMaxEnhancedMushroom) {
break;
}
}
// Call SCIZ
let sciz_url = 'https://www.sciz.fr/api/hook/mushrooms';
FF_XMLHttpRequest({
method: 'POST',
url: sciz_url,
headers: { 'Authorization': jwt, 'Content-Type': 'application/json' },
data: JSON.stringify({ ids: ids }),
onload: function (responseDetails) {
try {
if (responseDetails.status !== 200) {
logMZ('ERREUR - MZ/SCIZ - Appel à SCIZ en échec...', responseDetails);
return;
}
let mushrooms = JSON.parse(responseDetails.responseText);
if (mushrooms.mushrooms.length < 1) {
// logMZ('DEBUG - MZ/SCIZ - Aucun champignon trouvé dans la base SCIZ...');
return;
}
// Look for mushrooms to enhanced
mushrooms.mushrooms.forEach((m) => {
for (let i = 0; i < scizGlobal.mushrooms.length; i++) {
if (scizGlobal.mushrooms[i].id === m.id) {
// PrettyPrint
m = scizPrettyPrintMushroom(m);
// Store the SCIZ mushroom desc
scizGlobal.mushrooms[i].sciz_desc = m;
break;
}
}
});
} catch (exc) {
logMZ('ERREUR - MZ/SCIZ - Stacktrace', exc);
}
// Do the display overwrite and add the switches
do_scizSwitchMushrooms();
}
});
}
/* SCIZ View - BESTIAIRE */
cbx = MY_getValue(`${numTroll}.SCIZ_CB_BESTIAIRE`);
if (cbx !== '0') {
// Retrieve monsters
let mobs = [];
let xPathMonsterQuery = "//*/table[@id='VueMONSTRE']/tbody/tr";
let xPathMonsters = document.evaluate(xPathMonsterQuery, document, null, 0, null);
let xPathMonster;
while (xPathMonster = xPathMonsters.iterateNext()) {
let mob = xPathMonster.children[4].innerHTML.match(/([^<>]+?)\s*\[\s*(.+)\s*]/);
if (!mob) mob = xPathMonster.children[3].innerHTML.match(/([^<>]+?)\s*\[\s*(.+)\s*]/); // cas smartphone
if (!mob) {
logMZ("do_scizEnhanceView recup des monstres, échec de l'analyse"
+ "\n" + xPathMonster.children[0].innerHTML
+ "\n" + xPathMonster.children[1].innerHTML
+ "\n" + xPathMonster.children[2].innerHTML
+ "\n" + xPathMonster.children[3].innerHTML
+ "\n" + xPathMonster.children[4].innerHTML
);
continue;
}
scizGlobal.monsters.push({
id: parseInt(xPathMonster.children[2].innerHTML),
name: mob[1],
age: mob[2],
sciz_desc: null,
icon: null,
node: xPathMonster
});
mobs.push({ name: mob[1], age: mob[2] });
}
// Check the list against the SCIZ bestiaire
let sciz_url = 'https://www.sciz.fr/api/bestiaire/check';
FF_XMLHttpRequest({
method: 'POST',
url: sciz_url,
headers: { 'Authorization': jwt, 'Content-Type': 'application/json' },
data: JSON.stringify({ mobs: mobs }),
onload: function (responseDetails) {
try {
if (responseDetails.status !== 200) {
logMZ('ERREUR - MZ/SCIZ - Appel à SCIZ en échec...', responseDetails);
return;
}
mobs = JSON.parse(responseDetails.responseText);
// Add the SCIZ icons
scizGlobal.monsters.forEach((m) => {
if (mobs.bestiaire.includes(`${m.name} ${m.age}`)) {
let icon = scizCreateHoverable('15', 'inline', () => {
do_scizBestiaire(m);
});
m.icon = icon;
m.node.children[4].appendChild(icon);
}
});
} catch (exc) {
logMZ('ERREUR - MZ/SCIZ - Stacktrace', exc);
}
}
});
}
/* SCIZ View - TRAPS */
cbx = MY_getValue(`${numTroll}.SCIZ_CB_VIEW_TRAPS`);
if (cbx !== '0') {
// Retrieve traps
let ids = [];
let xPathPlaceQuery = "//*/table[@id='VueLIEU']/tbody/tr";
let xPathPlaces = document.evaluate(xPathPlaceQuery, document, null, 0, null);
let xPathPlace;
while (xPathPlace = xPathPlaces.iterateNext()) {
let trap = xPathPlace.children[3].innerHTML.match(/Piège\s+à\s+/);
if (trap === null) {
continue;
}
scizGlobal.traps.push({
id: parseInt(xPathPlace.children[2].innerHTML),
type: xPathPlace.children[3].innerHTML,
hidden: xPathPlace.children[3].innerHTML.includes('Caché'),
sciz_desc: null,
node: xPathPlace
});
ids.push(xPathPlace.children[2].innerHTML);
}
// Call SCIZ
let sciz_url = 'https://www.sciz.fr/api/hook/traps';
FF_XMLHttpRequest({
method: 'POST',
url: sciz_url,
headers: { 'Authorization': jwt, 'Content-Type': 'application/json' },
data: JSON.stringify({ pos_x: posX, pos_y: posY, pos_n: posN, view_h: viewH, view_v: viewV }),
onload: function (responseDetails) {
try {
if (responseDetails.status !== 200) {
logMZ('ERREUR - MZ/SCIZ - Appel à SCIZ en échec...', responseDetails);
return;
}
let traps = JSON.parse(responseDetails.responseText);
if (traps.traps.length < 1) {
return;
}
// Look for traps to enhanced
traps.traps.forEach((t) => {
let found = false;
for (let i = 0; i < scizGlobal.traps.length; i++) {
if (scizGlobal.traps[i].id === t.id) {
scizGlobal.traps[i].sciz_desc = scizPrettyPrintTrap(t);
// Adapt the sciz type (delete the hidden marker, the do_scizSwitchTraps will handle it)
scizGlobal.traps[i].type = scizGlobal.traps[i].node.children[3].firstChild.textContent;
found = true;
break;
}
}
if (!found) {
// Find the right index
let distance = Math.max(Math.abs(t.pos_x - posX), Math.abs(t.pos_y - posY), Math.abs(t.pos_n - posN));
xPathPlaces = document.evaluate(xPathPlaceQuery, document, null, 0, null);
while (xPathPlace = xPathPlaces.iterateNext()) {
if (parseInt(xPathPlace.children[0].innerHTML) > distance) {
break;
}
}
// Create the trap
let template = document.createElement('template');
template.innerHTML = `<tr class="mh_tdpage"><td>${distance}</td><td></td><td>${t.id}</td><td>Piège à ${t.type
}</td><td>${t.pos_x}</td><td>${t.pos_y}</td><td>${t.pos_n}</td></tr>`;
let trap = template.content.firstChild;
// Add the hidden trap
scizGlobal.traps.push({
id: t.id, type: `Piège à ${t.type}`, hidden: true, sciz_desc: scizPrettyPrintTrap(t), node: trap
});
if (xPathPlace !== null) {
xPathPlace.parentNode.insertBefore(trap, xPathPlace);
} else {
document.evaluate("//*/table[@id='VueLIEU']/tbody", document, null, 0, null).iterateNext().appendChild(trap);
}
}
});
} catch (exc) {
logMZ('ERREUR - MZ/SCIZ - Stacktrace', exc);
}
// Do the display overwrite and add the switches
do_scizSwitchTraps();
}
});
}
/* SCIZ View - PORTALS */
cbx = MY_getValue(`${numTroll}.SCIZ_CB_VIEW_PORTALS`);
if (cbx !== '0') {
// Retrieve portals
let ids = [];
let xPathPlaceQuery = "//*/table[@id='VueLIEU']/tbody/tr";
let xPathPlaces = document.evaluate(xPathPlaceQuery, document, null, 0, null);
let xPathPlace;
while (xPathPlace = xPathPlaces.iterateNext()) {
let portal = xPathPlace.children[3].innerHTML.match(/Portail/);
if (portal === null) {
continue;
}
scizGlobal.portals.push({
id: parseInt(xPathPlace.children[2].innerHTML),
type: xPathPlace.children[3].innerHTML,
sciz_desc: null,
node: xPathPlace
});
ids.push(xPathPlace.children[2].innerHTML);
}
// Call SCIZ
let sciz_url = 'https://www.sciz.fr/api/hook/portals';
FF_XMLHttpRequest({
method: 'POST',
url: sciz_url,
headers: { 'Authorization': jwt, 'Content-Type': 'application/json' },
data: JSON.stringify({ ids: ids }),
onload: function (responseDetails) {
try {
if (responseDetails.status !== 200) {
logMZ('ERREUR - MZ/SCIZ - Appel à SCIZ en échec...', responseDetails);
return;
}
let portals = JSON.parse(responseDetails.responseText);
if (portals.portals.length < 1) {
// logMZ('DEBUG - MZ/SCIZ - Aucun portail trouvé dans la base SCIZ...');
return;
}
// Look for treasures to enhanced
portals.portals.forEach((t) => {
for (let i = 0; i < scizGlobal.portals.length; i++) {
if (scizGlobal.portals[i].id === t.id) {
scizGlobal.portals[i].sciz_desc = scizPrettyPrintPortal(t);
break;
}
}
});
} catch (exc) {
logMZ('ERREUR - MZ/SCIZ - Stacktrace', exc);
}
// Do the display overwrite and add the switches
do_scizSwitchPortals();
}
});
}
}
function do_scizSwitchTrolls() {
scizGlobal.trolls.forEach((t) => {
if (t.sciz_desc !== null) {
let icon = scizCreateClickable('15', 'inline', do_scizSwitchTrolls);
t.displayed = !t.displayed;
// Do the switch
if (t.displayed) {
t.node.children[3].innerHTML = t.sciz_desc;
if (t.caracs !== null) {
icon.title = t.caracs;
}
} else {
t.node.children[3].innerHTML = t.name;
}
// Add the SCIZ switcher
t.node.children[3].appendChild(icon);
}
});
}
function do_scizSwitchTreasures() {
scizGlobal.treasures.forEach((t) => {
if (t.sciz_desc !== null) {
// Do the switch
let currentDesc = t.node.children[3].firstChild.textContent;
t.node.children[3].innerHTML = currentDesc === t.type ? t.sciz_desc !== null ? t.sciz_desc : t.type : t.type;
if (t.buried) {
t.node.children[3].innerHTML += '<img src="/mountyhall/Images/hidden.png" alt="[Enterré]" title="Enterré" width="15" height="15">';
}
// Add the SCIZ switcher
t.node.children[3].appendChild(scizCreateClickable('15', 'inline', do_scizSwitchTreasures));
}
});
}
function do_scizSwitchMushrooms() {
scizGlobal.mushrooms.forEach((m) => {
if (m.sciz_desc !== null) {
// Do the switch
let currentDesc = m.node.children[3].firstChild.textContent;
m.node.children[3].innerHTML = currentDesc === m.type ? m.sciz_desc !== null ? m.sciz_desc : m.type : m.type;
// Add the SCIZ switcher
m.node.children[3].appendChild(scizCreateClickable('15', 'inline', do_scizSwitchMushrooms));
}
});
}
function do_scizSwitchTraps() {
scizGlobal.traps.forEach((t) => {
if (t.sciz_desc !== null) {
// Do the switch
let currentDesc = t.node.children[3].firstChild.textContent;
t.node.children[3].innerHTML = currentDesc === t.type ? t.sciz_desc !== null ? t.sciz_desc : t.type : t.type;
if (t.hidden) {
t.node.children[3].innerHTML += '<img src="/mountyhall/Images/hidden.png" alt="[Caché]" title="Caché" width="15" height="15">';
}
// Add the SCIZ switcher
t.node.children[3].appendChild(scizCreateClickable('15', 'inline', do_scizSwitchTraps));
}
});
}
function do_scizSwitchPortals() {
scizGlobal.portals.forEach((m) => {
if (m.sciz_desc !== null) {
// Do the switch
let currentDesc = m.node.children[3].firstChild.textContent;
m.node.children[3].innerHTML = currentDesc === m.type ? m.sciz_desc !== null ? m.sciz_desc : m.type : m.type;
// Add the SCIZ switcher
m.node.children[3].appendChild(scizCreateClickable('15', 'inline', do_scizSwitchPortals));
}
});
}
function do_scizBestiaire(monster) {
// Ensure we have a JWT setup for the current user
let jwt = MY_getValue(`${numTroll}.SCIZJWT`);
if (jwt === null || jwt === undefined || jwt.trim() === '') {
return;
}
// Don't do anything if we already called the bestiary for this monster
if (monster.sciz_desc === null) {
// Call SCIZ
let sciz_url = 'https://www.sciz.fr/api/bestiaire';
FF_XMLHttpRequest({
method: 'POST',
url: sciz_url,
headers: { 'Authorization': jwt, 'Content-Type': 'application/json' },
data: JSON.stringify({ name: monster.name, age: monster.age }),
onload: function (responseDetails) {
try {
if (responseDetails.status !== 200) {
monster.sciz_desc = "Problème de JWT SCIZ, désactiver l'option Mountyzilla si non utilisée.";
logMZ('ERREUR - MZ/SCIZ - Appel à SCIZ en échec...', responseDetails);
}
monster.sciz_desc = JSON.parse(responseDetails.responseText).bestiaire;
// Add the tooltip (kind of)
if (monster.sciz_desc !== null && monster.sciz_desc !== undefined) {
let abbr = document.createElement('abbr');
abbr.title = monster.sciz_desc.replace(/Blason.*/, '');
monster.icon.parentNode.replaceChild(abbr, monster.icon);
abbr.appendChild(monster.icon);
}
} catch (exc) {
logMZ('ERREUR - MZ/SCIZ - Stacktrace', exc);
}
}
});
}
}
/* SCIZ - Events */
function scizPrettyPrintEvent(e) {
e.message = e.message.replace(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}\s[0-9]{2}h[0-9]{2}:[0-9]{2}/g, ''); // Delete date
e.message = e.message.replace(/\n\s*\n*/g, '<br/>');
let beings = [[e.att_id, e.att_nom], [e.def_id, e.def_nom], [e.mob_id, e.mob_nom], [e.owner_id, e.owner_nom], [e.troll_id, e.troll_nom]];
beings.forEach((b) => {
if (b[0] && b[1]) {
b[1] = b[1].replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
if (b[0].toString().length > 6) {
// Mob
b[1] = b[1].replace(/^une?\s/g, '');
e.message = e.message.replace(new RegExp(`(${b[1]})`, 'gi'), `<b><a href="/mountyhall/View/MonsterView.php?ai_IDPJ=${b[0]}" rel="modal:open" class="mh_monstres">\$1</a></b>`);
} else {
// Troll
e.message = e.message.replace(new RegExp(`(${b[1]})`, 'gi'), `<b><a href="javascript:EPV('${b[0]}')" class="mh_trolls_1">\$1</a></b>`);
}
}
});
return e;
}
function do_scizOverwriteEvents() {
scizGlobal.events = [];
let eventTableNode = null;
// Ensure we have a JWT setup for the current user
let jwt = MY_getValue(`${numTroll}.SCIZJWT`);
let cbx = MY_getValue(`${numTroll}.SCIZ_CB_EVENTS`);
if (jwt === null || jwt === undefined || jwt.trim() === '' || cbx === '0') {
return;
}
// Retrieve being ID
let url = new URL(window.location.href);
let id = url.searchParams.get('ai_IDPJ');
id = !id ? numTroll : id;
// Check for advanced profil
let advanced = document.querySelector("[href*='MH_Style_ProfilAvance.css']") !== null;
let xPathQuery = advanced ? "//*/table[@id='events']/tbody/tr" : "//*/tr[contains(@class, 'mh_tdpage')]";
// Retrieve local events
let xPathEvents = document.evaluate(xPathQuery, document, null, 0, null);
let xPathEvent;
while (xPathEvent = xPathEvents.iterateNext()) {
scizGlobal.events.push({
time: Date.parse(StringToDate(xPathEvent.children[0].innerHTML)),
type: xPathEvent.children[1].innerHTML,
desc: xPathEvent.children[2].innerHTML,
sciz_type: null,
sciz_desc: null,
node: xPathEvent,
});
if (eventTableNode === null) {
eventTableNode = xPathEvent.parentNode.parentNode;
}
}
let startTime = Math.min.apply(Math, scizGlobal.events.map((e) => {
return e.time;
})) - scizSetup.eventsMaxMatchingInterval;
let endTime = Math.max.apply(Math, scizGlobal.events.map((e) => {
return e.time;
})) + scizSetup.eventsMaxMatchingInterval;
// Check if events have been found in the page
if (scizGlobal.events.length < 1) {
logMZ('ERREUR - MZ/SCIZ - Aucun événement trouvé sur la page...');
return;
}
// Call SCIZ
let sciz_url = `https://www.sciz.fr/api/hook/events/${id}/${startTime}/${endTime}`;
let eventType = url.searchParams.get('as_EventType'); // Retrieve event type filter
sciz_url = sciz_url + (eventType !== null && eventType !== '' ? `/${eventType.split(' ')[0]}` : ''); // Only the first word used for filtering ("MORT par monstre" => "MORT");
FF_XMLHttpRequest({
method: 'GET',
url: sciz_url,
headers: { Authorization: jwt },
// trace: 'Appel à SCIZ pour l'entité ' + id,
onload: function (responseDetails) {
try {
if (responseDetails.status == 0) {
logMZ('ERREUR - MZ/SCIZ - Appel à SCIZ en échec...', responseDetails);
return;
}
let events = JSON.parse(responseDetails.responseText);
if (events.events.length < 1) {
// logMZ('DEBUG - MZ/SCIZ - Aucun événement trouvé dans la base SCIZ...');
return;
}
// Read if switch to SCIZ view or not
let bViewSCIZ = MY_getValue('SCIZ_view') !== 'no';
// Look for events to overwrite (based on timestamps)
events.events.forEach((e) => {
if (e.message.includes(id)) { // Exclude any event we were not looking for...
let t = Date.parse(StringToDate(e.time));
// Look for the best event matching and not already replaced
let i = -1;
let lastDelta = Infinity;
for (let j = 0; j < scizGlobal.events.length; j++) {
if (scizGlobal.events[j].sciz_desc === null) {
let delta = Math.abs(t - scizGlobal.events[j].time);
if (delta <= scizSetup.eventsMaxMatchingInterval && delta < lastDelta) {
lastDelta = delta;
i = j;
}
}
}
if (i > -1) {
// PrettyPrint
e = scizPrettyPrintEvent(e);
// Store the SCIZ event and icon
let div = scizCreateIcon('25', 'block', e.icon);
scizGlobal.events[i].sciz_type = div.outerHTML;
scizGlobal.events[i].sciz_desc = e.message;
// Actual display overwrite
scizGlobal.events[i].node.children[1].setAttribute("valign", "middle");
scizGlobal.events[i].node.children[2].setAttribute("valign", "middle");
if (bViewSCIZ) {
scizGlobal.events[i].node.children[1].innerHTML = scizGlobal.events[i].sciz_type;
scizGlobal.events[i].node.children[2].innerHTML = scizGlobal.events[i].sciz_desc;
}
}
}
});
// Add the switch button
if (eventTableNode !== null) {
let div = scizCreateClickable('50', 'block', do_scizSwitchEvents);
eventTableNode.parentNode.insertBefore(div, eventTableNode.nextSibling);
}
} catch (exc) {
logMZ('ERREUR - MZ/SCIZ - Stacktrace', exc);
}
}
});
}
function do_scizSwitchEvents() {
let bMaskSCIZ = false;
scizGlobal.events.forEach((e) => {
let currentType = e.node.children[1].innerHTML;
if (currentType === e.type) {
e.node.children[1].innerHTML = e.sciz_type !== null ? e.sciz_type : e.type;
} else {
e.node.children[1].innerHTML = e.type;
bMaskSCIZ = true;
}
let currentDesc = e.node.children[2].innerHTML;
e.node.children[2].innerHTML = currentDesc === e.desc ? e.sciz_desc !== null ? e.sciz_desc : e.desc : e.desc;
});
if (bMaskSCIZ) {
MY_setValue('SCIZ_view', 'no');
} else {
MY_removeValue('SCIZ_view');
}
}
/** x~x Missions ------------------------------------------------------- */
/* TODO
* MZ2.0 : gérer le nettoyage des missions terminées via script principal
* Roule 01/01/2017 : c'est fait dans do_mission_liste
*
* Note: nbKills n'est pas géré pour l'instant (voir avec Actions?)
*/
function isArray(a) {
return Boolean(a) && a.constructor === Array;
}
function saveMission(num, obEtape) {
let obMissions;
if (MY_getValue(`${numTroll}.MISSIONS`)) {
try {
// logMZ('JSON MISSION (before) = ' + MY_getValue(numTroll+'.MISSIONS'));
obMissions = JSON.parse(MY_getValue(`${numTroll}.MISSIONS`));
} catch (exc) {
logMZ('Mission parsage', exc);
return;
}
}
if (isArray(obMissions)) {
obMissions = new Object();
} // corrige certains cas issus d'anciennes versions MZ
if (obMissions == undefined) {
obMissions = new Object();
} // protection
// logMZ('saveMission, obEtape=' + obEtape); // debug roule
if (obEtape) {
obMissions[num] = obEtape;
} else if (obMissions[num]) {
delete obMissions[num];
}
MY_setValue(`${numTroll}.MISSIONS`, JSON.stringify(obMissions));
// logMZ('JSON MISSION (after) = ' + MY_getValue(numTroll+'.MISSIONS'));
}
function parseMissionSteps() {
try {
let titreMission = $("h2")[0].textContent;
let idMission = titreMission.match(/\d+/)[0];
let validationFound = false;
var $missionLines = $("[name='ActionForm'] tr");
$missionLines.each(function () {
let $this = $(this);
let children = $this.children("td");
let stepNode = children[1];
let stepText = stepNode.textContent;
let validationText = children[2].textContent;
if (0 > validationText.indexOf("Valider")) {
// Etape déjà réalisée ou pas encore réalisée
return;
}
validationFound = true;
if (0 < stepText.indexOf("monstre")) {
let step = handleMonsterStep(stepText);
MZ_troogle.addTroogleLinkToStep(stepNode, step);
saveMission(idMission, step);
return;
}
if (0 < stepText.indexOf("du pouvoir")) {
let step = handlePowerStep(stepText);
saveMission(idMission, step);
return;
}
debugMZ(`Texte de mission non traité:${step}`);
});
if (!validationFound) {
// S'il n'y a plus d'étape en cours (=mission finie), on supprime
debugMZ('MZ_troogle.addTroogleLinkToStep, la mission semble terminée');
saveMission(idMission, false);
}
} catch (e) {
warnMZ("Problème dans le traitement d'étape de mission", e);
}
}
function handlePowerStep(text) {
let powerExtract = /du pouvoir (.*)/i;
let pouvoir = powerExtract.exec(text)[1];
pouvoir = removeEnclosingSimpleCote(pouvoir);
return {
type: 'Pouvoir',
pouvoir: pouvoir,
libelle: text
};
}
function handleMonsterStep(text) {
let mission = {
type: 'Niveau',
niveau: 0,
mod: 'plus',
mundidey: text.indexOf('Mundidey') != -1,
libelle: text,
recherche: MZ_troogle.SEARCH_MONSTER
};
let raceExtract = /de la race des "(.*?)"/i;
let match = raceExtract.exec(text);
if (match) {
mission.type = 'Race'
let race = removeEnclosingSimpleCote(trim(match[1]));
mission.recherche += ` ${race}`;
}
let familyExtract = /de la famille "(.*?)"/i;
match = familyExtract.exec(text);
if (match) {
mission.type = 'Famille'
let famille = trim(match[1]);
mission.recherche += `:${famille}`;
}
let minLevelExtract = /niveau.* (\d+) au moins/i;
match = minLevelExtract.exec(text);
if (match) {
mission.niveau = atoi(match[1]);
}
var levelRangeExtract = /niveau.* (\d+) +\+ ou - +(\d+)/i;
match = levelRangeExtract.exec(text);
if (match) {
mission.niveau = atoi(match[1]);
mission.mod = atoi(match[2]);
}
return mission;
}
// un ParseInt un peu plus résistant aux Strings un peu loose
function atoi(s) {
if (!s) return undefined; // à valider
s = s.trim();
while (s.charAt(0) == '0' || s.charAt(0) == ':') {
s = s.substring(1, s.length);
if (s.length == 0) return 0;
}
return parseInt(s, 10);
}
// Namespace MZ_troogle: isoler l'api liée à Troogle dans un objet et ne présenter que les méthodes
// réellement publiques dans cet objet; les autres sont cachées dans le scope du bloc (évite de remplir la table des
// fonctions visibles) (import Chrall)
(function(MZ_troogle){
const BASE_TROOGLE_URL = `https://troogle.iktomi.eu/`;
const BASE_TROOGLE_SEARCH = `${BASE_TROOGLE_URL}entities/?entity_search[search]=`;
// Pseudo-constantes:
// Types de recherche
Object.defineProperty(MZ_troogle, "SEARCH_MONSTER", { value: '@monstre', configurable: false, writable: false });
// Ajoute un lien vers Troogle en ajoutant la position courante du troll dans les paramètres
// @param node element html (conteneur) dans lequel le lien va être ajouté
// @param step objet étape de mission (cf handleMonsterStep)
MZ_troogle.addTroogleLinkToStep = function(node, step) {
let search = `${step.recherche} `;
if (0 < step.niveau) {
let max = 'plus' === step.mod ? 100 : step.niveau + step.mod;
let min = 'plus' === step.mod ? step.niveau : step.niveau - step.mod;
search += ` level:${min}..${max} `;
}
MZ_troogle.addTroogleLink(node, search);
}
// Ajoute un lien vers Troogle en ajoutant la position courante du troll dans les paramètres
// @param node element html (conteneur) dans lequel le lien va être ajouté
// @param text texte de recherche (supposé correctement écrit)
MZ_troogle.addTroogleLink = function(node, text) {
let url = `${BASE_TROOGLE_SEARCH}${text} `;
url += playerPositionParameters();
let link = appendA(node, url);
link.target = 'Troogle';
let img = createImage(`${BASE_TROOGLE_URL}favicon.ico`, 'Rechercher sur Troogle', 'max-width: 1.5rem');
link.appendChild(img);
}
// Paramètres de recherche pour la position courante du troll actif
function playerPositionParameters(){
let positionX = MY_getValue(`${numTroll}.position.X`);
let positionY = MY_getValue(`${numTroll}.position.Y`);
let positionN = MY_getValue(`${numTroll}.position.N`);
return `&entity_search[position_x]=${positionX}&entity_search[position_y]=${positionY}&entity_search[position_z]=${positionN}`;
}
})(window.MZ_troogle = window.MZ_troogle || {});
// Namespace MZ_troc: isoler l'api liée au Troc de l'Hydre
(function(MZ_troc) {
const BASE_TROC_URL = 'https://troc.mountyhall.com/'; // search.php
// Ajoute un lien vers le Troc de l'Hydre
// @param node element html (conteneur) dans lequel le lien va être ajouté
// @param monster monstre pour lequel le composant est recherché
// @param part partie du monstre/composant
// @param quality qualité minimum (textuelle, sera convertie via qualiteNum)
MZ_troc.addTrocLink = function(node, monster, part, quality) {
quality = qualiteNum.indexOf(quality);
let url = `${BASE_TROC_URL}search.php?monster=${monster}&part=${part}&qualite=${quality}&q=min`;
let link = appendA(node, url);
link.target = 'Troc';
let img = createImage(`${BASE_TROC_URL}favicon.png`, "Rechercher sur le Troc de l'Hydre", 'max-width: 1.5rem');
link.appendChild(img);
}
})(window.MZ_troc = window.MZ_troc || {});
function removeEnclosingSimpleCote(x) { // Roule 29/03/2019
return x.replace(/'$/, '').replace(/^'/, '');
}
function do_mission() {
start_script(60, 'do_mission_log');
parseMissionSteps();
displayScriptTime(undefined, 'do_mission_log');
}
/** x~x Données sur les trous de météorites ---------------------------- */
var petitsTrous = {
'-52;57': true,
'55;70': true,
'64;70': true,
'12;-15': true,
'30;-52': true,
'48;-39': true
};
var grosTrous = {
'-35;65': true,
'-13;73': true,
'-64;9': true,
'-35;15': true,
'5;32': true,
'10;64': true,
'21;36': true,
'46;52': true,
'74;32': true,
'-71;-7': true,
'-67;-37': true,
'-60;-32': true,
'-51;-22': true,
'-36;-51': true,
'5;-49': true
};
var centreCarmine_X = 56.5;
var centreCarmine_Y = 23.5;
var rayonCarmine = 8.7;
function isTrou(x, y, n) {
if (petitsTrous[`${x};${y}`]) {
return n < 0 && n > -60;
}
if (grosTrous[`${x};${y}`] ||
grosTrous[`${x - 1};${y}`] ||
grosTrous[`${x};${y}${1}`] ||
grosTrous[`${x - 1};${y}${1}`]) {
return n < 0 && n > -70;
}
if (Math.sqrt(
Math.pow(x - centreCarmine_X, 2) + Math.pow(y - centreCarmine_Y, 2)
) <= rayonCarmine) {
return n < 0 && n > -100;
}
return false;
}
/** x~x Gestion des DEs ------------------------------------------------ */
function validateDestination() {
let dx = undefined, dy = undefined, dn = undefined;
for (let form of document.getElementsByTagName('form')) {
for (let eInput of form.getElementsByTagName('input')) {
if (eInput.name == 'depl_2D') {
if (!eInput.value) continue;
tDepl = eInput.value.split('_');
dx = parseInt(tDepl[0], 10);
dy = parseInt(tDepl[1], 10);
dn = parseInt(tDepl[2], 10);
break;
}
if (eInput.name == 'depl_x' && eInput.checked) dx = parseInt(eInput.value, 10);
if (eInput.name == 'depl_y' && eInput.checked) dy = parseInt(eInput.value, 10);
if (eInput.name == 'depl_n' && eInput.checked) dn = parseInt(eInput.value, 10);
}
}
if (dx === undefined || dy === undefined || dn == undefined ||
isNaN(dx) || isNaN(dy) || isNaN(dn)) {
debugMZ('validateDestination_log, impossible de retrouver les paramètres de Déplacement');
return true; // tant pis pour le pauvre Trõll
}
let sx = dx < 0 ? -1 : +1;
dx = Math.abs(dx);
let sy = dy < 0 ? -1 : +1;
dy = Math.abs(dy);
let sn = dn < 0 ? -1 : +1;
dn = Math.abs(dn);
let x = parseInt(MY_getValue(`${numTroll}.position.X`), 10);
let y = parseInt(MY_getValue(`${numTroll}.position.Y`), 10);
let n = parseInt(MY_getValue(`${numTroll}.position.N`), 10);
debugMZ(`validateDestination_log ${x}, ${y}, ${n} DE ${sx * dx}, ${sy * dy}, ${sn * dn}`);
let dmax = Math.max(dx, dy, dn);
for (let i = 1; i <= dmax; i++) {
let this_dx = Math.min(dx, i);
let this_dy = Math.min(dy, i);
let this_dn = Math.min(dn, i);
if (isTrou(x + sx * this_dx, y + sy * this_dy, n + sn * this_dn)) {
return window.confirm(
`La voix de mini TilK (n°36216) résonne dans votre tête :
Vous allez tomber dans un trou de météorite.
Êtes vous sûr de vouloir effectuer ce déplacement ?`);
}
}
return true;
}
function newsubmitDE(event) {
event.stopPropagation();
event.preventDefault();
debugMZ('newsubmitDE_log : vérification trou')
if (validateDestination()) {
this.submit();
}
}
function changeValidation() {
let forms = document.getElementsByTagName('form');
for (form of forms) {
for (input of form.getElementsByTagName('input')) {
if (input.name != 'depl_2D' && input.name != 'depl_x') continue;
form.addEventListener('submit', newsubmitDE, true);
debugMZ('changeValidation_log : activation de la détection des TP dangereux')
return;
}
}
console.log('changeValidation_log : pas de form compatible avec la détection des TP dangereux')
}
/** x~x Gestion des TPs ------------------------------------------------ */
function validateTPDestination() {
try {
let text = document.getElementsByTagName('B')[0];
let a = text.firstChild.nodeValue.split('|');
let pos_x = Number(a[0].substring(4, a[0].length - 1));
let pos_y = Number(a[1].substring(5, a[1].length - 1));
let pos_n = Number(a[2].substring(5, a[2].length));
let nbtrous = 0;
for (let signX = -1; signX <= 1; signX = signX + 2) {
for (let x = 0; x <= 2; x++) {
for (let signY = -1; signY <= 1; signY = signY + 2) {
for (let y = 0; y <= 2; y++) {
for (let signN = -1; signN <= 1; signN = signN + 2) {
for (let n = 0; n <= 1; n++) {
if (isTrou(
pos_x + signX * x, pos_y + signY * y, Math.min(-1, pos_n + signN * n)
)) {
nbtrous++;
}
}
}
}
}
}
}
if (nbtrous > 0 && nbtrous < 72) {
return window.confirm(
`La voix de mini TilK (n°36216) résonne dans votre tête :
Vous avez ${Math.floor(100 * nbtrous / 144)
}% de risque de tomber dans un trou de météorite.
Êtes-vous sûr de vouloir prendre ce portail ?`
);
} else if (nbtrous >= 72) {
return window.confirm(
`La voix de mini TilK (n°36216) tonne dans votre tête :
Malheureux, vous avez ${Math.floor(100 * nbtrous / 144)
}% de risque de tomber dans un trou de météorite !
Êtes-vous bien certain de vouloir prendre ce portail ?`
);
}
return true;
} catch (exc) {
avertissement(`Une erreur est survenue (validateTPDestination)`, null, null, exc);
}
}
function newsubmitTP(event) {
/*
event.stopPropagation();
event.preventDefault();
if (validateTPDestination()) {
this.submit();
}
*/
return validateTPDestination();
}
function changeButtonValidate() {
let forms = document.getElementsByTagName('form');
for (form of forms) {
for (input of form.getElementsByTagName('input')) {
if (input.name != 'portail') continue;
//form.addEventListener('submit', newsubmitTP, true);
form.onsubmit = newsubmitTP;
debugMZ('changeButtonValidate : activation de la détection des TP dangereux')
return;
}
}
console.log('changeButtonValidate_log : pas de form compatible avec la détection des TP dangereux')
}
/** x~x Partie Principale ---------------------------------------------- */
function do_move() {
debugMZ('do_move_log');
// Roule', vérification du risque de tomber dans un trou déplacée dans do_lieuTeleport pour le cas des TP
// if(isPage('MH_Play/Play_a_Move.php')) {
changeValidation();
// }
// else if(isPage('MH_Lieux/Lieu_Teleport.php')) {
// changeButtonValidate();
// }
}
/** x~x News ----------------------------------------------------------- */
// Nombre de news à afficher & nb max de caractères par news:
// let nbItems = 5; // WARNING (gath) - non utilisé -> commenté
// let maxCarDescription = 300; // WARNING (gath) - non utilisé -> commenté
/** x~x Utilitaires ---------------------------------------------------- */
// Ne semble avoir strictement aucun effet:
String.prototype.epureDescription = function () {
return this.replace(/\\(.)/g, "$1");
};
function appendTitledTable(node, titre, description) {
// Crée les tables contenant les infos (avec titre)
let table = document.createElement('table');
table.border = 0;
let ui_table = isDesktopView() ? 'mh_tdborder' : 'ui-body-a ui-corner-all';
table.className = ui_table;
table.cellSpacing = 1;
table.cellPadding = 1;
isDesktopView() ? table.style.maxWidth = '98%' : table.style.width = '100%';
table.style.marginLeft = 'auto';
table.style.marginRight = 'auto';
let tbody = document.createElement('tbody');
table.appendChild(tbody);
let ui_tr = isDesktopView() ? 'mh_tdtitre' : 'ui-bar-b ui-corner-top';
let tr = appendTr(tbody, ui_tr);
let td = appendTdCenter(tr, 2);
let span = document.createElement('span');
appendText(span, titre, true);
if (description) {
span.title = description;
}
td.appendChild(span);
node.appendChild(table);
return tbody;
}
function testCertif(paramURL, callbackOnError) {
try {
FF_XMLHttpRequest({
method: 'GET',
url: paramURL,
onload: function (responseDetails) {
// logMZ('testCertif(' + paramURL + '), callback, status=' + responseDetails.status);
if (responseDetails.status == 0) {
callbackOnError();
} // FAIL si status == 0
}
});
} catch (exc) {
logMZ(`erreur testCertif(${paramURL})`, exc);
callbackOnError();
}
}
function createOrGetGrandCadre() {
let rappels, grandCadre = document.getElementById('grandCadre');
if (grandCadre) {
return grandCadre;
}
try {
rappels = document.evaluate(
"//p[contains(a/text(),'messagerie')]", document, null, 9, null
).singleNodeValue;
} catch (exc) {
avertissement('Tu es en HTTPS. Pour bénéficier de MoutyZilla, tu devrais débloquer le contenu mixte');
grandCadre = document.createElement('div');
return grandCadre;
}
grandCadre = document.createElement('div');
grandCadre.id = 'grandCadre';
let sousCadre = document.createElement('div');
sousCadre.innerHTML = 'Tu es en <span style="color:blue">HTTPS</span>.';
sousCadre.style.textAlign = 'center';
sousCadre.style.fontSize = 'xx-large';
grandCadre.appendChild(sousCadre);
grandCadre.style.border = 'solid 5px red';
grandCadre.style.width = 'auto';
insertBefore(rappels, grandCadre);
return grandCadre;
}
function showHttpsErrorCadre1() {
logMZ('showHttpsErrorCadre1');
let grandCadre = createOrGetGrandCadre();
let sousCadre = document.createElement('div');
sousCadre.innerHTML = `${'<b>Tu n\'as pas accepté le certificat1 de Raistlin.</b>' +
'<br />Cela empêchera Moutyzilla de fonctionner' +
'<br /><a style="color:blue;font-size: inherits;" href="'}${URL_CertifRaistlin1
}" target="raistlin">clique ici</a>` +
`<br />puis « Avancé » ... « Ajouter une exception » ...` +
` « Confirmer l'exception de sécurité »` +
`<br /><i>Il suffit de faire ceci une seule fois jusqu'à ce que Raistlin change son certificat</i>`;
sousCadre.style.width = 'auto';
sousCadre.style.fontSize = 'large';
sousCadre.style.border = 'solid 1px black';
sousCadre.style.backgroundColor = 'red';
grandCadre.appendChild(sousCadre);
}
function showHttpsErrorCadre2() {
logMZ('showHttpsErrorCadre2');
let grandCadre = createOrGetGrandCadre();
let sousCadre = document.createElement('div');
sousCadre.innerHTML = `${'<b>Tu n\'as pas accepté le certificat2 de Raistlin.</b>' +
'<br />Cela empêchera le fonctionnement de l\'affichage des Potrõlls dans la vue<br />' +
'<a style="color:blue;font-size: inherits;" href="'}${URL_CertifRaistlin2
}" target="raistlin">clique ici</a>` +
`<br />puis « Avancé » ... « Ajouter une exception » ...` +
` « Confirmer l'exception de sécurité »` +
`<br />(Ignorer ensuite le message sur l'erreur de mot de passe)` +
`<br /><i>Il suffit de faire ceci une seule fois jusqu'à ce que Raistlin change son certificat</i>`;
sousCadre.style.width = 'auto';
sousCadre.style.fontSize = 'large';
sousCadre.style.border = 'solid 1px black';
sousCadre.style.backgroundColor = 'red';
grandCadre.appendChild(sousCadre);
}
function showHttpsErrorContenuMixte() {
logMZ('showHttpsErrorContenuMixte');
let grandCadre = createOrGetGrandCadre();
let sousCadre = document.createElement('div');
sousCadre.innerHTML = '<b>Tu n\'as pas autorisé le contenu mixte.</b><br />' +
'Cela interdit le fonctionnement des <b>services suivants</b> de Mountyzilla (le reste, dont l\'enrichissement de la vue, fonctionne à condition d\'accepter les certificats)' +
'<ul>' +
'<li>Interface Bricol\'Troll</li>' +
'<li>Nouveautés de Mountyzilla</li>' +
'</ul>' +
'Pour autoriser le contenu mixte, regarde <a href="https://support.mozilla.org/fr/kb/blocage-du-contenu-mixte-avec-firefox#w_daebloquer-le-contenu-mixte" target="_blank">cette page</a><br />' +
'<i>Il faudra malheureusement le faire à chaque nouvelle connexion</i>';
sousCadre.style.width = 'auto';
sousCadre.style.fontSize = 'large';
sousCadre.style.border = 'solid 1px black';
grandCadre.appendChild(sousCadre);
}
/** x~x Jubilaires ----------------------------------------------------- */
function traiterJubilaires() {
try {
let URL_anniv = URL_MZ + '/jubilaires.json?v=';
// forcer le fichier a être rafraîchi au changement de jour
let dNow = new Date();
URL_anniv += dNow.getMonth() + '.' + dNow.getDate();
FF_XMLHttpRequest({
method: 'GET',
url: URL_anniv,
onload: function (responseDetails) {
if (responseDetails.status == 0) {
logMZ(`status=0 à l'appel jubilaires, réponse=${responseDetails.responseText}`);
return;
}
let listeTrolls = JSON.parse(responseDetails.responseText);
if (!listeTrolls || listeTrolls.length == 0) {
return;
}
afficherJubilaires(listeTrolls);
},
});
} catch (exc) {
avertissement(`Une erreur est survenue (Jubilaires)`, null, null, exc);
}
}
function afficherJubilaires(listeTrolls) {
let footer = getFooter();
if (!footer) {
logMZ('afficherJubilaires_log, impossible de retrouver le footer');
return;
}
let p = document.createElement('p');
let tbody = appendTitledTable(p,
"Les Trõlls qui fêtent leur cycloversaire aujourd'hui :",
'Envoyez leur un message ou un cadeau !'
);
let tr = appendTr(tbody, 'mh_tdpage');
let td = appendTdCenter(tr);
let lastAge = undefined;
for (let troll of listeTrolls) {
if (lastAge != troll.age) {
if (lastAge !== undefined) appendText(td, ', ');
let eAge = document.createElement('span');
eAge.style.fontWeight = 'bold';
eAge.style.whiteSpace = 'nowrap';
appendText(eAge, `${troll.age} cycle${troll.age > 1 ? 's' : ''} : `)
td.appendChild(eAge);
} else {
appendText(td, ', ');
}
let span = document.createElement('span');
span.style.whiteSpace = 'nowrap';
if (troll.num_troll == numTroll) span.style.backgroundColor = '#98FB98';
let a = document.createElement('a');
a.href = `javascript:EPV(${troll.num_troll})`;
a.className = 'ui-link';
appendText(a, troll.nom_troll);
span.appendChild(a);
td.appendChild(span);
lastAge = troll.age;
}
insertBefore(footer, p);
}
/** x~x News MZ -------------------------------------------------------- */
function traiterNouvelles() {
let news = new Array();
news.push(['2024-05-05', "Affichage d'une alerte à l'approche de la DLA dans l'onglet du navigateur (il faut activer l'option)."]);
news.push(['2024-05-06', 'Les jubilaires sont revenus. Merci pour votre patience pas infinie mais presque.']);
let d2 = new Date();
if (d2.getMonth() == 0 && d2.getDate() < 10) {
news.push([new Date(d2.getFullYear(), 0, 1), `MZ vous souhaite bonne chasse pour ${d2.getFullYear()}`]);
}
afficherNouvelles(news);
}
function getLatestChanges() {
let changes = new Array();
for (let i = 0; i == 0 || MZ_changeLog[i].startsWith('\t- '); i++) {
changes.push(MZ_changeLog[i]);
}
return changes.join('\n');
}
function afficherNouvelles(items) {
let footer = getFooter();
if (!footer) {
logMZ('afficherNouvelles, impossible de retrouver le footer');
return;
}
let p, tbody, tr;
p = document.createElement('p');
tbody = appendTitledTable(p, 'Les nouvelles de Mountyzilla');
for (let i = 0; i < items.length; i++) {
let color = undefined;
let d = undefined;
if (items[i][0] != null) {
d = new Date(items[i][0]);
// plus vieux que 2 mois => ne pas afficher
let d2 = new Date();
d2.setMonth(d2.getMonth() - 3);
if (d < d2) {
continue;
}
// afficher en rouge si moins de 15 jours
d2 = new Date();
d2.setDate(d2.getDate() - 15);
if (d > d2) {
color = 'red';
}
}
tr = appendTr(tbody, 'mh_tdpage');
if (color) {
tr.style.color = color;
}
let td = appendTdCenter(tr);
td.style.verticalAlign = 'top'; // semble sans effet
if (d) {
td.appendChild(document.createTextNode(d.toLocaleDateString('fr-FR')));
}
td = appendTd(tr);
td.appendChild(document.createTextNode(items[i][1]));
}
// astuce : tr reste undefined s'il n'y a pas de nouvelle à afficher
if (tr) insertBefore(footer, p);
if (items.length > 0) {
}
// changelog
p = document.createElement('p');
tbody = appendTitledTable(p, 'Changelog de Mountyzilla');
let div = document.createElement('div');
div.style.position = 'absolute';
div.style.right = 0;
div.style.top = 0;
div.style.paddingRight = '3px';
div.style.whiteSpace = 'nowrap';
appendText(div, `(version ${GM_info.script.version})`);
tbody.rows[0].cells[0].style.position = 'relative';
tbody.rows[0].cells[0].appendChild(div);
tbody.rows[0].cells[0].style.cursor = 'pointer';
tbody.rows[0].cells[0].style.minWidth = '400px';
tr = appendTr(tbody, 'mh_tdpage');
let td = appendTd(tr);
td.colSpan = 2;
let pre = document.createElement('pre');
appendText(pre, getLatestChanges());
pre.id = 'mz_changelog'
pre.style.whiteSpace = 'pre-wrap';
td.appendChild(pre);
tbody.rows[0].cells[0].onclick = function () {
try {
tbody.rows[0].cells[0].onclick = undefined;
tbody.rows[0].cells[0].style.cursor = '';
let pre = document.getElementById('mz_changelog');
pre.innerText = MZ_changeLog.join('\n');
} catch (exc) {
logMZ('affichage changeLog', exc);
}
};
insertBefore(footer, p);
}
/** x~x Main -------------------------------------------------------- */
function do_news() {
start_script(undefined, 'do_news_log');
// mémorisation de décalage entre l'heure locale de ce PC/smartphone et l'heure du serveur MH
let eHServer = document.getElementById("hserveur");
//console.log('eHServer=' + eHServer);
if (eHServer) {
// intervertir jour/mois (satanés américains ! Même les Anglais ne font pas cette bêtise)
let mhInfo = eHServer.innerText.match(/^(\d+)\/(\d+)\/(.*)\]+$/);
if (mhInfo) {
// cette méthode permet de tenir compte du fuseau horaire GMT+0200 par exemple)
let mhDate = new Date(`${mhInfo[2]}/${mhInfo[1]}/${mhInfo[3]}`);
MY_setValue('MZ_rebours_diff_time', mhDate.getTime() - (new Date()).getTime());
//console.log(`do_news_log MH:${eHServer.innerText}, delta=${MY_getValue('MZ_rebours_diff_time')}ms`);
}
}
traiterJubilaires();
traiterNouvelles();
displayScriptTime(undefined, 'do_news_log');
}
/** x~x Tabcompo ------------------------------------------------------- */
function initPopupTabcompo() {
let popup = document.createElement('div');
popup.setAttribute('id', 'popupCompo');
popup.setAttribute('class', 'mh_textbox');
popup.setAttribute('style', 'position: absolute; visibility: hidden;' +
'display: inline; z-index: 3; max-width: 400px;');
document.body.appendChild(popup);
}
function showPopupCompo(evt) {
let texte = this.getAttribute("texteinfo");
let popup = document.getElementById('popupCompo');
popup.innerHTML = texte;
popup.style.left = `${evt.pageX + 15}px`;
popup.style.top = `${evt.pageY}px`;
popup.style.visibility = "visible";
}
function hidePopupCompo() {
let popup = document.getElementById('popupCompo');
popup.style.visibility = 'hidden';
}
function createPopupImage_tabcompo(url, text) {
let img = document.createElement('img');
img.setAttribute('src', url);
img.setAttribute('align', 'ABSMIDDLE');
img.setAttribute("texteinfo", text);
img.addEventListener("mouseover", showPopupCompo, true);
img.addEventListener("mouseout", hidePopupCompo, true);
return img;
}
function formateTexte_tabcompo(texte) {
texte = texte.replace(/\n/g, "<br/>");
texte = texte.replace(/^([^<]*) d'un/g, "<b>$1</b> d'un");
texte = texte.replace(/<br\/>([^<]*) d'un/g, "<br/><b>$1</b> d'un");
texte = texte.replace(/(d'une? )([^<]*) d'au/g, "$1<b>$2</b> d'au");
texte = texte.replace(/(Qualité )([^<]*) \[/g, "$1<b>$2</b> [");
texte = texte.replace(/\[([^<]*)\]/g, "[<b>$1</b>]");
return texte;
}
function arrondi(x) {
return Math.ceil(x - 0.5); // arrondi à l'entier le plus proche, valeurs inf
}
function traiteMinerai_tabcompo() {
if (currentURL.indexOf("as_type=Divers") == -1) {
return;
}
let node;
try {
node = document.evaluate("//form/table/tbody[@class='tablesorter-no-sort'" +
" and contains(./tr/th/text(),'Minerai')]", document, null, 9, null
).singleNodeValue;
node = node.nextSibling.nextSibling;
} catch (e) {
return;
}
let trlist = document.evaluate('./tr', node, null, 7, null);
for (let i = 0; i < trlist.snapshotLength; i++) {
node = trlist.snapshotItem(i);
let nature = node.childNodes[5].textContent;
let caracs = node.childNodes[7].textContent;
let taille = caracs.match(/\d+/)[0];
let coef = 1;
if (caracs.indexOf('Moyen') != -1) {
coef = 2;
} else if (caracs.indexOf('Normale') != -1) {
coef = 3;
} else if (caracs.indexOf('Bonne') != -1) {
coef = 4;
} else if (caracs.indexOf('Exceptionnelle') != -1) {
coef = 5;
}
if (nature.indexOf('Mithril') != -1) {
coef = 0.2 * coef;
appendText(node.childNodes[7], ` | UM: ${arrondi(taille * coef)}`);
} else {
coef = 0.75 * coef + 1.25;
if (nature.indexOf('Taill') != -1) {
coef = 1.15 * coef;
}
appendText(node.childNodes[7], ` | Carats: ${arrondi(taille * coef)}`);
}
}
}
// Roule' 06/01/2017 ne fonctionne plus, la récupération des nodes ne donne rien
function treateComposants() {
if (currentURL.indexOf("as_type=Compo") == -1) {
return;
}
// On récupère les composants
let nodes = document.evaluate(
"//a[starts-with(@href,'TanierePJ_o_Stock.php?IDLieu=') or starts-with(@href,'Comptoir_o_Stock.php?IDLieu=')]" +
"/following::table[@width = '100%']/descendant::tr[contains(td[1]/a/b/text(),']') " +
"and (contains(td[3]/text()[2],'Tous les trolls') or contains(td[3]/text()[1],'Tous les trolls') ) " +
"and td[1]/img/@alt = 'Identifié']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (nodes.snapshotLength == 0) {
// logMZ('treateComposants DOWN');
return;
}
// logMZ('treateComposants nbnodes=' + nodes.snapshotLength);
let texte = "";
for (let i = 0; i < nodes.snapshotLength; i++) {
let n1 = nodes.snapshotItem(i).childNodes[1];
let n3 = nodes.snapshotItem(i).childNodes[3];
let debut = n1.childNodes[2].nodeValue.replace(/\n/g, '');
let prix = n3.childNodes[0].nodeValue;
if (!prix) {
prix = `${n3.childNodes[3].getAttribute('value')} GG'`;
}
texte = `${texte}${debut.substring(debut.indexOf('[') + 1, debut.indexOf(']'))};${n1.childNodes[3].firstChild.nodeValue.replace(/\n/g, '')
}${n1.childNodes[3].childNodes[1].firstChild.nodeValue.replace(/\n/g, '')};${prix.replace(/\n/g, '')}\n`;
}
let c = document.evaluate("//div[@class = 'titre2']/text()",
document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
let id_taniere = c.snapshotItem(0).nodeValue;
id_taniere = id_taniere.substring(id_taniere.lastIndexOf('(') + 1, id_taniere.lastIndexOf(')'));
// gath: 'getFormComboDB' is not defined
let form = getFormComboDB(currentURL.indexOf('MH_Taniere') != -1 ? 'taniere' : 'grande_taniere', id_taniere,
texte.replace(/\240/g, " ").replace(/d'un/g, "d un"));
if (form) {
if (document.getElementsByTagName('form').length > 0) {
insertBefore(document.getElementsByTagName('form')[0].nextSibling, form);
} else {
let thisP = document.evaluate("//p/table/descendant::text()[contains(.,'Heure Serveur')]/../../../../..", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
insertBefore(thisP, form);
}
}
}
function treateAllComposants() {
if (currentURL.indexOf("as_type=Compo") == -1) {
return;
}
// On récupère les composants
let categ = document.evaluate("count(//table/descendant::text()[contains(.,'Sans catégorie')])",
document, null, 0, null).numberValue;
let cat = categ == 0 ? 3 : 4;
let nodes = document.evaluate(`${"//a[starts-with(@href,'TanierePJ_o_Stock.php?IDLieu=') " +
"or starts-with(@href,'Comptoir_o_Stock.php?IDLieu=')]/following::table[@width = '100%']" +
"/descendant::tr[contains(td[1]/a/b/text(),']') and (" +
"td["}${cat}]/text()[1] = '\u0040-\u0040' ` +
`or contains(td[${cat}]/text()[2],'Tous les trolls') ` +
`or contains(td[${cat}]/text()[1],'Tous les trolls') ` +
`or (count(td[${cat}]/text()) = 1 and td[${cat}]/text()[1]='n°') ) ` +
`and td[1]/img/@alt = 'Identifié']`,
document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (nodes.snapshotLength == 0) {
// avertissement('treateAllComposants DOWN');
return;
}
let texte = "";
for (let i = 0; i < nodes.snapshotLength; i++) {
let n1 = nodes.snapshotItem(i).childNodes[1];
let n3 = nodes.snapshotItem(i).childNodes[3];
let debut = n1.childNodes[2].nodeValue.replace(/\n/g, '');
let prix = n3.childNodes[0].nodeValue;
if (!prix) {
if (n3.childNodes[3].getAttribute('value') && n3.childNodes[3].getAttribute('value') != "") {
prix = `${n3.childNodes[3].getAttribute('value')} GG'`;
}
} else {
prix = prix.replace(/[\240 ]/g, "");
if (prix == "-") {
prix = null;
}
}
if (prix) {
texte = `${texte}${debut.substring(debut.indexOf('[') + 1, debut.indexOf(']'))};${n1.childNodes[3].firstChild.nodeValue.replace(/\n/g, '')
}${n1.childNodes[3].childNodes[1].firstChild.nodeValue.replace(/\n/g, '')};${prix.replace(/\n/g, '')}\n`;
} else {
texte = `${texte}${debut.substring(debut.indexOf('[') + 1, debut.indexOf(']'))};${n1.childNodes[3].firstChild.nodeValue.replace(/\n/g, '')
}${n1.childNodes[3].childNodes[1].firstChild.nodeValue.replace(/\n/g, '')};pas défini\n`;
}
}
let t2 = document.evaluate("//div[@class = 'titre2']/text()",
document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
let id_taniere = t2.snapshotItem(0).nodeValue;
id_taniere = id_taniere.substring(id_taniere.indexOf('(') + 1, id_taniere.indexOf(')'));
// gath: 'getFormComboDB' is not defined
let form = getFormComboDB(currentURL.indexOf('MH_Taniere') != -1 ? 'taniere' : 'grande_taniere', id_taniere,
texte.replace(/\240/g, " ").replace(/d'un/g, "d un"), "Vendre tous les composants non réservés sur le Troc de l\'Hydre");
if (form) {
if (document.getElementsByTagName('form').length > 0) {
insertBefore(document.getElementsByTagName('form')[0].nextSibling, form);
} else {
let thisP = document.evaluate("//p/table/descendant::text()[contains(.,'Heure Serveur')]/../../../../..", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
insertBefore(thisP, form);
}
}
}
function treateEM() {
if (1) {
return;
} // Roule' 06/01/2017 ne fonctionne plus depuis.... longtemps
if (currentURL.indexOf("as_type=Compo") == -1) {
return false;
}
let urlImg = `${URL_MZimg}Competences/ecritureMagique.png`;
let nodes = document.evaluate("//tr[@class='mh_tdpage']"
, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (nodes.snapshotLength == 0) {
return false;
}
for (let i = 0; i < nodes.snapshotLength; i++) {
let desc = nodes.snapshotItem(i).getElementsByTagName('td');
let link = desc[2].firstChild;
let nomCompoTotal = desc[2].textContent;
let nomCompo = nomCompoTotal.substring(0, nomCompoTotal.indexOf(" d'un"));
nomCompoTotal = nomCompoTotal.substring(nomCompoTotal.indexOf("d'un"), nomCompoTotal.length);
let nomMonstre = trim(nomCompoTotal.substring(nomCompoTotal.indexOf(" ") + 1, nomCompoTotal.length - 1));
let locqual = desc[3].textContent;
let qualite = trim(locqual.substring(locqual.indexOf("Qualité:") + 9));
let localisation = trim(locqual.substring(0, locqual.indexOf("|") - 1));
// gath: 'isEM' is not defined
if (isEM(nomMonstre).length > 0) {
let infos = composantEM(nomMonstre, trim(nomCompo), localisation, getQualite(qualite));
if (infos.length > 0) {
let shortDescr = "Variable";
let bold = 0;
if (infos != "Composant variable") {
shortDescr = infos.substring(0, infos.indexOf(" "));
if (parseInt(shortDescr) >= 0) {
bold = 1;
}
}
link.parentNode.appendChild(createImage(urlImg, infos));
appendText(link.parentNode, ` [${shortDescr}]`, bold);
}
}
}
}
function treateChampi_tabcompo() {
if (currentURL.indexOf('as_type=Champi') == -1) {
return false;
}
let nodes = document.evaluate("//img[@alt = 'Identifié']/../a/text()[1]",
document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (nodes.snapshotLength == 0) {
return false;
}
for (let i = 0; i < nodes.snapshotLength; i++) {
let node = nodes.snapshotItem(i);
let nomChampi = trim(node.nodeValue.replace(/\240/g, ' '));
if (moisChampi[nomChampi]) { // gath: 'moisChampi' is not defined
appendText(node.parentNode.parentNode, ` [Mois ${moisChampi[nomChampi]}]`);
}
}
}
function treateEnchant() {
if (currentURL.indexOf("as_type=Compo") == -1) {
return false;
}
try {
if (!listeMonstreEnchantement) {
computeCompoEnchantement();
}
let nodes = document.evaluate(
"//a[starts-with(@href,'TanierePJ_o_Stock.php?IDLieu=') or starts-with(@href,'Comptoir_o_Stock.php?IDLieu=')]" +
"/following::table[@width = '100%']/descendant::tr[contains(td[1]/a/b/text(),']') " +
"and td[1]/img/@alt = 'Identifié']/td[1]/a", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (nodes.snapshotLength == 0) {
return false;
}
let urlImg = `${URL_MZimg}enchant.png`;
for (let i = 0; i < nodes.snapshotLength; i++) {
let link = nodes.snapshotItem(i);
let nomCompoTotal = link.firstChild.nodeValue;
let nomCompo = nomCompoTotal.substring(0, nomCompoTotal.indexOf(" d'un"));
nomCompoTotal = nomCompoTotal.substring(nomCompoTotal.indexOf("d'un"), nomCompoTotal.length);
let nomMonstre = nomCompoTotal.substring(nomCompoTotal.indexOf(" ") + 1, nomCompoTotal.length);
nomCompoTotal = link.childNodes[1].childNodes[0].nodeValue;
let qualite = nomCompoTotal.substring(nomCompoTotal.indexOf("de Qualité") + 11, nomCompoTotal.indexOf(" ["));
let localisation = nomCompoTotal.substring(nomCompoTotal.indexOf("[") + 1, nomCompoTotal.indexOf("]"));
if (isEnchant(nomMonstre).length > 0) {
let infos = composantEnchant(nomMonstre, nomCompo, localisation, getQualite(qualite));
if (infos.length > 0) {
link.parentNode.appendChild(createImage(urlImg, infos));
}
}
}
} catch (exc) {
avertissement(`Une erreur est survenue (treateEnchant)`, null, null, exc);
}
}
function treateEquipEnchant() {
if (currentURL.indexOf('as_type=Arme') == -1 && currentURL.indexOf('as_type=Armure') == -1) {
return false;
}
initPopupTabcompo();
computeEnchantementEquipement(createPopupImage_tabcompo, formateTexte_tabcompo);
}
function do_tancompo() {
start_script(undefined, 'do_tancompo_log');
treateAllComposants();
treateComposants();
traiteMinerai_tabcompo();
if (MY_getValue('NOINFOEM') != 'true') {
treateChampi_tabcompo();
treateEM();
}
if (MY_getValue(`${numTroll}.enchantement.liste`) && MY_getValue(`${numTroll}.enchantement.liste`) != '') {
treateEnchant();
treateEquipEnchant();
}
displayScriptTime(undefined, 'do_tancompo_log');
}
/** x~x pjView --------------------------------------------------------- */
/* TODO
* - MZ2.0 : Implémenter les BDD en dur dans le module interne
*/
var DivInfo; // Bulle d'infos
var freezed = false; // Booléen stockant l'état de freezing de la bulle
// liste du matos
// mh_caracs ['Nom'] = [ 'Type', 'AttP', 'AttM', 'DegP','DegM', 'Esq',
// 'ArmP','ArmM', 'Vue', 'Reg', 'RM_Min', 'RM_Max', 'MM_Min', 'MM_Max',
// 'PV', 'DLA', 'Poids_Min', 'Poids_Max' ];
var mh_caracs = {
'anneau de protection':
['anneau', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 3.00, 3.00],
"armure d'anneaux":
['armure', 0, 0, 0, 0, -4, 8, 0, 0, 0, 90, 180, 0, 0, 0, 0.00, 50.00, 50.00],
'armure de bois':
['armure', 0, 0, 0, 0, -3, 6, 0, 0, 0, 50, 100, 0, 0, 15, 0.00, 40.00, 40.00],
'armure de cuir':
['armure', 0, 0, 0, 0, 3, 4, 0, 0, 0, 40, 80, 0, 0, 0, 0.00, 10.00, 10.00],
'armure de peaux':
['armure', 0, 0, 0, 0, -3, 9, 0, 0, 0, 70, 140, 0, 0, 0, 0.00, 45.00, 45.00],
'armure de pierre':
['armure', 0, 0, 0, 0, -6, 12, 0, 0, 3, 75, 150, 0, 0, 0, 0.00, 75.00, 75.00],
'armure de plates':
['armure', 0, 0, 0, 0, -2, 10, 0, 0, 0, 50, 100, 0, 0, 0, 0.00, 62.50, 62.50],
'baton lesté':
['arme', 10, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 10.00, 10.00],
'bâtons de parade':
['arme', 0, -3, 0, -2, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 10.00, 10.00],
'bottes':
['bottes', 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 5.00, 5.00],
'bouclier à pointes':
['bouclier', 1, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 20.00, 20.00],
'boulet et chaîne':
['arme', -1, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 7.50, 7.50],
'cagoule':
['casque', 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 5, 10, 0, 0.00, 2.50, 2.50],
'casque à cornes':
['casque', 0, 0, 1, 0, 0, 3, 0, -1, 0, 5, 10, 0, 0, 0, 0.00, 5.00, 5.00],
'casque à pointes':
['casque', 1, 0, 1, 0, 0, 3, 0, -1, 0, 0, 0, 0, 0, 0, 0.00, 6.00, 6.00],
'casque en cuir':
['casque', 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 10, 0, 0, 0, 0.00, 5.00, 5.00],
'casque en métal':
['casque', 0, 0, 0, 0, 0, 2, 0, -1, 0, 5, 10, 0, 0, 0, 0.00, 5.00, 5.00],
'chaîne cloutée':
['arme', -2, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 35.00, 35.00],
'chapeau pointu':
['casque', 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 5, 10, 0, 0.00, 5.00, 5.00],
'collier de dents':
['talisman', 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.00, 1.00, 1.00],
'collier de pierre':
['talisman', 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 10, 5, 10, 0, 0.00, 2.50, 2.50],
'collier à pointes':
['talisman', 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 1.00, 1.00],
'cotte de mailles':
['armure', 0, 0, 0, 0, -1, 7, 0, 0, 0, 30, 60, 0, 0, 0, 0.00, 42.50, 42.50],
'couronne de cristal':
['casque', 0, 0, 0, 1, -1, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0.00, 10.00, 10.00],
"couronne d'obsidienne":
['casque', 0, 0, 0, 0, 0, 1, 2, 0, -1, 0, 0, 0, 0, 0, 0.00, 10.00, 10.00],
"coutelas d'obsidienne":
['arme', 2, 0, 3, 0, 2, 0, 0, 0, -2, -10, -5, -30, -15, 0, 0.00, 5.00, 5.00],
'coutelas en os':
['arme', 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 4.00, 4.00],
'crochet':
['arme', -1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 6.50, 6.50],
'cuir bouilli':
['armure', 0, 0, 0, 0, 1, 8, 0, 0, 0, 20, 40, 0, 0, 0, 0.00, 20.00, 20.00],
"cuirasse d'ossements":
['armure', 0, 0, 0, 0, -3, 6, 0, 0, 0, 50, 100, 20, 40, 0, 0.00, 40.00, 40.00],
"cuirasse d'écailles":
['armure', 0, 0, 0, 0, -1, 6, 0, 0, 0, 38, 70, 0, 0, 0, 0.00, 37.50, 37.50],
'culotte en cuir':
['armure', 0, 0, 0, 0, 5, 0, 0, 0, 0, 60, 120, 0, 0, 0, 0.00, 2.50, 2.50],
'dague':
['arme', 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 2.50, 2.50],
'epée courte':
['arme', 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 5.00, 5.00],
'epée longue':
['arme', -1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 12.50, 12.50],
'espadon':
['arme', -6, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 40.00, 40.00],
'fouet':
['arme', 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 7.50, 7.50],
'fourrures':
['armure', 0, 0, 0, 0, 2, 6, 0, 0, 0, 30, 60, 0, 0, 0, 0.00, 15.00, 15.00],
'gantelet':
['arme', -1, 0, 1, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 4.00, 4.00],
'gorgeron en cuir':
['talisman', 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 2.50, 2.50],
'gorgeron en métal':
['talisman', 0, 0, 0, 0, 0, 3, 0, 0, -1, 10, 20, 0, 0, 0, 0.00, 2.50, 2.50],
'gourdin':
['arme', 2, 0, 5, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 12.50, 12.50],
'gourdin clouté':
['arme', -1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 15.00, 15.00],
'grimoire':
['bouclier', 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 10, 0, 15.00, 10.00, 10.00],
"gros'porte":
['bouclier', 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 20, 0, 0, 0, 0.00, 30.00, 30.00],
'grosse racine':
['arme', 0, 0, 0, 0, -1, 2, 0, 0, 0, 5, 10, 0, 0, 5, 0.00, 20.00, 20.00],
'grosse stalagmite':
['arme', -20, 0, 28, 0, -15, 0, 0, -4, 0, 0, 0, 0, 0, 0, 0.00, 90.00, 90.00],
'hache de bataille':
['arme', -2, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 18.00, 18.00],
'hache de guerre en os':
['arme', 0, -2, 0, 6, 0, 0, 0, 0, 0, 0, 0, 15, 30, 0, 0.00, 25.00, 25.00],
'hache de guerre en pierre':
['arme', -10, 0, 14, 0, 0, 0, 0, 0, 0, 5, 10, 0, 0, 0, 0.00, 60.00, 60.00],
"hache à deux mains d'obsidienne":
['arme', -8, 0, 16, 0, 0, 0, 0, 0, -4, -90, -45, -30, -15, 0, 0.00, 75.00, 75.00],
'hallebarde':
['arme', -5, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 37.50, 37.50],
"haubert d'écailles":
['armure', 0, 0, 0, 0, -2, 8, 0, 0, 0, 40, 80, 0, 0, 0, 0.00, 25.00, 25.00],
'haubert de mailles':
['armure', 0, 0, 0, 0, -3, 9, 0, 0, 0, 70, 140, 0, 0, 0, 0.00, 55.00, 55.00],
'heaume':
['casque', -1, 0, 0, 0, 0, 4, 0, -2, 0, 10, 20, 0, 0, 0, 0.00, 13.00, 13.00],
'jambières en cuir':
['bottes', 0, 0, 0, 0, 1, 2, 0, 0, 0, 5, 10, 0, 0, 0, 0.00, 10.00, 10.00],
'jambières en fourrure':
['bottes', 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 10, 0, 0, 0, 0.00, 2.50, 2.50],
'jambières en maille':
['bottes', 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 10, 0, 0, 0, 0.00, 13.00, 13.00],
'jambières en métal':
['bottes', 0, 0, 0, 0, -1, 4, 0, 0, 0, 5, 10, 0, 0, 0, 0.00, 15.00, 15.00],
'jambières en os':
['bottes', 0, 0, 0, 0, -1, 2, 0, 0, 0, 5, 10, 5, 10, 0, 0.00, 10.00, 10.00],
"lame d'obsidienne":
['arme', 3, 0, 7, 0, 0, 0, 0, 0, -3, -60, -30, -20, -10, 0, 0.00, 20.00, 20.00],
'lame en os':
['arme', 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 5, 10, 0, 0.00, 8.00, 8.00],
'lame en pierre':
['arme', -1, 0, 4, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0.00, 20.00, 20.00],
'lorgnons':
['casque', 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 10, 0, 0.00, 1.00, 1.00],
'machette':
['arme', 1, 0, 2, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 13.00, 13.00],
"masse d'arme":
['arme', 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 8.00, 8.00],
'pagne de mailles':
['armure', 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 4, 4],
'pagne en cuir':
['armure', 0, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 5.00, 5.00],
'robe de mage':
['armure', 0, 0, 0, 0, 2, 1, 3, 0, 0, 10, 20, 10, 20, 0, 0.00, 20.00, 20.00],
'rondache en bois':
['bouclier', 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0.00, 15.00, 15.00],
'rondache en métal':
['bouclier', 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 18.00, 18.00],
'sandales':
['bottes', 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 2.50, 2.50],
'souliers dorés':
['bottes', 0, 0, 0, 0, -1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0.00, 10.00, 10.00],
"talisman d'obsidienne":
['talisman', 1, 0, 2, 0, 0, 0, 0, 0, -4, 20, 40, 20, 40, 0, 0.00, 2.50, 2.50],
'talisman de pierre':
['talisman', 0, 0, 0, 0, 0, 0, 0, 0, 2, 10, 20, 10, 20, 0, 0.00, 2.50, 2.50],
'targe':
['bouclier', 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00, 3.00, 3.00],
'torche':
['arme', 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0.00, 8.00, 8.00],
'torque de pierre':
['talisman', 0, 0, 0, 0, 0, 0, 0, 0, -2, 20, 40, 20, 40, 0, 0.00, 2.50, 2.50],
'tunique':
['armure', 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 10, 5, 10, 0, 0.00, 2.50, 2.50],
"tunique d'écailles":
['armure', 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 30, 0, 0, 0, 0.00, 8.00, 8.00],
'turban':
['casque', 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 30, 15, 30, 0, 0.00, 2.50, 2.50],
'Couronne de ronces':
['casque', 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5, 0, 5, 5],
'Oeil de sang':
['talisman', 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 10, 20, -5, 0, 3, 3],
'Pendentif incandescent':
['talisman', 0, -1, 0, -1, 3, 0, 0, 0, 0, 10, 20, 10, 20, 0, 0, 3, 3],
'Filet':
['arme', 0, -1, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10],
'Menhir':
['arme', -4, 0, 0, 0, -5, 10, 0, -3, 0, 20, 40, 0, 0, 0, 0, 50, 50],
'Baton de mage':
['arme', 0, 8, 0, -2, 0, 0, 0, 0, 0, 0, 0, 15, 30, 0, 0, 10, 10],
};
// liste des templates
// mh_templates['Nom'] = [ 'AttP', 'AttM', 'DegP', 'DegM', 'Esq',
// 'ArmP', 'ArmM', 'Vue', 'Reg', 'RM_Min', 'RM_Max', 'MM_Min', 'MM_Max',
// 'PV', 'DLA', 'Poids_Min', 'Poids_Max');
var mh_templates = {
'de Feu':
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'de Résistance':
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"de l'Aigle":
[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'de la Salamandre':
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
'des Cyclopes':
[0, 1, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'des Enragés':
[0, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'des Tortues':
[0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0],
'des Vampires':
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
'du Glacier':
[0, 1, 0, 0, 0, 0, 1, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0],
'du Rat':
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'du Roc':
[0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'du Temps':
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -30, 0, 0],
'du Vent':
[0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'en Mithril':
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'des Anciens':
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'des Champions':
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'des Duellistes':
[0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'de la Terre':
[0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 30, 0, 0],
"de l'Orage":
[0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"de l'Ours":
[0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 30, 0, 0],
'des Béhémoths':
[0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0],
'des Mages':
[0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0],
'du Pic':
[0, 0, 0, 0, -1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'du Sable':
[0, 0, 0, 0, 3, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'acéré':
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'acérée':
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'équilibré':
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'équilibrée':
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'léger':
[0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0],
'légère':
[0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0],
'renforcé':
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1.5, 0, 0],
'renforcée':
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1.5, 0, 0],
'robuste':
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1.5, 0, 0],
};
function clone(arr) {
// Clonage rapide
return arr.slice(0);
}
function addArray(arr1, arr2) {
// Somme matricielle
let res = clone(arr1);
for (let i = res.length - 1; i >= 0; i--) {
res[i] += arr2[i];
}
return res;
}
function getTemplates(nomItem) {
// Déstructure le nom de l'item en array [nom, template1, ...]
let tempFound = true;
let str = nomItem.trim();
let arr = [];
while (tempFound) {
tempFound = false;
for (let temp in mh_templates) {
// on teste la fin du nom contre chaque template
if (str.slice(-temp.length) != temp) {
continue;
}
tempFound = true;
str = str.slice(0, -temp.length - 1);
arr.unshift(temp);
if (str.slice(-3) == ' et') {
str = str.slice(0, -3);
}
}
}
arr.unshift(str);
return arr;
}
function addMithril(arrayCaracs, typeItem) {
// Ajoute l'effet du Mithril sur les caracs
return arrayCaracs; // il n'y a plus de modif des caracs
// on garde la suite, si jamais ça revenait
/*
if (typeItem == 'arme') {
if (arrayCaracs[0] < 0) {
arrayCaracs[0] = Math.ceil(arrayCaracs[0] / 2);
}
} else if (arrayCaracs[4] < 0) {
arrayCaracs[4] = Math.ceil(arrayCaracs[4] / 2);
}
arrayCaracs[15] = arrayCaracs[15] / 2;
arrayCaracs[16] = arrayCaracs[16] / 2;
return arrayCaracs;
*/
}
function addRenfort(arrayCaracs, template) {
// Ajoute l'effet des pseudo-templates sur les caracs
// S'applique APRÈS le mithril
// WARNING - Cette formule n'a rien d'officiel, gare !
let coef = 0;
if ((/^lég[e,è]re?$/).test(template)) {
coef = -1;
} else if ((/^renforcée?$/).test(template) ||
template === 'robuste') {
coef = 1;
}
if (coef) {
arrayCaracs[15] = arrayCaracs[15] + coef * Math.floor(arrayCaracs[15] / 10);
arrayCaracs[16] = arrayCaracs[16] + coef * Math.floor(arrayCaracs[16] / 10);
}
arrayCaracs = addArray(arrayCaracs, mh_templates[template]);
return arrayCaracs;
}
function getCaracs(item) {
// Calcule les caractéristiques de l'item
let templates = getTemplates(item);
if (!mh_caracs[templates[0]]) {
// Si l'item est inconnu
return [];
}
let caracs = clone(mh_caracs[templates[0]]);
let typeItem = caracs[0];
caracs.shift();
templates.shift();
if (templates[templates.length - 1] == 'en Mithril') {
caracs = addMithril(caracs, typeItem);
templates.pop();
}
if ((/^acérée?$/).test(templates[0]) ||
(/^équilibrée?$/).test(templates[0]) ||
(/^lég[e,è]re?$/).test(templates[0]) ||
(/^renforcée?$/).test(templates[0]) ||
templates[0] == 'robuste') {
caracs = addRenfort(caracs, templates[0]);
templates.shift();
}
for (let i = templates.length - 1; i >= 0; i--) {
caracs = addArray(caracs, mh_templates[templates[i]]);
}
return caracs;
}
function getLine(tab) {
// Préparation de la ligne à afficher lors d'un mouseover
let str = '';
if (tab[0] != 0 || tab[1] != 0) {
str = `${str}<b>Att : </b>${aff(tab[0])}`;
if (tab[1] != 0) {
str = `${str}/${aff(tab[1])}`;
}
str = `${str} | `;
}
if (tab[4] != 0) {
str = `${str}<b>Esq : </b>${aff(tab[4])} | `;
}
if (tab[2] != 0 || tab[3] != 0) {
str = `${str}<b>Deg : </b>${aff(tab[2])}`;
if (tab[3] != 0) {
str = `${str}/${aff(tab[3])}`;
}
str = `${str} | `;
}
if (tab[8] != 0) {
str = `${str}<b>Reg : </b>${aff(tab[8])} | `;
}
if (tab[7] != 0) {
str = `${str}<b>Vue : </b>${aff(tab[7])} | `;
}
if (tab[5] != 0 || tab[6] != 0) {
str = `${str}<b>Arm : </b>${aff(tab[5])}`;
if (tab[6] != 0) {
str = `${str}/${aff(tab[6])}`;
}
str = `${str} | `;
}
if (tab[9] != 0 || tab[10] != 0) {
str = `${str}<b>RM : </b>${aff(tab[9])}%`;
if (tab[9] != tab[10]) {
str = `${str}/${aff(tab[10])}%`;
}
str = `${str} | `;
}
if (tab[11] != 0 || tab[12] != 0) {
str = `${str}<b>MM : </b>${aff(tab[11])}%`;
if (tab[11] != tab[12]) {
str = `${str}/${aff(tab[12])}%`;
}
str = `${str} | `;
}
if (tab[13] != 0) {
str = `${str}<b>PV : </b>${aff(tab[13])} | `;
}
if (tab[14] != 0) {
str = `${str}<b>DLA : </b>${aff(tab[14])} min | `;
}
str = `${str}<b>Poids : </b>${tab[15]} min`;
if (tab[15] != tab[16]) {
str = `${str} / ${tab[16]} min`;
}
return str;
}
function toolTipInit() {
DivInfo = document.createElement('div');
DivInfo.id = 'infosVue';
DivInfo.className = 'mh_textbox';
DivInfo.style =
'position: absolute;' +
'visibility:hidden;' +
'display:inline;' +
'z-index:99;';
document.body.appendChild(DivInfo);
document.onmousemove = getXY;
document.onclick = changeFreezeStatus;
}
function getXY(evt) {
if (!freezed && DivInfo.style.visibility == 'visible') {
DivInfo.style.left = `${evt.pageX}px`;
DivInfo.style.top = `${evt.pageY + 10}px`;
}
}
function changeFreezeStatus() {
if (DivInfo.style.visibility == 'visible') {
freezed = !freezed;
if (!freezed) {
hideInfos();
}
}
}
function showInfos() {
if (freezed) {
return;
}
let currentInfos = this.infos;
DivInfo.innerHTML = currentInfos;
DivInfo.style.visibility = 'visible';
let compStyles = window.getComputedStyle(DivInfo);
if (compStyles.getPropertyValue('background-color') == 'rgba(0, 0, 0, 0)') {
DivInfo.style.backgroundColor = 'rgb(255, 255, 238)';
}
}
function hideInfos() {
if (!freezed) {
DivInfo.style.visibility = 'hidden';
}
}
function treateEquipement() {
// Extrait les données du matos et réinjecte les infos déduites
if (MY_getValue('INFOCARAC') == 'false') {
return;
}
let faireLigne = false;
let caracs = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let nodes = document.evaluate(
"//td/b[text()='Equipement Utilisé']/../../" +
"td[2]/img[contains(@src,bullet)]",
document, null, 7, null);
if (nodes.snapshotLength > 0) {
// Si CSS de base
for (let i = 0; i < nodes.snapshotLength; i++) {
let node = nodes.snapshotItem(i);
let next = node.nextSibling;
let nnext = next.nextSibling;
let nom = next.nodeValue.toLowerCase();
if (nnext.childNodes.length == 1) {
nom = nom + nnext.firstChild.nodeValue;
}
nom = nom.trim();
// gestion winpostrophe
let c = String.fromCharCode(180);
while (nom.indexOf(c) != -1) {
nom = nom.replace(c, "'");
}
let arr = getCaracs(nom);
if (arr.length > 0) {
faireLigne = true;
caracs = addArray(caracs, arr);
let span = document.createElement('span');
span.appendChild(next);
span.appendChild(nnext);
span.infos = getLine(arr);
span.onmouseover = showInfos;
span.onmouseout = hideInfos;
insertBefore(node.nextSibling, span);
}
}
if (faireLigne) {
let node = document.evaluate("//td/b[text()='Equipement Utilisé']",
document, null, 9, null).singleNodeValue;
node.infos = getLine(caracs);
node.onmouseover = showInfos;
node.onmouseout = hideInfos;
}
} else {
// Si CSS avancée
nodes = document.evaluate("//dd[@class='equipement']/ul/li",
document, null, 7, null);
if (nodes.snapshotLength > 0) {
for (let i = 0; i < nodes.snapshotLength; i++) {
let node = nodes.snapshotItem(i);
let nom = node.firstChild.nodeValue.toLowerCase();
if (node.childNodes.length > 1 && node.childNodes[1].firstChild) {
nom = nom + node.childNodes[1].firstChild.nodeValue;
}
nom = nom.trim();
// gestion winpostrophe
let c = String.fromCharCode(180);
while (nom.indexOf(c) != -1) {
nom = nom.replace(c, "'");
}
let arr = getCaracs(nom);
if (arr.length != 0) {
caracs = addArray(caracs, arr);
node.infos = getLine(arr);
node.onmouseover = showInfos;
node.onmouseout = hideInfos;
}
}
nodes = document.evaluate("//dt[@class='equipement']",
document, null, 7, null);
let node = nodes.snapshotItem(0);
node.infos = getLine(caracs);
node.onmouseover = showInfos;
node.onmouseout = hideInfos;
}
}
}
function do_pjview() {
treateEquipement();
toolTipInit();
}
/** x~x Option --------------------------------------------------------- */
/* TODO
* Passer le HTML injecté aux conventions HTML5
*/
/** x~x Fonctions de sauvegarde ---------------------------------------- */
function saveITData() {
let IT = document.getElementById('itSelect').value;
let nBricol = 1;
if (IT == 'bricol') {
for (let iBricol = 0; ; iBricol++) {
let extClef = nBricol == 1 ? '' : nBricol;
let eltSystem = document.getElementById(`urlbricol${iBricol}`);
if (eltSystem == undefined) {
break;
}
let system = eltSystem.value;
let login = document.getElementById(`loginbricol${iBricol}`).value;
let pass = document.getElementById(`passbricol${iBricol}`).value;
let affhv = document.getElementById('affhvbricol').checked ? 1 : 0;
if (system && login) {
if (pass) {
let v = `bricol$${system}$${login}$${hex_md5(pass)}$${affhv}`;
MY_setValue(`${numTroll}.INFOSIT${extClef}`, v);
logMZ(`saveITData() save ${numTroll}.INFOSIT${extClef}`);
} else {
// vérif que rien n'a changé
let str = MY_getValue(`${numTroll}.INFOSIT${extClef}`);
if (str) {
let arr = str.split('$');
if (system != arr[1] || login != arr[2] || affhv != arr[4]) {
window.alert(`Attention, système tactique Bricol'Trolls ${system} sans mot de passe => non modifié`);
}
}
}
nBricol++;
}
}
} else {
for (let iBricol = 1; ; iBricol++) {
let extClef = nBricol == 1 ? '' : iBricol;
let sInfo = MY_getValue(`${numTroll}.INFOSIT${extClef}`);
if (!sInfo) {
break;
}
MY_removeValue(`${numTroll}.INFOSIT${extClef}`);
logMZ(`saveITData() remove ${numTroll}.INFOSIT${extClef}`);
nBricol++;
}
}
}
function saveLinks() {
let numLinks = document.getElementById('linksBody').childNodes.length;
let data = [[]];
/* Récupération et tri des liens */
for (let i = 1; i <= numLinks; i++) {
MY_removeValue(`URL${i}`);
MY_removeValue(`URL${i}.nom`);
MY_removeValue(`URL${i}.ico`);
let url = document.getElementById(`url${i}`).value;
let nom = document.getElementById(`nom${i}`).value;
let ico = document.getElementById(`ico${i}`).value;
if (url && (nom || ico)) {
data.push([url, nom ? nom : '', ico ? ico : '']);
}
}
/* Sauvegarde */
for (let i = 1; i < data.length; i++) {
MY_setValue(`URL${i}`, data[i][0]);
MY_setValue(`URL${i}.nom`, data[i][1]);
MY_setValue(`URL${i}.ico`, data[i][2]);
}
}
function saveAll() {
try {
let urlIco = document.getElementById('icoMenuIco').value;
if (urlIco) {
MY_setValue(`${numTroll}.ICOMENU`, urlIco);
} else {
MY_removeValue(`${numTroll}.ICOMENU`, urlIco);
document.getElementById('icoMenuIco').value = '';
}
saveLinks();
refreshLinks();
MZ_setOrRemoveValue('VUEEXT', document.getElementById('vueext').value);
let maxcdm = parseInt(document.getElementById('maxcdm').value);
if (maxcdm) {
MZ_setOrRemoveValue(`${numTroll}.MAXCDM`, maxcdm);
} else {
MY_removeValue(`${numTroll}.MAXCDM`);
document.getElementById('maxcdm').value = '';
}
MZ_setOrRemoveValue('NOINFOEM', document.getElementById('noInfoEM').checked);
MZ_setOrRemoveValue('HIGHLIGHTSAMEXYN', document.getElementById('highlightSameXYN').checked);
MZ_setOrRemoveValue('HIGHLIGHTSAMEXYNCOORDSONLY', document.getElementById('highlightSameXYNCoordsOnly').checked);
// Pourquoi Tilk stockait-il tout en str ?
// -> parce que les booléens c'est foireux (vérifié)
MZ_setOrRemoveValue(`${numTroll}.USECSS`, document.getElementById('usecss').checked);
MZ_setOrRemoveValue('INFOCARAC', document.getElementById('infocarac').checked);
// MY_setValue(numTroll+'.SEND_IDT', document.getElementById('send_idt').checked);
// Fonctionnalité désactivée
MZ_setOrRemoveValue(`${numTroll}.AUTOCDM`, document.getElementById('autoCdM').checked);
// MY_setValue('VUECARAC', // Roule 12/12/2019 ça ne fait plus rien
// document.getElementById('vueCarac').checked ? 'true' : 'false');
MZ_setOrRemoveValue('PRINTSTACK', document.getElementById('printstack').checked);
MZ_setOrRemoveValue('CONFIRMEDECALAGE', document.getElementById('confirmeDecalage').checked);
MZ_setOrRemoveValue('COMPTEAREBOURSDLA', document.getElementById('compteAreboursDLA').checked);
MZ_setOrRemoveValue('COMPTEAREBOURSTITRE', document.getElementById('compteAreboursTitre').checked);
//MZ_setOrRemoveValue('COMPTEAREBOURSSUIVANTE', document.getElementById('compteAreboursSuivante').checked);
MZ_setOrRemoveValue('MZ_SuivantsOrdres', document.getElementById('MZ_SuivantsOrdres').value);
MZ_setOrRemoveValue('MZ_SuivantsCompress', document.getElementById('MZ_SuivantsCompress').checked);
MZ_setOrRemoveValue('MZ_SuivantsTresUnique', document.getElementById('MZ_SuivantsTresUnique').checked);
/* SCIZ */
let sciz_jwt = document.getElementById('sciz_jwt').value;
if (sciz_jwt !== null && sciz_jwt !== undefined) {
sciz_jwt = sciz_jwt.replace(new RegExp('[^a-zA-Z0-9\._\-]', 'g'), '');
MY_setValue(`${numTroll}.SCIZJWT`, sciz_jwt);
}
let sciz_cb_events = document.getElementById('sciz_cb_events').checked;
sciz_cb_events = sciz_cb_events !== null ? sciz_cb_events : true;
MY_setValue(`${numTroll}.SCIZ_CB_EVENTS`, sciz_cb_events);
let sciz_cb_view_treasures = document.getElementById('sciz_cb_view_treasures').checked;
sciz_cb_view_treasures = sciz_cb_view_treasures !== null ? sciz_cb_view_treasures : true;
MY_setValue(`${numTroll}.SCIZ_CB_VIEW_TREASURES`, sciz_cb_view_treasures);
let sciz_cb_view_mushrooms = document.getElementById('sciz_cb_view_mushrooms').checked;
sciz_cb_view_mushrooms = sciz_cb_view_mushrooms !== null ? sciz_cb_view_mushrooms : true;
MY_setValue(`${numTroll}.SCIZ_CB_VIEW_MUSHROOMS`, sciz_cb_view_mushrooms);
let sciz_cb_bestiaire = document.getElementById('sciz_cb_bestiaire').checked;
sciz_cb_bestiaire = sciz_cb_bestiaire !== null ? sciz_cb_bestiaire : true;
MY_setValue(`${numTroll}.SCIZ_CB_BESTIAIRE`, sciz_cb_bestiaire);
let sciz_cb_view_trolls = document.getElementById('sciz_cb_view_trolls').checked;
sciz_cb_view_trolls = sciz_cb_view_trolls !== null ? sciz_cb_view_trolls : true;
MY_setValue(`${numTroll}.SCIZ_CB_VIEW_TROLLS`, sciz_cb_view_trolls);
let sciz_cb_view_user = document.getElementById('sciz_cb_view_user').checked;
sciz_cb_view_user = sciz_cb_view_user !== null ? sciz_cb_view_user : true;
MY_setValue(`${numTroll}.SCIZ_CB_VIEW_USER`, sciz_cb_view_user);
let sciz_cb_view_traps = document.getElementById('sciz_cb_view_traps').checked;
sciz_cb_view_traps = sciz_cb_view_traps !== null ? sciz_cb_view_traps : true;
MY_setValue(`${numTroll}.SCIZ_CB_VIEW_TRAPS`, sciz_cb_view_traps);
let sciz_cb_view_portals = document.getElementById('sciz_cb_view_portals').checked;
sciz_cb_view_portals = sciz_cb_view_portals !== null ? sciz_cb_view_portals : true;
MY_setValue(`${numTroll}.SCIZ_CB_VIEW_PORTALS`, sciz_cb_view_portals);
saveITData();
} catch (exc) {
let bouton = document.getElementById('saveAll');
logMZ('saveAll()', exc);
bouton.value = "il y a eu une erreur";
return;
}
let bouton = document.getElementById('saveAll');
bouton.value = bouton.value == 'Sauvegardé !' ? 'Re-sauvegardé !' : 'Sauvegardé !';
}
/** x~x EventListeners ------------------------------------------------- */
function addBricolIT(sSystem, sLogin, nAffhv, bFirst, bLast) {
let itBody = document.getElementById('itBody');
let nTr = itBody.rows.length;
// enlever tous les "+" des lignes précédentes
for (let iTr = 0; iTr < nTr; iTr++) {
let td = itBody.rows[iTr].cells[0];
td.innerHTML = '';
td.title = '';
td.style.cursor = 'default';
}
// ajouter une ligne
let tr = appendTr(itBody, 'mh_tdpage');
let td = appendTd(tr);
if (bLast) {
td.style.whiteSpace = 'nowrap';
appendText(td, '(+)');
td.style.cursor = 'pointer';
td.title = 'Cliquer ici pour ajouter un autre système Bricol\'Troll';
td.onclick = function (e) {
addBricolIT(undefined, undefined, undefined, false, true);
};
}
td = appendTd(tr);
td.style.whiteSpace = 'nowrap';
appendText(td, 'Nom du système : ');
appendTextbox(td, 'text', 'urlbricol', 20, 50, sSystem, `urlbricol${nTr}`);
td = appendTd(tr);
td.style.whiteSpace = 'nowrap';
appendText(td, 'Login du compte : ');
appendTextbox(td, 'text', 'loginbricol', 20, 50, sLogin, `loginbricol${nTr}`);
td = appendTd(tr);
td.style.whiteSpace = 'nowrap';
appendText(td, 'Mot de passe du compte : ');
appendTextbox(td, 'password', 'passbricol', 20, 50, undefined, `passbricol${nTr}`);
td = appendTd(tr);
if (bFirst) {
td.style.whiteSpace = 'nowrap';
appendText(td, 'Affichage des Trõlls hors vue : ');
appendCheckBox(td, 'affhvbricol', nAffhv > 0);
}
}
function onChangeIT() {
let IT = document.getElementById('itSelect').value;
let itBody = document.getElementById('itBody');
itBody.innerHTML = '';
let tabStr = new Array();
if (IT == 'bricol') {
for (let iBricol = 1; ; iBricol++) {
let str = MY_getValue(`${numTroll}.INFOSIT${iBricol == 1 ? '' : iBricol}`);
// logMZ('onChangeIT str=' + str);
if (!str) {
break;
}
tabStr.push(str);
}
if (tabStr.length == 0) {
addBricolIT('', '', 0, true, true);
} else {
for (let iBricol = 0; iBricol < tabStr.length; iBricol++) {
let arr = tabStr[iBricol].split('$');
let system = arr[1];
let login = arr[2];
let affhv = arr[4];
addBricolIT(system, login, affhv, iBricol == 0, iBricol == tabStr.length - 1);
}
}
}
}
function refreshLinks() {
document.getElementById('linksBody').innerHTML = '';
let anotherURL = MY_getValue('URL1');
if (!anotherURL) {
addLinkField();
}
let i = 1;
while (anotherURL && i < 99) {
addLinkField(i, anotherURL,
MY_getValue(`URL${i}.nom`), MY_getValue(`URL${i}.ico`));
i++;
anotherURL = MY_getValue(`URL${i}`);
}
}
function addLinkField(i, url, nom, ico) {
let linksBody = document.getElementById('linksBody');
if (!(i > 0)) {
i = linksBody.childNodes.length + 1;
}
let tr = appendTr(linksBody);
let td = appendTdCenter(tr);
appendText(td, `Lien ${i} : `);
appendTextbox(td, 'text', `url${i}`, 40, 150, url);
td = appendTdCenter(tr);
appendText(td, 'Nom : ');
appendTextbox(td, 'text', `nom${i}`, 20, 150, nom);
td = appendTdCenter(tr);
appendText(td, 'Icône : ');
appendTextbox(td, 'text', `ico${i}`, 40, 150, ico);
}
function removeLinkField() {
let linksBody = document.getElementById('linksBody');
let i = linksBody.childNodes.length;
MY_removeValue(`URL${i}`);
MY_removeValue(`URL${i}.nom`);
MY_removeValue(`URL${i}.ico`);
linksBody.removeChild(linksBody.lastChild);
if (linksBody.childNodes.length == 0) {
addLinkField();
}
}
function resetMainIco() {
document.getElementById('icoMenuIco').value = `${URL_MZimg}mz_logo_small.png`;
}
/** x~x Fonctions d'insertion ------------------------------------------ */
function insertTitle(next, txt) {
let div = document.createElement('div');
div.className = isDesktopView() ? 'titre2' : 'ui-bar-b ui-corner-top';
appendText(div, txt);
insertBefore(next, div);
return div;
}
function insertMainTable(next) {
let table = document.createElement('table');
table.border = 0;
table.align = 'center';
table.cellPadding = 2;
table.cellSpacing = 1;
table.className = isDesktopView() ? 'mh_tdborder' : 'ui-body-a ui-corner-bottom';
let tbody = document.createElement('tbody');
table.appendChild(tbody);
if (isDesktopView()) {
table.style.maxWidth = '98%'
insertBefore(next, table);
} else {
let div = document.createElement('div');
div.style.overflowX = "scroll";
div.appendChild(table);
insertBefore(next, div);
}
return tbody;
}
function appendSubTable(node) {
let table = document.createElement('table');
table.width = '100%';
let tbody = document.createElement('tbody');
table.appendChild(tbody);
node.appendChild(table);
return tbody;
}
function insertOptionTable(insertPt) {
let mainBody = insertMainTable(insertPt);
/* Liens dans le Menu */
let tr = appendTr(mainBody, 'mh_tdtitre');
let td = appendTdText(tr, 'Hyperliens ajoutés dans le Menu :', true);
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
appendText(td, 'Icône du Menu: ');
let url = MY_getValue(`${numTroll}.ICOMENU`);
if (!url || url.indexOf('mountyzilla.tilk.info/scripts_0.9/images/MY_logo_small') > 0) {
url = `${URL_MZimg}mz_logo_small.png`;
}
appendTextbox(td, 'text', 'icoMenuIco', 50, 200, url);
appendButton(td, 'Réinitialiser', resetMainIco);
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
let tbody = appendSubTable(td);
tbody.id = 'linksBody';
refreshLinks();
td = appendTdCenter(appendTr(mainBody, 'mh_tdpage'));
appendButton(td, 'Ajouter', addLinkField);
appendButton(td, 'Supprimer', removeLinkField);
/* Options de la Vue : vue externe, nb de CdM, etc */
tr = appendTr(mainBody, 'mh_tdtitre');
appendTdText(tr, 'Options de la Vue :', true);
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
tbody = appendSubTable(td);
tr = appendTr(tbody);
td = appendTdText(tr, 'Vue externe : ');
let select = document.createElement('select');
select.id = 'vueext';
td.appendChild(select);
let listeVues2D = [
'Bricol\' Vue',
'Vue du CCM',
'Vue Gloumfs 2D',
'Vue Gloumfs 3D',
'Grouky Vue!'
];
for (let i = 0; i < listeVues2D.length; i++) {
appendOption(select, listeVues2D[i], listeVues2D[i]);
}
if (MY_getValue('VUEEXT')) {
select.value = MY_getValue('VUEEXT');
}
td = appendTd(tr);
appendCheckBoxBlock(td, 'noInfoEM', "Masquer les informations à propos de l'écriture magique", MY_getValue('NOINFOEM') == 'true');
tr = appendTr(tbody);
td = appendTdText(tr, 'Nombre de CdM automatiquement récupérées : ');
appendTextbox(td, 'text', 'maxcdm', 5, 10, MY_getValue(`${numTroll}.MAXCDM`));
td = appendTd(tr);
appendCheckBoxBlock(td, 'usecss', 'Utiliser la CSS pour les couleurs de la diplomatie', MY_getValue(`${numTroll}.USECSS`) == 'true');
tr = appendTr(tbody);
td = appendTd(tr);
appendCheckBoxBlock(td, 'highlightSameXYN', "Réhausse des lignes de tableau", MY_getValue('HIGHLIGHTSAMEXYN') == 'true');
appendCheckBoxBlock(td, 'highlightSameXYNCoordsOnly', "uniquement au survol des coordonnées", MY_getValue('HIGHLIGHTSAMEXYNCOORDSONLY') == 'true');
/* Interface Tactique */
td = appendTd(appendTr(mainBody, 'mh_tdtitre'));
appendText(td, 'Interface Tactique : ', true);
select = document.createElement('select');
select.id = 'itSelect';
appendOption(select, 'none', 'Aucune');
appendOption(select, 'bricol', 'Système Tactique des Bricol\'Trolls');
// seule interface supportée !
td.appendChild(select);
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
tbody = appendSubTable(td);
tbody.id = 'itBody';
select.onchange = onChangeIT;
let str = MY_getValue(`${numTroll}.INFOSIT`);
if (str) {
select.value = str.slice(0, str.indexOf('$'));
onChangeIT();
}
/* SCIZ */
// JWT
td = appendTd(appendTr(mainBody, 'mh_tdtitre'));
appendText(td, 'SCIZ :', true);
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
td = appendTdText(td, 'JWT : ');
appendTextbox(td, 'text', 'sciz_jwt', 150, 500, MY_getValue(`${numTroll}.SCIZJWT`));
// Event checkbox
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
tbody = appendSubTable(td);
tr = appendTr(tbody);
td = appendTd(tr);
td.setAttribute('align', 'center');
appendCheckBoxBlock(td, 'sciz_cb_events', 'Surcharger les événements', [null, '1'].includes(MY_getValue(`${numTroll}.SCIZ_CB_EVENTS`)));
// Bestiaire checkbox
td = appendTd(tr);
td.setAttribute('align', 'center');
appendCheckBoxBlock(td, 'sciz_cb_bestiaire', 'Afficher les données du bestiaire', [null, '1'].includes(MY_getValue(`${numTroll}.SCIZ_CB_BESTIAIRE`)));
// Treasures checkbox
td = appendTd(tr);
td.setAttribute('align', 'center');
appendCheckBoxBlock(td, 'sciz_cb_view_treasures', 'Afficher les trésors identifiés', [null, '1'].includes(MY_getValue(`${numTroll}.SCIZ_CB_VIEW_TREASURES`)));
// Mushrooms checkbox
td = appendTd(tr);
td.setAttribute('align', 'center');
appendCheckBoxBlock(td, 'sciz_cb_view_mushrooms', 'Afficher les champignons identifiés', [null, '1'].includes(MY_getValue(`${numTroll}.SCIZ_CB_VIEW_MUSHROOMS`)));
// Trolls data checkbox
td = appendTd(tr);
td.setAttribute('align', 'center');
appendCheckBoxBlock(td, 'sciz_cb_view_trolls', 'Afficher les données des trolls', [null, '1'].includes(MY_getValue(`${numTroll}.SCIZ_CB_VIEW_TROLLS`)));
// User data checkbox
td = appendTd(tr);
td.setAttribute('align', 'center');
appendCheckBoxBlock(td, 'sciz_cb_view_user', 'S\'afficher soi-même', [null, '1'].includes(MY_getValue(`${numTroll}.SCIZ_CB_VIEW_USER`)));
// Traps checkbox
td = appendTd(tr);
td.setAttribute('align', 'center');
appendCheckBoxBlock(td, 'sciz_cb_view_traps', 'Afficher les pièges', [null, '1'].includes(MY_getValue(`${numTroll}.SCIZ_CB_VIEW_TRAPS`)));
// Portals checkbox
td = appendTd(tr);
td.setAttribute('align', 'center');
appendCheckBoxBlock(td, 'sciz_cb_view_portals', 'Afficher les destinations de portails', [null, '1'].includes(MY_getValue(`${numTroll}.SCIZ_CB_VIEW_PORTALS`)));
/* Options diverses */
td = appendTd(appendTr(mainBody, 'mh_tdtitre'));
appendText(td, 'Options diverses :', true);
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
appendCheckBoxBlock(td, 'infocarac', 'Afficher les caractéristiques des équipements des autres Trõlls', MY_getValue('INFOCARAC') != 'false');
/* td = appendTd(appendTr(mainBody,'mh_tdpage'));
appendCheckBox(td,'send_idt',MY_getValue(numTroll+'.SEND_IDT') != 'non')
appendText(td,' Envoyer les objets identifiés au système de stats');*/
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
appendCheckBoxBlock(td, 'autoCdM', 'Envoyer automatiquement les CdM vers la base MountyZilla', MY_getValue(`${numTroll}.AUTOCDM`) == 'true');
// td = appendTd(appendTr(mainBody,'mh_tdpage')); // Roule 12/12/2019 ça ne fait plus rien
// appendCheckBox(td,'vueCarac',MY_getValue('VUECARAC')=='true');
// appendText(td,' Afficher la Vue avec les caractéristiques dans le Profil');
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
appendCheckBoxBlock(td, 'printstack', "Joindre les rapports d'erreurs aux avertissements", MY_getValue('PRINTSTACK') == 'true');
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
appendCheckBoxBlock(td, 'confirmeDecalage', "Demander confirmation lors d'un décalage de DLA", MY_getValue('CONFIRMEDECALAGE') == 'true');
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
appendCheckBoxBlock(td, 'compteAreboursDLA', 'Compte à rebours de DLA', MY_getValue('COMPTEAREBOURSDLA') == 'true');
appendCheckBoxBlock(td, 'compteAreboursTitre', 'Aussi dans le titre (pas sur smartphone)', MY_getValue('COMPTEAREBOURSTITRE') == 'true');
//appendCheckBoxBlock(td, 'compteAreboursSuivante', 'Aussi pour la DLA suivante', MY_getValue('COMPTEAREBOURSSUIVANTE') == 'true');
td = appendTd(appendTr(mainBody, 'mh_tdpage'));
appendText(td, 'Page des suivants : ');
let e = appendTextboxBlock(td, 'text', 'MZ_SuivantsOrdres', 'Ordres', 3, 3, MY_getValue('MZ_SuivantsOrdres'), undefined, true);
e.setAttribute('Title', "Permet de voir les ordres des Gowaps dans la page des suivants\n" +
"Vide : pas d'affichage\n" +
"0 : tous les ordres\n" +
"1 à 99 : limité à ce nombre\n" +
"-1 : jusqu'à Arrêt, Ramassage, Ébrouage, Suivre");
e = appendCheckBoxBlock(td, 'MZ_SuivantsCompress', 'Vue compressée', MY_getValue('MZ_SuivantsCompress') == 'true');
e.setAttribute('Title', 'Permet de réduire la longueur de la page pour beaucoup de suivants\nSupprime "Aucune équipement sur ce suivant"');
e = appendCheckBoxBlock(td, 'MZ_SuivantsTresUnique', 'Aff. trésors uniques', MY_getValue('MZ_SuivantsTresUnique') == 'true');
e.setAttribute('Title', "Permet de rémplacer la liste par le trésor unique s'il n'y en a qu'un dans une catégorie\nTrès pratique pour les Gowaps qui ne portent qu'un trésor");
/* Bouton SaveAll */
td = appendTdCenter(appendTr(mainBody, 'mh_tdtitre'));
let input = appendButton(td, 'Sauvegarder', saveAll);
input.id = 'saveAll';
}
function insertCreditsTable(insertPt) {
let tbody = insertMainTable(insertPt);
let td = appendTdText(appendTr(tbody, 'mh_tdtitre'),
'Depuis son origine, nombreux sont ceux qui ont contribué à faire ' +
'de MountyZilla ce qu\'il est aujourd\'hui. Merci à eux !');
let ul = document.createElement('ul');
td.appendChild(ul);
appendLi(ul, 'Tilk (36216), puis Dabihul (79738) pour avoir créé puis maintenu à bout de bras MZ pendant des années');
appendLi(ul, 'Fine fille (6465) pour les popup javascript');
appendLi(ul, 'Reivax (4234) pour les infos bulles');
appendLi(ul, 'Noc (2770) pour les moyennes des caracs');
appendLi(ul, 'Endymion (12820) pour les infos sur les comp/sorts');
appendLi(ul, 'Ratibus (15916) pour l\'envoi de CdM');
appendLi(ul, 'TetDure (41931) pour les PVs restants dans les CdM');
appendLi(ul, 'Les Teubreux pour leur bestiaire !');
appendLi(ul, 'Les développeurs de vue qui font des efforts pour s\'intégrer à Mountyzilla');
appendLi(ul, 'Gros Kéké (233) qui permet de tester le script aux limites du raisonnable avec sa vue de barbare');
appendLi(ul, 'Ashitaka (9485) pour le gros nettoyage de l\'extension, des scripts, et beaucoup de choses à venir');
appendLi(ul, 'Tous ceux de l\'ancienne génération oubliés par Tilk');
appendLi(ul, 'Zorya (28468), Vapulabehemot (82169), Breizhou13 (50233) et tous les participants au projet ZoryaZilla');
appendLi(ul, 'Yoyor (87818) pour diverses améliorations de code');
appendLi(ul, 'Rokü Menton-brûlant (108387) pour avoir incité à passer sur GitHub');
appendLi(ul, 'Marmotte (93138) pour son support technique récurrent');
appendLi(ul, 'Hennet (74092) pour le script du nouveau profil');
appendLi(ul, 'Raistlin (61214, 109327) pour le script sur les caracs de l\'équipement et maintenant pour l\'hébergement');
appendLi(ul, 'Markotroll (27637) pour les tests sous LINUX');
appendLi(ul, 'Tous les testeurs de la nouvelle génération oubliés par Dabihul puis Rouletabille');
}
/* [functions] Obsolètes */
function deleteEnchantement() {
try {
let idEquipement = this.getAttribute('name');
MY_removeValue(`${numTroll}.enchantement.${idEquipement}.objet`);
MY_removeValue(`${numTroll}.enchantement.${idEquipement}.enchanteur`);
MY_removeValue(`${numTroll}.enchantement.${idEquipement}.composant.0`);
MY_removeValue(`${numTroll}.enchantement.${idEquipement}.composant.1`);
MY_removeValue(`${numTroll}.enchantement.${idEquipement}.composant.2`);
let listeEquipement = MY_getValue(`${numTroll}.enchantement.liste`).split(";");
let string = "";
for (let i = 0; i < listeEquipement.length; i++) {
if (listeEquipement[i] != idEquipement) {
if (string == "") {
string = listeEquipement[i];
} else {
string = `${string};${listeEquipement[i]}`;
}
}
}
if (string == "") {
MY_removeValue(`${numTroll}.enchantement.liste`);
let table = this.parentNode.parentNode.parentNode.parentNode;
let parent = table.parentNode;
for (let i = 0; i < parent.childNodes.length; i++) {
if (parent.childNodes[i] == table) {
parent.removeChild(parent.childNodes[i - 1]);
parent.removeChild(parent.childNodes[i - 1]);
parent.removeChild(parent.childNodes[i - 1]);
break;
}
}
} else {
MY_getValue(`${numTroll}.enchantement.liste`, string);
this.parentNode.parentNode.parentNode
.removeChild(this.parentNode.parentNode);
}
} catch (exc) {
avertissement(`Une erreur est survenue (deleteEnchantement)`, null, null, exc);
}
}
/* [functions] fin Obsolètes */
/** x~x Partie principale ---------------------------------------------- */
function do_option() {
start_script(712, 'do_option_log');
debugger;/* */
let insertPoint = getFooter();
insertBefore(insertPoint, document.createElement('p'));
let ti = insertTitle(insertPoint, 'Mountyzilla : Options'); // 02/02/2017 SHIFT-Click pour copier la conf
ti.onclick = function (e) {
let evt = e || window.event;
if (evt.shiftKey) {
let tabVal = [];
for (let i = 0, len = localStorage.length; i < len; ++i) {
let k = localStorage.key(i);
if (k.match(/INFOSIT/i)) {
continue;
} // masquer le mdp Bricol'Troll
if (k.match(/SCIZJWT/i)) {
continue;
} // masquer le jeton SCIZ
tabVal.unshift(`${k}\t${localStorage.getItem(k)}`);
}
tabVal = tabVal.sort(function (a, b) {
let ta = a.split('.');
let ia = parseInt(ta[0]);
let tb = b.split('.');
let ib = parseInt(tb[0]);
if (isNaN(ia)) {
if (isNaN(ib)) {
return (a < b) ? -1 : ((a > b) ? +1 : 0);
} else {
return 1;
}
} else {
if (isNaN(ib)) {
return -1;
} else if (ia == ib) {
return (a < b) ? -1 : ((a > b) ? +1 : 0);
} else {
return ia - ib;
}
}
})
copyTextToClipboard(tabVal.join("\n"));
avertissement('La configuration MZ a été copiée dans le presse-papier (sauf le mot de passe Bricol\'Trõll)');
} else if (evt.ctrlKey) {
let tabK = [];
let sMatch = `${numTroll}.`;
let lMatch = sMatch.length;
for (let i = 0, len = localStorage.length; i < len; ++i) {
let k = localStorage.key(i);
if (k.substring(0, lMatch) == sMatch) {
tabK.push(k);
}
}
for (let i = 0; i < tabK.length; ++i) {
MY_removeValue(tabK[i]);
}
avertissement(`${tabK.length} informations locales du Trõll ${numTroll} ont été effacées-${sMatch}-${lMatch}`);
}
};
ti.title = `Version ${GM_info.script.version}`;
insertOptionTable(insertPoint);
insertBefore(insertPoint, document.createElement('p'));
ti = insertTitle(insertPoint, 'Mountyzilla : Crédits'); // 23/12/2016 SHIFT-Click pour passer en mode dev
ti.onclick = function (e) {
let evt = e || window.event;
if (!evt.shiftKey) {
return;
}
let oldDev = MY_getValue('MZ_dev');
if (oldDev) {
MY_removeValue('MZ_dev');
} else {
window.alert('passage en mode DEV, shift-click sur le mot "Crédits" pour revenir en mode normal');
MY_setValue('MZ_dev', 1);
}
document.location.href = document.location.href;
};
insertCreditsTable(insertPoint);
insertBefore(insertPoint, document.createElement('p'));
displayScriptTime(undefined, 'do_option_log');
}
/** x~x Equip ---------------------------------------------------------- */
/**
* 2014-02-08 - v2.0a (from scratch)
* 2014-02-18 - v2.0a0
* - ajout calcul Carats / UM des minerais + totaux
* 2014-03-06 - v2.0a1
* - retour Infos EM des Champis
* TODO
* Ces fonctions sont dev ici en test, à terme elles seront à intégrer dans libs
*/
function traiteChampis() {
let trlist;
try {
let tr = document.getElementById('mh_objet_hidden_Champignon');
trlist = document.evaluate('./td/table/tbody/tr', tr, null, 7, null);
} catch (e) {
return;
}
if (trlist.length <= 0) {
return;
}
for (let i = 0; i < trlist.snapshotLength; i++) {
let node = trlist.snapshotItem(i).childNodes[7];
let str = node.textContent.trim();
let type = str.slice(0, str.lastIndexOf(' '));
let mundi = mundiChampi[type];
if (!mundi) {
continue;
}
let urlImg = `${URL_MZimg}Competences/ecritureMagique.png`;
let img = createAltImage(urlImg, 'EM', `Mundidey ${mundi}`);
appendText(node, ' ');
node.appendChild(img);
}
}
function traiteCompos() {
let tbody;
try {
let tr = document.getElementById('mh_objet_hidden_Composant');
tbody = document.evaluate("./td/table/tbody", tr, null, 9, null).singleNodeValue;
} catch (e) {
return;
}
insererInfosEM(tbody);
}
function traiteMinerai() {
let trlist;
try {
let tr = document.getElementById('mh_objet_hidden_Minerai');
trlist = document.evaluate('./td/table/tbody/tr', tr, null, 7, null);
} catch (e) {
return;
}
if (trlist.length <= 0) {
return;
}
let totaux = {};
let str;
for (let i = 0; i < trlist.snapshotLength; i++) {
let node = trlist.snapshotItem(i);
let nature = node.childNodes[7].textContent,
caracs = node.childNodes[9].textContent;
let taille = Number(caracs.match(/\d+/)[0]);
let coef = 1;
if (caracs.indexOf('Moyen') != -1) {
coef = 2;
} else if (caracs.indexOf('Normale') != -1) {
coef = 3;
} else if (caracs.indexOf('Bonne') != -1) {
coef = 4;
} else if (caracs.indexOf('Exceptionnelle') != -1) {
coef = 5;
}
if (nature.indexOf('Mithril') != -1) {
coef = 0.2 * coef;
str = ' | UM: ';
} else {
coef = 0.75 * coef + 1.25;
if (nature.indexOf('Taill') != -1) {
coef = 1.15 * coef;
}
str = ' | Carats: ';
}
let carats = Math.round(taille * coef);
appendText(node.childNodes[9], str + carats);
if (!totaux[nature]) {
totaux[nature] = [taille, carats];
} else {
totaux[nature][0] += taille;
totaux[nature][1] += carats;
}
}
str = 'Total : ';
for (let nature in totaux) {
if (str.length > 8) {
str = `${str}, `;
}
if (nature.indexOf('Mithril') != -1) {
str = `${str}${nature + totaux[nature][1]} UM`;
} else {
str = `${str}${nature + totaux[nature][0]}U/${totaux[nature][1]}c`;
}
}
/* let node = document.getElementById('mh_plus_Minerai');
let titre = document.evaluate("./td[contains(./b/text(),'Minerai')]",
node.parentNode.parentNode.parentNode, null, 9, null).singleNodeValue;
if(!titre) return;*/
// Il faut préalablement injecter du CSS pour ne pas hériter de 'mh_titre3'
let td = appendTdText(trlist.snapshotItem(0).parentNode, `(${str})`);
td.colSpan = 7;
}
function do_equip() {
start_script(undefined, 'do_equip_log');
traiteChampis();
traiteCompos();
traiteMinerai();
displayScriptTime(undefined, 'do_equip_log');
}
/** x~x Diplo ---------------------------------------------------------- */
/*
TODO:
V Étape 1: Gestion comme actuellement, avec 2 couleurs (amis/ennemis)
V Étape 2: Gestion couleurs par catégorie (10 couleurs)
V Étape 3: Ajout de la diplo perso
X Étape 4: Gestion distante (sécurisée par mdp) de cette option
V Étape 5: Ajout des fioritures (preview de la couleur...)
Options Globales:
Actuelles:
numTroll.USECSS,
numTroll.NODIPLO
NOMYTH
Nouvelles:
TODO numTroll.USECSS
numTroll.diplo.off (remplace NODIPLO)
numTroll.diplo.guilde
numTroll.diplo.perso
Structure de diplo.guilde:
isOn: 'true' ou 'false'
isDetailOn: 'true' ou 'false'
guilde
> id
> couleur
AllAmis,AllEnnemis: couleur
Amis0,...,Ennemis5
> Troll: idTroll1;...;
> Guilde: idGuilde1;...;
> titre
> couleur
Structure de diplo.perso:
isOn: 'true' ou 'false'
mythiques: couleur
Troll,Guilde,Monstre:
> id
> couleur
> description
*/
/** x~x Fonctions utilitaires ------------------------------------------ */
function couleurAleatoire() {
let alph = '0123456789ABCDEF'.split('');
let clr = '#';
for (let i = 0; i < 6; i++) {
clr = clr + alph[Math.floor(16 * Math.random())];
}
return clr;
}
function isCouleur(str) {
return (/^#[0-9A-F]{6}$/i).test(str);
}
/** x~x Analyse de la page --------------------------------------------- */
function appendChoixCouleur(node, id) {
let span = document.createElement('span');
span.id = `span${id}`;
// C'est un grand jour quand on utilise un OU Exclusif
if (isDetailOn ^ (id.indexOf('All') < 0)) {
span.style.display = 'none';
}
let couleur = '#AAFFAA';
if (id.indexOf('nnemi') > 0) couleur = '#FFAAAA';
if (diploGuilde[id]) {
couleur = diploGuilde[id].couleur;
}
appendText(span, ' - Couleur HTML: ');
let input = appendTextbox(span, 'text', id, 8, 7, couleur);
input.onkeyup = previewCouleur;
input.onchange = previewCouleur;
input.onkeyup();
node.appendChild(span);
}
function insertChoixCouleur(node, id) {
let span = document.createElement('span');
span.id = `span${id}`;
// La couleur détaillée passera à une valeur aléatoire
// si toggle vers isDetailOn
let couleur = couleurAleatoire();
if (!isDetailOn) {
span.style.display = 'none';
} else if (diploGuilde[id]) {
couleur = diploGuilde[id].couleur;
}
appendText(span, ' - Couleur HTML: ');
let input = appendTextbox(span, 'text', id, 8, 7, couleur);
input.onkeyup = previewCouleur;
input.onchange = previewCouleur;
input.onkeyup();
insertBefore(node, span);
}
function setChoixCouleurs() {
try {
let eAmis = document.getElementById('amis');
eAmis.parentNode.id = 'insertPt';
let i, mode, Mode;
for (let e of eAmis.parentNode.children) {
switch (e.id) {
case 'amis':
i = 0;
mode = 'ami';
Mode = 'Ami';
appendChoixCouleur(e, `AllAmis`);
continue;
case 'ennemis':
i = 0;
mode = 'ennemi';
Mode = 'Ennemi';
appendChoixCouleur(e, `AllEnnemis`);
continue
}
if (e.tagName != 'H3') continue;
e.id = `td${Mode}s${i}`;
appendChoixCouleur(e, `${Mode}s${i}`);
i++;
}
return true;
} catch (exc) {
logMZ('Diplomatie Structure de la page non reconnue', exc);
return false;
}
}
function fetchDiploGuilde() {
try {
for (let AE in { Amis: 0, Ennemis: 0 }) {
for (let i = 0; i < 5; i++) {
/* Récup des A/E de rang i */
let h3 = document.getElementById(`td${AE}${i}`);
let form = h3.nextSibling;
while (form && form.nodeType != 1) {
form = form.nextSibling; // sauter le texte
}
if (!form) {
logMZ(`Diplomatie fetchDiploGuilde pour td${AE}${i}, pas d'élément`);
continue;
}
let ligne = form.getElementsByTagName('table')[0].rows;
let titre = trim(h3.textContent);
// On laisse la gestion des couleurs à setChoixCouleurs:
let couleur = document.getElementById(AE + i).value;
diploGuilde[AE + i] = {
Troll: '',
Guilde: '',
titre: titre,
couleur: couleur
};
for (let j = 1; j < ligne.length; j++) {
let str = trim(ligne[j].cells[0].textContent);
let idx = str.lastIndexOf('(');
let num = str.slice(idx + 1, -1);
let type = trim(ligne[j].cells[1].textContent);
diploGuilde[AE + i][type] += `${num};`;
}
}
}
} catch (exc) {
logMZ('Diplomatie récupération de la diplo', exc);
return false;
}
return true;
}
/** x~x Handlers ------------------------------------------------------- */
function toggleDetails() {
isDetailOn = !isDetailOn;
for (let AE in { Amis: 0, Ennemis: 0 }) {
document.getElementById(`spanAll${AE}`).style.display = isDetailOn ? 'none' : '';
for (let i = 0; i < 5; i++) {
document.getElementById(`span${AE}${i}`).style.display = isDetailOn ? '' : 'none';
}
}
}
function toggleMythiques() {
isMythiquesOn = !isMythiquesOn;
document.getElementById('spanMythiques').style.display = isMythiquesOn ? '' : 'none';
}
function previewCouleur() {
let value = this.value;
let eErrMsg = this.nextSibling;
if (eErrMsg && !eErrMsg.classList.contains('MZ_error')) eErrMsg = undefined;
if (isCouleur(value)) {
this.style.backgroundColor = value;
if (eErrMsg) eErrMsg.parentNode.removeChild(eErrMsg);
} else {
this.style.backgroundColor = '';
if (!eErrMsg) {
eErrMsg = document.createElement('span');
eErrMsg.appendChild(document.createTextNode('Entrez une couleur au format #789ABC'));
eErrMsg.style.color = 'red';
eErrMsg.style.marginLeft = '5px';
eErrMsg.style.fontSize = 'small';
eErrMsg.className = 'MZ_error';
this.parentNode.insertBefore(eErrMsg, this.nextSibling);
}
}
}
function appendMenuType(node, duType) {
let select = document.createElement('select');
select.className = 'SelectboxV2';
let type = ['Guilde', 'Troll', 'Monstre'];
for (let i = 0; i < 3; i++) {
appendOption(select, type[i], type[i]);
if (type[i] == duType) {
select.selectedIndex = i;
}
}
node.appendChild(select);
}
function ajouteChamp(type, num, couleur, descr) {
let champs = document.getElementById('diploPerso');
let nb = champs.rows.length;
let tr = champs.insertRow(-1);
let td = appendTd(tr);
appendMenuType(td, type);
td = appendTd(tr);
appendText(td, ' n°');
appendTextbox(td, 'text', `num${nb}`, 6, 15, num);
td = appendTd(tr);
appendText(td, ' couleur HTML:');
let input = appendTextbox(td, 'text', `couleur${nb}`, 8, 7, couleur);
input.onkeyup = previewCouleur;
input.onchange = previewCouleur;
input.onkeyup();
td = appendTd(tr);
appendText(td, ' Description:');
appendTextbox(td, 'text', `descr${nb}`, 30, 150, descr);
td = appendTd(tr);
let span = document.createElement('span');
appendText(span, '[ok!]', true);
span.style.visibility = 'hidden';
td.appendChild(span);
td = appendTd(tr);
appendButton(td, 'Suppr.', retireCeChamp); // let bouton = appendButton(..)
}
function retireCeChamp() {
let thisTr = this.parentNode.parentNode;
thisTr.parentNode.removeChild(thisTr);
let champs = document.getElementById('diploPerso');
if (champs.rows.length == 0) {
ajouteChamp();
}
}
function valideChamp(champ) {
let isValide = (/^\d+$/).test(champ.cells[1].childNodes[1].value) &&
isCouleur(champ.cells[2].childNodes[1].value);
if (isValide) {
champ.cells[4].firstChild.style.visibility = 'visible';
} else {
champ.cells[4].firstChild.style.visibility = 'hidden';
}
return isValide;
}
function sauvegarderTout() {
/* Diplo de guilde */
diploGuilde.isOn = document.getElementById('isGuildeOn').checked ? 'true' : 'false';
diploGuilde.isDetailOn = isDetailOn ? 'true' : 'false';
let numGuilde = Number(document.getElementById('numGuilde').value);
let couleur = document.getElementById('couleurGuilde').value;
if (numGuilde) {
diploGuilde.guilde = {
id: numGuilde,
couleur: couleur
};
} else {
delete diploGuilde.guilde;
}
for (let AE in { Amis: 0, Ennemis: 0 }) {
diploGuilde[`All${AE}`] = document.getElementById(`All${AE}`).value;
for (let i = 0; i < 5; i++) {
if (isDetailOn) {
diploGuilde[AE + i].couleur = document.getElementById(AE + i).value;
} else {
diploGuilde[AE + i].couleur = diploGuilde[`All${AE}`];
}
}
}
MY_setValue(`${numTroll}.diplo.guilde`, JSON.stringify(diploGuilde));
/* Diplo personnelle (ex-fonction saveChamps) */
let champs = document.getElementById('diploPerso');
diploPerso = {
isOn: document.getElementById('isPersoOn').checked ? 'true' : 'false',
Guilde: {},
Troll: {},
Monstre: {}
};
if (isMythiquesOn &&
isCouleur(document.getElementById('couleurMythiques').value)) {
diploPerso.mythiques = document.getElementById('couleurMythiques').value;
}
for (let i = 0; i < champs.rows.length; i++) {
if (valideChamp(champs.rows[i])) {
let type = champs.rows[i].cells[0].firstChild.value;
let num = champs.rows[i].cells[1].childNodes[1].value;
couleur = champs.rows[i].cells[2].childNodes[1].value;
let descr = champs.rows[i].cells[3].childNodes[1].value;
diploPerso[type][num] = {
couleur: couleur
};
if (descr) {
diploPerso[type][num].titre = descr;
}
}
}
MY_setValue(`${numTroll}.diplo.perso`, JSON.stringify(diploPerso));
avertissement('Données sauvegardées');
}
/** x~x Modifications de la page --------------------------------------- */
function creeTablePrincipale() {
let insertPt = document.getElementById('insertPt');
/* Titre + bouton de Sauvegarde */
let tr = insertTr(insertPt, 'mh_tdtitre');
let td = appendTdText(tr, '[Mountyzilla] Options de Diplomatie ', true);
appendButton(td, 'Sauvegarder', sauvegarderTout);
/* Options fixes */
tr = insertTr(insertPt, 'mh_tdpage');
td = appendTdText(tr, 'Diplomatie de guilde:', true);
appendBr(td);
appendCheckBox(td, 'isGuildeOn', diploGuilde.isOn != 'false');
appendText(td, 'Afficher la diplomatie de guilde dans la Vue');
appendBr(td);
appendCheckBox(td, 'detailOn', isDetailOn, toggleDetails);
appendText(td, 'Utiliser des couleurs détaillées (10)');
/* Diplo personnelle */
tr = insertTr(insertPt, 'mh_tdpage');
td = appendTdText(tr, 'Diplomatie personnelle:', true);
appendBr(td);
// Diplo Mythiques
appendCheckBox(td, 'isMythiquesOn', isMythiquesOn, toggleMythiques);
appendText(td, 'Ajouter les monstres Mythiques à la Diplomatie');
let span = document.createElement('span');
span.id = 'spanMythiques';
if (!isMythiquesOn) {
span.style.display = 'none';
}
let couleur = '#FFAAAA';
if (diploPerso.mythiques) {
couleur = diploPerso.mythiques;
}
appendText(span, ' - couleur HTML:');
let input = appendTextbox(span, 'text', 'couleurMythiques', 7, 7, couleur);
input.onkeyup = previewCouleur;
input.onchange = previewCouleur;
input.onkeyup();
td.appendChild(span);
appendBr(td);
// Diplo éditable
appendCheckBox(td, 'isPersoOn', diploPerso.isOn != 'false');
appendText(td, 'Afficher la diplomatie personnelle dans la Vue:');
appendBr(td);
let table = document.createElement('table');
table.id = 'diploPerso';
td.appendChild(table);
for (let type in { Guilde: 0, Troll: 0, Monstre: 0 }) {
for (let num in diploPerso[type]) {
ajouteChamp(
type,
num,
diploPerso[type][num].couleur,
diploPerso[type][num].titre
);
}
}
if (table.rows.length == 0) {
ajouteChamp();
}
appendButton(td, 'Ajouter', ajouteChamp);
// Prévisualisation couleurs (merci à Vys d'avoir implémenté ça xD)
appendText(td, ' ');
appendButton(td,
'Exemples de couleur',
() => {
let fenetre = window.open(
'/mountyhall/MH_Play/Options/Play_o_Color.php',
'Divers',
'width=500,height=550,toolbar=0,location=0,directories=0,' +
'status=0,menubar=0,resizable=1,scrollbars=1'
);
fenetre.focus();
}
);
/* Couleur de Guilde */
tr = insertTr(insertPt, 'mh_tdtitre');
td = appendTdText(tr, 'GUILDE', true);
appendText(td, ' - n°');
appendTextbox(td, 'text', 'numGuilde', 5, 10,
diploGuilde.guilde && diploGuilde.guilde.id ?
diploGuilde.guilde.id : ''
);
appendText(td, ' - Couleur HTML: ');
input = appendTextbox(td, 'text', 'couleurGuilde', 7, 7,
diploGuilde.guilde && diploGuilde.guilde.couleur ?
diploGuilde.guilde.couleur : '#BBBBFF'
);
input.onkeyup = previewCouleur;
input.onchange = previewCouleur;
input.onkeyup();
}
/** x~x Main ----------------------------------------------------------- */
function initDiplo(sType) {
let sDiplo = MY_getValue(`${numTroll}.diplo.${sType}`);
// logMZ('sDiplo' + sType + '=' + sDiplo);
if (sDiplo && sDiplo != 'null') { // le stockage JSON nous donne parfois 'null'
return JSON.parse(sDiplo);
}
return {};
}
var diploGuilde = initDiplo('guilde');
var diploPerso = initDiplo('perso');
var isDetailOn = diploGuilde.isDetailOn == 'true';
var isMythiquesOn = diploPerso.mythiques != undefined;
function do_diplo() {
if (setChoixCouleurs() && fetchDiploGuilde()) {
creeTablePrincipale();
}
}
/** x~x CdmComp -------------------------------------------------------- */
// let cdm = ''; // Roule 11/03/2017 une variable globale de moins \o/
function getNonNegInts(str) {
let nbrs = str.match(/\d+/g);
for (let i = 0; i < nbrs.length; i++) {
nbrs[i] = Number(nbrs[i]);
}
return nbrs;
}
function MZ_comp_traiteCdMcomp() {
// envoi au serveur (PHP) d'un objet avec
// cmd: un tableau de chaines (éléments HTML <p>) ou de tableaux (les <TD> des lignes des tableaux HTML)
// tstamp: l'horodatage
let oContexteCdM = MZ_analyseCdM('msgEffet', true); // analyse de la CdM, prépare l'envoi, prépare l'ajout de PV min/max selon blessure
oContexteCdM.nameBut = 'termAction'; // nom du bouton avant lequel insérer le bouton ou les textes
if (!oContexteCdM.ok) {
if (!oContexteCdM.error) {
oContexteCdM = MZ_analyseCdM('msgDiv', true);
}
if (!oContexteCdM.ok) {
if (oContexteCdM.error) {
logMZ(`MZ_comp_traiteCdMcomp, ${oContexteCdM.error}`);
MZ_comp_addMessage(oContexteCdM, `Erreur MZ, ${oContexteCdM.error}`);
}
return;
}
}
debugMZ(`oData=${JSON.stringify(oContexteCdM.oData)}`);
MZ_comp_addPvRestant(oContexteCdM);
let tstamp, etimestamp = document.getElementById('hserveur');
if (etimestamp != undefined) {
tstamp = etimestamp.innerText || etimestamp.textContent;
}
if (tstamp == undefined) {
/* dans le cas de la comp, le serveur se repliera sur la date/heure courante
logMZ('MZ_comp_traiteCdMcomp, pas de date/heure');
MZ_comp_addMessage(oContexteCdM, 'Impossible d\'envoyer la CdM à MZ, pas de date/heure');
return;
*/
} else {
oContexteCdM.oData.tstamp = tstamp.replace(/\]/, '').trim();
}
// Envoi auto ou insertion bouton envoi (suivant option)
if (MY_getValue(`${numTroll}.AUTOCDM`) == 'true') {
oContexteCdM.sendInfoCDM();
MZ_comp_addMessage(oContexteCdM, 'CdM envoyée vers la base MountyZilla !', 'MZ_msgCdM');
} else {
insertButtonCdm('termAction', oContexteCdM.sendInfoCDM);
}
}
function MZ_comp_addMessage(oContexteCdM, msg, id) {
let eBefore = document.getElementsByName(oContexteCdM.nameBut)[0];
if (eBefore) eBefore = eBefore.parentNode;
else eBefore = document.getElementById(oContexteCdM.nameBut);
if (!eBefore) {
logMZ(`MZ_comp_addMessage, pas de ${oContexteCdM.nameBut}`);
return;
}
let p = document.createElement('p');
if (id) p.id = id;
p.style.color = 'green';
appendText(p, msg);
insertBefore(eBefore, p);
}
function MZ_analyseCdM(idHTMLCdM, bIgnoreEltAbsent) { // rend un contexte
let eltCdM = document.getElementById(idHTMLCdM);
let oRet = {};
if (!eltCdM) {
oRet.ok = false;
if (!bIgnoreEltAbsent) {
oRet.error = `Pas d'elt ${idHTMLCdM}`;
}
return oRet;
}
// le contexte contiendra
// txtHeure : le texte de l'heure de la CdM
// trBlessure : le <tr> de la ligne "blessure"
// txtBlessure : le texte donnant le % de blessure
// txtPv : le texte donnant les PV
// ok : 1 si on a bien reconnu une CdM
// oData : les data à envoyer en JSON au serveur MZ
oRet.oData = {};
oRet.oData.tabCdM = new Array();
for (let iElt = 0; iElt < eltCdM.childNodes.length; iElt++) { // eHTML of msgEffet.childNodes) { for...of pas supporté par IE et Edge
let eHTML = eltCdM.childNodes[iElt];
let s = undefined;
switch (eHTML.nodeName) {
case '#text':
s = eHTML.nodeValue;
// suite : même code que <B> ou <p>
case 'P':
case 'B':
if (s === undefined) {
s = eHTML.innerText || eHTML.textContent;
} // récupération du contenu texte d'un élément HTML
s = s.trim();
if (s != '') {
if (s.match(/aux *alentours* *de/i)) {
oRet.txtHeure = s;
}
if (s.match(/Connaissance *des* *Monstres/i)) {
oRet.ok = true;
}
oRet.oData.tabCdM.push(s);
}
break;
case 'TABLE':
s = 'table';
for (let iTr = 0; iTr < eHTML.rows.length; iTr++) { // eTr of eHTML.rows) {
let eTr = eHTML.rows[iTr];
let tabTd = new Array();
for (let iTd = 0; iTd < eTr.cells.length; iTd++) { // eTd of eTr.cells) {
let eTd = eTr.cells[iTd];
s = eTd.innerText || eTd.textContent; // récupération du contenu texte d'un élément HTML
s = s.trim();
tabTd.push(s);
}
if (tabTd.length >= 2) {
if (tabTd[0].match(/Blessure/i)) {
oRet.trBlessure = eTr;
oRet.txtBlessure = tabTd[1];
} else if (tabTd[0].match(/Points* *de *Vie/i)) {
oRet.txtPv = tabTd[1];
}
}
oRet.oData.tabCdM.push(tabTd);
}
break;
case 'BR':
case '#comment':
case 'STYLE':
break; // ignore
default:
s = eHTML.innerText || eHTML.textContent; // récupération du contenu texte d'un élément HTML
if (s != '') {
oRet.oData.tabCdM.push(s);
}
logMZ(`MZ_analyseCdM, type d'élément non traité : ${eHTML.nodeName} ${s}`);
break;
}
}
oRet.oData.idTroll = numTroll;
// préparation de l'envoi d'une CdM issue de compte-rendu de compétence
// fonction définie ici pour avoir vue sur la variable tabCdM
oRet.sendInfoCDM = function () {
MY_setValue('CDMID', 1 + parseInt(MY_getValue('CDMID')));
let buttonCDM = this;
let setMsgResultat = function(texte) {
if (!buttonCDM.appendChild) {
buttonCDM = document.getElementById('MZ_msgCdM');
texte = `Envoi à MZ : ${texte}`;
}
if (!buttonCDM.appendChild) {
logMZ(`MZ setMsgResultat pas d'endroi où afficher le résultat qui est : ${texte}`);
return;
}
// logMZ('buttonCDM.parentNode.firstChild.nodeName=' + buttonCDM.parentNode.firstChild.nodeName);
switch (buttonCDM.nodeName) {
case 'INPUT':
case 'BUTTON':
buttonCDM.value = texte;
break;
default:
replaceContentByText(buttonCDM, texte);
break;
}
if (this.parentNode && this.parentNode.firstChild && this.parentNode.firstChild.nodeName == 'SPAN') { // smartphone
replaceContentByText(this.parentNode.firstChild, texte);
}
}
FF_XMLHttpRequest({
method: 'POST',
url: URL_pageDispatcherV2,
data: `cdm_json=${encodeURIComponent(JSON.stringify(oRet.oData))}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
trace: 'envoi CdM',
onload: function (responseDetails) {
setMsgResultat(responseDetails.responseText);
if (!isDEV) buttonCDM.disabled = true;
},
onerror: function (responseDetails) {
let msgError = 'inconnue';
if (responseDetails.status == 0) {
msgError = ' HTTPS ou CORS';
}
if (responseDetails.error) {
msgError = responseDetails.error;
}
setMsgResultat(`Erreur MZ ${msgError}`);
},
});
};
return oRet;
}
function MZ_comp_addPvRestant(oContexteCdM) {
// Insertion de l'estimation des PV restants
debugMZ(`txtBlessure=${oContexteCdM.txtBlessure}, txtPv=${oContexteCdM.txtPv}`);
if (oContexteCdM.txtBlessure === undefined || oContexteCdM.txtPv === undefined) {
return;
}
let pv = getPVsRestants(oContexteCdM.txtPv, oContexteCdM.txtBlessure);
debugMZ(`pv=${pv}`);
if (!pv) {
return;
} // pv null si le monstre n'est pas blessé
let tr = document.createElement('tr');
oContexteCdM.trBlessure.parentNode.insertBefore(tr, oContexteCdM.trBlessure.nextSibling);
let th = appendThText(tr, pv[0], false);
th.className = oContexteCdM.trBlessure.cells[0].className;
let td = appendTdText(tr, pv[1], false);
let eSpan = document.createElement('span');
appendText(eSpan, ' (Calculé par Mountyzilla)');
eSpan.style.fontSize = "small";
eSpan.style.fontStyle = "italic";
td.appendChild(eSpan);
}
function do_cdmcomp() {
start_script(31, 'do_cdmcomp_log');
MZ_comp_traiteCdMcomp();
displayScriptTime(undefined, 'do_cdmcomp_log');
}
/** x~x CdmBot --------------------------------------------------------- */
/* v0.2 by Dab - 2013-08-20
* - patch dégueu pour gérer la décomposition P/M de l'armure
*/
var buttonCDM;
/** *****************************************************************************************
CDM :
Vous avez RÉUSSI à utiliser cette compétence au niveau 5 : jet de 34 sur 95 %.
Il ne vous est pas possible d'améliorer cette compétence.
Le Monstre Ciblé fait partie des : Mort-Vivant (Archi-Nécromant [Antique] - N°4571589)
Niveau : Inimaginable (entre 49 et 51)
Points de Vie : Surtrollesque (entre 450 et 470)
Blessure (Approximatif) : 0 %
Dés d'Attaque : Impressionnant (entre 30 et 32)
Dés d'Esquive : Impressionnant (entre 28 et 30)
Dés de Dégat : Très Fort (entre 18 et 20)
Dés de Régénération : Excellent (égal à 13)
Armure Physique : Moyen (entre 10 et 12)
Armure Magique : Faible (inférieur à 6)
Vue : Moyen (entre 9 et 11)
Maitrise Magique : Inimaginable (supérieur à 6000)
Résistance Magique : Inimaginable (supérieur à 6000)
Nombre d'attaques : 1
Vitesse de Déplacement : Normale
Voir le Caché : Oui
Attaque à distance : Non
Attaque magique : Oui
Vole : Non
Sang froid : Inexistant
DLA : Milieu
Durée Tour : Remarquable (entre 9 et 11)
Chargement : Vide
Bonus Malus : Aucun
Vous avez également gagné 1 PX pour la réussite.
*******************************************************************************************
BOT :
Vous avez utilisé CONNAISSANCE DES MONSTRES sur un Capitan Ronfleur [Naissant] (4768960)
Le Monstre ciblé fait partie des : Mort-Vivant
Niveau : Incroyable (entre 36 et 38)
*******************************************************************************************/
function getNNInt(str) {
let nbrs = str.match(/\d+/g);
for (let i = 0; i < nbrs.length; i++) {
nbrs[i] = parseInt(nbrs[i]);
}
return nbrs;
}
// envoi d'une CdM issue d'un message du BOT
function sendCDM() {
let td = document.evaluate(
"//td/text()[contains(.,'CONNAISSANCE DES MONSTRES')]/..", document, null, 9, null
).singleNodeValue;
let tdTxt = td.innerText || td.textContent; // récupération du contenu texte d'un élément HTML
let oData = {};
oData.tabCdM = tdTxt.split(/\n/);
// nettoyage entête : enlève le premier élément tant que
// - suite de *
// - "MOUNTYHALL - La Terre des Trõlls"
// - ligne vide (la première expression régulière matche les lignes vides)
while (oData.tabCdM[0].match(/^=*$/) || oData.tabCdM[0].match(/^MOUNTYHALL/i)) {
oData.tabCdM.shift();
}
// nettoyage entête : enlève tout ce qui suit une ligne composée uniquement d'étoiles suivie de '^Vous avez configuré' + les lignes vides au dessus
let iLigneNonVide;
for (let i = 0; i < oData.tabCdM.length; i++) {
if (oData.tabCdM[i].match(/^\*+$/) && oData.tabCdM[i + 1].match(/^Vous avez configuré/i)) {
if (iLigneNonVide === undefined) {
oData.tabCdM.splice(i);
} else {
oData.tabCdM.splice(iLigneNonVide + 1);
}
break;
}
if (!oData.tabCdM[i].match(/^$/)) {
iLigneNonVide = i;
}
}
FF_XMLHttpRequest({
method: 'POST',
url: URL_pageDispatcherV2,
data: `cdm_json=${encodeURIComponent(JSON.stringify(oData))}`,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
trace: 'envoi CdM msg du bot',
onload: function (responseDetails) {
buttonCDM.value = responseDetails.responseText;
buttonCDM.disabled = true;
}
});
}
function MZ_traiteCdMmsg() {
let oContexteCdM = MZ_analyseCdM('messageContent'); // analyse de la CdM, prépare l'envoi, prépare l'ajout de PV min/max selon blessure
oContexteCdM.nameBut = 'bForward'; // nom du bouton avant lequel insérer le bouton ou les textes
if (!oContexteCdM.ok) {
if (oContexteCdM.error) {
logMZ(`MZ_traiteCdMmsg, ${oContexteCdM.error}`);
MZ_comp_addMessage(oContexteCdM, `Erreur MZ, ${oContexteCdM.error}`);
}
return;
}
debugMZ(`oContexteCdM=${JSON.stringify(oContexteCdM)}`);
MZ_comp_addPvRestant(oContexteCdM);
let txtHeure, tstamp;
if (oContexteCdM.txtHeure) {
txtHeure = oContexteCdM.txtHeure;
} else {
let etimestamp = document.getElementById('messageDateHeure');
if (etimestamp) {
txtHeure = etimestamp.innerText || etimestamp.textContent;
}
}
if (txtHeure) {
let m = txtHeure.match(/\d+\/\d+\/\d+ +\d+:\d+:\d+/);
if (m) {
tstamp = m[0];
}
}
if (tstamp == undefined) {
logMZ('MZ_traiteCdMmsg, pas de date/heure');
MZ_comp_addMessage(oContexteCdM, 'Impossible d\'envoyer la CdM à MZ, pas de date/heure');
return;
}
oContexteCdM.oData.tstamp = tstamp.trim();
oContexteCdM.oData.bMsgBot = 1;
// Insertion bouton envoi
insertButtonCdm(oContexteCdM.nameBut, oContexteCdM.sendInfoCDM);
}
function do_cdmbot() { // Roule 17/10/2016, restreint à la page des message du bot
MZ_traiteCdMmsg();
}
/** x~x Menu ----------------------------------------------------------- */
// n'est lancé que sur refresh du volet de menu (activation ou [Refresh])
let menuRac, mainIco;
function updateNumTroll() {
let eltId = document.getElementById('id');
if (!eltId) {
warnMZ(`updateNumTroll_log: numéro Troll introuvable (desktop)`);
return null;
}
let l_numTroll = parseInt(eltId.getAttribute('data-id'));
if (isNaN(l_numTroll)) {
warnMZ(`updateNumTroll_log: numéro Troll introuvable: eltId=${eltId}`);
return null;
}
MY_setValue('NUM_TROLL', l_numTroll);
debugMZ(`updateNumTroll_log: numTroll=${l_numTroll}`);
return l_numTroll;
}
function updateNomTroll() {
let eltId = document.getElementById('id');
let l_nomTroll = eltId.innerText;
if (l_nomTroll === 'Troll') {
warnMZ(`updateNomTroll_log: nom Troll générique: Troll`);
return null;
}
MY_setValue('NOM_TROLL', l_nomTroll);
debugMZ(`updateNomTroll_log: nomTroll=${l_nomTroll}`);
return l_nomTroll;
}
// met à jour les carac sauvegardées (position, DLA, etc.)
function updateData() {
let l_numTroll = updateNumTroll()
if (l_numTroll === null) {
return;
}
updateNomTroll()
let eltDLA_xyn = document.getElementById('DLA_xyn');
if (!eltDLA_xyn) {
logMZ('erreur updateData_log: position et DLA inconnus, pas de DLA_xyn');
return;
}
let txt_dla_xyn = eltDLA_xyn.innerText;
let m = txt_dla_xyn.match(/DLA:* *(.*)[ \n\r]*X *= *(-*\d+)[ \|]*Y *= *(-*\d+)[ \|]*N *= *(-*\d+)/);
if (!m) {
logMZ(`erreur updateData_log: position et DLA inconnus, échec de l'analyse de ${txt_dla_xyn}`);
return;
}
let DLA = new Date(StringToDate(m[1]));
if (MY_getValue(`${l_numTroll}.DLA.encours`)) {
let DLAstockee = new Date(
StringToDate(MY_getValue(`${l_numTroll}.DLA.encours`))
);
if (DLA > DLAstockee) {
MY_setValue(`${l_numTroll}.DLA.ancienne`, MZ_formatDateMS(DLAstockee, false));
debugMZ(`updateData_log: DLA précédente=${MZ_formatDateMS(DLAstockee, false)}`);
// Pose un pb en cas de décalage de DLA
}
}
MY_setValue(`${l_numTroll}.DLA.encours`, MZ_formatDateMS(DLA, false));
debugMZ(`updateData_log: DLA =${MZ_formatDateMS(DLA, false)}`);
let x = parseInt(m[2]);
let y = parseInt(m[3]);
let n = parseInt(m[4]);
if (isNaN(x) || isNaN(y) || isNaN(n)) {
logMZ(`erreur updateData_log, à la récupération de la position, analyse=${JSON.stringify(m)}`);
} else {
MY_setValue(`${l_numTroll}.position.X`, x);
MY_setValue(`${l_numTroll}.position.Y`, y);
MY_setValue(`${l_numTroll}.position.N`, n);
}
}
// ajoute les raccourcis (paramétrables dans Options/Pack Graphique)
function initRaccourcis() {
let anotherURL = MY_getValue('URL1');
if (!anotherURL) {
return;
}
/* Création de l'icône faisant apparaître le menu */
mainIco = document.createElement('img');
let urlIco = MY_getValue(`${numTroll}.ICOMENU`);
if (!urlIco) {
urlIco = `${URL_MZimg}mz_logo_small.png`;
}
mainIco.src = urlIco;
mainIco.alt = 'MZ';
mainIco.style = 'position:fixed; top:0px; left:0px';
mainIco.onmouseover = afficheMenu;
document.body.appendChild(mainIco);
/* Création du menu des Raccourcis */
menuRac = document.createElement('div');
menuRac.className = 'mh_textbox';
menuRac.style =
'position:fixed; top:10px; left:10px;' +
'max-width:190px;' +
'border-radius: 4px; padding: 4px;' +
'z-index: 500;' +
'visibility: hidden;';
document.body.appendChild(menuRac);
document.addEventListener('mousemove', cacheMenu, false);
let i = 1;
while (anotherURL) {
let a = document.createElement('a');
let url = MY_getValue(`URL${i}`);
let nom = MY_getValue(`URL${i}.nom`);
let ico = MY_getValue(`URL${i}.ico`);
a.href = url;
a.target = '_blank';
if (ico) {
let txt = nom ? nom : '';
let img = createImage(ico, txt);
a.appendChild(img);
} else {
appendText(a, `[${nom}]`);
}
menuRac.appendChild(a);
appendBr(menuRac);
i++;
anotherURL = MY_getValue(`URL${i}`);
}
}
function afficheMenu() {
menuRac.style.visibility = 'visible';
}
function cacheMenu(e) {
if (menuRac.style.visibility == 'hidden') {
return;
}
// Position souris
let ptX = e.clientX;
let ptY = e.clientY;
// On recalcule en live les BoundingBox pour mainIco et menuRac
// Moins optimal, mais évite des erreurs (d'originie inconnue)
let menuRect = menuRac.getBoundingClientRect();
let icoRect = mainIco.getBoundingClientRect();
if ((ptX > icoRect.width || ptY > icoRect.height) &&
(ptX < 10 || ptX > 10 + menuRect.width || ptY < 10 || ptY > 10 + menuRect.height)) {
menuRac.style.visibility = 'hidden';
}
}
// ajout de l'icône, branchée sur un refresh
function initUpdateCoordGauche() {
let div = document.evaluate("//div[@class='infoMenu']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
// logMZ('initUpdateCoordGauche ' + div.innerHTML);
if (!div) {
return;
}
let img = document.createElement('img');
img.src = `${URL_MZimg}recycl.png`;
img.onclick = function (evt) {
document.location.href = document.location.href;
};
img.title = 'Mise à jour de la localisation';
img.style.cursor = 'pointer';
img.style.position = 'absolute';
img.style.bottom = 0;
img.style.left = 0;
div.appendChild(img);
}
// ajout sur les raccoucis des mêmes popup que dans le profil
function MZ_initPopupFrameGauche() {
let eListeFavoris = document.getElementById('listeFavori');
if (!eListeFavoris) {
logMZ('**erreur** pas de listeFavori dans la frame de gauche');
return;
}
let tabA = eListeFavoris.getElementsByTagName('A');
for (let i = 0; i < tabA.length; i++) {
let a = tabA[i];
setInfos(a, epure(trim(a.textContent)), '*', 1);
}
}
function do_menu() {
// met à jour les carac sauvegardées (position, DLA, etc.)
updateData();
// ajoute les raccourcis (paramétrables dans Options/Pack Graphique)
initRaccourcis();
// Ajout du compte à rebours de DLA
initCompteAreboursDLA();
// Ajout bouton de mise à jour coordonnées
initUpdateCoordGauche();
// Ajout popup sur les raccourcis des actions
// MZ_initPopupFrameGauche();
}
/** x~x Vue ------------------------------------------------------------ */
/* TODO
* /!\ bug latent sur diminution bonusPV (perte Telaite / template Ours),
* prévoir fix ("delete infos")
*/
/** x~x Variables Globales --------------------------------------------- */
// Position actuelle
var currentPosition = [0, 0, 0];
// Portées de la vue : [vueHpure, vueVpure, vueHlimitée, vueVlimitée]
var porteeVue = [0, 0, 0, 0];
// Fenêtres déplaçables
var winCurr = null;
var offsetX, offsetY;
// Diplomatie
var Diplo = {
Guilde: {},
Troll: {},
Monstre: {}
// .mythiques: uniquement si option activée
};
var isDiploRaw = true; // = si la Diplo n'a pas encore été analysée
// Infos tactiques
// => MZ_Tactique.popup
// Utilisé pour supprimer les monstres "engagés"
var listeEngages = {};
var isEngagesComputed = false;
var cursorOnLink = false; // DEBUG: wtf ?
var needComputeEnchantement = MY_getValue(`${numTroll}.enchantement.liste`) &&
MY_getValue(`${numTroll}.enchantement.liste`) != '';
// Checkboxes de filtrage
var checkBoxGG, checkBoxCompos, checkBoxBidouilles, checkBoxIntangibles,
checkBoxDiplo, checkBoxTrou, checkBoxMythiques, checkBoxEM, checkBoxTresorsNonLibres,
checkBoxTactique, checkBoxLevels, checkBoxGowapsS, checkBoxGowapsA, checkBoxEngages,
comboBoxNiveauMin, comboBoxNiveauMax, comboBoxFamille;
/* Acquisition & Stockage des données de DB */
var typesAFetcher = {
monstres: 1,
trolls: 1,
tresors: 1,
champignons: 1,
lieux: 1
};
var MZ_EtatCdMs = { // zone où sont stockées les variables "globales" pour la gestion des cdM et infos tactiques
nbMonstres: 0,
tr_monstres: [],
lastIndexDone: 0,
isCDMsRetrieved: false, // = si les CdM ont déjà été DL
listeCDM: [],
indexCellDist: -1,
indexCellActions: -1,
indexCellID: -1,
indexCellNivMZ: -1,
indexCellX: -1,
indexCellY: -1,
indexCellN: -1,
// Gère l'affichage en cascade des popups de CdM
yIndexCDM: 0,
tdWitdh: 110,
};
var VueContext = {};
var tr_trolls = {}, tr_tresors = {}, tr_champignons = {}, tr_lieux = {};
var nbTrolls = 0, nbTresors = 0, nbChampignons = 0, nbLieux = 0;
function fetchData(type) {
try {
let node = document.getElementById(`vue2toggle_${type}`);
// slice pour faire un shallow clone car la collection HTML est cassée par le tri de footable :(
let a = Array.prototype.slice.call(node.getElementsByTagName('tr'));
// footable ajoute une ligne cachée quand un tableau et vide. Ça nous met le bronx. On vire la ligne ici
if (a[a.length - 1].className == 'footable-empty') a.pop();
VueContext[`tr_${type}`] = a;
debugMZ(`fetch ${type} recup ` + VueContext[`tr_${type}`].length + ' lignes');
VueContext[`nb${type[0].toUpperCase()}${type.slice(1)}`] = VueContext[`tr_${type}`].length - 1;
return true;
} catch (exc) {
// warnMZ(`Erreur acquisition type ${type}`, exc);
return false;
}
}
/** x~x Fonctions utilitaires ------------------------------------------ */
function positionToString(arr) {
return arr.join(';');
}
function MZ_deltaH(pos1, pos2) { // pos1 et pos2 doivent être des tableaux [x, y, n]
return Math.max(Math.abs(pos1[0] - pos2[0]), Math.abs(pos1[1] - pos2[1]));
}
function MZ_deltaV(pos1, pos2) {
return Math.abs(pos1[2] - pos2[2]);
}
function savePosition() {
// Stocke la position (à jour) de la vue pour les autres scripts
// DEBUG: Lesquels et pourquoi?
let pos = getPosition();
let x = pos[0], y = pos[1], n = pos[2];
if (isNaN(x) || isNaN(y) || isNaN(n)) {
logMZ(`erreur savePosition_log, pos=${JSON.stringify(pos)}`);
} else {
MY_setValue(`${numTroll}.position.X`, x);
MY_setValue(`${numTroll}.position.Y`, y);
MY_setValue(`${numTroll}.position.N`, n);
}
}
/** x~x Fonctions de récupération de données (DOM) --------------------- */
/* INFOS :
* les champs-titres (table>tbody>tr>td>table>tbody>tr>td>a)
* sont identifiables via leur Name
* les tables-listings sont identifiables via l'ID du tr conteneur
* (mh_vue_hidden_XXX, XXX=trolls, champignons, etc)
*/
/* [functions] Récup données Utilisateur */
function getPosition() {
// Pour rétrocompatibilité
return currentPosition;
}
function getPorteVue() {
// Pour rétrocompatibilité
return porteeVue;
}
function getVue() {
// Retourne [vueHpure, vueVpure]
let vues = getPorteVue();
return [vues[0], vues[1]];
}
// Roule 11/03/2016
/* [functions] Récup données monstres, trolls, etc. */
function getXxxDistance(xxx, i) {
return MZ_getDistanceAvecSplit(VueContext[`tr_${xxx.toLowerCase()}`][i].cells[0].textContent);
}
function getXxxPosition(xxx, i) {
let tds = VueContext[`tr_${xxx.toLowerCase()}`][i].childNodes;
let l = tds.length;
return [
parseInt(tds[l - 3].textContent),
parseInt(tds[l - 2].textContent),
parseInt(tds[l - 1].textContent)
];
}
/* [functions] Récup données monstres */
function getMonstreDistance(i) {
// debugMZ('getMonstreDistance, i=' + i + ', tr=' + MZ_EtatCdMs.tr_monstres[i].innerHTML);
let s = MZ_EtatCdMs.tr_monstres[i].cells[MZ_EtatCdMs.indexCellDist].textContent;
if (s.indexOf('|') < 0) {
return parseInt(s);
}
let m = s.match(/(\d+)[^\d]+(\d+)/);
if (!(m && m.length >= 3)) {
return 0;
}
return Math.max(m[1], m[2]);
}
function getMonstreID(i) {
return Number(MZ_EtatCdMs.tr_monstres[i].cells[MZ_EtatCdMs.indexCellID].firstChild.nodeValue);
}
function getMonstreIDByTR(tr) {
return tr.cells[MZ_EtatCdMs.indexCellID].firstChild.nodeValue;
}
function getMonstreLevelNode(i) {
let tr = MZ_EtatCdMs.tr_monstres[i];
if (!tr) {
printMZ(window.console.error, true, `Pas de monstre n°${i} / ${MZ_EtatCdMs.tr_monstres.length}`);
return;
}
return tr.cells[MZ_EtatCdMs.indexCellNivMZ];
}
function isMonstreLevelOutLimit(i, limitMin, limitMax) {
if (!MZ_EtatCdMs.isCDMsRetrieved) {
return false;
}
let donneesMonstre = MZ_EtatCdMs.listeCDM[getMonstreID(i)];
if (!donneesMonstre) {
return false;
}
let niv = donneesMonstre.niv;
if (niv == undefined) {
return false;
}
if (limitMin > 0 && niv.max && niv.max < limitMin) {
return true;
}
if (limitMax > 0 && niv.min && niv.min > limitMax) {
return true;
}
return false;
}
function getMonstreNomNode(i) {
try {
let td = document.evaluate(
"./td/a[starts-with(@href, 'javascript:PVM')]/..",
MZ_EtatCdMs.tr_monstres[i], null, 9, null
).singleNodeValue;
return td;
} catch (exc) {
avertissement(`[getMonstreNomNode] Impossible de trouver le monstre ${i}`, null, null, exc);
}
}
function getMonstreNom(i) {
return getMonstreNomByTR(MZ_EtatCdMs.tr_monstres[i], i);
}
function getMonstreNomByTR(tr, i = 'undef') {
try {
let nom = document.evaluate(
"./td/a[starts-with(@href, 'javascript:PVM')]/text()", tr, null, 2, null
).stringValue;
return nom.replace(/&#(\d+);/g, function (match, dec) {
return String.fromCharCode(dec);
});
} catch (exc) {
avertissement(`[getMonstreNom] Impossible de trouver le monstre ${i}`, null, null, exc);
}
}
function getMonstrePosition(i) {
let tds = MZ_EtatCdMs.tr_monstres[i].childNodes;
return [
parseInt(tds[MZ_EtatCdMs.indexCellX].textContent),
parseInt(tds[MZ_EtatCdMs.indexCellY].textContent),
parseInt(tds[MZ_EtatCdMs.indexCellN].textContent)
];
}
function isMonstreVisible(i) {
let tr = MZ_EtatCdMs.tr_monstres[i];
// logMZ('isMonstreVisible(' + i + '), display=' + tr.style.display);
return tr.style.display !== 'none';
}
function appendMonstres(txt) {
for (let i = 1; i <= MZ_EtatCdMs.nbMonstres; i++) {
txt = `${txt}${getMonstreID(i)};${getMonstreNom(i)};${positionToString(getMonstrePosition(i))}\n`;
}
return txt;
}
function getMonstres() {
let vue = getVue();
return appendMonstres(`${positionToString(getPosition())};${vue[0]};${vue[1]}\n`);
}
function bddMonstres(start, stop, limitH, limitV) {
start = start || 1;
stop = stop || MZ_EtatCdMs.nbMonstres;
stop = Math.min(MZ_EtatCdMs.nbMonstres, stop);
let txt = '';
let myPosition = getPosition();
for (let i = start; i <= stop; i++) {
let monstrePosition = getMonstrePosition(i);
if (MZ_deltaH(myPosition, monstrePosition) > limitH) {
continue;
}
if (MZ_deltaV(myPosition, monstrePosition) > limitV) {
continue;
}
if (!isMonstreVisible(i)) {
continue;
}
let thisTxt = `${getMonstreID(i)};${getMonstreNom(i).replace(';', ',').replace(/[\u2000-\u{FFFFF}]/ug, '?')};${positionToString(monstrePosition)}\n`;
//debugMZ(thisTxt);
txt += thisTxt;
}
return txt ? `#DEBUT MONSTRES\n${txt}#FIN MONSTRES\n` : '';
}
/** x~x Récup données Trolls ------------------------------------------- */
// Roule 12/07/2017 détecte les colonnes à partir des titres. Mamoune vient de les faire bouger :(
var COL_TROLL_DIST = 0; // celui-là, on le garde en dur
function getTrollDistance(i) {
return parseInt(tr_trolls[i].cells[COL_TROLL_DIST].textContent);
}
var MZ_cache_col_TrollID;
var MZ_cache_col_TrollNOM;
var MZ_cache_col_TrollGUILDE;
var MZ_cache_col_TrollNIV;
function MZ_find_col_titre(trs, titre) {
let l = titre.length;
for (let i = 0; i < trs[0].cells.length; i++) {
if (trs[0].cells[i].textContent.toLowerCase().substr(0, l) == titre) {
return i;
}
}
logMZ(`impossible de trouver la colonne de titre ${titre} dans ${trs[0].textContent}`);
return 0;
}
function getTrollID(i) {
if (MZ_cache_col_TrollID === undefined) {
MZ_cache_col_TrollID = MZ_find_col_titre(tr_trolls, 'réf');
}
// Roule 08/03/2017 protection
let iTroll = parseInt(tr_trolls[i].cells[MZ_cache_col_TrollID].textContent);
if (isNaN(iTroll)) {
return;
}
if (iTroll == 0) {
return;
}
return iTroll;
}
function getTrollNomNode(i) {
if (MZ_cache_col_TrollNOM === undefined) {
MZ_cache_col_TrollNOM = MZ_find_col_titre(tr_trolls, 'nom');
}
if (!tr_trolls[i]) {
logMZ(`getTrollNomNode: pas de Trol n°${i}`);
return;
}
return tr_trolls[i].cells[MZ_cache_col_TrollNOM];
}
function getTrollNivNode(i) {
if (MZ_cache_col_TrollNIV === undefined) {
MZ_cache_col_TrollNIV = MZ_find_col_titre(tr_trolls, 'niv');
}
return tr_trolls[i].cells[MZ_cache_col_TrollNIV];
}
function getTrollGuilde(i) {
if (MZ_cache_col_TrollGUILDE === undefined) {
MZ_cache_col_TrollGUILDE = MZ_find_col_titre(tr_trolls, 'guild');
}
return trim(tr_trolls[i].cells[MZ_cache_col_TrollGUILDE].textContent);
}
function getTrollGuildeID(i) {
if (MZ_cache_col_TrollGUILDE === undefined) {
MZ_cache_col_TrollGUILDE = MZ_find_col_titre(tr_trolls, 'guild');
}
if (tr_trolls[i].childNodes[MZ_cache_col_TrollGUILDE].childNodes.length > 0) {
let href;
try {
if (!tr_trolls[i].childNodes[MZ_cache_col_TrollGUILDE].firstChild || !tr_trolls[i].childNodes[MZ_cache_col_TrollGUILDE].firstChild.getAttribute) {
return -1;
} // Roule 21/12/2016 protection contre le "bug Marsak"
href = tr_trolls[i].childNodes[MZ_cache_col_TrollGUILDE].firstChild.getAttribute('href');
} catch (exc) { // debug pb remonté par Marsak
logMZ(`getTrollGuildeID: nb child=${tr_trolls[i].childNodes[MZ_cache_col_TrollGUILDE].childNodes.length}` + tr_trolls[i].innerHTML.replace(/</g, '‹'), exc);
return -1;
}
return href.substring(href.indexOf('(') + 1, href.indexOf(','));
}
return -1;
}
function MZ_getTrollPosition(i) {
let tds = tr_trolls[i].childNodes;
let l = tds.length;
return [
parseInt(tds[l - 3].textContent),
parseInt(tds[l - 2].textContent),
parseInt(tds[l - 1].textContent)
];
}
function bddTrolls(limitH, limitV) {
let myPosition = getPosition();
let txt = `#DEBUT TROLLS\n${numTroll};${positionToString(myPosition)}\n`;
let tabDedoubTroll = {};
tabDedoubTroll[numTroll] = true;
for (let i in tr_trolls) {
if (!tr_trolls[i].childNodes) {
continue;
}
let troll_id = getTrollID(i);
if (!troll_id) {
continue;
}
if (tabDedoubTroll[troll_id]) {
continue;
}
tabDedoubTroll[troll_id] = true;
let trollPosition = MZ_getTrollPosition(i);
if (MZ_deltaH(myPosition, trollPosition) > limitH) {
continue;
}
if (MZ_deltaV(myPosition, trollPosition) > limitV) {
continue;
}
let position;
try {
position = positionToString(trollPosition);
txt = `${txt}${troll_id};${position}\n`;
} catch (e) {
console.log(`vue externe, erreur sur le troll ${troll_id}`);
console.log(e);
}
}
return `${txt}#FIN TROLLS\n`;
}
/* [functions] Récup données Trésors */
function getTresorDistance(i) {
return MZ_getDistanceAvecSplit(tr_tresors[i].cells[0].innerText);
}
function MZ_getDistanceAvecSplit(cellTxt) {
cellTxt = cellTxt.replace('\u2007', ' ').replace('\u2212', '-');
let txtSplitted = cellTxt.split('|');
if (txtSplitted.length == 1) {
txtSplitted = cellTxt.split('/');
}
if (txtSplitted.length == 1) {
return parseInt(txtSplitted[0], 10);
}
let dH = Math.abs(txtSplitted[0]);
let dV = Math.abs(txtSplitted[1]);
return Math.max(dH, dV);
}
function getTresorID(i) {
let tds = tr_tresors[i].childNodes;
let l = tds.length;
return trim(tr_tresors[i].cells[l - 5].textContent);
}
function getTresorNom(i) {
let tds = tr_tresors[i].childNodes;
let l = tds.length;
// Utilisation de textContent pour régler le "bug de Pollux"
return trim(tr_tresors[i].cells[l - 4].textContent).replace(/&#(\d+);/g, function (match, dec) {
return String.fromCharCode(dec);
});
}
function getTresorPosition(i) {
let tds = tr_tresors[i].childNodes;
let l = tds.length;
return [
parseInt(tds[l - 3].textContent),
parseInt(tds[l - 2].textContent),
parseInt(tds[l - 1].textContent),
];
}
function bddTresors(dmin, start, stop, limitH, limitV) {
// On retire les trésors proches (dmin) pour Troogle à cause de leur description
dmin = dmin || 0;
start = start || 1;
stop = stop || nbTresors;
stop = Math.min(nbTresors, stop);
let myPosition = getPosition();
let txt = '';
for (let i = start; i <= stop; i++) {
let tresorPosition = getTresorPosition(i);
// debugMZ('bddTresors, i=' + i + ', ' + getTresorID(i)+';'+ getTresorNom(i)+';'+ positionToString(tresorPosition) + ', dmin=' + dmin + ', start=' + start + ', stop=' + stop + ', limitH=' + limitH + ', limitV=' + limitV + ', MZ_deltaH=' + MZ_deltaH(myPosition, tresorPosition) + ', MZ_deltaV=' + MZ_deltaV(myPosition, tresorPosition) + ', distance=' + getTresorDistance(i));
if (MZ_deltaH(myPosition, tresorPosition) > limitH) {
continue;
}
if (MZ_deltaV(myPosition, tresorPosition) > limitV) {
continue;
}
if (getTresorDistance(i) >= dmin) {
txt = `${txt}${getTresorID(i)};${getTresorNom(i).replace(/[\u2000-\u{FFFFF}]/ug, '?')};${positionToString(tresorPosition)}\n`;
}
}
return txt ? `#DEBUT TRESORS\n${txt}#FIN TRESORS\n` : '';
}
/** x~x Récup données Champignons -------------------------------------- */
// DEBUG: Pas de colonne "Référence" sur serveur de test
function getChampignonNom(i) {
return trim(tr_champignons[i].cells[2].textContent);
}
function getChampignonPosition(i) {
let tds = tr_champignons[i].childNodes;
let l = tds.length;
return [
parseInt(tds[l - 3].textContent),
parseInt(tds[l - 2].textContent),
parseInt(tds[l - 1].textContent)
];
}
function bddChampignons(limitH, limitV) {
let myPosition = getPosition();
let txt = '';
for (let i = 1; i <= nbChampignons; i++) {
let champignonPosition = getChampignonPosition(i);
if (MZ_deltaH(myPosition, champignonPosition) > limitH) {
continue;
}
if (MZ_deltaV(myPosition, champignonPosition) > limitV) {
continue;
}
txt = `${txt};${ // Les champis n'ont pas de Référence
getChampignonNom(i)};${positionToString(champignonPosition)}\n`;
}
return txt ? `#DEBUT CHAMPIGNONS\n${txt}#FIN CHAMPIGNONS\n` : '';
}
/* [functions] Récup données Lieux */
function getLieuDistance(i) {
return MZ_getDistanceAvecSplit(tr_tresors[i].cells[0].firstChild.nodeValue);
}
function getLieuID(i) {
return parseInt(tr_lieux[i].cells[2].textContent);
}
function getLieuNom(i) {
// Conversion ASCII pour éviter les bugs des Vues externes
return trim(tr_lieux[i].cells[3].textContent);
}
function getLieuPosition(i) {
let tds = tr_lieux[i].childNodes;
let l = tds.length;
return [
parseInt(tds[l - 3].textContent),
parseInt(tds[l - 2].textContent),
parseInt(tds[l - 1].textContent)
];
}
// function appendLieux(txt) {
// for (let i = 1; i < nbLieux + 1; i++) {
// // gath: 'x_lieux' is not defined
// let tds = x_lieux[i].childNodes;
// txt = `${txt}${tds[1].firstChild.nodeValue};${getLieuNom(i)};${tds[3].firstChild.nodeValue};${tds[4].firstChild.nodeValue};${tds[5].firstChild.nodeValue}\n`;
// }
// return txt;
// }
// function getLieux() {
// let vue = getVue();
// return appendLieux(`${positionToString(getPosition())};${vue[0]};${vue[1]}\n`);
// }
function bddLieux(start, stop, limitH, limitV) {
start = start || 1;
stop = stop || nbLieux;
stop = Math.min(nbLieux, stop);
let myPosition = getPosition();
let txt = '';
for (let i = start; i <= stop; i++) {
let lieuPosition = getLieuPosition(i);
if (MZ_deltaH(myPosition, lieuPosition) > limitH) {
continue;
}
if (MZ_deltaV(myPosition, lieuPosition) > limitV) {
continue;
}
txt = `${txt}${getLieuID(i)};${epure(getLieuNom(i))};${positionToString(lieuPosition)}\n`;
}
return txt ? `#DEBUT LIEUX\n${txt}#FIN LIEUX\n` : '';
}
/** x~x Gestion Préférences Utilisateur -------------------------------- */
function saveCheckBox(chkbox, pref) {
// Enregistre et retourne l'état d'une CheckBox
let etat = chkbox.checked;
MY_setValue(pref, etat ? 'true' : 'false');
return etat;
}
function recallCheckBox(chkbox, pref) {
// Restitue l'état d'une CheckBox
chkbox.checked = MY_getValue(pref) == 'true';
}
function saveComboBox(cbb, pref) {
if (!cbb) {
return;
}
// Enregistre et retourne l'état d'une ComboBox
let opt = cbb.options[cbb.selectedIndex];
if (!opt) {
return;
}
let etat = cbb.options[cbb.selectedIndex].value;
MY_setValue(pref, etat);
return etat;
}
function recallComboBox(cbb, pref) {
// Restitue l'état d'une ComboBox
let nb = MY_getValue(pref);
if (nb && cbb) {
cbb.value = nb;
}
return nb;
}
function synchroniseFiltres() {
// Récupération de toutes les options de la vue
let wasActive =
Number(recallComboBox(comboBoxNiveauMin, 'NIVEAUMINMONSTRE')) +
Number(recallComboBox(comboBoxNiveauMax, 'NIVEAUMAXMONSTRE')) +
(recallComboBox(comboBoxFamille, 'FAMILLEMONSTRE') == 0 ? 0 : 1); // Roule 30/01/2020 on obtient du non numérique si il y a filtre par famille
if (wasActive > 0) {
debutFiltrage('Monstres');
}
recallCheckBox(checkBoxGowapsS, 'NOGOWAPS');
recallCheckBox(checkBoxGowapsA, 'NOGOWAPA');
recallCheckBox(checkBoxMythiques, 'NOMYTH');
recallCheckBox(checkBoxEngages, 'NOENGAGE');
recallCheckBox(checkBoxLevels, 'NOLEVEL');
recallCheckBox(checkBoxIntangibles, 'NOINT');
recallCheckBox(checkBoxGG, 'NOGG');
recallCheckBox(checkBoxCompos, 'NOCOMP');
recallCheckBox(checkBoxBidouilles, 'NOBID');
recallCheckBox(checkBoxDiplo, `${numTroll}.diplo.off`);
recallCheckBox(checkBoxTrou, 'NOTROU');
recallCheckBox(checkBoxTresorsNonLibres, 'NOTRESORSNONLIBRES');
recallCheckBox(checkBoxTactique, 'NOTACTIQUE');
if (MY_getValue('NOINFOEM') != 'true') {
recallCheckBox(checkBoxEM, 'NOEM');
}
}
/** x~x Initialisation: Ajout des Boutons ------------------------------ */
function getVueScript() {
try {
let limitH, eLimitH = document.getElementById('MZvueExtMaxH');
if (eLimitH) {
limitH = eLimitH.value;
}
if (limitH != '') {
limitH = parseInt(limitH);
}
let limitV, eLimitV = document.getElementById('MZvueExtMaxV');
if (eLimitV) {
limitV = eLimitV.value;
}
if (limitV != '') {
limitV = parseInt(limitV);
}
let porteeVueExt;
if (limitH == '' || limitH == 0) {
MY_removeValue('MZ_VueExtMaxH');
porteeVueExt = getPorteVue()[2]; // vue limitée horizontale
limitH = 999;
} else {
MY_setValue('MZ_VueExtMaxH', limitH);
porteeVueExt = limitH;
}
if (limitV == '' || limitV == 0) {
MY_removeValue('MZ_VueExtMaxV');
limitV = 999;
} else {
MY_setValue('MZ_VueExtMaxV', limitV);
}
let txt = `${bddTrolls(limitH, limitV) +
bddMonstres(null, null, limitH, limitV) +
bddChampignons(limitH, limitV) +
bddTresors(null, null, null, limitH, limitV) +
bddLieux(null, null, limitH, limitV)
}#DEBUT ORIGINE\n${porteeVueExt};${positionToString(getPosition())
}\n#FIN ORIGINE\n`;
debugMZ(`getVueScript nbTrolls=${nbTrolls}, txt=${txt}`);
logMZ(`fin getVueScript`);
return txt;
} catch (exc) {
avertissement("[getVueScript] Erreur d'export vers Vue externe", null, null, exc);
}
}
/** x~x Menu Vue 2D ---------------------------------------------------- */
var vue2Ddata = {
'Bricol\' Vue': {
url: `${URL_bricol_mountyhall}vue_form.php`,
paramid: 'vue',
func: getVueScript,
extra_params: {
mode: 'vue_SP_Vue2',
screen_width: window.screen.width
}
},
'Vue du CCM': {
url: URL_vue_CCM,
paramid: 'vue',
func: getVueScript,
extra_params: {
id: `${numTroll};${positionToString(getPosition())}`
}
},
'Vue Gloumfs 2D': {
url: URL_vue_Gloumfs2D,
paramid: 'vue_mountyzilla',
func: getVueScript,
extra_params: {}
},
'Vue Gloumfs 3D': {
url: URL_vue_Gloumfs3D,
paramid: 'vue_mountyzilla',
func: getVueScript,
extra_params: {}
},
'Grouky Vue!': {
url: URL_vue_Grouky,
paramid: 'vue',
func: getVueScript,
extra_params: {
type_vue: 'V5b1'
}
},
'Cube': {
noform: true,
func: function () {
MZ_AnalyseVue.openVueExterne(`${URL_MZ}/${URL_vue_cube}`);
},
extra_params: {},
},
/* 'DEBUG': {
url: 'http://weblocal/testeur.php',
paramid: 'vue',
func: getVueScript,
extra_params: {}
},*/
};
function refresh2DViewButton() {
// = EventListener menu+bouton vue 2D
let vueext = document.getElementById('selectVue2D').value;
MY_setValue('VUEEXT', vueext);
let oParamVue = vue2Ddata[vueext];
let form = document.getElementById('viewForm');
form.innerHTML = '';
form.method = 'post';
form.action = oParamVue.url;
form.target = '_blank';
if (oParamVue.paramid) {
appendHidden(form, oParamVue.paramid, '');
}
for (let key in oParamVue.extra_params) {
appendHidden(form, key, oParamVue.extra_params[key]);
}
if (oParamVue.noform) {
appendButton(form, 'Voir', oParamVue.func);
} else {
appendSubmit(form, 'Voir',
() => {
logMZ('click voir vue externe');
document.getElementsByName(oParamVue.paramid)[0].value =
oParamVue.func();
}
);
}
}
function set2DViewSystem() {
// Initialise le système de vue 2D
// Recherche du point d'insertion
let center;
try {
// Roule 09/03/2019, encore un changement MH, je fais suivre comme je peux
center = document.getElementById('MHTitreH2');
// version initiale "pré-Roule"
if (!center) {
center = document.evaluate(
"//h2[@id='MHTitreH2']/following-sibling::center", document, null, 9, null
).singleNodeValue;
}
// Roule 09/12/2016 J'ai remplacé following-sibling::center par following-sibling::div suite à une modification MH
if (!center) {
center = document.evaluate(
"//h2[@id='MHTitreH2']/following-sibling::div", document, null, 9, null
).singleNodeValue;
}
} catch (exc) {
avertissement("Erreur d'initialisation du système de vue 2D", null, null, exc);
return;
}
// Récupération de la dernière vue utilisée
let vueext = MY_getValue('VUEEXT');
if (!vueext || !vue2Ddata[vueext]) {
// sinon, la vue Bricol'Trolls est employée par défaut
vueext = 'Bricol\' Vue';
}
try {
// Création du sélecteur de vue externe
let selectVue2D = document.createElement('select');
selectVue2D.id = 'selectVue2D';
selectVue2D.className = 'SelectboxV2';
// logMZ('[MZd ' + GM_info.script.version + '] préparation ' + Object.keys(vue2Ddata).length + ' types de vue, troll n°' + numTroll);
for (let view in vue2Ddata) {
appendOption(selectVue2D, view, view);
}
selectVue2D.value = vueext;
selectVue2D.onchange = refresh2DViewButton;
// Création du formulaire d'envoi (vide, le submit est géré via handler)
let form = document.createElement('form');
form.id = 'viewForm';
// Insertion du système de vue
let table = document.createElement('table');
let tr = appendTr(table);
let stylesEspacement = { paddingLeft: '1px', paddingRight: '1px', whiteSpace: 'nowrap' };
let td = appendTd(tr, stylesEspacement);
td.appendChild(selectVue2D); //.style.marginRight = '2px';
appendTdText(tr, 'Limiter à ', false, stylesEspacement);
td = appendTd(tr, stylesEspacement);
appendTextbox(td, 'input', 'MZvueExtMaxH', 3, 3, MY_getValue('MZ_VueExtMaxH'), 'MZvueExtMaxH');
appendTdText(tr, ' cases horizontales et ', false, stylesEspacement);
td = appendTd(tr, stylesEspacement);
appendTextbox(td, 'input', 'MZvueExtMaxV', 3, 3, MY_getValue('MZ_VueExtMaxV'), 'MZvueExtMaxV');
appendTdText(tr, ' cases verticales', false, stylesEspacement);
td = appendTd(tr, stylesEspacement);
// Roule : fontSize à 0 enlève le texte du bouton !!!! Qu'est-ce que c'est que le "bug de l'extra character" ?
//td.style.fontSize = '0px'; // gère le bug de l'extra character
td.appendChild(form);
if (center.id == 'MHTitreH2') { // 09/03/2019 nouvelle méthode
let eDiv = document.createElement('div');
eDiv.appendChild(table);
eDiv.style.witdth = '100%';
eDiv.style.textAlign = 'center';
table.style.width = '180px';
table.style.margin = '0 auto';
center.parentNode.insertBefore(eDiv, center.nextSibling);
} else { // ancienne méthode
center.insertBefore(table, center.firstChild);
insertBr(center.childNodes[1]);
}
// Appelle le handler pour initialiser le bouton de submit
refresh2DViewButton();
logMZ('fin préparation des vues externes');
} catch (exc) {
avertissement("Erreur de traitement du système de vue externe", null, null, exc);
}
}
/** x~x Tableau d'Infos ------------------------------------------------ */
function initialiseInfos() {
let infoTab = document.getElementById('infoTab'),
tbody = infoTab.tBodies[0],
thead = infoTab.createTHead(),
tr = appendTr(thead, 'mh_tdtitre'),
td = appendTdText(tr, 'INFORMATIONS', true),
span = document.createElement('span');
if (!infoTab) {
avertissement('Vue Position joueur : infoTab non trouvé');
return;
}
let ePosition = document.getElementById('position');
if (!ePosition) {
avertissement('Vue Position joueur : element non trouvée');
return;
}
let oPosition = JSON.parse(ePosition.getAttribute('data-position'));
if (!oPosition) {
avertissement('Vue Position joueur : data non trouvée');
return;
}
try {
currentPosition[0] = oPosition.x;
currentPosition[1] = oPosition.y;
currentPosition[2] = oPosition.n;
porteeVue = [];
porteeVue[0] = oPosition.vueH;
porteeVue[1] = oPosition.vueV;
porteeVue[2] = oPosition.porteeH;
porteeVue[3] = oPosition.porteeV;
} catch (exc) {
// Si on ne trouve pas le "X ="
logMZ('Vue Position joueur non trouvée', exc);
}
infoTab.id = 'infoTab'; // Pour scripts externes
tbody.id = 'corpsInfoTab';
tbody.rows[0].cells[0].colSpan = 2;
if (tbody.rows.length > 1) {
tbody.rows[1].cells[0].colSpan = 2;
}
td.colSpan = 3;
td.style.cursor = 'pointer';
/* quel intérêt de changer de className ? et ça fait bouger toute la frame d'un pixel ou deux, c'est désagréable
td.onmouseover = function() {
this.style.cursor = 'pointer';
this.className = 'mh_tdpage';
};
td.onmouseout = function() {
this.className = 'mh_tdtitre';
};
*/
td.onclick = function () {
toggleTableauInfos(false);
};
span.id = 'msgInfoTab';
span.style.display = 'none';
appendText(span,
` => Position : X = ${currentPosition[0]
}, Y = ${currentPosition[1]
}, N = ${currentPosition[2]
} --- Vue : ${porteeVue[0]}/${porteeVue[1]
} (${porteeVue[2]}/${porteeVue[3]})`,
true
);
td.appendChild(span);
tr = appendTr(tbody, 'mh_tdpage');
td = appendTdText(tr, 'EFFACER : ', true);
td.align = 'center';
td.className = 'mh_tdtitre';
td.width = 100;
td = appendTdCenter(tr, 2);
// DEBUG : à quoi servent les ids si on utilise des variables globales ?
checkBoxGG = appendCheckBoxSpan(td, 'delgg', filtreTresors, " Les GG'").firstChild;
checkBoxCompos = appendCheckBoxSpan(td, 'delcomp', filtreTresors, ' Les Compos').firstChild;
checkBoxBidouilles = appendCheckBoxSpan(td, 'delbid', filtreTresors, ' Les Bidouilles').firstChild;
checkBoxIntangibles = appendCheckBoxSpan(td, 'delint', filtreTrolls, ' Les Intangibles').firstChild;
checkBoxGowapsA = appendCheckBoxSpan(td, 'delgowapA', filtreMonstres, ' Les Gowaps Apprivoisés').firstChild;
checkBoxGowapsS = appendCheckBoxSpan(td, 'delgowapS', filtreMonstres, ' Les Gowaps Sauvages').firstChild;
checkBoxEngages = appendCheckBoxSpan(td, 'delengage', filtreMonstres, ' Les Engagés').firstChild;
checkBoxLevels = appendCheckBoxSpan(td, 'delniveau', toggleLevelColumn, ' Les Niveaux').firstChild;
checkBoxDiplo = appendCheckBoxSpan(td, 'delDiplo', refreshDiplo, ' La Diplomatie').firstChild;
checkBoxTrou = appendCheckBoxSpan(td, 'deltrou', filtreLieux, ' Les Trous').firstChild;
checkBoxMythiques = appendCheckBoxSpan(td, 'delmyth', filtreMonstres, ' Les Mythiques').firstChild;
if (MY_getValue('NOINFOEM') != 'true') {
checkBoxEM = appendCheckBoxSpan(td, 'delem', filtreMonstres, ' Les Composants EM').firstChild;
}
checkBoxTresorsNonLibres = appendCheckBoxSpan(td, 'deltres', filtreTresors, ' Les Trésors non libres').firstChild;
checkBoxTactique = appendCheckBoxSpan(td, 'deltactique', updateTactique, ' Les Infos tactiques').firstChild;
if (MY_getValue('INFOPLIE')) {
toggleTableauInfos(true);
}
}
function toggleTableauInfos(firstRun) {
let msg = document.getElementById('msgInfoTab'),
corps = document.getElementById('corpsInfoTab'),
infoplie = parseInt(MY_getValue('INFOPLIE')); // 27/032016 Roule, pb sur récupération booléen, force numérique
// logMZ('toggleTableauInfos(' + firstRun + '), début, INFOPLIE=' + MY_getValue('INFOPLIE') + ', !INFOPLIE=' + !MY_getValue('INFOPLIE') + ', infoplie=' + infoplie); // debug Roule
if (!firstRun) {
infoplie = !infoplie;
MY_setValue('INFOPLIE', infoplie ? 1 : 0); // 27/032016 Roule, pb sur récupération booléen, force numérique
// logMZ('toggleTableauInfos(' + firstRun + '), après toggle et set, INFOPLIE=' + MY_getValue('INFOPLIE') + ', infoplie=' + infoplie); // Debug Roule
}
if (infoplie) {
msg.style.display = '';
corps.style.display = 'none';
} else {
msg.style.display = 'none';
corps.style.display = '';
}
}
/* [functions] Filtres */
function prepareFiltrage(ref, width) {
if (!isDesktopView()) {
return false; // gath: skip si version mobile
}
// = Initialise le filtre 'ref'
let tdTitre;
try {
tdTitre = document.getElementById(`vue_toggle_selector_${ref.toLowerCase()}`).parentNode;
} catch (exc) {
warnMZ(`[prepareFiltrage] Référence filtrage ${ref} non trouvée`, exc);
return false;
}
if (width) {
tdTitre.width = `${width}px`;
}
// Ajout du tr de Filtrage (masqué)
let tbody = tdTitre.parentNode.parentNode;
let tr = appendTr(tbody, 'mh_tdpage');
tr.style.display = 'none';
tr.id = `trFiltre${ref}`;
let td = appendTd(tr);
td.colSpan = 5;
// Ajout du bouton de gestion de Filtrage
let tdBtn = insertAfterTd(tdTitre);
tdBtn.id = `tdInsert${ref}`;
let btn = appendButton(tdBtn, 'Filtrer');
btn.id = `btnFiltre${ref}`;
btn.onclick = function () {
debutFiltrage(ref);
};
return td;
}
function debutFiltrage(ref) {
// = Handler de début de filtrage (filtre 'ref')
let e = document.getElementById(`trFiltre${ref}`);
if (e) {
e.style.display = '';
}
let btn = document.getElementById(`btnFiltre${ref}`);
if (btn) {
btn.value = 'Annuler Filtre';
btn.onclick = function () {
finFiltrage(ref);
};
}
}
function finFiltrage(ref) {
// = Handler de fin de filtrage (filtre 'ref')
/* On réassigne le bouton 'Filtrer' */
document.getElementById(`trFiltre${ref}`).style.display = 'none';
let btn = document.getElementById(`btnFiltre${ref}`);
btn.value = 'Filtrer';
btn.onclick = function () {
debutFiltrage(ref);
};
/* Réinitialisation filtres */
document.getElementById(`str${ref}`).value = '';
switch (ref) {
case 'Monstres':
document.getElementById('nivMinMonstres').value = 0;
document.getElementById('nivMaxMonstres').value = 0;
document.getElementById('FamilleMonstres').value = 0;
break;
case 'Trolls':
document.getElementById('strGuildes').value = '';
}
/* Nettoyage (=lance le filtre) */
// Ici this = MZ.global = sandBox de travail de MZ
// Roule 11/03/2016, ne fonctionne plus, il faut traiter les cas
// this['filtre'+ref]();
switch (ref) {
case 'Monstres':
filtreMonstres();
break;
case 'Trolls':
filtreTrolls();
break;
case 'Tresors':
filtreTresors();
break;
case 'Lieux':
filtreLieux();
break;
default:
logMZ(`cas incongru dans finFiltrage : ${ref}`);
break;
}
}
function ajoutFiltreStr(td, nomBouton, id, onClick) {
let bouton = appendButton(td, nomBouton, onClick);
appendText(td, '\u00a0');
let textbox = appendTextbox(td, 'text', id, 15, 30);
textbox.onkeypress = function (event) {
try {
if (event.keyCode == 13) {
event.preventDefault();
bouton.click();
}
} catch (exc) {
avertissement(`Une erreur est survenue (ajoutFiltreStr)`, null, null, exc);
}
};
}
function ajoutFiltreMenu(tr, id, onChange, liste) {
let select = document.createElement('select');
select.id = id;
select.onchange = onChange;
appendOption(select, 0, 'Aucun');
if (liste == undefined) {
for (let i = 1; i <= 60; i++) {
appendOption(select, i, i);
}
} else {
liste.forEach((f) => {
appendOption(select, f, f);
});
}
tr.appendChild(select);
return select;
}
function ajoutDesFiltres() {
/* Monstres */
let td = prepareFiltrage('Monstres', 150);
if (td) {
ajoutFiltreStr(td, 'Nom du monstre:', 'strMonstres', filtreMonstres);
appendText(td, '\u00a0\u00a0\u00a0');
appendText(td, 'Niveau Min: ');
comboBoxNiveauMin = ajoutFiltreMenu(td, 'nivMinMonstres', filtreMonstres);
appendText(td, '\u00a0');
appendText(td, 'Niveau Max: ');
comboBoxNiveauMax = ajoutFiltreMenu(td, 'nivMaxMonstres', filtreMonstres);
appendText(td, '\u00a0');
appendText(td, 'Famille: ');
comboBoxFamille = ajoutFiltreMenu(td, 'FamilleMonstres', filtreMonstres, ['Animal', 'Insecte', 'Démon', 'Humanoide', 'Monstre', 'Mort-Vivant']);
}
/* Trõlls */
td = prepareFiltrage('Trolls', 70);
if (td) {
ajoutFiltreStr(td, 'Nom du trõll:', 'strTrolls', filtreTrolls);
appendText(td, '\u00a0\u00a0\u00a0');
ajoutFiltreStr(td, 'Nom de guilde:', 'strGuildes', filtreTrolls);
}
/* Trésors */
td = prepareFiltrage('Tresors', 75);
if (td) {
ajoutFiltreStr(td, 'Nom du trésor:', 'strTresors', filtreTresors);
}
/* Lieux */
td = prepareFiltrage('Lieux', 70);
if (td) {
ajoutFiltreStr(td, 'Nom du lieu:', 'strLieux', filtreLieux);
}
}
/** x~x Fonctions Monstres --------------------------------------------- */
function MZ_insertStyleNth(eStyle, newCol, newStyle, maxCol) { // DOMElement du style, numéro de colonne insérée, Style supplémentaire, nombre max de col (pas grave si c'est beaucoup plus grand)
// cette fonction patche la série de styles en "déplaçant" les colonnes qui suivent celle insérée
let sStyle = eStyle.innerHTML;
for (let i = maxCol; i >= newCol; i--) { // on déplace à partir de la fin
// Roule : j'avais utilisé string.replaceAll() mais ce n'est pas supporté par Firefox ESR
let rNeedle = new RegExp(`\\(${i + 1}\\)`, "g"); // les styles "nth" comptent à partir de "1"
sStyle = sStyle.replace(rNeedle, `(${i + 2})`);
}
sStyle = sStyle + newStyle;
eStyle.innerHTML = sStyle;
}
/* [functions] Affichage de la colonne des niveaux */
function insertLevelColumn() {
// Appelé dans le code attaché à la page de vue et au click/unclick de la checkbox
MZ_EtatCdMs.indexCellNivMZ = MZ_EtatCdMs.indexCellID + 1; // la colonne des niveaux sera insérée après la colonne des ID
MZ_EtatCdMs.indexCellX = MZ_EtatCdMs.indexCellX + 1; // et ça décale les colonnes suivantes
MZ_EtatCdMs.indexCellY = MZ_EtatCdMs.indexCellY + 1;
MZ_EtatCdMs.indexCellN = MZ_EtatCdMs.indexCellN + 1;
if (MZ_EtatCdMs.tr_monstres[1] && MZ_EtatCdMs.tr_monstres[1].cells[MZ_EtatCdMs.indexCellDist].innerText.indexOf('|') > -1)
MZ_EtatCdMs.tr_monstres[0].cells[MZ_EtatCdMs.indexCellDist].style.width = '50px'; // forcer l'affichage large
let td = insertThText(getMonstreLevelNode(0), 'Niv.', false);
td.style.width = '20px';
/* plus de colgroup le 08/07/2020. Mais comme ça pourrait revenir, je laisse le bout de code en commentaire (Roule)
let eColGroup = getMonstreLevelNode(0).closest('table').getElementsByTagName('colgroup')[0];
let eCol = document.createElement('col');
eCol.style.width= '35px';
insertBefore(eColGroup.children[3],eCol);
*/
let monsterStyle = document.getElementById('vue2toggle_monstres').getElementsByTagName('style')[0];
if (monsterStyle) {
let styleColNivMZ = `.mh_tdborder.footable#VueMONSTRE th:nth-child(${MZ_EtatCdMs.indexCellNivMZ + 1}) {width:35px; text-align:center;}`;
styleColNivMZ = `${styleColNivMZ}.mh_tdborder.footable#VueMONSTRE td:nth-child(${MZ_EtatCdMs.indexCellNivMZ + 1}) {font-weight:bold;text-align:center;}`;
MZ_insertStyleNth(monsterStyle, MZ_EtatCdMs.indexCellNivMZ, styleColNivMZ, MZ_EtatCdMs.indexCellN);
} else {
//logMZ("[MZ] vue, pas de style spécial monstre, pas d'adaptation");
}
td.id = 'MZ_TITRE_NIVEAU_MONSTRE';
for (let i = 1; i <= MZ_EtatCdMs.nbMonstres; i++) {
// logMZ('nbMonstres=' + MZ_EtatCdMs.nbMonstres + ', MZ_EtatCdMs.tr_monstres.length=' + MZ_EtatCdMs.tr_monstres.length); // debug Roule
td = insertTdText(getMonstreLevelNode(i), '-');
td.style.display = 'table-cell';
}
}
function toggleLevelColumn() { // Appelé par le code attaché à la page de vue et au click/unclick de la checkbox NOCDM
let eltMZ_TITRE_NIVEAU_MONSTRE = document.getElementById('MZ_TITRE_NIVEAU_MONSTRE'); // test si la colonne a déjà été ajoutée
if (saveCheckBox(checkBoxLevels, 'NOLEVEL')) {
if (!eltMZ_TITRE_NIVEAU_MONSTRE) {
return;
} // rien à faire si la colonne n'existe pas. C'est le cas à l'ouverture de la page avec NOCMD coché
// cacher tous les td
for (let i = 0; i <= MZ_EtatCdMs.nbMonstres; i++) {
getMonstreLevelNode(i).style.display = 'none';
}
} else if (!eltMZ_TITRE_NIVEAU_MONSTRE) {
insertLevelColumn();
retrieveCDMs();
} else {
// afficher tous les td
for (let i = 0; i <= MZ_EtatCdMs.nbMonstres; i++) {
getMonstreLevelNode(i).style.display = '';
}
}
}
/* [functions] Gestion de l'AFFICHAGE des CdMs */
function basculeCDM(nom, id) {
// = Bascule l'affichage des popups CdM
if (MZ_EtatCdMs.listeCDM[id]) {
if (!document.getElementById(`popupCDM${id}`)) {
afficherCDM(nom, id);
} else {
cacherPopupCDM(`popupCDM${id}`);
}
} else {
// DEBUG: prévoir un "else" ou désactiver l'effet onmouseover si pas de CdM
logMZ(`pas de CdM pour id=${id}, nom=${nom}`);
}
}
function cacherPopupCDM(titre) {
let popup = document.getElementById(titre);
popup.parentNode.removeChild(popup);
}
function removeTableFromClickEvent() { // "this" est supposé être un <td> ou <th> d'une <table>
let table = this.parentNode.parentNode.parentNode; // <tr><tbody/thead/tfoot><table>
table.parentNode.removeChild(table);
}
/* DEBUG: Section à mettre à jour */
var selectionFunction;
function startDrag(evt) {
winCurr = this.parentNode;
evt = evt || window.event; // est-ce utile sous FF ? sous FF24+ ?
offsetX = evt.pageX - parseInt(winCurr.style.left);
offsetY = evt.pageY - parseInt(winCurr.style.top);
selectionFunction = document.body.style.MozUserSelect;
document.body.style.MozUserSelect = 'none';
winCurr.style.MozUserSelect = 'none';
return false;
}
function stopDrag(evt) {
winCurr.style.MozUserSelect = selectionFunction;
document.body.style.MozUserSelect = selectionFunction;
winCurr = null;
}
function drag(evt) {
if (winCurr == null) {
return;
}
evt = evt || window.event;
winCurr.style.left = `${evt.pageX - offsetX}px`;
winCurr.style.top = `${evt.pageY - offsetY}px`;
return false;
}
/* FIN DEBUG */
if (!isPage("MH_Play/Play_equipement")) {
// Conflit overlib/Tout_MZ:
// Double définition du "onmousemove" sur la page d'équipement
document.onmousemove = drag;
}
function afficherCDM(nom, id) {
// Crée la table de CdM du mob n° id
let donneesMonstre = MZ_EtatCdMs.listeCDM[id];
/* Début création table */
let table = createCDMTable(id, nom, donneesMonstre, removeTableFromClickEvent);
/* Ajout du titre avec gestion Drag & Drop */
let tr = table.firstChild;
tr.style.cursor = 'move';
tr.onmousedown = startDrag;
tr.onmouseup = stopDrag;
table.id = `popupCDM${id}`;
table.style.position = 'fixed';
table.style.backgroundColor = 'rgb(229, 222, 203)';
table.style.zIndex = 1;
// let topY = +(300+(30*MZ_EtatCdMs.yIndexCDM))%(30*Math.floor((window.innerHeight-400)/30));
table.style.left = `${Number(window.innerWidth - 365)}px`;
table.style.width = '300px';
/* Fin création table & Affichage */
document.body.appendChild(table);
let topY = 90 + 30 * MZ_EtatCdMs.yIndexCDM;
// logMZ('topY=' + topY + ', offsetHeight=' + table.offsetHeight + ', innerHeight=' + window.innerHeight);
if (topY + table.offsetHeight > window.innerHeight) {
MZ_EtatCdMs.yIndexCDM = 0; // on se repositionne en haut s'il n'y a pas assez de place
topY = 90;
} else {
MZ_EtatCdMs.yIndexCDM++; // décalage pour la fois suivante
}
table.style.top = `${topY}px`;
}
/* [functions] Gestion de l'AFFICHAGE des Infos de combat */
function showPopupError(sHTML) {
logMZ(`affichage PopupError ${sHTML}`);
let divpopup = document.createElement('div');
divpopup.id = 'divpopup';
divpopup.style =
'position: fixed;' +
'border: 3px solid #000000;' +
'top: 300px;left: 10px;' +
'background-color: red;' +
'color: white;' +
'font-size: xx-large;' +
'z-index: 200;';
divpopup.innerHTML = sHTML;
let divcroix = document.createElement('div');
divcroix.style =
'position: absolute;' +
'top: 0;right: 0;' +
'color: inherit;' +
'font-size: inherit;' +
'cursor: pointer;' +
'z-index: 201;';
divcroix.innerHTML = "X";
divcroix.onclick = function () {
document.getElementById('divpopup').style.display = 'none';
};
document.body.appendChild(divpopup);
divpopup.appendChild(divcroix);
}
function retrieveCDMs() {
// Récupère les CdM disponibles dans la BDD
// Lancé uniquement sur toggleLevelColumn
if (checkBoxLevels.checked) {
return;
}
if (MZ_EtatCdMs.nbMonstres < 1) {
return;
}
let tReq = [];
let nbReq = 0;
let prevLastIndexDone = MZ_EtatCdMs.lastIndexDone;
let i = prevLastIndexDone + 1;
for (; i <= MZ_EtatCdMs.nbMonstres; i++) {
// tReq.push(i + "\t" + getMonstreID(i) + "\t" + getMonstreNom(i));
// ne pas demander pour les Gowaps
let nom = getMonstreNom(i);
if (nom.match(/^[^\[]*Gowap/i)) { // le mot Gowap peut être précédé par un template (qui ne contient donc pas [)
getMonstreLevelNode(i).innerHTML = '';
continue;
}
tReq.push({ index: i, id: getMonstreID(i), nom: nom });
nbReq++;
if (nbReq >= 500) {
break;
} // limitation pour ne pas faire attendre, et aussi car on a un dépassement mémoire coté serveur si c'est trop gros
}
MZ_EtatCdMs.lastIndexDone = i;
// let startAjaxCdM = new Date(); // WARNING (gath) - non utilisé -> commenté
logMZ(`${MZ_formatDateMS()} lancement AJAX ${nbReq} demandes niveaux monstres V2`);
FF_XMLHttpRequest({
method: 'POST',
url: URL_MZgetCaracMonstre,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
// data: 'l=' + tReq.join("\n"),
data: `l=${JSON.stringify(tReq)}`,
trace: 'demande niveaux monstres V2',
onload: function (responseDetails) {
let texte;
try {
// logMZ('retrieveCDMs readyState=' + responseDetails.readyState + ', error=' + responseDetails.error + ', status=' + responseDetails.status);
if (responseDetails.status == 0) {
return;
}
// logMZ('[MZd] ' + (+new Date) + ' ajax niv monstres début');
texte = responseDetails.responseText;
let infos = JSON.parse(texte);
displayScriptTime(new Date().getTime() - date_debut.getTime(), 'Analyse des CdM MZ');
if (infos.length == 0) {
return;
}
// ajouter les styles CSS pour les popup
addStyleSheet(`
.MZtooltip { position: relative;color:red;text-align:center; }
.MZtooltip .MZtooltiptext { visibility: hidden;width: 250px;padding: 5px 0;border:solid 1px;position: absolute;z-index: 1;color:black;background-color:white }
.MZtooltip:hover .MZtooltiptext {visibility: visible;}
`);
// if (MY_DEBUG) {
// for (let i = 0; i < 20; i++) logMZ('infos[' + i + ']=' + JSON.stringify(infos[i]));
// }
// let begin2, end2, index; // WARNING (gath) - non utilisé -> commenté
for (let j = 0; j < infos.length; j++) {
let info = infos[j];
if (info.index == undefined) {
continue;
}
let eTdLevel = getMonstreLevelNode(info.index);
this.className = 'mh_tdpage';
let myColor = undefined;
if (info.niv != undefined && info.niv.max == -1 && info.Mode != 'cdm') {
eTdLevel.className = "MZtooltip";
eTdLevel.style.color = "black";
eTdLevel.innerHTML = 'Var.<span class="MZtooltiptext">Ce monstre est variable.<br />On ne peut pas avoir d\'information sans CdM.</span>';
} else if (!(info && info.esq)) {
// debugMZ("pas d'esquive id=" + info.id + ", index=" + info.index);
eTdLevel.className = "MZtooltip";
eTdLevel.innerHTML = `${mkMinMaxHTML(info.niv)}<span class="MZtooltiptext">Désolé, pas de CdM dans MZ pour ce type de monstre (même âge, même template).<br />Vous pouvez aider en envoyant une CdM à MZ.</span>`;
} else {
eTdLevel.innerHTML = mkMinMaxHTML(info.niv);
// info.iTR = info.index; // Roule 29/04/2017 permet de récupérer la position du monstres dans analyseTactique (pour calcul de distance pour le PM). 15/11/2019 index contient l'info
myColor = MZ_CdMColorFromMode(info);
eTdLevel.style.cursor = 'pointer';
eTdLevel.onclick = function () {
basculeCDM(getMonstreNomByTR(this.parentNode), getMonstreIDByTR(this.parentNode));
};
}
eTdLevel.style.width = '20px';
MZ_EtatCdMs.listeCDM[info.id] = info;
if (myColor) {
eTdLevel.style.color = myColor;
}
/* Roule' à étudier plus tard, cette différence de style selon la diplo...
eTdLevel.onmouseover = function() {
this.className = 'mh_tdtitre';
};
eTdLevel.onmouseout = function() {
if(this.parentNode.diploActive=='oui') {
this.className = '';
} else {
this.className = 'mh_tdpage';
}
};
*/
}
debugMZ(`${MZ_formatDateMS()} ajax niv monstres avant computeMission`);
computeMission(prevLastIndexDone + 1, MZ_EtatCdMs.nbMonstres);
debugMZ(`${MZ_formatDateMS()} ajax niv monstres avant filtreMonstres`);
filtreMonstres(); // ajout Roule' 20/01/2017 car il y a des cas où les données arrivent après le filtrage
debugMZ(`${MZ_formatDateMS()} ajax niv monstres fin`);
document.body.dataset.MZ_Etat = 2; // indiquer aux scripts tiers qu'on a récupéré les carac
if (document.body.MZ_Callback_fin_vue !== undefined) {
for (let iCallback = 0; iCallback < document.body.MZ_Callback_fin_vue.length; iCallback++) {
document.body.MZ_Callback_fin_vue[iCallback]();
}
}
} catch (exc) {
logMZ(`retrieveCDMs: ${URL_MZgetCaracMonstre}\n${texte}`, exc);
}
// debugMZ('id=6376829, info=' + JSON.stringify(MZ_EtatCdMs.listeCDM[6376829]));
MZ_EtatCdMs.isCDMsRetrieved = true;
// afficher/supprimer le bouton pour demander la suite
let eltBoutonSuite = document.getElementById('MZ_boutonSuiteCdM');
debugMZ(`lastIndexDone=${MZ_EtatCdMs.lastIndexDone}, nbMonstres=${MZ_EtatCdMs.nbMonstres}, eltBoutonSuite=${eltBoutonSuite}`);
if (MZ_EtatCdMs.lastIndexDone < MZ_EtatCdMs.nbMonstres) {
if (eltBoutonSuite) {
replaceContentByText(eltBoutonSuite, `en cours ${MZ_EtatCdMs.lastIndexDone}/${MZ_EtatCdMs.nbMonstres}`);
retrieveCDMs(); // lancer la suite
} else {
eltBoutonSuite = document.createElement('div');
eltBoutonSuite.id = 'MZ_boutonSuiteCdM';
eltBoutonSuite.style.position = 'fixed';
eltBoutonSuite.style.border = '1px solid black';
eltBoutonSuite.style.top = '10px';
eltBoutonSuite.style.right = '10px';
// eltBoutonSuite.style.backgroundColor = 'white';
eltBoutonSuite.style.backgroundImage = 'url("/mountyhall/MH_Packs/packMH_parchemin/fond/fond2.jpg")';
eltBoutonSuite.style.color = 'black';
eltBoutonSuite.style.fontSize = 'large';
eltBoutonSuite.style.padding = '5px';
eltBoutonSuite.style.borderRadius = '10px';
eltBoutonSuite.style.cursor = 'pointer';
eltBoutonSuite.style.zIndex = '500';
appendText(eltBoutonSuite, `${nbReq} CdM(s) récupérées`);
appendBr(eltBoutonSuite); // C'est plus classe que d'utiliser innerHTML ☺
appendText(eltBoutonSuite, 'Cliquer ici pour demander les CdMs');
appendBr(eltBoutonSuite);
appendText(eltBoutonSuite, `des ${MZ_EtatCdMs.nbMonstres} monstres`);
eltBoutonSuite.title = 'Shift-Click pour faire disparaitre ce bouton sans demander les CdMs';
eltBoutonSuite.onclick = MZ_SuiteCdMs;
document.body.appendChild(eltBoutonSuite);
}
} else if (eltBoutonSuite) {
eltBoutonSuite.parentNode.removeChild(eltBoutonSuite);
}
},
});
debugMZ(`${MZ_formatDateMS()} requête ajax partie pour ${tReq.length} monstres`);
}
function MZ_CdMColorFromMode(info) {
switch (info.Mode) {
case 'cdm':
return 'blue';
case 'stat':
return 'purple';
case 'statV1':
return 'orange';
}
}
function MZ_SuiteCdMs(e) { // handler du click sur le bouton pour demander la suite des CdMs
let evt = e || window.event;
if (evt.shiftKey) {
this.parentNode.removeChild(this);
return;
}
replaceContentByText(this,`en cours ${MZ_EtatCdMs.lastIndexDone}/${MZ_EtatCdMs.nbMonstres}`);
this.title = 'Shift-Click pour faire disparaitre ce bouton';
this.style.cursor = ''; // default
this.onclick = MZ_SupprBoutonCdMs;
retrieveCDMs();
}
function MZ_SupprBoutonCdMs(e) {
let evt = e || window.event;
if (evt.shiftKey) {
this.parentNode.removeChild(this);
}
}
function mkMinMaxHTML(oMM) {
if (oMM == undefined) {
return '';
}
if (oMM.min == undefined) {
if (oMM.max == undefined) {
return;
}
return `\u2A7D${oMM.max}`; // U+2A7D "LESS-THAN OR SLANTED EQUAL TO"
}
if (oMM.max == undefined) {
return `\u2A7E${oMM.min}`; // U+2A7E "GREATER-THAN OR SLANTED EQUAL TO"
} else if (oMM.min == oMM.max) {
return oMM.min;
} else if (oMM.min < oMM.max) {
return `${oMM.min}-${oMM.max}`;
}
return `<span style="color:red">${oMM.min}-${oMM.max}</span>`;
}
function computeMission(begin, end) {
// pk begin/end ? --> parce qu'au chargement c'est RetrieveCdMs qui le lance
// +++logMZ('computeMission, begin=' + begin + ', end=' + end);
computeVLC(begin, end);
// +++logMZ('computeMission, après computeVLC');
begin = begin || 1;
end = end || MZ_EtatCdMs.nbMonstres;
let str = MY_getValue(`${numTroll}.MISSIONS`);
if (!str) {
return;
}
let urlImg = `${URL_MZimg}mission.png`;
let obMissions = JSON.parse(str);
for (let i = end; i >= begin; i--) {
let mess = '';
let bPeutEtreIcone = false;
for (let num in obMissions) {
let mobMission = false;
let mobMissionPeutEtre = undefined;
let donneesMonstre;
switch (obMissions[num].type) {
case 'Race':
let race = epure(obMissions[num].race.toLowerCase());
let nom = epure(getMonstreNom(i).toLowerCase());
if (nom.indexOf(race) != -1) {
if (race == 'crasc') {
if (nom.indexOf('medius') != -1) {
// pas éligible
} else if (nom.indexOf('maexus') != -1) {
// pas éligible
} else if (nom.indexOf('parasitus') != -1) {
if (nom.match(/^crasc parasitus \[/ui)) {
// on ne peut pas savoir
mobMissionPeutEtre = 'Impossible de savoir si ce monstre a comme race "Crasc" ou "Crasc Parasitus"\n' +
'Faire une CdM. Si la portée de pouvoir est "automatique", il s\'agit d\'un "Crasc", si elle est "au toucher", il s\'agit d\'un "Crasc Parasitus"';
} else {
// c'est un monstre de la race des Crasc Parasitus
mobMission = false;
}
} else {
mobMission = true;
}
} else if (race == 'crasc parasitus') {
if (nom.match(/^crasc parasitus \[/ui)) {
// on ne peut pas savoir
mobMissionPeutEtre = 'Impossible de savoir si ce monstre a comme race "Crasc" ou "Crasc Parasitus"\n' +
'Faire une CdM. Si la portée de pouvoir est "automatique", il s\'agit d\'un "Crasc", si elle est "au toucher", il s\'agit d\'un "Crasc Parasitus"';
} else {
// c'est un monstre de la race des Crasc Parasitus
mobMission = true;
}
} else if (race == 'shai') {
if (nom.match(/abishai/ui)) {
mobMission = false;
} else {
mobMission = true;
}
} else if (race == 'ombre') {
if (nom.match(/roche/ui)) {
mobMission = false;
} else {
mobMission = true;
}
} else if (race == 'geck\'oo') {
if (nom.match(/majestueux/ui)) {
mobMission = false;
} else {
mobMission = true;
}
} else if (race == 'bouj\'dla') {
if (nom.match(/placide/ui)) {
mobMission = false;
} else {
mobMission = true;
}
} else {
mobMission = true;
}
}
break;
case 'Niveau':
let minMimi, maxMimi;
donneesMonstre = MZ_EtatCdMs.listeCDM[getMonstreID(i)];
if (donneesMonstre) {
let nivMimi = Number(obMissions[num].niveau);
let mod = obMissions[num].mod; // mission nivMimi±mod si mod est numérique, sinon, c'est >= nivMimi
if (isNaN(mod)) {
minMimi = nivMimi;
maxMimi = nivMimi + 999999;
} else {
minMimi = nivMimi - mod;
maxMimi = nivMimi + mod;
}
if (donneesMonstre.niv) { // nouveau mode
if (donneesMonstre.niv.max && donneesMonstre.niv.min) {
if (donneesMonstre.niv.max <= maxMimi && donneesMonstre.niv.min >= minMimi) {
mobMission = true;
} else if (!(donneesMonstre.niv.max < minMimi || donneesMonstre.niv.min > maxMimi)) {
mobMissionPeutEtre = 'Il reste à déterminer le niveau exact du monstre';
if (isDEV) {
mobMissionPeutEtre = `${mobMissionPeutEtre}\nMonstre=(${donneesMonstre.niv.min}, ${donneesMonstre.niv.max}), mimi=(${minMimi}, ${maxMimi})`;
}
}
} else if (donneesMonstre.niv.max) {
if (donneesMonstre.niv.max >= minMimi) {
mobMissionPeutEtre = 'Il reste à déterminer le niveau exact du monstre';
}
} else if (donneesMonstre.niv.min) {
if (donneesMonstre.niv.min <= maxMimi) {
mobMissionPeutEtre = 'Il reste à déterminer le niveau exact du monstre';
}
}
}
}
break;
case 'Famille':
donneesMonstre = MZ_EtatCdMs.listeCDM[getMonstreID(i)];
if (donneesMonstre && donneesMonstre.fam) {
let familleMimi = epure(obMissions[num].famille.toLowerCase()).replace(/[']/g, ''); // Roule 27/02/2019 simple quote dans les familles
let familleMob = epure(donneesMonstre.fam.toLowerCase());
if (familleMob.indexOf(familleMimi) != -1) {
mobMission = true;
}
}
break;
case 'Pouvoir':
donneesMonstre = MZ_EtatCdMs.listeCDM[getMonstreID(i)];
if (donneesMonstre && donneesMonstre.pouv) {
let pvrMimi = epure(obMissions[num].pouvoir.toLowerCase());
let pvrMob = epure(donneesMonstre.pouv.toLowerCase());
if (pvrMob.indexOf(pvrMimi) != -1) {
mobMission = true;
}
}
}
if (mobMission) {
mess = mess + (mess ? '\n\n' : '');
mess = `${mess}Mission ${num} :\n${obMissions[num].libelle}`;
} else if (mobMissionPeutEtre !== undefined) {
mess = mess + (mess ? '\n\n' : '');
mess = `${mess}${mobMissionPeutEtre}\n`;
bPeutEtreIcone = true;
mess = `${mess}Mission ${num} :\n${obMissions[num].libelle}`;
}
}
if (mess) {
let td = getMonstreNomNode(i);
appendText(td, ' ');
let myURL;
if (bPeutEtreIcone) {
myURL = `${URL_MZimg}missionX.png`;
} else {
myURL = urlImg;
}
td.appendChild(createImage(myURL, mess));
}
}
}
function computeVLC(begin, end) {
// pk begin/end ? --> parce qu'au chargement c'est RetrieveCdMs qui le lance via computeMission
// +++logMZ('computeVLC, begin=' + begin + ', end=' + end);
computeTactique(begin, end);
// +++logMZ('computeVLC, après computeTactique');
begin = begin || 1;
end = end || MZ_EtatCdMs.nbMonstres;
let cache = getSortComp("Invisibilité") > 0 || getSortComp("Camouflage") > 0;
if (!cache) {
return false;
}
let urlImg = `${URL_MZimg}oeil.png`;
for (let i = end; i >= begin; i--) {
let id = getMonstreID(i);
let donneesMonstre = MZ_EtatCdMs.listeCDM[id];
if (donneesMonstre && donneesMonstre.vlc) {
// if (donneesMonstre) logMZ('computeVLC i=' + i + ' id=' + id + ' ' + JSON.stringify(donneesMonstre));
let td = getMonstreNomNode(i);
td.appendChild(document.createTextNode(" "));
td.appendChild(createImage(urlImg, "Voit le caché"));
}
if (donneesMonstre && donneesMonstre.gen) {
let imgPh, txtPh;
switch (donneesMonstre.gen) {
case 1:
imgPh = `${URL_MZimg}Phoenix1.png`;
txtPh = 'Phœnix de première génération';
break;
case 2:
imgPh = `${URL_MZimg}Phoenix2.png`;
txtPh = 'Phœnix de deuxième génération';
break;
case 3:
imgPh = `${URL_MZimg}Phoenix3.png`;
txtPh = 'Phœnix de troisième génération';
break;
case 23:
imgPh = `${URL_MZimg}Phoenix23.png`;
txtPh = 'Phœnix de deuxième ou troisième génération';
break;
}
let td = getMonstreNomNode(i);
td.appendChild(document.createTextNode(" "));
let img = td.appendChild(createImage(imgPh, txtPh));
img.style.height = '15px';
img.style.width = 'auto';
}
}
}
/* appelé
par updateTactique
par initialiseInfos
par do_vue
par computeVLC
par computeMission
par filtreMonstres
par retrieveCDMs
*/
function computeTactique(begin, end) {
// pk begin/end ? --> parce qu'au chargement c'est RetrieveCdMs qui le lance via computeVLC
begin = begin || 1;
end = end || MZ_EtatCdMs.nbMonstres;
let j = end;
try {
// +++logMZ('computeTactique, begin=' + begin + ', end=' + end + ', checkBoxTactique=' + checkBoxTactique);
let noTactique = saveCheckBox(checkBoxTactique, 'NOTACTIQUE');
// +++logMZ('computeTactique, noTactique=' + noTactique);
if (noTactique || !isProfilActif()) {
return;
}
// +++logMZ('computeTactique, après isProfilActif');
for (; j >= begin; j--) {
let id = getMonstreID(j);
let nom = getMonstreNom(j);
let donneesMonstre = MZ_EtatCdMs.listeCDM[id];
let bShowTactique = false;
if (donneesMonstre && donneesMonstre.esq) {
bShowTactique = true;
}
if (bShowTactique) {
let td = getMonstreNomNode(j);
if (!td) {
logMZ(`computeTactique, pas de <td> pour j=${j}`);
continue;
}
appendText(td, ' ');
td.appendChild(MZ_Tactique.createImage(id, nom));
}
}
} catch (exc) {
logMZ(`computeTactique: mob num : ${j}`, exc);
}
filtreMonstres();
}
function updateTactique() {
// = Handler checkBox noTactique
let noTactique = saveCheckBox(checkBoxTactique, 'NOTACTIQUE');
// +++logMZ('updateTactique, noTactique=' + noTactique);
if (!MZ_EtatCdMs.isCDMsRetrieved) {
return;
}
// +++logMZ('updateTactique, isCDMsRetrieved=' + MZ_EtatCdMs.isCDMsRetrieved);
if (noTactique) {
for (let i = MZ_EtatCdMs.nbMonstres; i > 0; i--) {
let tr = getMonstreNomNode(i);
let img = document.evaluate(`img[@src='${URL_MZimg}calc2.png']`, tr, null, 9, null).singleNodeValue;
if (img) {
img.parentNode.removeChild(img.previousSibling);
img.parentNode.removeChild(img);
}
}
} else {
computeTactique();
}
}
function filtreMonstres() {
// = Handler universel pour les fonctions liées aux monstres
let urlImg = `${URL_MZimg}Competences/ecritureMagique.png`,
urlEnchantImg = `${URL_MZimg}enchant.png`;
/* Vérification/Sauvegarde de tout ce qu'il faudra traiter */
let useCss = MY_getValue(`${numTroll}.USECSS`) == 'true';
let noGowapsS = saveCheckBox(checkBoxGowapsS, 'NOGOWAPS');
let noGowapsA = saveCheckBox(checkBoxGowapsA, 'NOGOWAPA');
let noEngages = saveCheckBox(checkBoxEngages, 'NOENGAGE');
let nivMin = saveComboBox(comboBoxNiveauMin, 'NIVEAUMINMONSTRE');
let nivMax = saveComboBox(comboBoxNiveauMax, 'NIVEAUMAXMONSTRE');
let famille = saveComboBox(comboBoxFamille, 'FAMILLEMONSTRE');
// old/new : détermine s'il faut ou non nettoyer les tr
let oldNOEM = true, noEM = true;
if (MY_getValue('NOINFOEM') != 'true') {
noEM = saveCheckBox(checkBoxEM, 'NOEM');
}
// Filtrage par nom
let eMonstre = document.getElementById('strMonstres');
if (!eMonstre) {
return;
} // cas smartphone
let strMonstre = eMonstre.value.toLowerCase();
// Génère la liste des mobs engagés (si filtrés)
if (noEngages && !isEngagesComputed) {
for (let i = nbTrolls; i > 0; i--) {
let pos = MZ_getTrollPosition(i);
if (!listeEngages[pos[0]]) {
listeEngages[pos[0]] = {};
}
if (!listeEngages[pos[0]][pos[1]]) {
listeEngages[pos[0]][pos[1]] = {};
}
listeEngages[pos[0]][pos[1]][pos[2]] = 1;
}
isEngagesComputed = true;
}
/** * FILTRAGE ***/
/* À computer :
* - EM (nom suffit)
* - Enchant (nom suffit)
* - Mission (nécessite CdM)
* - mob VlC (nécessite CdM)
* Sans computation :
* - Gowap ? engagé ?
*/
for (let i = MZ_EtatCdMs.nbMonstres; i > 0; i--) {
let pos = getMonstrePosition(i);
let nom = getMonstreNom(i).toLowerCase();
if (noEM != oldNOEM) {
let tr = getMonstreNomNode(i);
if (noEM) {
// Si noEM passe de false à true, on nettoie les td "Nom"
// DEBUG: Sauf que ce serait carrément mieux avec des id...
while (tr.childNodes.length > 1) {
tr.removeChild(tr.childNodes[1]);
}
} else {
let TypeMonstre = getEM(nom);
if (TypeMonstre != '') {
let infosCompo = compoMobEM(TypeMonstre);
if (infosCompo.length > 0) {
tr.appendChild(document.createTextNode(' '));
tr.appendChild(createImage(urlImg, infosCompo));
}
}
}
}
if (needComputeEnchantement || noEM != oldNOEM && noEM) {
let texte = getInfoEnchantementFromMonstre(nom);
if (texte != '') {
let td = getMonstreNomNode(i);
td.appendChild(document.createTextNode(' '));
td.appendChild(createImage(urlEnchantImg, texte));
}
}
let dataV2 = MZ_EtatCdMs.listeCDM[getMonstreID(i)];
MZ_EtatCdMs.tr_monstres[i].style.display =
noGowapsS &&
nom.indexOf('gowap sauvage') != -1 &&
getMonstreDistance(i) > 1 ||
noGowapsA &&
nom.indexOf('gowap apprivoisé') != -1 &&
getMonstreDistance(i) > 1 ||
noEngages &&
getMonstreDistance(i) != 0 &&
listeEngages[pos[0]] &&
listeEngages[pos[0]][pos[1]] &&
listeEngages[pos[0]][pos[1]][pos[2]] ||
strMonstre != '' &&
nom.indexOf(strMonstre) == -1 ||
isMonstreLevelOutLimit(i, nivMin, nivMax) &&
getMonstreDistance(i) > 1 &&
nom.toLowerCase().indexOf("kilamo") == -1 ||
famille != '0' &&
dataV2 &&
dataV2.fam &&
dataV2.fam != famille ?
'none' : '';
}
if (MY_getValue('NOINFOEM') != 'true') {
if (noEM != oldNOEM) {
if (noEM && MZ_EtatCdMs.isCDMsRetrieved) {
computeMission();
}
}
oldNOEM = noEM;
}
needComputeEnchantement = false;
}
/** x~x Fonctions Trõlls ----------------------------------------------- */
function filtreTrolls() {
let noIntangibles = saveCheckBox(checkBoxIntangibles, 'NOINT');
let strTroll = document.getElementById('strTrolls').value.toLowerCase();
let strGuilde = document.getElementById('strGuildes').value.toLowerCase();
for (let i = 1; i <= nbTrolls; i++) {
tr_trolls[i].style.display =
noIntangibles &&
getTrollNomNode(i).firstChild.className == 'mh_trolls_0' ||
strTroll != '' &&
getTrollNomNode(i).textContent.toLowerCase().indexOf(strTroll) == -1 ||
strGuilde != '' &&
getTrollGuilde(i).toLowerCase().indexOf(strGuilde) == -1 ?
'none' : '';
}
}
/* [functions] Bulle PX Trolls */
function initPXTroll() {
let bulle = document.createElement('div');
bulle.id = 'bulleTrollPX';
let ui_classes = isDesktopView() ? 'mh_textbox mh_tdtitre' : 'ui-body-a ui-corner-all';
bulle.className = `${ui_classes}`;
bulle.style =
'position: absolute;' +
'visibility: hidden;' +
'display: inline;' +
'z-index: 2;';
document.body.appendChild(bulle);
for (let i = nbTrolls; i > 0; i--) {
let td_niv = getTrollNivNode(i);
td_niv.onmouseover = showPXTroll;
td_niv.onmouseout = hidePXTroll;
}
}
function showPXTroll(evt) {
let lvl = this.firstChild.nodeValue;
let lvInt = isLetter(lvl[0]) ? lvl.substring(1) : lvl;
let bulle = document.getElementById('bulleTrollPX');
bulle.innerHTML = `Niveau ${lvInt}${analysePXTroll(lvInt)}`;
bulle.style.left = `${evt.pageX + 15}px`;
bulle.style.top = `${evt.pageY}px`;
bulle.style.visibility = 'visible';
}
function hidePXTroll() {
let bulle = document.getElementById('bulleTrollPX');
bulle.style.visibility = 'hidden';
}
/* [functions] Envoi PX / MP */
function putBoutonPXMP() {
// Bouton d'initialisation du mode Envoi
// WARNING - Nécessite que le Filtre Trõll ait été mis en place
let td = document.getElementById('tdInsertTrolls');
if (!td) {
return;
}
td.width = 100;
td = insertAfterTd(td);
td.style.verticalAlign = 'top';
let bouton = appendButton(td, 'Envoyer...', prepareEnvoi);
bouton.id = 'btnEnvoi';
}
function prepareEnvoi() {
// = 1er Handler du bouton d'envoi
/* Ajout de la colonne des CheckBoxes */
let td = insertThText(getTrollNomNode(0), '');
td.style.width = '17px';
for (let i = nbTrolls; i > 0; i--) {
td = insertTd(getTrollNomNode(i));
td.style.width = '17px';
appendCheckBox(td, `envoi${i}`);
}
/* Ajout du radio de choix PX ou MP */
let btnEnvoi = document.getElementById('btnEnvoi');
if (!btnEnvoi) {
return;
}
let tdEnvoi = btnEnvoi.parentNode;
appendText(tdEnvoi, ' ');
let label = document.createElement('label');
label.style.whiteSpace = 'nowrap';
let radioElt = document.createElement('input');
radioElt.type = 'radio';
radioElt.name = 'envoiPXMP';
radioElt.id = 'radioPX';
label.appendChild(radioElt);
appendText(label, 'des PX ');
tdEnvoi.appendChild(label);
label = document.createElement('label');
radioElt = document.createElement('input');
radioElt.type = 'radio';
radioElt.name = 'envoiPXMP';
radioElt.checked = true;
label.appendChild(radioElt);
appendText(label, 'un MP');
tdEnvoi.appendChild(label);
/* Insertion du bouton Annuler */
insertButton(btnEnvoi, 'Annuler', annuleEnvoi);
/* Modification de l'effet du bouton Envoi */
document.getElementById('btnEnvoi').onclick = effectueEnvoi;
}
function annuleEnvoi() {
// = Handler bouton Annuler
/* Nettoyage du td du bouton Envoi */
let btnEnvoi = document.getElementById('btnEnvoi');
let tdEnvoi = btnEnvoi.parentNode;
while (tdEnvoi.firstChild) {
tdEnvoi.removeChild(tdEnvoi.firstChild);
}
/* Retour à l'effet de base du bouton Envoi */
btnEnvoi.onclick = prepareEnvoi;
tdEnvoi.appendChild(btnEnvoi);
/* Suppression CheckBoxes */
for (let i = nbTrolls; i >= 0; i--) {
let td = getTrollNomNode(i);
td.parentNode.removeChild(td);
}
}
function effectueEnvoi() {
// = 2e Handler du bouton d'envoi (charge un nouveau frame)
let str = '';
let errID = false;
for (let i = nbTrolls; i > 0; i--) {
let chb = document.getElementById(`envoi${i}`);
if (chb.checked) {
let idTroll = getTrollID(i);
if (idTroll == undefined) {
errID = true;
} else {
str = str + ((str ? ',' : '') + idTroll);
}
}
}
if (errID) {
avertissement('MZ : il y a eu une erreur dans la liste, vérifiez à qui vous faites l\'envoi');
}
let PXchecked = document.getElementById('radioPX').checked;
if (PXchecked) {
window.open(`./Play_a_Action.php?type=A&id=9&dest=${str}`, 'Contenu');
} else {
window.open(`../Messagerie/MH_Messagerie.php?cat=3&dest=${str}`, 'Contenu');
}
}
/** x~x Fonctions Trésors ---------------------------------------------- */
function filtreTresors() {
// += Handler checkboxes : gg, compos, bidouilles, non libres
let noGG = saveCheckBox(checkBoxGG, 'NOGG');
let noCompos = saveCheckBox(checkBoxCompos, 'NOCOMP');
let noBidouilles = saveCheckBox(checkBoxBidouilles, 'NOBID');
let noEngages = saveCheckBox(checkBoxTresorsNonLibres, 'NOTRESORSNONLIBRES');
if (noEngages && !isEngagesComputed) {
for (let i = nbTrolls; i > 0; i--) {
let pos = MZ_getTrollPosition(i);
if (!listeEngages[pos[2]]) {
listeEngages[pos[2]] = [];
}
if (!listeEngages[pos[2]][pos[1]]) {
listeEngages[pos[2]][pos[1]] = [];
}
listeEngages[pos[2]][pos[1]][pos[0]] = 1;
}
isEngagesComputed = true;
}
let strTresor = document.getElementById('strTresors').value.toLowerCase();
for (let i = nbTresors; i > 0; i--) {
let nom = getTresorNom(i);
let pos = getTresorPosition(i);
tr_tresors[i].style.display =
noGG &&
nom.indexOf('Gigots de Gob') != -1 ||
noCompos &&
nom.indexOf('Composant') != -1 ||
noEngages &&
listeEngages[pos[2]] &&
listeEngages[pos[2]][pos[1]] &&
listeEngages[pos[2]][pos[1]][pos[0]] &&
getTresorDistance(i) > 0 ||
strTresor != '' &&
nom.toLowerCase().indexOf(strTresor) == -1 ||
noBidouilles &&
nom.indexOf('Bidouille') != -1 ?
'none' : '';
}
}
/** x~x Fonctions Lieux ------------------------------------------------ */
function filtreLieux() {
// += Handler checkbox trous
let noTrou = saveCheckBox(checkBoxTrou, 'NOTROU');
let strLieu = document.getElementById('strLieux').value.toLowerCase();
for (let i = nbLieux; i > 0; i--) {
tr_lieux[i].style.display =
strLieu &&
getLieuNom(i).toLowerCase().indexOf(strLieu) == -1 ||
noTrou &&
getLieuNom(i).toLowerCase().indexOf("trou de météorite") != -1 &&
getLieuDistance(i) > 1 ? 'none' : '';
}
}
/** x~x Diplomatie ----------------------------------------------------- */
function refreshDiplo() {
MY_setValue(`${numTroll}.diplo.off`,
checkBoxDiplo.checked ? 'true' : 'false'
);
if (isDiploRaw) {
computeDiplo();
}
appliqueDiplo();
}
function computeDiplo() {
// On extrait les données de couleur et on les stocke par id
// Ordre de préséance :
// source Guilde < source Perso
// guilde cible < troll cible
/* Diplo de Guilde */
diploGuilde = MY_getValue(`${numTroll}.diplo.guilde`) ? JSON.parse(MY_getValue(`${numTroll}.diplo.guilde`)) : {};
if (diploGuilde && diploGuilde.isOn == 'true') {
// Guilde perso
if (diploGuilde.guilde) {
Diplo.Guilde[diploGuilde.guilde.id] = {
couleur: diploGuilde.guilde.couleur,
titre: 'Ma Guilde'
};
}
// Guildes/Trolls A/E
for (let AE in { Amis: 0, Ennemis: 0 }) {
for (let i = 0; i < 5; i++) {
if (!diploGuilde[AE + i]) {
continue;
}
for (let type in { Guilde: 0, Troll: 0 }) {
let liste = diploGuilde[AE + i][type].split(';');
for (let j = liste.length - 2; j >= 0; j--) {
Diplo[type][liste[j]] = {
couleur: diploGuilde[AE + i].couleur,
titre: diploGuilde[AE + i].titre
};
}
}
}
}
}
/* Diplo Perso */
// let diploPerso = MY_getValue(numTroll+'.diplo.perso') ? JSON.parse(MY_getValue(numTroll+'.diplo.perso')) : {}; // déjà chargé
if (diploPerso && diploPerso.isOn == 'true') {
for (let type in { Guilde: 0, Troll: 0, Monstre: 0 }) {
for (let id in diploPerso[type]) {
Diplo[type][id] = diploPerso[type][id];
}
}
}
if (diploPerso.mythiques) {
Diplo.mythiques = diploPerso.mythiques;
}
isDiploRaw = false;
}
function appliqueDiplo() {
let aAppliquer = Diplo;
if (checkBoxDiplo.checked) {
// Pour retour à l'affichage basique sur désactivation de la diplo
aAppliquer = {
Guilde: {},
Troll: {},
Monstre: {}
};
}
/* On applique "aAppliquer" */
// Diplo Trõlls
for (let i = nbTrolls; i > 0; i--) {
let idG = getTrollGuildeID(i);
let idT = getTrollID(i);
let tr = tr_trolls[i];
// logMZ('diplo i=' + i + ', troll=' + idT + ', guilde=' + idG + ', HTML=' + tr.innerHTML);
if (aAppliquer.Troll[idT]) {
tr.classList.remove('mh_tdpage');
let descr = aAppliquer.Troll[idT].titre;
if (descr) {
getTrollNomNode(i).title = descr;
}
tr.style.backgroundColor = aAppliquer.Troll[idT].couleur;
} else if (aAppliquer.Guilde[idG]) {
tr.classList.remove('mh_tdpage');
let descr = aAppliquer.Guilde[idG].titre;
if (descr) {
getTrollNomNode(i).title = descr;
}
tr.style.backgroundColor = aAppliquer.Guilde[idG].couleur;
} else {
tr.classList.add('mh_tdpage'); // ne fait rien si déjà là
getTrollNomNode(i).removeAttribute('title');
}
}
// Diplo Monstres
for (let i = MZ_EtatCdMs.nbMonstres; i > 0; i--) {
let id = getMonstreID(i);
let nom = getMonstreNom(i).toLowerCase();
let tr = MZ_EtatCdMs.tr_monstres[i];
if (aAppliquer.Monstre[id]) {
tr.className = '';
tr.style.backgroundColor = aAppliquer.Monstre[id].couleur;
tr.diploActive = 'oui';
let descr = aAppliquer.Monstre[id].titre;
if (descr) {
getMonstreNomNode(i).title = descr;
}
} else if (aAppliquer.mythiques &&
(nom.indexOf('liche') == 0 ||
nom.indexOf('hydre') == 0 ||
nom.indexOf('balrog') == 0 ||
nom.indexOf('beholder') == 0 ||
nom.indexOf('sidoine') == 0)) {
tr.className = '';
tr.style.backgroundColor = aAppliquer.mythiques;
tr.diploActive = 'oui';
getMonstreNomNode(i).title = 'Monstre Mythique';
} else {
tr.className = 'mh_tdpage';
tr.diploActive = '';
}
}
}
/** x~x Actions à distance --------------------------------------------- */
function computeActionDistante(dmin, dmax, keltypes, oussa, urlIcon, message) {
let monN = parseInt(getPosition()[2]),
isLdP = oussa == 'self';
for (let type in keltypes) {
debugMZ(`computeActionDistante(${dmin}, ${dmax}, ${oussa}, ${urlIcon}, ${message}) type=${type}`);
let alt = oussa == 'self' ? type.slice(0, -1) : oussa;
for (let i = VueContext[`nb${type}`]; i > 0; i--) {
let tr = VueContext[`tr_${type.toLowerCase()}`][i];
// Roule 11/03/2016, on passe par les nouvelles fonctions getXxxPosition et getXxxDistance
// let sonN = this['get'+type.slice(0,-1)+'Position'](i)[2];
// let d = this['get'+type.slice(0,-1)+'Distance'](i);
let sonN = getXxxPosition(type, i)[2];
let d = getXxxDistance(type, i);
let thismessage = message;
if (isLdP) {
let chanceToucher = getTalent("Lancer de Potions") + Math.min(10,
10 - 10 * d +
parseInt(MY_getValue(`${numTroll}.caracs.vue`)) +
parseInt(MY_getValue(`${numTroll}.caracs.vue.bm`))
);
thismessage = `${thismessage} (${chanceToucher}%)`;
}
if (sonN == monN && d >= dmin && d <= dmax) {
let iconeAction = document.evaluate(
`./descendant::img[@alt='${alt}']`, tr, null, 9, null
).singleNodeValue;
let tdAction = tr.getElementsByTagName('td')[1];
if (iconeAction) {
if (iconeAction.title) {
iconeAction.title = `${iconeAction.title}\n${thismessage}`;
} else {
iconeAction.title = thismessage;
}
iconeAction.src = urlIcon;
} else {
let icon = document.createElement('img');
icon.src = urlIcon;
icon.height = 20;
icon.alt = alt;
icon.title = thismessage;
tdAction.appendChild(icon);
}
tdAction.style.whiteSpace = 'nowrap';
}
}
}
}
function computeCharge() {
computeActionDistante(1,
getPortee(
Math.ceil(MY_getValue(`${numTroll}.caracs.pv`) / 10) +
MY_getValue(`${numTroll}.caracs.regeneration`)
),
{ Monstres: 1, Trolls: 1 },
'Attaquer',
`${MHicons}E_Metal09.png`,
'Cible à portée de Charge'
);
}
function computeProjo() {
computeActionDistante(0,
getPortee(
parseInt(MY_getValue(`${numTroll}.caracs.vue`)) +
parseInt(MY_getValue(`${numTroll}.caracs.vue.bm`))
),
{ Monstres: 1, Trolls: 1 },
'Attaquer',
`${MHicons}S_Fire05.png`,
'Cible à portée de Projo'
);
}
function computeTelek() {
computeActionDistante(0,
Math.floor((
parseInt(MY_getValue(`${numTroll}.caracs.vue`)) +
parseInt(MY_getValue(`${numTroll}.caracs.vue.bm`))
) / 2),
{ Tresors: 1 },
'Telek',
`${MHicons}S_Magic04.png`,
'Trésor à portée de Télékinésie'
);
}
function computeLdP() {
computeActionDistante(0,
2 + Math.floor((
parseInt(MY_getValue(`${numTroll}.caracs.vue`)) +
parseInt(MY_getValue(`${numTroll}.caracs.vue.bm`))
) / 5),
{ Monstres: 1, Trolls: 1 },
'self',
`${MHicons}P_Red01.png`,
'Cible à portée de Lancer de Potions'
);
}
/** x~x Systèmes Tactiques --------------------------------------------- */
function putScriptExterne() {
for (let iBricol = 1; ; iBricol++) {
let extClef = iBricol == 1 ? '' : iBricol;
let sInfo = MY_getValue(`${numTroll}.INFOSIT${extClef}`);
if (!sInfo) {
break;
}
putScriptExterneOneIT(sInfo);
}
}
function putScriptExterneOneIT(sInfo) {
if (!sInfo || sInfo == '' || !tr_trolls) {
return;
}
let nomit = sInfo.slice(0, sInfo.indexOf('$'));
if (nomit == 'bricol') {
let data = sInfo.split('$');
try {
// Roule' 07/11/2016. Travail avec Ratibus, remplacement du script par l'envoi de JSON
// appendNewScript(URL_bricol+data[1]
// +'/mz.php?login='+data[2]
// +'&password='+data[3]
// );
FF_XMLHttpRequest({
method: 'GET',
url: `${URL_bricol + data[1]}/mz_json.php?login=${encodeURIComponent(data[2])}&password=${data[3]}`,
trace: 'bricolTroll',
onload: function (responseDetails) {
try {
if (responseDetails.status == 0) {
logMZ('status=0 à l\'appel bricol\'troll');
if (isHTTPS) {
avertissement('<br />Pour utiliser l\'interface Bricol\'Troll en HTTPS, il faut accepter le certificat2 de Raistlin (voir page d\'accueil)');
} else {
avertissement('<br />Erreur générale avec l\'interface Bricol\'Troll<');
}
return;
}
let ratibusData;
try {
ratibusData = JSON.parse(responseDetails.responseText);
} catch (e) { }
if (ratibusData === undefined) {
avertissement(`<br />Erreur à l'appel de l'interface Bricol'Troll. Code HTTP=${responseDetails.status}. Pas de JSON`);
return;
}
if (ratibusData.error) {
avertissement(`<br />Bricol'Troll (${data[1]}) a répondu :<br />${ratibusData.error}`);
} else {
putInfosTrolls(ratibusData.data.trolls, data[1]);
}
} catch (exc) {
logMZ('retour bricol\'troll', exc);
avertissement(`<br />Erreur dans la réponse de Bricol'Troll<br />${exc}<br />${responseDetails.responseText}`);
}
}
});
} catch (exc) {
if (isHTTPS) {
avertissement('<br />Pour utiliser l\'interface Bricol\'Troll en HTTPS, il faut autoriser le contenu mixte (voir page d\'accueil)');
} else {
logMZ('appel bricol\'troll', exc);
avertissement(`<br />Erreur générale avec l'interface Bricol'Troll<br />${exc}`);
}
}
}
}
/*
* Roule 07/11/2016, on utilise mz_json qui envoie
{
"data": {
"trolls": {
"59424": {
"id": 59424,
"pv": xx,
"pv_max": xx,
"updated_at": "2016-10-31 07:28:40",
"dla": "2016-10-05 07:28:04",
"pa": 0
},
}
}
}
*/
// Roule 07/11/2016 ATTENTION, il faudrait modifier ici (remplacer [0] par .pa, etc.)
function corrigeBricolTrolls(infosTrolls) {
for (let i in infosTrolls) {
let pv = infosTrolls[i][0];
let pvmax = infosTrolls[i][1];
let pvmem = MY_getValue(`${i}.caracs.pv.max`);
if (pvmem && pvmem > pvmax) {
infosTrolls[i][1] = pvmem;
pvmax = pvmem;
}
if (pv > pvmax) {
let newpvmax = 5 * Math.ceil(pv / 5);
MY_setValue(`${i}.caracs.pv.max`, newpvmax);
infosTrolls[i][1] = newpvmax;
}
}
}
// insère 2 TD avant nextTD avec les infos venant de l'IT
function addTdInfosTroll(infos, TR, itName) {
// inject lifebar css MH
document.head.innerHTML += '<link rel="stylesheet" href="/mountyhall/libs/lifebar.css">';
let pv_cadre = document.createElement('div');
pv_cadre.className = "barre";
pv_cadre.title = `${infos.pv}/${infos.pv_max} PV le ${SQLDateToFrenchTime(infos.updated_at)}`;
let pv_jauge = document.createElement('div');
let pourcentVie = Math.floor(100 * infos.pv / infos.pv_max);
let dateLimite = new Date();
dateLimite.setDate(dateLimite.getDate() - 7);
if (infos.oUpdatedAt < dateLimite) {
pv_jauge.className = "barre-vie";
pv_jauge.style.backgroundColor = '#C8C8C8'; // infos de plus de 7 jours => grisé
pv_cadre.title = `${pv_cadre.title}\nLes informations sont trop vieilles pour être fiables`;
} else if (pourcentVie > 66) {
pv_jauge.className = "barre-vie full-vie";
} else if (pourcentVie > 33) {
pv_jauge.className = "barre-vie vie";
} else {
pv_jauge.className = "barre-vie vie-critique";
}
pv_jauge.style.width = `${pourcentVie}%`;
pv_cadre.appendChild(pv_jauge);
if (MZ_cache_col_TrollNOM === undefined) {
MZ_cache_col_TrollNOM = MZ_find_col_titre(tr_trolls, 'nom');
}
let tdNom = TR.childNodes[MZ_cache_col_TrollNOM];
if (infos.camoufle || infos.invisible) {
let title = infos.camoufle ? "Camouflé" : "Invisible";
tdNom.appendChild(createImage('/mountyhall/Images/hidden.png', title, 'padding-left:2px'));
}
/* lien vers l'IT */
let lien = document.createElement('a');
// let nomit = MY_getValue(numTroll+'.INFOSIT').split('$')[1];
lien.href = `${URL_bricol + itName}/index.php`;
lien.target = '_blank';
lien.appendChild(pv_cadre);
if (MZ_cache_col_TrollGUILDE === undefined) {
MZ_cache_col_TrollGUILDE = MZ_find_col_titre(tr_trolls, 'guild');
}
// logMZ('[MZd] MZ_cache_col_TrollGUILDE=' + MZ_cache_col_TrollGUILDE);
// let tdGuilde = TR.childNodes[MZ_cache_col_TrollGUILDE];
// insertTdElement(tdGuilde,lien);
TR.childNodes[MZ_cache_col_TrollGUILDE].appendChild(lien);
/* PAs dispos */
let span = document.createElement('span');
span.title = `DLA : ${SQLDateToFrenchTime(infos.dla)}`;
appendText(span, `${infos.pa} PA`);
// logMZ('dla=' + infos.dla + ', SQLDateToObject(infos.dla)=' + SQLDateToObject(infos.dla) + ', now=' + Date.now());
if (infos.pa > 0 || SQLDateToObject(infos.dla) < Date.now()) {
// surligner en verdâtre pour exprimer que ce Trõll peut jouer maintenant
span.style.backgroundColor = 'B8EEB8';
}
// insertTdElement(tdGuilde, span);
TR.childNodes[MZ_cache_col_TrollGUILDE + 1].appendChild(span);
}
function createTrollRowFromRef(infos, ref_tr) {
let tr = ref_tr.cloneNode(true);
tr.style.color = 'cc7000';
// [dist, [act,] ref, name, pv, pa, guild, niv, [race,] x, y , z]
let desktopView = isDesktopView();
let idx = 0; // distance
tr.cells[idx].innerHTML = ref_tr.cells[idx].innerHTML.replace('r_dist', infos.dist);
if (desktopView) {
idx++; // action
tr.cells[idx].innerHTML = ref_tr.cells[idx].innerHTML.replace('r_ref', infos.id);
tr.cells[idx].innerHTML = ref_tr.cells[idx].innerHTML.replace('r_ref', infos.id);
}
idx++; // ref
tr.cells[idx].innerText = ref_tr.cells[idx].innerText.replace('r_ref', infos.id);
idx++; // name
tr.cells[idx].innerHTML = ref_tr.cells[idx].innerHTML.replace('r_ref', infos.id).replace('r_name', infos.nom);
idx += 3; // guild (skip: pv, pa)
tr.cells[idx].innerHTML = ref_tr.cells[idx].innerHTML.replace('r_guild', infos.guilde ? infos.guilde : '');
if (desktopView) {
idx++; // niv
tr.cells[idx].innerText = ref_tr.cells[idx].innerText.replace('r_niv', infos.niveau ? infos.niveau : '');
idx++; // race
tr.cells[idx].innerText = ref_tr.cells[idx].innerText.replace('r_race', infos.race ? infos.race : '');
} else {
idx++; // Race + Niveau
let lettreRace = { "Kastar": "K", "Durakuir": "D", "Skrim": "S", "Tomawak": "T", "Darkling": "G", " Nkrwapu": "N" };
let race_niv = infos.race ? `${lettreRace[infos.race]}` : '';
race_niv = infos.niveau ? `${race_niv}${infos.niveau}` : race_niv;
tr.cells[idx].innerText = ref_tr.cells[idx].innerText.replace('r_niv', race_niv);
}
idx++; // x
tr.cells[idx].innerText = ref_tr.cells[idx].innerText.replace('r_x', infos.x);
idx++; // y
tr.cells[idx].innerText = ref_tr.cells[idx].innerText.replace('r_y', infos.y);
idx++; // n
tr.cells[idx].innerText = ref_tr.cells[idx].innerText.replace('r_n', infos.n);
return tr;
}
function createTrollRow(infos, tr) {
if (tr) {
return createTrollRowFromRef(infos, tr);
}
// créer le tr si pas de ref disponible
tr = document.createElement('tr');
tr.className = 'mh_tdpage';
tr.style.color = 'cc7000';
let desktopView = isDesktopView();
let td = appendTd(tr); // distance
appendText(td, infos.dist);
if (desktopView) {
td = appendTd(tr); // actions
}
td = appendTd(tr); // ID
appendText(td, infos.id);
td = appendTd(tr); // Nom
// <A HREF="javascript:EPV(1649)" CLASS='mh_trolls_1'>Krounch</A>
appendA(td, `javascript:EPV(${infos.id})`, 'mh_trolls_1 ui-link', infos.nom);
td = appendTd(tr); // PA
td = appendTd(tr); // PV
td = appendTd(tr); // Guilde
if (infos.guilde !== undefined) {
// La réponse de Bricol'Troll ne contient pas la guilde des Trolls membrent de la cohorte
appendText(td, infos.guilde);
}
if (desktopView) {
td = appendTd(tr); // Niveau
if (infos.niveau !== undefined) {
appendText(td, infos.niveau);
}
td.align = 'center';
td = appendTd(tr); // Race
if (infos.race) {
appendText(td, infos.race);
}
} else {
td = appendTd(tr); // Race + Niveau
let lettreRace = { "Kastar": "K", "Durakuir": "D", "Skrim": "S", "Tomawak": "T", "Darkling": "G", " Nkrwapu": "N" };
let race_niv = infos.race ? `${lettreRace[infos.race]}` : '';
race_niv = infos.niveau ? `${race_niv}${infos.niveau}` : race_niv;
appendText(td, race_niv);
}
td = appendTd(tr); // X
if (infos.x !== undefined) {
appendText(td, infos.x);
}
td = appendTd(tr); // Y
if (infos.y !== undefined) {
appendText(td, infos.y);
}
td = appendTd(tr); // N
if (infos.n !== undefined) {
appendText(td, infos.n);
}
// récupération des colonnes cachées par VueContext
let ctx_cols = VueContext["tr_trolls"][0].children, tr_cols = tr.children;
// debugMZ(`cols == td ? ${cols.length == tr.children.length}`) // normalement tjrs vrai
for (let i = 0; i < ctx_cols.length; i++) {
tr_cols[i].setAttribute("style", ctx_cols[i].style.cssText);
}
return tr;
}
var MZ_tabTrTrollById;
function putInfosTrolls(infosTrolls, itName) {
try {
let ref_tr = undefined;
let ref_anchors = ['r_dist', 'r_ref', 'r_name', 'r_pv', 'r_pa', 'r_guild', 'r_niv', 'r_x', 'r_y', 'r_n'];
isDesktopView() ? ref_anchors.splice(1, 0, 'r_act') : '';
isDesktopView() ? ref_anchors.splice(8, 0, 'r_race') : '';
if (MZ_tabTrTrollById === undefined) {
MZ_tabTrTrollById = new Array();
// ajout des 2 colonnes dans la table HTML des Trõlls + construire le tableau MZ_tabTrTrollById
if (MZ_cache_col_TrollGUILDE === undefined) {
MZ_cache_col_TrollGUILDE = MZ_find_col_titre(tr_trolls, 'guilde');
}
let td = insertThText(tr_trolls[0].childNodes[MZ_cache_col_TrollGUILDE + 2], 'PA', false);
td.style.width = "50px";
td = insertThText(tr_trolls[0].childNodes[MZ_cache_col_TrollGUILDE + 2], 'PV', false);
for (let i = nbTrolls; i > 0; i--) {
let td = insertTd(tr_trolls[i].childNodes[MZ_cache_col_TrollGUILDE]);
td = insertTd(tr_trolls[i].childNodes[MZ_cache_col_TrollGUILDE]);
MZ_tabTrTrollById[getTrollID(i)] = tr_trolls[i];
if (ref_tr === undefined) {
// gath: on construit pour afficher les trolls hors-vue.
// Le premier troll visible (hors PNJ) est dupliqué puis
// ses attributs sont réinitilisés pour servir de référence
// (gère les cas de colonne invisible type 'guilde').
if (tr_trolls[i].innerText.includes('[PNJ]')) {
continue;
}
ref_tr = tr_trolls[i].cloneNode(true);
for (let j = 0, col; col = tr_trolls[i].cells[j]; j++) {
// [dist, [act,] ref, name, pv, pa, guild, niv, [race,] x, y , z]
let r_a = ref_anchors[j];
if (r_a == 'r_pa' || r_a == 'r_pv') {
// ref_tr.cells[j].innerHTML = "";
continue;
} else if (r_a == 'r_act') {
let s_id = isDesktopView() ? tr_trolls[i].cells[2].innerText : tr_trolls[i].cells[1].innerText;
ref_tr.cells[j].innerHTML = ref_tr.cells[j].innerHTML.replace(s_id, 'r_ref').replace(s_id, 'r_ref');
} else if (r_a == 'r_dist' || r_a == 'r_name' || r_a == 'r_guild') {
Array.from(ref_tr.cells[j].getElementsByTagName('img')).forEach((img) => {
img.remove(); // supprime les mentions Troll à Ghé/Pogé/Prieur de ...
});
let s_id = isDesktopView() ? tr_trolls[i].cells[2].innerText : tr_trolls[i].cells[1].innerText;
let s_name = tr_trolls[i].cells[j].innerText.trim();
r_a == 'r_dist' ? ref_tr.cells[j].removeAttribute('id') : '';
ref_tr.cells[j].innerHTML = ref_tr.cells[j].innerHTML.replace(s_name, r_a).replace(s_id, 'r_ref');
} else {
let s_txt = ref_tr.cells[j].innerText;
ref_tr.cells[j].innerText = (s_txt != '') ? ref_tr.cells[j].innerText.replace(s_txt, r_a) : r_a;
}
}
}
}
}
// Roule 07/11/2016 je ne suis pas trop fana de corriger les données de Bricol'Troll
// corrigeBricolTrolls(infosTrolls);
// supression des infos trop vieilles (un mois)
// conversion de la date de mise à jour en objet date (on en a besoin 2 fois)
let dateLimite = new Date();
dateLimite.setMonth(dateLimite.getMonth() - 1);
// Roule 07/12/2016 ajout des Trolls invi/camou/hors de portée
let str = MY_getValue(`${numTroll}.INFOSIT`);
let affhv = false;
if (str) {
let arr = str.split('$');
affhv = arr[4] > 0;
}
let tBody = tr_trolls[0].parentNode;
if (tr_trolls[1] !== undefined) {
tBody = tr_trolls[1].parentNode;
}
// logMZ('nb Troll IT : ' + IDs.length);
let pos = getPosition();
// mise à jour des infos dans le HTML (et ajout de ligne si nécessaire)
for (let idTroll in infosTrolls) {
let infos = infosTrolls[idTroll];
infos.oUpdatedAt = SQLDateToObject(infos.updated_at); // trop vieux
if (infos.oUpdatedAt < dateLimite) {
continue; // infos trop vieilles
}
if (idTroll == numTroll) {
continue; // pas nous-même
}
let tr;
if (idTroll in MZ_tabTrTrollById) {
// logMZ('putInfosTrolls, le Troll ' + idTroll + ' est déjà dans la table HTML');
tr = MZ_tabTrTrollById[idTroll];
} else {
if (!affhv) {
continue;
}
// logMZ('putInfosTrolls, le Troll ' + idTroll + ' doit être ajouté à la table HTML');
infos.dist = Math.max(Math.abs(pos[0] - infos.x), Math.abs(pos[1] - infos.y), Math.abs(pos[2] - infos.n));
// trouver où insérer ce Troll
let next = undefined;
for (let j = 0; j < tr_trolls.length; j++) {
let thisDist = parseInt(tr_trolls[j].cells[0].textContent);
if (thisDist > infos.dist) {
next = tr_trolls[j];
break;
}
}
tr = createTrollRow(infos, ref_tr);
(next !== undefined) ? insertBefore(next, tr) : tBody.appendChild(tr);
MZ_tabTrTrollById[idTroll] = tr;
tr_trolls[++nbTrolls] = tr;
}
if (!tr.done) {
addTdInfosTroll(infos, tr, itName);
tr.done = true;
}
}
} catch (exc) {
avertissement('Erreur de traitement des informations Bricol\'Troll', null, null, exc);
}
}
/** x~x Mode Tétalanvert! ------------------------------------------------- */
function calculeDistance(maPos, posArr) {
return Math.max(
Math.abs(maPos[0] - posArr[0]),
Math.abs(maPos[1] - posArr[1]),
Math.abs(maPos[2] - posArr[2])
);
}
function inversionCoord() {
let maPos = getPosition();
let listeOffsets = {
monstres: checkBoxLevels.checked ? 4 : 3,
trolls: 6,
};
for (let type in listeOffsets) {
let trList = VueContext[`tr_${type}`];
let offset = listeOffsets[type];
for (let i = trList.length - 1; i > 0; i--) {
let oldX = parseInt(trList[i].cells[offset].textContent);
let oldY = parseInt(trList[i].cells[offset + 1].textContent);
let oldN = parseInt(trList[i].cells[offset + 2].textContent);
trList[i].cells[offset].innerHTML = oldY;
trList[i].cells[offset + 1].innerHTML = oldX;
trList[i].cells[0].innerHTML = calculeDistance(maPos, [oldY, oldX, oldN]);
}
}
}
/* Partie principale */
function do_vue() {
let skip = [];
for (let type in typesAFetcher) {
let ok = fetchData(type);
if (!ok) { skip.push(type); }
}
// roule' 11/03/2016
// maintenant, tr_monstres et this['tr_monstres'], ce n'est plus la même chose
// je fais une recopie :(
MZ_EtatCdMs.tr_monstres = VueContext.tr_monstres;
if (MZ_EtatCdMs.tr_monstres && MZ_EtatCdMs.tr_monstres[0]) {
for (let i = 0; i < MZ_EtatCdMs.tr_monstres[0].cells.length; i++) { // Roule 22/07/2020
if (MZ_EtatCdMs.tr_monstres[0].cells[i].innerText.match(/Dist/i)) {
MZ_EtatCdMs.indexCellDist = i;
}
if (MZ_EtatCdMs.tr_monstres[0].cells[i].innerText.match(/Action/i)) {
MZ_EtatCdMs.indexCellActions = i;
}
if (MZ_EtatCdMs.tr_monstres[0].cells[i].innerText.match(/r[eéè]f/i)) {
MZ_EtatCdMs.indexCellID = i;
}
if (MZ_EtatCdMs.tr_monstres[0].cells[i].innerText.match(/^X$/i)) {
MZ_EtatCdMs.indexCellX = i;
}
if (MZ_EtatCdMs.tr_monstres[0].cells[i].innerText.match(/^Y$/i)) {
MZ_EtatCdMs.indexCellY = i;
}
if (MZ_EtatCdMs.tr_monstres[0].cells[i].innerText.match(/^N$/i)) {
MZ_EtatCdMs.indexCellN = i;
}
}
}
tr_trolls = VueContext.tr_trolls;
tr_tresors = VueContext.tr_tresors;
tr_champignons = VueContext.tr_champignons;
tr_lieux = VueContext.tr_lieux;
MZ_EtatCdMs.nbMonstres = VueContext.nbMonstres;
nbTrolls = VueContext.nbTrolls;
nbTresors = VueContext.nbTresors;
nbChampignons = VueContext.nbChampignons;
nbLieux = VueContext.nbLieux;
try {
start_script(31, 'do_vue_log');
initialiseInfos();
savePosition();
// Fonctionnalité "Têtalenvert" cachée, en test :
if (MY_getValue(`${numTroll}.VERLAN`) == 'true') {
inversionCoord();
}
ajoutDesFiltres();
set2DViewSystem();
// putBoutonTroogle();
putBoutonPXMP();
synchroniseFiltres();
if (!skip.includes("monstres")) {
toggleLevelColumn(); // appel des CdM, ne fait rien si la checkbox NOCDM est cochée
}
refreshDiplo();
// 400 ms
let noGG = saveCheckBox(checkBoxGG, "NOGG");
let noCompos = saveCheckBox(checkBoxCompos, "NOCOMP");
let noBidouilles = saveCheckBox(checkBoxBidouilles, "NOBID");
let noGowapsS = saveCheckBox(checkBoxGowapsS, "NOGOWAPS");
let noGowapsA = saveCheckBox(checkBoxGowapsA, "NOGOWAPA");
let noEngages = saveCheckBox(checkBoxEngages, "NOENGAGE");
let noTresorsEngages = saveCheckBox(checkBoxTresorsNonLibres, "NOTRESORSNONLIBRES");
let noTrou = saveCheckBox(checkBoxTrou, "NOTROU");
let noIntangibles = saveCheckBox(checkBoxIntangibles, "NOINT");
filtreMonstres();
if (noIntangibles) {
filtreTrolls();
}
if (noGG || noCompos || noBidouilles || noTresorsEngages) {
filtreTresors();
}
if (noTrou) {
filtreLieux();
}
MZ_Tactique.initPopup();
initPXTroll();
if (getTalent("Projectile Magique")) {
computeProjo();
}
if (getTalent("Charger")) {
computeCharge();
}
if (getTalent("Télékinésie")) {
computeTelek();
}
if (getTalent("Lancer de Potions")) {
computeLdP();
}
putScriptExterne();
displayScriptTime(undefined, 'do_vue_log');
} catch (exc) {
// gath: on garde le message sympa plutôt qu'ajouter un '- Plus d'infos
// en console (F12)' sans ame !
avertissement(`Une erreur est survenue. Seriez-vous sous l'effet d'un Fumeux ?`);
logMZ('do_vue', exc);
}
}
/** x~x profil2 -------------------------------------------------------- */
/* Variables globales */
var
// Anatrolliseur
urlAnatrolliseur,
// Infobulles talents
hauteur = 50, bulleStyle = null,
// Caracteristiques
// Infos troll
race, niv, datecrea,
idguilde, nomguilde,
// Etats du troll
fatigue, bmfatigue,
// Experience, Pi, ...
pxdistribuables, pxperso,
piutilisable, pitotal,
nbmeurtres, nbmorts,
// utilisee pour les moyennes MM/jour, kill/jour, etc
NBjours,
// calcul des DLA suivantes
DLA, DLAsuiv, HeureServeur,
// details duree du tour (calcul pvdispo) :
dtb, pdm, bmt, adb, dpt, dtbm, dtreserve, bmmouche,
// posale
posX, posY, posN,
// caracs physiques
vue, vuebp, vuebm, vuetotale,
pvbase, pvbpm, pvtotal, pvcourant, pvmax,
reg, regbp, regbm, regmoy,
att, attbp, attbm, attmoy, atttourD, atttour, attmoytour,
esq, esqbp, esqbm, esqmoy, esqtourD, esqmoytour,
deg, degbp, degbm, degmoy, degmoycrit, degtour, degmoytour, degmoycrittour,
arm, armbp, armbm, armmoy, armtourD, armmoytour,
rm, rmbp, rmbm, rmtotale,
mm, mmbp, mmbm, mmtotale,
// Variables speciales Kastars
pvActuelKastar, minParPV, overDLA,
// id pour edition manuelle de lastDLA :
inJour, inMois, inAn, inHr, inMin, inSec,
// id pour auto-refresh lastDLA :
lastDLAZone, maxAMZone, cumulZone,
lastDLA, DLAaccel;
/* -[functions] Fonctions utiles */
// Retourne la valeur de l'element unique et identifie par son "selector" (cf querySelector())
// http://www.w3schools.com/jsref/met_document_queryselector.asp
function getUniqueValueBySelector(selector, defaultValue) {
let valNode = document.querySelector(selector);
if (valNode != null) {
if (valNode.hasChildNodes()) {
return valNode.childNodes[0].nodeValue;
}
return defaultValue;
}
debugMZ(`Pas d'element trouve correspondant au selecteur : ${selector}`);
return defaultValue;
}
function getUniqueStringValueBySelector(selector) {
return getUniqueValueBySelector(selector, "");
}
function getUniqueIntValueBySelector(selector) {
let ret = getUniqueValueBySelector(selector, 0);
if (ret == null || (/^\s*$/).test(ret)) { // test si chaine de caracteres composee de " "
ret = 0;
}
return parseInt(ret);
}
function getUniqueFloatValueBySelector(selector) {
let ret = getUniqueValueBySelector(selector, 0.0);
if (ret == null || (/^\s*$/).test(ret)) { // test si chaine de caracteres composee de " "
ret = 0.0;
}
return parseFloat(ret);
}
function resiste(Ddeg, bm) {
// version naive mais compréhensible ^^
// DEBUG: à revoir
if (!bm) {
return 2 * Math.floor(Ddeg / 2);
}
return 2 * Math.floor(Ddeg / 2) + Math.round(bm / 2);
}
function retourAZero(fatig) {
let fat = fatig, raz = 0;
while (fat > 0) {
raz++;
fat = Math.floor(fat / 1.25);
}
return raz;
}
function coefDecumul(i) {
switch (i) {
case 2: return 0.67;
case 3: return 0.4;
case 4: return 0.25;
case 5: return 0.15;
default: return 0.1;
}
}
function dureeHM(dmin) {
let ret = "";
dmin = Math.floor(dmin);
if (dmin > 59) {
ret = `${Math.floor(dmin / 60)}h`;
}
let mins = dmin % 60;
if (mins != 0) {
ret = ret + (ret ? `${addZero(mins)}min` : `${mins}min`);
}
return ret ? ret : "-";
}
// extraction d'une durée
// l'élément pointé par le sélecteur contient "9 h 33 m" ou "- 2 h 30 m"
// c'est protégé (rend 0 si l'élément est absent)
// Roule' 24/12/2016
function extractionDuree(selecteur) {
let s = getUniqueStringValueBySelector(selecteur);
if (!s) {
return 0;
}
let tabN = getNumbers(s);
if (tabN.length < 1) {
return 0;
}
if (tabN.length == 1) {
tabN = [tabN[0], 0];
} // pas de minutes dans le texte si on a un nombre exact d'heures
if (s.includes('-')) {
return -tabN[0] * 60 - tabN[1];
}
return tabN[0] * 60 + tabN[1];
}
/* -[functions] Extraction / Sauvegarde des donnees */
function extractionDonnees() {
// Variables temporaires
let Nbrs = {};
// *********************
// Cadre "Description"
// *********************
race = getUniqueStringValueBySelector('#descr #race');
debugMZ(`Race : ${race}`);
let idtroll = getUniqueStringValueBySelector('#descr #id');
numTroll = idtroll;
debugMZ(`Id troll : ${idtroll}`);
let strDateCrea = getUniqueStringValueBySelector('#descr td#crea>span');
strDateCrea = strDateCrea.slice(strDateCrea.indexOf("(") + 1, strDateCrea.indexOf(")"));
datecrea = new Date(StringToDate(strDateCrea));
debugMZ(`Date creation : ${datecrea}`);
// Guilde
idguilde = getUniqueIntValueBySelector('#descr #idguilde');
nomguilde = getUniqueStringValueBySelector('#descr #nomguilde');
debugMZ(`Guilde: ${idguilde} ${nomguilde}`);
// *******************
// Cadre "Experience"
// *******************
// Niveau de troll
niv = getUniqueIntValueBySelector('#exp #niv');
nivTroll = niv;
debugMZ(`Niveau : ${niv}`);
// PX
pxdistribuables = getUniqueIntValueBySelector('#exp #px');
pxperso = getUniqueIntValueBySelector('#exp #px_perso');
debugMZ(`Px Distrib/Perso: ${pxdistribuables} / ${pxperso}`);
// PI
piutilisable = getUniqueIntValueBySelector('#exp #pi');
pitotal = getUniqueIntValueBySelector('#exp #pitot');
debugMZ(`PI utilisables/total: ${piutilisable} / ${pitotal}`);
// Meutres/Morts
nbmeurtres = getUniqueIntValueBySelector('#exp #kill');
nbmorts = getUniqueIntValueBySelector('#exp #mort');
debugMZ(`Nb Meutres/Morts: ${nbmeurtres} / ${nbmorts}`);
// *********************
// Cadre "Tour de Jeu"
// *********************
// DLA
Nbrs.dla = getUniqueStringValueBySelector('#dla #dla>b');
DLA = new Date(StringToDate(Nbrs.dla));
debugMZ(`DLA: ${DLA}`);
// DLA suivante
Nbrs.dlasuiv = getUniqueStringValueBySelector('#dla #dla_next');
DLAsuiv = new Date(StringToDate(Nbrs.dlasuiv));
debugMZ(`DLAsuiv: ${DLAsuiv}`);
// Duree normale de mon Tour
dtb = extractionDuree('#dla #tour');
debugMZ(`Duree normale de mon Tour : ${dtb}`);
// Bonus/malus
dtbm = extractionDuree('#dla #bm');
debugMZ(`Bonus/Malus équipement sur la duree : ${dtbm}`);
// Réserve
dtreserve = extractionDuree('#dla #reserve');
debugMZ(`Durée de réserve : ${dtreserve}`);
// Poids de l'equipement
pdm = extractionDuree('#dla #poids');
debugMZ(`Poids de l'equipement : ${pdm}`);
// Bonus/Malus equipement
bmt = extractionDuree('#dla #bmequipement'); // Roule' 24/12/2016 on a trouvé un Troll qui n'a pas de bmt !
debugMZ(`Bonus/Malus équipement sur la duree : ${bmt}`);
// Augmentation due aux blessures
adb = extractionDuree('#dla #blessure');
debugMZ(`Augmentation due aux blessures : ${adb}`);
// Mouches
bmmouche = extractionDuree('#dla #mouche');
debugMZ(`Bonus des mouches : ${bmmouche}`);
// Duree de mon prochain Tour
dpt = extractionDuree('#dla #duree>b');
debugMZ(`Duree de mon prochain Tour : ${dpt}`);
// ****************
// Cadre "Etats"
// ****************
// Position du troll :
posX = getUniqueIntValueBySelector('#pos #x');
posY = getUniqueIntValueBySelector('#pos #y');
posN = getUniqueIntValueBySelector('#pos #n');
debugMZ(`(X Y Z) : ${posX} ${posY} ${posN}`);
// PV actuel
pvcourant = getUniqueIntValueBySelector('#pos #pv_courant');
pvActuelKastar = pvcourant;
debugMZ(`PV actuel : ${pvcourant}`);
// Fatigue
fatigue = getUniqueIntValueBySelector('#pos #fatigue');
bmfatigue = getUniqueIntValueBySelector('#pos #fatiguebm');
debugMZ(`Fatigue : ${fatigue} + ${bmfatigue}`);
// **************************
// Cadre "Caracteristiques"
// **************************
// Attaque
att = getUniqueIntValueBySelector('#carac #att');
attbp = getUniqueIntValueBySelector('#carac #att_p');
attbm = getUniqueIntValueBySelector('#carac #att_m');
atttour = getUniqueIntValueBySelector('#carac #att_tour'); // % bonus AdA
atttourD = getUniqueIntValueBySelector('#carac #att_tour_d'); // malus Parade
attmoy = 3.5 * att + attbp + attbm;
let DAttBonus = Math.floor((att + atttourD) * atttour / 100); // À vérifier
attmoytour = 3.5 * (att + DAttBonus) + attbp + attbm;
debugMZ(
`ATT: ${att}+(${attbp})+(${attbm}) ;AttMoy:${attmoy
}; BM Dé att/tour:(${atttourD}D;${atttour}%) ${atttourD + DAttBonus
}D ;AttMoyTour:${attmoytour}`
);
// Esquive
esq = getUniqueIntValueBySelector('#carac #esq');
esqbp = getUniqueIntValueBySelector('#carac #esq_p');
esqbm = getUniqueIntValueBySelector('#carac #esq_m');
esqtourD = getUniqueIntValueBySelector('#carac #esq_tour_d');
esqmoy = 3.5 * esq + esqbp + esqbm;
esqmoytour = 3.5 * (esq + esqtourD) + esqbp + esqbm;
debugMZ(`ESQ: ${esq}+(${esqbp})+(${esqbm}) ;EsqMoy:${esqmoy}; esq/tour:${esqtourD} ;EsqMoyTour:${esqmoytour}`);
// Degat
deg = getUniqueIntValueBySelector('#carac #deg');
degbp = getUniqueIntValueBySelector('#carac #deg_p');
degbm = getUniqueIntValueBySelector('#carac #deg_m');
degtour = getUniqueIntValueBySelector('#carac #deg_tour'); // % bonus AdD
degmoy = 2 * deg + degbp + degbm;
degmoycrit = 2 * (deg + Math.floor(deg / 2)) + degbp + degbm;
let DDegBonus = Math.floor(deg * degtour / 100);
degmoytour = 2 * (deg + DDegBonus) + degbp + degbm;
degmoycrittour = degmoytour + 2 * Math.floor(deg / 2);
debugMZ(
`DEG: ${deg}+(${degbp})+(${degbm}) ;DegMoy:${degmoy}/${degmoycrit
} ;deg/tour:(${degtour}%) ${DDegBonus
}D; DegMoyTour:${degmoytour}/${degmoycrittour}`
);
// PV
pvbase = getUniqueIntValueBySelector('#carac #pv');
pvbpm = getUniqueIntValueBySelector('#carac #pv_p_m');
pvtotal = getUniqueIntValueBySelector('#carac #pv_tot');
pvmax = getUniqueIntValueBySelector('#pv_max');
debugMZ(`PV: ${pvbase} + (${pvbpm}) = ${pvtotal}`);
// Regeneration
reg = getUniqueIntValueBySelector('#carac #reg');
regbp = getUniqueIntValueBySelector('#carac #reg_p');
regbm = getUniqueIntValueBySelector('#carac #reg_m');
regmoy = 2 * reg + regbp + regbm; // D3
debugMZ(`REG: ${reg}+(${regbp})+(${regbm}) ;RegMoy:${regmoy}`);
// Armure
arm = getUniqueIntValueBySelector('#carac #arm');
armbp = getUniqueIntValueBySelector('#carac #arm_p');
armbm = getUniqueIntValueBySelector('#carac #arm_m');
armtourD = getUniqueIntValueBySelector('#carac #arm_tour_d');
armmoy = 2 * arm + armbp + armbm;
armmoytour = 2 * Math.max(arm + armtourD, 0) + armbp + armbm;
debugMZ(`ARM: ${arm}+(${armbp})+(${armbm}); ArmMoy:${armmoy}; arm/tour:${armtourD}; ArmMoyTour:${armmoytour}`);
// TODO : D d'armure non active
// Vue
vue = getUniqueIntValueBySelector('#carac #vue');
vuebp = getUniqueIntValueBySelector('#carac #vue_p');
vuebm = getUniqueIntValueBySelector('#carac #vue_m');
vuetotale = getUniqueIntValueBySelector('#carac #vue_tot');
debugMZ(`Vue: ${vue} + (${vuebp}) + (${vuebm}) = ${vuetotale}`);
// RM
rm = getUniqueIntValueBySelector('#carac #rm');
rmbp = getUniqueIntValueBySelector('#carac #rm_p');
rmbm = getUniqueIntValueBySelector('#carac #rm_m');
rmtotale = getUniqueIntValueBySelector('#carac #rm_tot');
rmTroll = rmtotale;
debugMZ(`RM: ${rm} + (${rmbp}) + (${rmbm}) = ${rmtotale}`);
// MM
mm = getUniqueIntValueBySelector('#carac #mm');
mmbp = getUniqueIntValueBySelector('#carac #mm_p');
mmbm = getUniqueIntValueBySelector('#carac #mm_m');
mmtotale = getUniqueIntValueBySelector('#carac #mm_tot');
mmTroll = mmtotale;
debugMZ(`MM: ${mm} + (${mmbp}) + (${mmbm}) = ${mmtotale}`);
// Heure Serveur
try {
let heureServeurSTR = document.querySelector("#hserveur").innerHTML;
heureServeurSTR = heureServeurSTR.slice(heureServeurSTR.indexOf("/") - 2, heureServeurSTR.lastIndexOf(":") + 3);
HeureServeur = new Date(StringToDate(heureServeurSTR));
} catch (exc) {
warnMZ(`Heure Serveur introuvable, utilisation de l'heure actuelle`, exc);
HeureServeur = new Date();
}
debugMZ(`HeureServeur: ${HeureServeur}`);
// ***INIT GLOBALE*** NBjours
NBjours = Math.floor((HeureServeur - datecrea) / jour_en_ms) + 1;
// Calcul debut lien anatroliseur avec les caracteristiques connues
let amelio_dtb = function (dtbb) {
if (dtbb > 555) {
return Math.floor((21 - Math.sqrt(8 * dtbb / 3 - 1479)) / 2);
}
return 10 + Math.ceil((555 - dtbb) / 2.5);
},
amelio_pv = Math.floor(pvbase / 10) - 3,
amelio_vue = vue - 3,
amelio_att = att - 3,
amelio_esq = esq - 3,
amelio_deg = deg - 3,
amelio_reg = reg - 1,
amelio_arm = arm - 1;
if (race === "Darkling") {
amelio_reg--;
}
if (race === "Durakuir") {
amelio_pv--;
}
if (race === "Kastar") {
amelio_deg--;
}
if (race === "Skrim") {
amelio_att--;
}
if (race === "Tomawak") {
amelio_vue--;
}
urlAnatrolliseur = `${URL_AnatrolDispas
}outils_anatrolliseur.php?anatrolliseur=v8` +
`|r=${race.toLowerCase()
}|dla=${amelio_dtb(dtb)
}|pv=${amelio_pv},${pvbpm},0` +
`|vue=${amelio_vue},${vuebp},${vuebm
}|att=${amelio_att},${attbp},${attbm
}|esq=${amelio_esq},${esqbp},${esqbm
}|deg=${amelio_deg},${degbp},${degbm
}|reg=${amelio_reg},${regbp},${regbm
}|arm=${amelio_arm},${armbp},${armbm
}|mm=${mmtotale
}|rm=${rmtotale}|`;
}
function saveProfil() {
logMZ('saveProfil()')
let l_numTroll = MY_getValue('NUM_TROLL');
if (l_numTroll === null) {
logMZ('Troll encore inconnu: pas de sauvegarde de caracs')
return;
}
MY_setValue(`${l_numTroll}.caracs.attaque`, att);
MY_setValue(`${l_numTroll}.caracs.attaque.bm`, attbp + attbm);
MY_setValue(`${l_numTroll}.caracs.attaque.bmp`, attbp);
MY_setValue(`${l_numTroll}.caracs.attaque.bmm`, attbm);
if (atttourD || atttour) {
let DAttBonus = atttourD + Math.floor((att + atttourD) * atttour / 100);
MY_setValue(`${l_numTroll}.bonus.DAttM`, DAttBonus);
} else {
MY_removeValue(`${l_numTroll}.bonus.DAttM`);
}
MY_setValue(`${l_numTroll}.caracs.esquive`, esq);
MY_setValue(`${l_numTroll}.caracs.esquive.bm`, esqbp + esqbm);
MY_setValue(`${l_numTroll}.caracs.esquive.bmp`, esqbp);
MY_setValue(`${l_numTroll}.caracs.esquive.bmm`, esqbm);
MY_setValue(`${l_numTroll}.caracs.esquive.nbattaques`, esqtourD);
MY_setValue(`${l_numTroll}.caracs.degats`, deg);
MY_setValue(`${l_numTroll}.caracs.degats.bm`, degbp + degbm);
MY_setValue(`${l_numTroll}.caracs.degats.bmp`, degbp);
MY_setValue(`${l_numTroll}.caracs.degats.bmm`, degbm);
if (degtour) {
let DDegBonus = Math.floor(deg * degtour / 100);
MY_setValue(`${l_numTroll}.bonus.DDeg`, DDegBonus);
} else {
MY_removeValue(`${l_numTroll}.bonus.DDeg`);
}
MY_setValue(`${l_numTroll}.caracs.regeneration`, reg);
MY_setValue(`${l_numTroll}.caracs.regeneration.bm`, regbp + regbm);
MY_setValue(`${l_numTroll}.caracs.regeneration.bmp`, regbp);
MY_setValue(`${l_numTroll}.caracs.regeneration.bmm`, regbm);
MY_setValue(`${l_numTroll}.caracs.vue`, vue);
MY_setValue(`${l_numTroll}.caracs.vue.bm`, vuebp + vuebm);
MY_setValue(`${l_numTroll}.caracs.vue.bmp`, vuebp);
MY_setValue(`${l_numTroll}.caracs.vue.bmm`, vuebm);
MY_setValue(`${l_numTroll}.caracs.pv`, pvcourant);
MY_setValue(`${l_numTroll}.caracs.pv.base`, pvbase);
MY_setValue(`${l_numTroll}.caracs.pv.max`, pvtotal);
MY_setValue(`${l_numTroll}.caracs.rm`, rm);
MY_setValue(`${l_numTroll}.caracs.rm.bm`, rmtotale);
MY_setValue(`${l_numTroll}.caracs.rm.bmp`, rmbp);
MY_setValue(`${l_numTroll}.caracs.rm.bmm`, rmbm);
MY_setValue(`${l_numTroll}.caracs.mm`, mm);
MY_setValue(`${l_numTroll}.caracs.mm.bm`, mmtotale);
MY_setValue(`${l_numTroll}.caracs.mm.bmp`, mmbp);
MY_setValue(`${l_numTroll}.caracs.mm.bmm`, mmbm);
MY_setValue(`${l_numTroll}.caracs.armure`, arm);
MY_setValue(`${l_numTroll}.caracs.armure.bm`, armbp + armbm);
MY_setValue(`${l_numTroll}.caracs.armure.bmp`, armbp);
MY_setValue(`${l_numTroll}.caracs.armure.bmm`, armbm);
MY_setValue(`${l_numTroll}.caracs.dureeProchainTour`, dpt);
MY_setValue(`${l_numTroll}.position.X`, posX);
MY_setValue(`${l_numTroll}.position.Y`, posY);
MY_setValue(`${l_numTroll}.position.N`, posN);
MY_setValue(`${l_numTroll}.race`, race);
MY_setValue(`${l_numTroll}.niveau`, niv);
MY_setValue(`${l_numTroll}.idguilde`, idguilde);
MY_setValue(`${l_numTroll}.nomguilde`, nomguilde);
}
/* -[functions] Fonctions modifiant la page */
function setInfosCaracteristiques() {
// Modification de l'entete
let thTotal = document.querySelector("table#caracs>thead>tr>th:nth-child(6)");
thTotal.innerHTML = `${thTotal.innerHTML}|<i>Moyenne</i>`;
thTotal.title = "Moyenne (Moyenne ce tour)";
// Ajout des informations calculees
let tdAttTotal = document.querySelector("table#caracs td#att").parentElement.children[5];
tdAttTotal.innerHTML = `<i>${attmoy}</i>`;
if (attmoy != attmoytour) {
tdAttTotal.innerHTML = `${tdAttTotal.innerHTML} (${attmoytour})`;
}
let tdEsqTotal = document.querySelector("table#caracs td#esq").parentElement.children[5];
tdEsqTotal.innerHTML = `<i>${esqmoy}</i>`;
if (esqmoy != esqmoytour) {
tdEsqTotal.innerHTML = `${tdEsqTotal.innerHTML} (${esqmoytour})`;
}
let tdDegTotal = document.querySelector("table#caracs td#deg").parentElement.children[5];
tdDegTotal.innerHTML = `<i>${degmoy}/${degmoycrit}</i>`;
if (degmoy != degmoytour) {
tdDegTotal.innerHTML = `${tdDegTotal.innerHTML} (${degmoytour}/${degmoycrittour})`;
}
let trRegeneration = document.querySelector("table#caracs td#reg").parentElement;
let tdRegTotal = trRegeneration.children[5];
tdRegTotal.innerHTML = `<i>${regmoy}</i>`;
// Temps recupere par reg (propale R')
let regmoyTemp = Math.max(0, regmoy);
let regTitle = `Temps moyen récupéré par régénération: ${Math.floor(250 * regmoyTemp / pvtotal)} min`;
let sec = Math.floor(15000 * regmoyTemp / pvtotal) % 60;
if (sec != 0) {
regTitle = `${regTitle} ${sec} sec`;
}
trRegeneration.title = regTitle;
let tdArmTotal = document.querySelector("table#caracs td#arm").parentElement.children[5];
tdArmTotal.innerHTML = `<i>${armmoy}</i>`;
if (armmoy != armmoytour) {
tdArmTotal.innerHTML = `${tdArmTotal.innerHTML} (${armmoytour})`;
}
let trRM = document.querySelector("table#caracs #rm").parentElement;
trRM.title = `${Math.round(10 * rm / NBjours) / 10} (${Math.round(10 * rmTroll / NBjours) / 10}) points de RM par jour | ${Math.round(10 * rm / niv) / 10} (${Math.round(10 * rmtotale / niv) / 10}) points de RM par niveau`;
let trMM = document.querySelector("table#caracs #mm").parentElement;
trMM.title = `${Math.round(10 * mm / NBjours) / 10} (${Math.round(10 * mmTroll / NBjours) / 10}) points de MM par jour | ${Math.round(10 * mm / niv) / 10} (${Math.round(10 * mmtotale / niv) / 10}) points de MM par niveau`;
let tdRefl = document.querySelector("#refl");
// TODO : prendre en compte bonus/malus D esq du tour ?
let refMoy = Math.floor(2 * (reg + esq) / 3) * 3.5 + esqbp + esqbm;
tdRefl.innerHTML = `${tdRefl.innerHTML} <i>(moyenne : ${refMoy})</i>`;
}
function setLienAnatrolliseur() {
let pTableAmelio = document.querySelector("#carac>div>p");
if (!pTableAmelio) {
pTableAmelio = document.querySelector("#carac>div>div>p");
}
if (!pTableAmelio) {
return;
}
pTableAmelio.appendChild(document.createTextNode(' - '));
let aElt = document.createElement("a");
aElt.setAttribute("href", urlAnatrolliseur);
aElt.setAttribute("target", "_blank");
aElt.className = "AllLinks ui-link";
aElt.innerHTML = "Anatrolliser";
pTableAmelio.appendChild(aElt);
}
function setInfoDescription() {
let txtDateCrea = NBjours != 1 ?
` (${NBjours} jours dans le hall)` :
" (Bienvenue à toi pour ton premier jour dans le hall)";
appendText(document.querySelector("#descr td#crea"), txtDateCrea, false);
}
function setInfosEtatLieux() {
let urlBricol = `${URL_bricol_mountyhall}lieux.php?search=position&orderBy=distance&posx=${posX}&posy=${posY}&posn=${posN}&typeLieu=3`;
let tdPosition = document.querySelector("#pos td span#x").parentElement;
appendBr(tdPosition);
let aElt = document.createElement("a");
aElt.setAttribute("href", urlBricol);
aElt.setAttribute("target", "_blank");
aElt.className = "AllLinks ui-link";
aElt.innerHTML = "Lieux à proximité";
tdPosition.appendChild(aElt);
}
function setInfosEtatPV() { // pour AM et Sacro
let
txt = `1 PV de perdu = +${Math.floor(250 / pvtotal)} min`,
sec = Math.floor(15000 / pvtotal) % 60,
lifebar = document.querySelector("#pos .barre-vie"),
tr_line = document.querySelector("#pos #pv_courant").parentElement.parentElement.parentElement;
if (sec != 0) {
txt = `${txt} ${sec} sec`;
}
if (lifebar && isDesktopView()) {
lifebar.title = txt;
} else {
tr_line = appendTrDetail(tr_line, '[MZ] Durée de blessure', txt);
}
if (pvcourant <= 0) {
return;
}
// Difference PV p/r a equilibre de temps (propale R')
// Note : pvmin pour 0 malus = pvtotal + ceiling(pvtotal/250*(dtreserve + pdm + bmt + bmmouche))
// ***INIT GLOBALE*** pvdispo
let bmPVHorsBlessure = dtbm + dtreserve + pdm + bmt + bmmouche;
let pvdispo = pvcourant - pvtotal - Math.ceil(bmPVHorsBlessure * pvtotal / 250);
let span = document.createElement("span");
span.title = txt;
span.style.fontStyle = "italic";
span.className = 'detail';
if (bmPVHorsBlessure >= 0) {
txt = "Vous ne pouvez compenser aucune blessure actuellement.";
} else if (pvdispo > 0) {
txt = `Vous pouvez encore perdre ${Math.min(pvdispo, pvcourant)} PV sans malus de temps.`;
} else if (pvdispo < 0) {
txt = `Il vous manque ${-pvdispo} PV pour ne plus avoir de malus de temps.`;
} else {
txt = "Vous êtes à l'équilibre en temps (+/- 30sec).";
}
if (isDesktopView()) {
appendText(span, `[MZ] ${txt}`);
document.querySelector("#pos #pv_courant").parentElement.parentElement.appendChild(span);
} else {
tr_line = appendTrDetail(tr_line, '[MZ] Compensation', txt);
}
let marge = dtbm + dtreserve + pdm + bmt + adb + bmmouche;
let tr = document.createElement('tr');
tr.className = 'detail';
let th = document.createElement('th');
if (marge <= 0) {
appendText(th, '[MZ] Marge');
} else {
appendText(th, '[MZ] Augmentation');
tr.style.color = 'red';
}
tr.appendChild(th);
let td = document.createElement('td');
appendText(td, MZ_FormatHeureMinute(marge, true));
tr.appendChild(td);
document.querySelector("#dla #duree").parentElement.parentElement.appendChild(tr);
}
function MZ_FormatHeureMinute(duree, bPlus) {
let txt = '';
if (duree < 0) {
txt = '- ';
duree = -duree;
} else if (duree > 0 && bPlus) {
txt = '+ ';
}
let h = Math.floor(duree / 60);
if (h) {
txt = `${txt}${h} h `;
}
txt = `${txt}${duree % 60} m`;
return txt;
}
// Complete le cadre "Experience"
function setInfosExp() {
let tdNiv = document.querySelector("#exp #niv");
// Calcul niveau monstre/troll min pour gain PX
let nivCibleMin = Math.ceil((2 * nivTroll - 10) / 3);
tdNiv.parentElement.title = `Vos cibles doivent être au minim de niveau ${nivCibleMin} pour qu'elles vous rapportent des PX`;
// Calcul PX restant
let pxRestant = pxdistribuables + pxperso - 2 * nivTroll;
if (pxRestant >= 0) {
let tdinfoEntrainement = document.querySelector("#exp table tr:nth-child(4) td span");
if (tdinfoEntrainement) {
tdinfoEntrainement.innerHTML = `${tdinfoEntrainement.innerHTML} <i>Il vous restera ${pxRestant} PX</i>`;
}
}
// Calul pi/jour
let tdPiTotal = document.querySelector("#exp #pitot").parentElement,
tdPi = document.querySelector("#exp #pi").parentElement;
tdPiTotal.title = `${Math.round(10 * (pitotal + pxperso + pxdistribuables) / NBjours) / 10} PI par jour`;
tdPi.title = tdPiTotal.title;
// Rapports meurtres,morts
let tdKill = document.querySelector("#exp #kill");
tdKill.setAttribute("colspan", 1);
appendTdText(tdKill.parentElement, `${Math.round(10 * NBjours / nbmeurtres) / 10} jours/kill`, false);
let tdMort = document.querySelector("#exp #mort");
tdMort.setAttribute("colspan", 1);
appendTdText(tdMort.parentElement, `${Math.round(10 * NBjours / nbmorts) / 10} jours/mort`, false);
tdKill.parentElement.title = `Rapport meurtres/décès: ${Math.floor(nbmeurtres / nbmorts * 100) / 100}`;
tdMort.parentElement.title = `Rapport décès/meurtres: ${Math.floor(nbmorts / nbmeurtres * 100) / 100}`;
}
/* -[functions] Fonctions speciales Kastars */
function minParPVsac(fat, bm) {
// Calcule le nombre de min gagnees / PV sacrifies pour une AM realisee sous
// fatigue = 'fat', sans et avec un bm de fatigue = 'bm'
let out = [];
out[0] = fat > 4 ? Math.floor(120 / (fat * (1 + Math.floor(fat / 10)))) : 30;
if (bm && bm > 0) {
let totalfat = fat + bm;
// en principe inutile pour des bm fat >= 15 mais bon...
out[1] = totalfat > 4 ? Math.floor(120 / (totalfat * (1 + Math.floor(totalfat / 10)))) : 30;
}
return out;
}
function toInt(str) {
str = parseInt(str);
return str ? str : 0;
}
function saveLastDLA() {
// pour les calculs d'AM max
let str = `${addZero(toInt(inJour.value))}/${addZero(toInt(inMois.value))
}/${toInt(inAn.value)} ${addZero(toInt(inHr.value))
}:${addZero(toInt(inMin.value))}:${addZero(toInt(inSec.value))}`;
lastDLA = new Date(StringToDate(str));
MY_setValue(`${numTroll}.DLA.ancienne`, str);
lastDLAZone.innerHTML = '';
let b = document.createElement('b');
b.addEventListener('click', inputMode, false);
appendText(b, str);
lastDLAZone.appendChild(b);
refreshAccel();
}
function inputMode() {
// Edition manuelle lastDLA
let date;
if (lastDLA) {
date = new Date(lastDLA);
} else {
date = new Date(DLAaccel);
}
lastDLAZone.innerHTML = '';
inJour = appendTextbox(lastDLAZone, 'text', 'inJour', 1, 2, date.getDate());
appendText(lastDLAZone, '/');
inMois = appendTextbox(lastDLAZone, 'text', 'inMois', 1, 2, 1 + date.getMonth());
appendText(lastDLAZone, '/');
inAn = appendTextbox(lastDLAZone, 'text', 'inAn', 3, 4, date.getFullYear());
appendText(lastDLAZone, ' - ');
inHr = appendTextbox(lastDLAZone, 'text', 'inHr', 1, 2, `${date.getHours()}`);
appendText(lastDLAZone, ':');
inMin = appendTextbox(lastDLAZone, 'text', 'inMin', 1, 2, `${date.getMinutes()}`);
appendText(lastDLAZone, ':');
inSec = appendTextbox(lastDLAZone, 'text', 'inSec', 1, 2, `${date.getSeconds()}`);
appendText(lastDLAZone, ' - ');
appendButton(lastDLAZone, 'Enregistrer', saveLastDLA);
}
function setAccel() {
let BMfrais = false,
fat = fatigue, listeBmFat = [],
tr, th, insertPt;
// Creation ligne speciale pour AM dans le cadre "Etat"
tr = document.createElement('tr');
th = document.createElement('th');
appendText(th, '[MZ] Fatigue et AM', true);
tr.appendChild(th);
insertPt = document.createElement('td');
tr.appendChild(insertPt);
document.querySelector('#pos table>tbody').insertBefore(tr, null);
// Est-on en over-DLA ?
// ***INIT GLOBALE*** overDLA
overDLA = HeureServeur > DLA.getTime() + 3e5;
if (overDLA) {
fat = Math.floor(fatigue / 1.25);
}
// Gestion des BM de fatigue
if (bmfatigue > 0) {
debugMZ(`setAccel, bmfatigue=${bmfatigue}, ${numTroll}.bm.fatigue=${MY_getValue(`${numTroll}.bm.fatigue`)}`);
// On tente de recuperer les BM de fatigue de la page des BM
if (MY_getValue(`${numTroll}.bm.fatigue`)) {
let BMmemoire = MY_getValue(`${numTroll}.bm.fatigue`).split(';');
BMmemoire.pop();
for (let i = 0; i < BMmemoire.length; i++) {
let nbrs = BMmemoire[i].match(/\d+/g); // [tour,fatigue]
let s = `0000${nbrs[0]}`;
BMmemoire[i] = `${s.substr(s.length - 4)} ${nbrs[1]}`;
}
BMmemoire.sort(); // tri par n° de tour
let tour = 0;
for (let i = 0; i < BMmemoire.length; i++) {
let nbrs = BMmemoire[i].match(/\d+/g); // [tour,fatigue]
while (tour <= parseInt(nbrs[0])) {
listeBmFat[tour] = parseInt(nbrs[1]);
tour++;
}
}
}
if (listeBmFat[0] == bmfatigue) {
// Si (bm profil=1er bm stocke), on suppose que les bm stockes sont a jour
BMfrais = true;
// Roule 17/06/2020 je ne vois pas du tout pourquoi on viderait xxx;bm.fatigue ici. Et ça fait que la fatigue des Kastars affiche une erreur la 2e fois qu'on va sur le profil... J'enlève
// MY_removeValue(numTroll+".bm.fatigue");
}
} else {
// S'il n'y a pas de bm de fatigue sur le profil, on est a jour
BMfrais = true;
}
if (!BMfrais && bmfatigue > 0) {
// si les BM n'ont pas ete rafraichis, on conjecture le pire:
if (bmfatigue == 15) {
listeBmFat = [15, 15, 15];
} else {
listeBmFat = [30, 30, 15];
}
}
let skip = false;
if (pvcourant <= 0) {
appendText(insertPt, 'Aucun calcul possible : vous êtes mort voyons !');
skip = true;
}
if (!skip && fat > 30) {
appendText(insertPt, 'Vous êtes trop fatigué pour accélérer.');
skip = true;
}
// Setup lastDLAZone
if (overDLA) {
// Si on est en over-DLA, on decale les bm d'un tour
listeBmFat.shift();
// bypass des infos de "menu_FF.js" en cas d'overDLA
DLAaccel = new Date(DLAsuiv);
lastDLA = new Date(DLA);
MY_setValue(`${numTroll}.DLA.ancienne`, MZ_formatDateMS(DLA, false));
// ***INIT GLOBALE*** pvActuelKastar
pvActuelKastar = Math.min(pvcourant + regmoy, pvtotal);
appendText(insertPt, 'Votre DLA est dépassée, calculs basés sur des estimations.', true, 'red');
appendBr(insertPt);
} else {
DLAaccel = new Date(DLA);
pvActuelKastar = pvcourant;
if (MY_getValue(`${numTroll}.DLA.ancienne`)) {
lastDLA = new Date(StringToDate(MY_getValue(`${numTroll}.DLA.ancienne`)));
} else {
lastDLA = false;
}
}
// ***INIT GLOBALE*** minParPV
let minppv = minParPVsac(fat, listeBmFat[0]);
minParPV = listeBmFat[0] == void 0 ? minppv[0] : minppv[1];
if (!skip) {
appendText(insertPt, 'Dernière DLA enregistrée : ');
lastDLAZone = document.createElement('span');
lastDLAZone.style.cursor = 'pointer';
let b = document.createElement('b');
b.onclick = inputMode;
lastDLAZone.appendChild(b);
insertPt.appendChild(lastDLAZone);
if (lastDLA) {
appendText(b, MZ_formatDateMS(lastDLA, false));
} else {
appendText(b, 'aucune');
}
appendBr(insertPt);
// Setup maxAMZone et cumulZone
appendText(insertPt, 'Accélération maximale possible : ');
maxAMZone = document.createElement('b');
insertPt.appendChild(maxAMZone);
appendBr(insertPt);
cumulZone = document.createElement('span');
insertPt.appendChild(cumulZone);
refreshAccel();
}
if (!(fat > 0 || listeBmFat[0] > 0)) {
return; // skip si rien a calculer
}
// ancre pour afficher le warning d'erreur de calcul
let err_node = document.createElement('div');
insertPt.appendChild(err_node);
// Tableau des fatigues et accel futures
let table, tbody, col, ligneTour, ligneFat, ligneMin, tr_detail;
let nbsp = '\u00A0';
let desktopView = isDesktopView();
if (desktopView) {
appendHr(insertPt);
table = document.createElement('table');
table.className = 'mh_tdborder';
table.border = 0;
table.cellSpacing = 1;
table.cellPadding = 1;
table.style.textAlign = "center";
tbody = document.createElement('tbody');
table.appendChild(tbody);
insertPt.appendChild(table);
ligneTour = appendTr(tbody, 'mh_tdtitre');
ligneTour.style.fontWeight = "bold";
let td = appendTdText(ligneTour, 'Tour :', true);
td.align = 'left';
ligneFat = appendTr(tbody, 'mh_tdpage');
td = appendTdText(ligneFat, 'Fatigue :', true);
td.className = 'mh_tdtitre';
td.align = 'left';
ligneMin = appendTr(tbody, 'mh_tdpage');
td = appendTdText(ligneMin, '1 PV =', true);
td.className = 'mh_tdtitre';
td.align = 'left';
} else {
tr_detail = appendTrDetail(insertPt.parentElement, `[MZ] Tour`, `${'Fatigue'.padEnd(12, '\u00A0')}|${'1 PV ='.padStart(12, nbsp)}`, true)
}
col = 0;
while (col < 9 && (fat > 0 || listeBmFat[col])) {
let txt_tour = col == 0 ? 'En cours' : `\u00A0\u00A0+${col}\u00A0\u00A0`,
txt_fat, txt_min;
if (col == 0 && overDLA) {
txt_tour = 'A activer';
let i = document.createElement('i');
appendText(i, txt_tour);
ligneTour.appendChild(i);
} else {
appendTdText(ligneTour, txt_tour);
}
if (listeBmFat[col]) {
txt_fat = (BMfrais || !overDLA && col == 0) ? `${fat}+${listeBmFat[col]}` : `${fat}+${listeBmFat[col]} (?)`;
txt_min = (BMfrais || !overDLA && col == 0) ? `${Math.max(1, minppv[1])}'` : `${minppv[1]}' (${minppv[0]}')`;
} else {
txt_fat = fat;
txt_min = `${minppv[0]}'`;
}
appendTdText(ligneFat, txt_fat);
appendTdText(ligneMin, txt_min);
tr_detail = desktopView ? '' : appendTrDetail(tr_detail, `[MZ] ${txt_tour}`, `${txt_fat.toString().padEnd(12, '\u00A0')}|${txt_min.padStart(12, nbsp)}`, true);
col++;
fat = Math.floor(fat / 1.25);
minppv = minParPVsac(fat, listeBmFat[col]);
}
if (fat > 1 || fat == 1 && !overDLA) {
appendTdText(ligneTour, '\u00A0\u00A0...\u00A0\u00A0', true);
appendTdText(ligneFat, '-');
appendTdText(ligneMin, '-');
}
col = overDLA ? Math.max(retourAZero(fatigue) - 1, col) : Math.max(retourAZero(fatigue), col);
appendTdText(ligneTour, `\u00A0\u00A0+${col}\u00A0\u00A0`);
appendTdText(ligneFat, '0');
appendTdText(ligneMin, '30\'');
tr_detail = desktopView ? '' : appendTrDetail(tr_detail, `[MZ] \u00A0\u00A0+${col}\u00A0\u00A0`, `${'0'.padEnd(12, '\u00A0')}|${'30\''.padStart(12, nbsp)}`, true);
if (!BMfrais && bmfatigue) {
// si les BM n'ont pas ete rafraichis, on signale:
appendText(err_node, 'Attention, ce tableau est probablement faux.' +
' Visitez la page des Bonus/Malus pour mettre à jour votre fatigue.', true, 'red');
}
}
function refreshAccel() {
let pvs, pvsmax;
// Acceleration pour cumul instantane
// debugMZ(`refreshAccel: pvActuelKastar=${pvActuelKastar},DLAaccel=${DLAaccel},lastDLA=${lastDLA},minParPV=${minParPV}`);
if (lastDLA) {
pvsmax = Math.min(
pvActuelKastar - 1,
Math.ceil(Math.floor((DLAaccel - lastDLA) / 6e4) / minParPV)
);
maxAMZone.innerHTML = `${pvsmax} PV`;
} else {
pvsmax = pvActuelKastar - 1;
maxAMZone.innerHTML = 'inconnue';
}
// pvAccel = (nb min avant DLA (arr. sup) / nb min p/ PVsac) (arrondi sup)
pvs = Math.ceil(Math.ceil((DLAaccel - HeureServeur) / 6e4) / minParPV);
cumulZone.innerHTML = '';
if (pvs <= pvsmax) {
appendText(cumulZone, 'Vous devez accélérer d\'au moins ');
appendText(cumulZone, `${pvs} PV`, true);
appendText(cumulZone, ' pour activer immédiatement un nouveau tour.');
if (pvs != 1) {
let gainSec = Math.floor((DLAaccel - HeureServeur) / 1e3) - (pvs - 1) * 60 * minParPV;
appendText(
cumulZone,
` (${pvs - 1} PV dans ${Math.floor(gainSec / 60)}min${addZero(gainSec % 60)}s)`
);
}
} else {
let avantDLA = new Date(DLAaccel - HeureServeur - pvsmax * minParPV * 6e4);
appendText(
cumulZone,
`Après votre accélération maximale, il vous faudra encore attendre ${dureeHM(avantDLA / 6e4)} avant de réactiver.`
);
}
}
function setInfosFatiguesOptimiales() {
let thFatigue = document.querySelector('#fatigue').parentElement.parentElement,
title = 'Fat. optimale',
txt = '29 / 23 / 18 / 14 / 11 / 8 / 6 / 4';
if (isDesktopView()) {
thFatigue.title = `${title} : ${txt}`;
} else {
appendTrDetail(thFatigue, `[MZ] ${title}`, `${txt}`)
}
}
/* -[functions] Fonctions gerant les infos-bulles */
function traitementTalents() {
let trCompetence = document.querySelectorAll("#comp table#competences>tbody>tr");
let trSorts = document.querySelectorAll("#sort table#sortileges>tbody>tr");
removeAllTalents();
let totalComp = injecteInfosBulles(trCompetence, 'competences');
let totalSort = injecteInfosBulles(trSorts, 'sortileges');
let comps = document.querySelector('#comp>div>h3.mh_tdtitre');
comps.innerHTML = comps.innerHTML.replace('Compétences', `Compétences (Total : ${totalComp}%)`);
let sorts = document.querySelector('#sort>div>h3.mh_tdtitre');
sorts.innerHTML = sorts.innerHTML.replace('Sortilèges', `Sortilèges (Total : ${totalSort}%)`);
}
function injecteInfosBulles(liste, fonction) {
let totalpc = 0;
// on parse la liste des talents du type 'fonction'
for (let trTalent of liste) {
let node = trTalent.getElementsByTagName('a')[0];
let jsonInfo = trTalent.getAttribute('data-json');
if (!jsonInfo) {
debugMZ(`pas de json dans ${trTalent.innerHTML}`);
continue;
}
let oInfo = JSON.parse(jsonInfo);
//console.log('[MZ] totalpc = ' + totalpc + ', nb<a>=' + trTalent.getElementsByTagName('a').length + ', info=' + JSON.stringify(oInfo));
let nivMax = oInfo.maitrise.length - 1;
if (nivMax < 1) continue; // cas des sorts avec un apprentissage Ogham non actifs
let sousCompetences = null;
if (oInfo.notes) sousCompetences = oInfo.notes;
if (oInfo.pieges) sousCompetences = oInfo.pieges;
if (oInfo.peintures) sousCompetences = oInfo.peintures;
let maitrise = oInfo.maitrise[nivMax];
if (node)
setInfos(node.parentNode, oInfo.nom, fonction, nivMax);
for (let niv = 1; niv <= nivMax; niv++)
setTalent(oInfo.nom, oInfo.maitrise[niv], niv, sousCompetences);
totalpc = totalpc + maitrise;
}
return totalpc;
}
function setInfos(node, nom, fonction, niveau) {
node.nom = nom;
node.fonction = fonction;
node.niveau = niveau;
node.onmouseover = setBulle;
node.onmouseout = cacherBulle;
}
var arrayModifAnatroll = {
Glue: 'Glu',
PuM: 'PuiM',
HE: 'Hurlement',
// 'Insultes':'Insu',
Pistage: 'Pist',
PuC: 'Planter',
Golemo: 'Golem',
};
function setTalent(nom, pc, niveau, sousCompetences) {
// Nota : voir plus tard si stocker les effets des comps/sorts directement
// (et pas les % dont osf) ne serait pas plus rentable
let nomEnBase = arrayTalents[epure(nom)];
if (!nomEnBase) {
debugMZ(`setTalent: le talent ${nom} n'est pas dans la base MZ`);
return;
}
if (!niveau) {
niveau = 1;
}
switch (nomEnBase) {
case 'Insultes':
urlAnatrolliseur = `${urlAnatrolliseur}Insu${niveau}|`;
case 'IdT':
nomEnBase = nomEnBase + niveau;
break;
case 'Piege':
for (let i = 0; i < sousCompetences.length; i++) {
urlAnatrolliseur = `${urlAnatrolliseur}${arrayModifAnatroll[sousCompetences[i]] ?
arrayModifAnatroll[sousCompetences[i]] : sousCompetences[i]}|`;
}
break;
case 'AP':
case 'CdB':
case 'CdM':
case 'Parer':
case 'Retraite':
case 'RB':
case 'SInterposer':
nomEnBase = nomEnBase + niveau;
default:
urlAnatrolliseur = `${urlAnatrolliseur}${arrayModifAnatroll[nomEnBase] ?
arrayModifAnatroll[nomEnBase] : nomEnBase}|`;
}
// debugMZ("setTalent: nom=" + nom + ", pc=" + pc + ", niveau=" + niveau + ", sousCompetences=" + JSON.stringify(sousCompetences) + "=>setValue(" + numTroll+'.talent.'+nomEnBase+", " + pc + ")");
MY_setValue(`${numTroll}.talent.${nomEnBase}`, pc);
}
function creerBulleVide() {
let table = document.createElement('table');
table.id = 'bulle';
table.className = 'mh_tdborder';
table.width = 300;
table.border = 0;
table.cellPadding = 5;
table.cellSpacing = 1;
table.style =
'position:absolute;' +
'visibility:hidden;' +
'z-index:800;' +
'height:auto;';
let tr = appendTr(table, 'mh_tdtitre');
appendTdText(tr, 'Titre');
tr = appendTr(table, 'mh_tdpage');
appendTdText(tr, 'Contenu');
let aList = document.getElementsByTagName('a');
aList[aList.length - 1].parentNode.appendChild(table);
return table;
}
function cacherBulle() {
if (bulleStyle) {
bulleStyle.visibility = 'hidden';
}
}
function setBulle(evt) {
let nom = this.nom;
let fonction = this.fonction;
let niveau = parseInt(this.niveau);
let str = '';
if (fonction == 'competences') {
str = competences(nom, niveau);
} else if (fonction == 'sortileges') {
str = sortileges(nom);
} else if (fonction == '*') { // pour les raccourcis de la frame de gauche : on ne sait pas si c'est compétence ou sort
str = competences(nom, niveau);
if (str == '') {
str = sortileges(nom);
}
}
if (str == '') {
debugMZ(`setBulle, pas de description sur ${nom}`);
return;
}
if (nom.indexOf('Golem') != -1) {
nom = 'Golemologie';
}
let xfenetre, yfenetre, xpage, ypage, element = null;
let offset = 15;
let bulleWidth = 300;
if (!hauteur) {
hauteur = 50;
}
element = document.getElementById('bulle');
if (!element) {
element = creerBulleVide();
}
xfenetre = evt.clientX;
yfenetre = evt.clientY;
xpage = xfenetre;
ypage = yfenetre;
if (evt.pageX) {
xpage = evt.pageX;
}
if (evt.pageY) {
ypage = evt.pageY;
}
if (element) {
bulleStyle = element.style;
element.firstChild.firstChild.innerHTML = `<b>${nom}</b>`;
element.childNodes[1].firstChild.innerHTML = str;
}
if (bulleStyle) {
if (xfenetre > bulleWidth + offset) {
xpage = xpage - (bulleWidth + offset);
} else {
xpage = xpage + offset;
}
if (yfenetre > hauteur + offset) {
ypage = ypage - (hauteur + offset);
}
bulleStyle.width = bulleWidth + 'px';
bulleStyle.left = `${xpage}px`;
bulleStyle.top = `${ypage}px`;
bulleStyle.visibility = 'visible';
bulleStyle.border = 'solid black 1px';
}
}
/* -[functions] Textes des infos-bulles pour les competences et sortileges - */
function competences(comp, niveau) {
let modA = atttour ? Math.floor((att + atttourD) * atttour / 100) : 0,
modD = degtour ? Math.floor(deg * degtour / 100) : 0,
texte = "";
if (comp.indexOf('Acceleration du Metabolisme') != -1 && minParPV != null) {
texte = `<b>1</b> PV = <b>${minParPV}</b> minute`;
if (minParPV > 1) {
texte = `${texte}s`;
}
if (overDLA) {
texte = `${texte}<br/><i>(Votre DLA est dépassée.)</i>`;
}
} else if (comp.indexOf("Attaque Precise") != -1) {
let pc, lastmax = 0,
jetatt, espatt = 0,
notMaxedOut = false;
for (let i = niveau; i > 0; i--) {
pc = getTalent(comp, i);
if (lastmax != 0 && pc <= lastmax) {
// Si %AP(i)<%AP(i+1), on passe AP(i)
continue;
}
jetatt = Math.round(3.5 * (
Math.min(Math.floor(1.5 * att), att + 3 * i) + modA
)) + attbp + attbm;
espatt = espatt + (pc - lastmax) * jetatt;
texte = `${texte}Attaque niv. ${i} (${pc - lastmax}%) : <b>${Math.min(Math.floor(att * 1.5), att + 3 * i)}</b> D6 `;
if (modA) {
texte = `${texte}<i>${aff(modA)}D6</i> `;
}
texte = `${texte}${aff(attbp + attbm)} => <b>${jetatt}</b><br>`;
lastmax = pc;
if (i < niveau) {
// Si l'un des % de niveau inf est > % nivmax,
// on affiche l'espérance à la fin
notMaxedOut = true;
}
}
if (notMaxedOut) {
texte = `${texte}<i>Attaque moyenne (si réussite) : <b>${Math.floor(10 * espatt / lastmax) / 10}</b></i><br>`;
}
texte = `${texte}Dégâts : <b>${deg}</b> D3 `;
if (modD) {
texte = `${texte}<i>${aff(modD)}D3</i> `;
}
texte = `${texte}${aff(degbp + degbm)} => <b>${degmoytour}/${degmoycrittour}</b>`;
} else if (comp.indexOf("Balayage") != -1) {
texte = `Déstabilisation : <b>${att}</b> D6 `;
if (modA) {
texte = `${texte}<i>${aff(modA)}D6</i> `;
}
texte = `${texte}${aff(attbp + attbm)} => <b>${attmoytour}</b><br>` +
`Effet : <b>Met à terre l'adversaire</b>`;
} else if (comp.indexOf('Bidouille') != -1) {
texte = 'Bidouiller un trésor permet de compléter le nom d\'un objet ' +
'de votre inventaire avec le texte de votre choix.';
} else if (comp.indexOf('Baroufle') != -1) {
texte = 'Vous voulez encourager vos compagnons de chasse ? ' +
'Ramassez quelques Coquillages, et en avant la musique !<br>';
texte = `${texte}${'<table class="mh_tdborder" cellspacing="1" cellpadding="1" border="0"><tbody>' +
'<tr class="mh_tdtitre"><th>Nom</th><th>Effet</th></tr>' +
'<tr class="mh_tdpage"><td>Badaboum</td><td>att +1</td></tr>' +
'<tr class="mh_tdpage"><td>Booong</td><td>deg +1 / esq -1</td></tr>' +
'<tr class="mh_tdpage"><td>Gaaaw</td><td>Fatigue +1</td></tr>' +
'<tr class="mh_tdpage"><td>Ghimighimighimi</td><td>Impacte le baroufleur</td></tr>' +
'<tr class="mh_tdpage"><td>Huitsch</td><td>deg -1</td></tr>' +
'<tr class="mh_tdpage"><td>Kliketiiik</td><td>esq -1 / concentration -1</td></tr>' +
'<tr class="mh_tdpage"><td>Krouiiik</td><td>concentration -2</td></tr>' +
'<tr class="mh_tdpage"><td>Kssksss</td><td>esq +1</td></tr>' +
'<tr class="mh_tdpage"><td>Praaaouuut</td><td>reg-1 </td></tr>' +
'<tr class="mh_tdpage"><td>Sssrileur</td><td>seuil 6, rend visible</td></tr>' +
'<tr class="mh_tdpage"><td>Tagadagada</td><td>augmente le nombre de tours (1 tour par tranche de 2)</td></tr>' +
'<tr class="mh_tdpage"><td>Tuutuuuut</td><td>att -1</td></tr>' +
'<tr class="mh_tdpage"><td>Whaaag</td><td>augmente la portée horizontale (1 case par tranche de 4)</td></tr>' +
'<tr class="mh_tdpage"><td>Whoooom</td><td>concentration +2</td></tr>' +
'<tr class="mh_tdpage"><td>Ytseukayndof</td><td>seuil 2, rend les bonus magiques</td></tr>' +
'<tr class="mh_tdpage"><td>Zbouing </td><td>reg +1</td></tr>' +
'</tbody></table>'}`;
} else if (comp.indexOf("Botte Secrète") != -1) {
modA = atttour ? Math.floor(Math.floor(2 * att / 3) * atttour / 100) : 0;
modD = degtour ? Math.floor(Math.floor(att / 2) * degtour / 100) : 0;
texte = `Attaque : <b>${Math.floor(2 * att / 3)}</b> D6 `;
if (modA) {
texte = `${texte}<i>${aff(modA)}D6</i> `;
}
texte = `${texte}${aff(Math.floor((attbp + attbm) / 2))
} => <b>${Math.round(
3.5 * (Math.floor(2 * att / 3) + modA) + Math.floor((attbp + attbm) / 2)
)}</b><br/>Dégâts : <b>${Math.floor(att / 2)}</b> D3 `;
if (modD) {
texte = `${texte}<i>${aff(modD)}D3</i> `;
}
texte = `${texte}${aff(Math.floor((degbp + degbm) / 2))} => <b>${2 * (Math.floor(att / 2) + modD) + Math.floor((degbp + degbm) / 2)
}/${2 * (Math.floor(1.5 * Math.floor(att / 2)) + modD) +
Math.floor((degbp + degbm) / 2)}</b>`;
} else if (comp.indexOf('Camouflage') != -1) {
let camou = getTalent('Camouflage');
texte = `${'Pour conserver son camouflage, il faut réussir un jet sous:<br/>' +
'<i>Déplacement :</i> <b>'}${Math.floor(0.75 * camou)}%</b><br/>` +
`<i>Attaque :</i> <b>perte automatique</b>.<br/>` +
`<i>Projectile Magique :</i> <b>${Math.floor(0.25 * camou)}%</b>`;
} else if (comp.indexOf("Charger") != -1) {
if (pvcourant <= 0) {
// N'est plus censé se produire : activation obligatoire si mort
return "<i>On ne peut charger personne quand on est mort !</i>";
}
let portee = Math.min(
Math.max(
getPortee(reg + Math.floor(pvcourant / 10)) -
Math.floor((fatigue + bmfatigue) / 5),
1
),
vuetotale
);
if (portee < 1) {
return "<b>Impossible de charger</b>";
}
texte = `Attaque : <b>${att}</b> D6 `;
if (modA) {
texte = `${texte}<i>${aff(modA)}D6</i> `;
}
texte = `${texte}${aff(attbp + attbm)
} => <b>${attmoytour}</b><br>` +
`Dégâts : <b>${deg}</b> D3 `;
if (modD) {
texte = `${texte}<i>${aff(modD)}D3</i> `;
}
texte = `${texte}${aff(degbp + degbm)
} => <b>${degmoytour}/${degmoycrittour}</b><br>` +
`Portée : <b>${portee}</b> case`;
if (portee > 1) {
texte = `${texte}s`;
}
} else if (comp.indexOf('Connaissance des Monstres') != -1) {
texte = `Portée horizontale : <b>${vuetotale}</b> case`;
if (vuetotale > 1) {
texte = `${texte}s`;
}
texte = `${texte}<br/>Portée verticale : <b>${Math.ceil(vuetotale / 2)}</b> case`;
if (vuetotale > 2) {
texte = `${texte}s`;
}
} else if (comp.indexOf('Piège') != -1) {
texte = 'Piège à Glue :<ul><li>Et si vous colliez vos adversaires au sol ?</li></ul>';
texte = `${texte}<hr style="margin:3px!important; border-top: 1px solid black!important">`;
texte = `${texte}Piège à Feu: <ul><li>À moins que vous ne préfériez les envoyer en l'air !</li>`;
texte = `${texte}<li>Dégats du piège à feu : <b>${Math.floor((esq + vue) / 2)}</b> D3` +
` => <b>${2 * Math.floor((esq + vue) / 2)} (${resiste((esq + vue) / 2)})</b></li></ul>`;
} else if (comp.indexOf("Contre-Attaquer") != -1) {
modA = atttour ? Math.floor(Math.floor(att / 2) * atttour / 100) : 0;
texte = `Attaque : <b>${Math.floor(att / 2)}</b> D6 `;
if (modA) {
texte = `${texte}<i>${aff(modA)}D6</i> `;
}
texte = `${texte}${aff(Math.floor((attbp + attbm) / 2))
} => <b>${Math.round(
3.5 * (Math.floor(att / 2) + modA) + Math.floor((attbp + attbm) / 2)
)}</b><br>` +
`Dégâts : <b>${deg}</b> D3 `;
if (modD) {
texte = `${texte}<i>${aff(modD)}D3</i> `;
}
texte = `${texte}${aff(degbp + degbm)
} => <b>${degmoytour}/${degmoycrittour}</b>`;
} else if (comp.indexOf("Coup de Butoir") != -1) {
let pc, lastmax = 0,
jetdeg, espdeg = 0,
notMaxedOut = false;
texte = `Attaque : <b>${att}</b> D6 `;
if (modA) {
texte = `${texte}<i>${aff(modA)}D6</i> `;
}
texte = `${texte}${aff(attbp + attbm)
} => <b>${attmoytour}</b>`;
for (let i = niveau; i > 0; i--) {
pc = getTalent(comp, i);
if (lastmax != 0 && pc <= lastmax) {
// Si %CdB(i)<%CdB(i+1), on passe CdB(i)
continue;
}
jetdeg = 2 * (
Math.min(Math.floor(1.5 * deg), deg + 3 * i) + modD
) + degbp + degbm;
espdeg = espdeg + (pc - lastmax) * jetdeg;
texte = `${texte}<br>Dégâts niv. ${i} (${pc - lastmax}%) : <b>${Math.min(Math.floor(deg * 1.5), deg + 3 * i)}</b> D3 `;
if (modD) {
texte = `${texte}<i>${aff(modD)}D3</i> `;
}
texte = `${texte}${aff(degbp + degbm)
} => <b>${jetdeg
}/${jetdeg + 2 * Math.floor(deg / 2)}</b>`;
lastmax = pc;
if (i < niveau) {
// Si l'un des % de niveau inf est > % nivmax,
// on affiche l'espérance à la fin
notMaxedOut = true;
}
}
if (notMaxedOut) {
texte = `${texte}<br><i>Dégâts moyens (si réussite) : <b>${Math.floor(10 * espdeg / lastmax) / 10}/${Math.floor(10 * espdeg / lastmax) / 10 + 2 * Math.floor(deg / 2)
}</b></i>`;
}
} else if (comp.indexOf('Course') != -1) {
texte = `Déplacement gratuit : <b>${Math.floor(getTalent('Course') / 2)
} %</b> de chance`;
} else if (comp.indexOf('Déplacement Eclair') != -1) {
texte = 'Permet d\'économiser <b>1</b> PA ' +
'par rapport au déplacement classique';
} else if (comp.indexOf('Dressage') != -1) {
texte = 'Le dressage permet d\'apprivoiser un Gowap redevenu sauvage, un Mouch\'oo Sauvage ' +
'ou un Gnu Sauvage. La portée est de une case.';
} else if (comp.indexOf('Ecriture Magique') != -1) {
texte = 'Réaliser la copie d\'un sortilège après en avoir découvert ' +
'la formule nécessite de réunir les composants de cette formule, ' +
'd\'obtenir un parchemin vierge sur lequel écrire, et de récupérer ' +
'un champignon adéquat pour confectionner l\'encre.';
} else if (comp.indexOf('Frenesie') != -1) {
texte = `Attaque : <b>${att}</b> D6 ${aff(attbp + attbm)
} => <b>${attmoy}</b><br/>` +
`Dégâts : <b>${deg}</b> D3 ${aff(degbp + degbm)
} => <b>${degmoy}/${degmoycrit}</b>`;
} else if (comp.indexOf('Golem') != -1) {
texte = 'Animez votre golem en assemblant divers matériaux ' +
'autour d\'un cerveau minéral.';
} else if (comp.indexOf('Grattage') != -1) {
texte = 'Permet de confectionner un Parchemin Vierge ' +
'à partir de composants et de Gigots de Gob\'.';
} else if (comp.indexOf('Hurlement Effrayant') != -1) {
texte = 'Fait fuir un monstre si tout se passe bien.' +
'<br/>Lui donne de gros bonus sinon...';
} else if (comp.indexOf('Identification des Champignons') != -1) {
texte = `Portée horizontale : <b>${Math.floor(vuetotale / 2)}</b> case`;
if (vuetotale > 2) {
texte = `${texte}s`;
}
texte = `${texte}<br/>Portée verticale : <b>${Math.floor(vuetotale / 4)}</b> case`;
if (vuetotale > 4) {
texte = `${texte}s`;
}
} else if (comp.indexOf('Insultes') != -1) {
texte = `Portée horizontale : <b>${Math.min(vuetotale, 1)}</b> case`;
} else if (comp.indexOf('interposer') != -1) {
texte = `Jet de réflexe : <b>${Math.floor(2 * (esq + reg) / 3)}</b> D6 ${aff(esqbp + esqbm)
} => <b>${Math.round(3.5 * Math.floor(2 * (esq + reg) / 3) + (esqbp + esqbm))}</b>`;
} else if (comp.indexOf('Lancer de Potions') != -1) {
texte = `Portée : <b>${2 + Math.floor(vuetotale / 5)}</b> cases`;
} else if (comp.indexOf('Marquage') != -1) {
texte = 'Marquage permet de rajouter un sobriquet à un monstre. Il faut ' +
'bien choisir le nom à ajouter car celui-ci sera définitif. Il faut ' +
'se trouver dans la même caverne que le monstre pour le marquer.';
} else if (comp.indexOf('Mélange Magique') != -1) {
texte = 'Cette Compétence permet de combiner deux Potions pour ' +
'en réaliser une nouvelle dont l\'effet est la somme ' +
'des effets des potions initiales.';
} else if (comp.indexOf('Travail de la Pierre') != -1) {
texte = `Miner :<ul><li>Portée horizontale (officieuse) : <b>${2 * vuetotale}</b> cases</li>` +
`<li>Portée verticale (officieuse) : <b>${2 * Math.ceil(vuetotale / 2)}</b> cases</li></ul>` +
`Tailler: <ul><li>Permet d'augmenter sensiblement la valeur marchande de certains ` +
`minerais. Mais cette opération délicate n'est pas sans risques...</li></ul>`;
} else if (comp.indexOf('Necromancie') != -1) {
texte = 'La Nécromancie permet à partir des composants d\'un monstre ' +
'de faire "revivre" ce monstre.';
} else if (comp.indexOf('Painthure de Guerre') != -1) {
texte = 'Grimez vos potrõlls et réveillez l\'esprit guerrier ' +
'qui sommeille en eux ! Un peu d\'encre, une Tête Réduite ' +
'pour s\'inspirer, et laissez parler votre créativité.';
} else if (comp.indexOf("Parer") != -1) {
modA = atttour ? Math.floor(Math.floor(att / 2) * atttour / 100) : 0;
texte = `Jet de parade : <b>${Math.floor(att / 2)}</b> D6 `;
if (modA) {
texte = `${texte}<i>${aff(modA)}D6</i> `;
}
texte = `${texte}${aff(Math.floor((attbp + attbm) / 2))
} => <b>${Math.round(
3.5 * (Math.floor(att / 2) + modA) +
Math.floor((attbp + attbm) / 2)
)}</b><hr style="margin:3px!important; border-top: 1px solid black!important">Equivalent esquive : <b>${Math.floor(att / 2) + esq}</b> D6 `;
if (modA) {
texte = `${texte}<i>${aff(modA)}D6</i> `;
}
texte = `${texte}${aff(Math.floor((attbp + attbm) / 2) + esqbp + esqbm)
} => <b>${Math.round(
3.5 * (Math.floor(att / 2) + modA + esq) +
Math.floor((attbp + attbm) / 2)
) + esqbp + esqbm}</b></i>`;
} else if (comp.indexOf('Pistage') != -1) {
texte = `Portée horizontale : <b>${2 * vuetotale}</b> cases<br/>` +
`Portée verticale : <b>${2 * Math.ceil(vuetotale / 2)}</b> cases`;
} else if (comp.indexOf('Planter un Champignon') != -1) {
texte = 'Planter un Champignon est une compétence qui vous permet de ' +
'créer des colonies d\'une variété donnée de champignon à partir de ' +
'quelques exemplaires préalablement enterrés.';
} else if (comp.indexOf('Regeneration Accrue') != -1) {
texte = `Régénération : <b>${Math.floor(pvtotal / 15)}</b> D3` +
` => <b>+${2 * Math.floor(pvtotal / 15)}</b> PV`;
} else if (comp.indexOf('Reparation') != -1) {
texte = 'Marre de ces arnaqueurs de forgerons ? Prenez quelques outils, ' +
'et réparez vous-même votre matériel !';
} else if (comp.indexOf('Retraite') != -1) {
texte = 'Vous jugez la situation avec sagesse et estimez qu\'il serait ' +
'préférable de préparer un repli stratégique pour déconcerter ' +
'l\'ennemi et lui foutre une bonne branlée ... plus tard. MOUAHAHA ! ' +
'Quelle intelligence démoniaque.';
} else if (comp.indexOf("RotoBaffe") != -1) {
let Datt = att, vattbm = attbp + attbm,
Ddeg = deg, vdegbm = degbp + degbm,
tabTxt = [];
for (let iNiveau = 0, iAttaque = 1; iNiveau <= niveau; iNiveau++) {
for (let i2 = 0; i2 < (iNiveau == 0 ? 1 : iNiveau); i2++, iAttaque++) {
texte = `<b>Attaque n°${iAttaque} :</b><br>` +
`Attaque : <b>${Datt}</b> D6 `;
if (modA) {
texte = `${texte}<i>${aff(modA)}D6</i> `;
}
texte = `${texte}${aff(vattbm)
} => <b>${Math.round(3.5 * (Datt + modA)) + vattbm}</b><br>` +
`Dégâts : <b>${Ddeg}</b> D3 `;
if (modD) {
texte = `${texte}<i>${aff(modD)}D3</i> `;
}
texte = `${texte}${aff(vdegbm)
} => <b>${2 * (Ddeg + modD) + vdegbm
}/${2 * (Math.floor(1.5 * Ddeg) + modD) + vdegbm}</b>`;
tabTxt.push(texte);
}
// Datt = Math.floor(0.75*Datt); // il n'y a plus de baisse d'attaque
modA = atttour ? Math.floor((Datt + atttourD) * atttour / 100) : 0;
// vattbm = Math.floor(0.75*vattbm);
Ddeg = Math.floor(0.75 * Ddeg);
modD = degtour ? Math.floor(Ddeg * degtour / 100) : 0;
vdegbm = Math.floor(0.75 * vdegbm);
}
texte = tabTxt.join('<hr style="margin:3px!important; border-top: 1px solid black!important">');
} else if (comp.indexOf('Shamaner') != -1) {
texte = 'Permet de contrecarrer certains effets des pouvoirs spéciaux ' +
'des monstres en utilisant des champignons (de 1 à 3).';
}
return texte;
}
function sortileges(sort) {
sort = sort.toLowerCase();
let
// Fonctions utiles uniquement à "sortileges"
decumul_buff = function (nom, str, buff) {
// Décumul des sorts de buff (old school)
let txt = `1<sup>ere</sup>${nom} : <b>${str} +${buff}</b>`,
dec = buff,
total = buff,
i = 1;
while (i < 6) {
i++;
dec = Math.floor(coefDecumul(i) * buff);
if (dec <= 1 || i == 6) {
break;
}
total = total + dec;
txt = `${txt}<br/><i>${i}<sup>e</sup> ${nom} : ${str} +${dec} (+${total})</i>`;
}
txt = `${txt}<br/><i>${i}<sup>e</sup> et + : ${str} +${dec}</i>`;
return txt;
},
nbrAdX = function (pc) {
// Détermine le nombre d'AdX actifs à partir du % de D
switch (Number(pc)) {
case 0: return 0;
case 20: return 1;
case 33: return 2;
case 41: return 3;
case 46: return 4;
default: return Math.floor((Number(pc) - 39) / 2);
}
},
decumulPc = function (n) {
// Détermine le % de D décumulé du n-ième AdX
switch (Number(n)) {
case 0: return 0;
case 1: return 20;
case 2: return 13;
case 3: return 8;
case 4: return 5;
case 5: return 3;
default: return 2;
}
},
decumulFixe = function (bm, n) {
// Détermine le bonus fixe décumulé du n-ième AdX
switch (Number(n)) {
case 0: return 0;
case 1: return Math.max(1, bm);
case 2: return Math.max(1, Math.round(bm * 6.7) / 10);
case 3: return Math.max(1, Math.round(bm * 4) / 10);
default: return 1; // Sous les 1 de moyenne même en D6
}
},
texte = "";
if (sort.indexOf('analyse anatomique') != -1) {
texte = `Portée horizontale : <b>${Math.floor(vuetotale / 2)}</b> case`;
if (vuetotale > 3) {
texte = `${texte}s`;
}
texte = `${texte}<br/>Portée verticale : <b>${Math.floor((vuetotale + 1) / 4)}</b> case`;
if (vuetotale > 7) {
texte = `${texte}s`;
}
} else if (sort.indexOf('armure etheree') != -1) {
texte = decumul_buff('AE', 'Armure magique', reg);
} else if (sort.indexOf("augmentation") != -1 && sort.indexOf("attaque") != -1) {
let categoriesAdA = {
"attx1": {
// Affichage: code MZ (cf arrayTalents)
AN: true,
AP: "AP1",
Balayage: "Balayage",
Charge: "Charger",
CdB: "CdB1",
Frénésie: "Frenesie",
RB: "RB1",
GdS: "GdS",
Siphon: "Siphon"
},
"attx2/3": {
"Botte Secrète": "BS"
},
"attx1/2": {
CA: "CA",
Parer: "Parer1"
},
"degx2/3": {
Vampirisme: "Vampi"
},
"vuex1": {
"Projectile Magique": "Projo"
}
};
let baseAdA = {
"attx1": att,
"attx2/3": Math.floor(2 * att / 3),
"attx1/2": Math.floor(att / 2),
"degx2/3": Math.floor(2 * deg / 3),
"vuex1": vue
};
let pc = atttour,
pcInit = pc,
nbrAdA = nbrAdX(pc),
newTalent,
i, DSup, fixe = 0;
i = nbrAdA;
while (i++ < nbrAdA + 3) {
pc = pc + decumulPc(i);
fixe = fixe + decumulFixe(3.5, i);
if (texte) {
texte = `${texte}<hr style="margin:3px!important; border-top: 1px solid black!important">`;
}
texte = `${texte}<b>${i}<sup>e</sup> AdA : ${aff(pc)}% de Dés d'attaque :</b><br>`;
for (let categorie in categoriesAdA) {
// On génére la liste: "talent1, talent2"
DSup = Math.floor(baseAdA[categorie] * pc / 100) -
Math.floor(baseAdA[categorie] * pcInit / 100);
newTalent = false;
for (let talent in categoriesAdA[categorie]) {
if (getTalent(categoriesAdA[categorie][talent])) {
if (newTalent) {
texte = `${texte}, `;
}
texte = texte + talent;
newTalent = true;
}
}
if (newTalent) {
// Si le trõll a au moins un talent dans la catégorie :
texte = `${texte}: <b>+${DSup}D6 +${Math.floor(fixe)}</b> <i>(+${Math.floor(3.5 * DSup + fixe)})</i><br>`;
}
}
}
} else if (sort.indexOf('augmentation') != -1 && sort.indexOf('esquive') != -1) {
texte = decumul_buff('AdE', 'Esquive', Math.floor((esq - 1) / 2));
} else if (sort.indexOf("augmentation des dégâts") != -1) {
let categoriesAdD = {
"attx1/2": {
"Botte Secrète": "BS"
},
"degx1": {
AN: true,
AP: "AP1",
Charge: "Charger",
CA: "CA",
CdB: "CdB1",
Frénésie: "Frenesie",
RB: "RB1",
Rafale: "Rafale",
Vampi: "Vampi"
},
"degx1/2": {
"Griffe du Sorcier": "GdS"
},
"vuex1/2": {
"Projectile Magique": "Projo"
},
"regx1": {
"Siphon des Âmes": "Siphon"
}
};
let baseAdD = {
"attx1/2": Math.floor(att / 2),
"degx1": deg,
"degx1/2": Math.floor(deg / 2),
"vuex1/2": Math.floor(vue / 2),
"regx1": reg
};
let pc = degtour,
pcInit = pc,
nbrAdD = nbrAdX(pc),
newTalent,
i, DSup, fixe = 0;
i = nbrAdD;
while (i++ < nbrAdD + 3) {
pc = pc + decumulPc(i);
fixe = fixe + decumulFixe(2, i);
if (texte) {
texte = `${texte}<hr style="margin:3px!important; border-top: 1px solid black!important">`;
}
texte = `${texte}<b>${i}<sup>e</sup> AdD : ${aff(pc)}% de Dés de dégâts :</b><br>`;
for (let categorie in categoriesAdD) {
// On génére la liste: "talent1, talent2"
DSup = Math.floor(baseAdD[categorie] * pc / 100) -
Math.floor(baseAdD[categorie] * pcInit / 100);
newTalent = false;
for (let talent in categoriesAdD[categorie]) {
if (getTalent(categoriesAdD[categorie][talent])) {
if (newTalent) {
texte = `${texte}, `;
}
texte = texte + talent;
newTalent = true;
}
}
if (newTalent) {
// Si le trõll a au moins un talent dans la catégorie :
texte = `${texte}: <b>+${DSup}D3 +${Math.floor(fixe)}</b> <i>(+${Math.floor(2 * DSup + fixe)})</i><br>`;
}
}
}
} else if (sort.indexOf('bulle anti-magie') != -1) {
texte = `RM : <b>+${rm}</b><br/>MM : <b>-${mm}</b>`;
} else if (sort.indexOf('bulle magique') != -1) {
texte = `RM : <b>-${rm}</b><br/>MM : <b>+${mm}</b>`;
} else if (sort.indexOf('explosion') != -1) {
texte = `Dégâts : <b>${Math.floor(1 + (deg + Math.floor(pvbase / 10)) / 2)}</b> D3 ` +
` => <b>${2 * Math.floor(1 + (deg + Math.floor(pvbase / 10)) / 2)
} (${resiste(1 + (deg + Math.floor(pvbase / 10)) / 2)})</b>`;
} else if (sort.indexOf('faiblesse passagère') != -1) {
if (pvcourant <= 0) {
return '<i>Dans votre état, vous n\'affaiblirez personne...</i>';
}
texte = `Portée horizontale : <b>${Math.min(1, vuetotale)}</b> case<br/>` +
`Dégâts physiques : <b>-${Math.ceil((Math.floor(pvcourant / 10) + deg - 5) / 4)
} (-${Math.ceil((Math.floor(pvcourant / 10) + deg - 5) / 8)})</b><br/>` +
`Dégâts magiques : <b>-${Math.floor((Math.floor(pvcourant / 10) + deg - 4) / 4)
} (-${Math.floor((Math.floor(pvcourant / 10) + deg - 2) / 8)})</b>`;
} else if (sort.indexOf('flash aveuglant') != -1) {
texte = `Vue, Attaque, Esquive : <b>-${1 + Math.floor(vue / 5)}</b>`;
} else if (sort.indexOf('glue') != -1) {
texte = `Portée : <b>${1 + Math.floor(vuetotale / 3)}</b> case`;
if (vuetotale > 2) {
texte = `${texte}s`;
}
} else if (sort.indexOf("griffe du sorcier") != -1) {
let modD = 0,
addVenin = function (type, effet, duree) {
let ret = `<b>Venin ${type} : </b><br/><b>${effet}</b> D3 pendant <b>${duree}</b> tour`,
dureeReduite = Math.max(Math.floor(duree / 2), 1);
if (duree > 1) {
ret = `${ret}s`;
}
return `${ret} => <b>${2 * effet} x ${duree} = ${2 * effet * duree}</b> (${2 * effet} x ${dureeReduite} = ${2 * effet * dureeReduite})`;
},
effet = 1 + Math.floor((Math.floor(pvmax / 10) + reg) / 3);
// Frappe
texte = `Attaque : <b>${att}</b> D6 `;
if (atttour != 0) {
modD = Math.floor(att * atttour / 100);
texte = `${texte}<i>${aff(modD)}D6</i> `;
}
texte = `${texte}${aff(attbm)
} => <b>${Math.round(3.5 * (att + modD)) + attbm}</b><br/>` +
`Dégâts : <b>${Math.floor(deg / 2)}</b> D3 `;
if (degtour != 0) {
modD = Math.floor(Math.floor(deg / 2) * degtour / 100);
texte = `${texte}<i>${aff(modD)}D3</i> `;
} else {
modD = 0;
}
texte = `${texte}${aff(degbm)
} => <b>${2 * (Math.floor(deg / 2) + modD) + degbm
}/${2 * (Math.floor(deg / 2) + Math.floor(deg / 4) + modD) + degbm
} (${resiste(Math.floor(deg / 2) + modD, degbm)
}/${resiste(Math.floor(deg / 2) + Math.floor(deg / 4) + modD, degbm)
})</b>`;
// Venins
texte = `${texte}<hr style="margin:3px!important; border-top: 1px solid black!important">${addVenin("insidieux", effet, 2 + Math.floor(vue / 5))}`;
effet = Math.floor(1.5 * effet);
texte = `${texte}<hr style="margin:3px!important; border-top: 1px solid black!important">${addVenin("virulent", effet, 1 + Math.floor(vue / 10))}`;
} else if (sort.indexOf('hypnotisme') != -1) {
texte = `Esquive : <b>-${Math.floor(1.5 * esq)}</b> Dés (<b>-${Math.floor(esq / 3)}</b> Dés)`;
} else if (sort.indexOf('dentification des tr') != -1) {
texte = 'Permet de connaitre les caractéristiques et effets précis d\'un trésor.';
} else if (sort.indexOf('nvisibilit') != -1) {
texte = 'Un troll invisible est indétectable même quand on se trouve ' +
'sur sa zone. Toute action physique ou sortilège d\'attaque ' +
'fait disparaître l\'invisibilité.';
} else if (sort.indexOf('vitation') != -1) {
texte = 'Prendre un peu de hauteur permet parfois d\'éviter les ennuis. Comme les pièges ou les trous par exemple...';
} else if (sort.indexOf("projectile magique") != -1) {
let modD = 0,
portee = getPortee(vuetotale);
// Att
texte = `Attaque : <b>${vue}</b> D6 `;
if (atttour != 0) {
modD = Math.floor(vue * atttour / 100);
texte = `${texte}<i>${aff(modD)}D6</i> `;
}
texte = `${texte}${aff(attbm)
} => <b>${Math.round(3.5 * (vue + modD)) + attbm}</b><br>` +
`Dégâts : <b>${Math.floor(vue / 2)}</b> D3 `;
// Deg
if (degtour != 0) {
modD = Math.floor(Math.floor(vue / 2) * degtour / 100);
texte = `${texte}<i>${aff(modD)}D3</i> `;
} else {
modD = 0;
}
texte = `${texte}${aff(degbm)
} => <b>${2 * (Math.floor(vue / 2) + modD) + degbm
}/${2 * (Math.floor(1.5 * Math.floor(vue / 2)) + modD) + degbm
} (${resiste(Math.floor(vue / 2) + modD, degbm)
}/${resiste(1.5 * Math.floor(vue / 2) + modD, degbm)
}) (+ 1D3 par bonus de portée)</b>`;
// Portée
texte = `${texte}<br/>Portée : <b>${portee}</b> case`;
if (portee > 1) {
texte = `${texte}s`;
}
} else if (sort.indexOf('projection') != -1) {
texte = 'Si le jet de résistance de la victime est raté:<br/>' +
'la victime est <b>déplacée</b> et perd <b>1D6</b> d\'Esquive<hr style="margin:3px!important; border-top: 1px solid black!important">' +
'Si le jet de résistance de la victime est réussi:<br/>' +
'la victime ne <b>bouge pas</b> mais perd <b>1D6</b> d\'Esquive.';
} else if (sort.indexOf("rafale psychique") != -1) {
let modD = 0;
texte = `Dégâts : <b>${deg}</b> D3 `;
if (degtour != 0) {
modD = Math.floor(deg * degtour / 100);
texte = `${texte}<i>${aff(modD)}D3</i> `;
}
texte = `${texte}${aff(degbm)
} => <b>${2 * (deg + modD) + degbm
} (${resiste(deg + modD, degbm)})</b><br>` +
`Malus : régénération <b>-${deg + modD}</b>`;
} else if (sort.indexOf("sacrifice") != -1) {
if (pvcourant <= 0) {
// N'est plus censé se produire : activation obligatoire si mort
return "<i>Qui voulez-vous donc soigner ? Vous êtes mort !</i>";
}
let perteSacro = function (sac) {
return ` (-${sac + 2 * (1 + Math.floor(sac / 5))} PV)`;
},
sac = Math.floor((pvcourant - 1) / 2);
let bmPVHorsBlessure = dtbm + dtreserve + pdm + bmt + bmmouche;
let pvdispoSansMalusTemps = pvcourant - pvtotal - Math.ceil(bmPVHorsBlessure * pvtotal / 250);
texte = `Portée horizontale : <b>${Math.min(1, vuetotale)}</b> case<br>` +
`Soin maximal : <b>${sac}</b> PV${perteSacro(sac)}`;
// Sacros max et optimal sans malus (propale R')
sac = Math.floor((pvdispoSansMalusTemps - 2) * 5 / 7);
if (sac > 0) {
texte = `${texte}<hr style="margin:3px!important; border-top: 1px solid black!important">Soin maximum limitant les risques de malus
de temps : <b>${sac}</b> PV${perteSacro(sac)}`;
} else {
texte = `${texte}<hr style="margin:3px!important; border-top: 1px solid black!important">Vous ne pouvez pas compenser de blessures dues à un sacrifice`;
}
} else if (sort.indexOf("siphon") != -1) {
let modD = 0;
texte = `Attaque : <b>${att}</b> D6 `;
if (atttour != 0) {
modD = Math.floor(att * atttour / 100);
texte = `${texte}<i>${aff(modD)}D6</i> `;
}
texte = `${texte}${aff(attbm)
} => <b>${Math.round(3.5 * (att + modD) + attbm)}</b><br>` +
`Dégâts : <b>${reg}</b> D3 `;
if (degtour != 0) {
modD = Math.floor(reg * degtour / 100);
texte = `${texte}<i>${aff(modD)}D3</i> `;
} else {
modD = 0;
}
texte = `${texte}${aff(degbm)
} => <b>${2 * (reg + modD) + degbm
}/${2 * (Math.floor(1.5 * reg) + modD) + degbm
} (${resiste(reg + modD, degbm)
}/${resiste(1.5 * reg + modD, degbm)})</b>`;
texte = `${texte}<br>Nécrose : attaque magique <b>-${reg + modD}</b>`;
} else if (sort.indexOf('télékinésie') != -1) {
texte = 'Portée horizontale :';
let vt = Math.floor(vuetotale / 2) + 2;
let strList = ['d\'une Plum\' ou Très Léger', 'Léger', 'Moyen', 'Lourd', 'Très Lourd ou d\'une Ton\''];
for (let i = 0; i < 5; i++) {
texte = `${texte}<br/><i>Trésor ${strList[i]} : </i><b>${vt}</b> case`;
if (vt > 1) {
texte = `${texte}s`;
}
vt = Math.max(0, vt - 1);
}
} else if (sort.indexOf('téléportation') != -1) {
let portee = getPortee(pitotal / 5); // Roule, 30/09/2016, TP basé sur les PI
debugMZ(`calcul portée Teleportation, pitotal=${pitotal}, portée=${portee}`);
let pmh = 20 + vue + portee;
let pmv = 3 + Math.floor(portee / 3);
texte = `Portée horizontale : <b>${pmh}</b> cases<br/>` +
`Portée verticale : <b>${pmv}</b> cases<hr style="margin:3px!important; border-top: 1px solid black!important">` +
`X compris entre ${posX - pmh} et ${posX + pmh}<br/>` +
`Y compris entre ${posY - pmh} et ${posY + pmh}<br/>` +
`N compris entre ${posN - pmv} et ${Math.min(-1, posN + pmv)}<br/>`;
} else if (sort.indexOf('vampirisme') != -1) {
let modD = 0;
texte = `Attaque : <b>${Math.floor(2 * deg / 3)}</b> D6 `;
if (atttour != 0) {
modD = Math.floor(Math.floor(2 * deg / 3) * atttour / 100);
texte = `${texte}<i>${aff(modD)}D6</i> `;
}
texte = `${texte}${aff(attbm)
} => <b>${Math.round(3.5 * (Math.floor(2 * deg / 3) + modD) + attbm)
}</b><br/>Dégâts : <b>${deg}</b> D3 `;
if (degtour != 0) {
modD = Math.floor(deg * degtour / 100);
texte = `${texte}<i>${aff(modD)}D3</i> `;
} else {
modD = 0;
}
texte = `${texte}${aff(degbm)
} => <b>${2 * (deg + modD) + degbm
}/${2 * (Math.floor(1.5 * deg) + modD) + degbm
} (${resiste(deg + modD, degbm)
}/${resiste(1.5 * deg + modD, degbm)})</b>`;
} else if (sort.indexOf('vision accrue') != -1) {
texte = decumul_buff('VA', 'Vue', Math.floor(vue / 2));
} else if (sort.indexOf('vision lointaine') != -1) {
texte = 'En ciblant une zone située n\'importe où dans le ' +
'Monde Souterrain, votre Trõll peut voir comme s\'il s\'y trouvait.';
} else if (sort.indexOf('voir le caché') != -1) {
texte = `<b>Sur soi :</b><br/>Portée horizontale : <b>${Math.min(5, getPortee(vue))}</b> cases<hr style="margin:3px!important; border-top: 1px solid black!important">` +
`<b>A distance :</b><br/>Portée horizontale : <b>${getPortee(vuetotale)}</b> cases`;
} else if (sort.indexOf('vue troublée') != -1) {
texte = `Portée horizontale : <b>${Math.min(1, vuetotale)}</b> case<br/>` +
`Vue : <b>-${Math.floor(vue / 3)}</b>`;
}
//else texte = `Non documenté`;
return texte;
}
/* Main */
function do_profil2() {
try {
start_script(31, 'do_profil2_log');
extractionDonnees();
setInfosCaracteristiques();
setInfoDescription();
setInfosEtatLieux();
setInfosEtatPV();
setInfosExp();
setInfosFatiguesOptimiales();
creerBulleVide();
traitementTalents();
setLienAnatrolliseur();
// Cette fonction modifie lourdement le DOM, à placer en dernier :
if (race == 'Kastar' || MY_DEBUG) {
setAccel();
}
saveProfil();
displayScriptTime(undefined, 'do_profil2_log');
} catch (exc) {
avertissement(`Une erreur est survenue (do_profil2)`, null, null, exc);
}
}
/** x~x md5.js --------------------------------------------------------- */
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
/*
* Configurable variables. You may need to tweak these to be compatible with
* the server-side, but the defaults work in most cases.
*/
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function hex_md5(s) {
return binl2hex(core_md5(str2binl(s), s.length * chrsz));
}
function b64_md5(s) {
return binl2b64(core_md5(str2binl(s), s.length * chrsz));
}
function str_md5(s) {
return binl2str(core_md5(str2binl(s), s.length * chrsz));
}
function hex_hmac_md5(key, data) {
return binl2hex(core_hmac_md5(key, data));
}
function b64_hmac_md5(key, data) {
return binl2b64(core_hmac_md5(key, data));
}
function str_hmac_md5(key, data) {
return binl2str(core_hmac_md5(key, data));
}
/*
* Perform a simple self-test to see if the VM is working
*/
function md5_vm_test() {
return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}
/*
* Calculate the MD5 of an array of little-endian words, and a bit length
*/
function core_md5(x, len) {
/* append padding */
x[len >> 5] |= 0x80 << len % 32;
x[(len + 64 >>> 9 << 4) + 14] = len;
let a = 1732584193;
let b = -271733879;
let c = -1732584194;
let d = 271733878;
for (let i = 0; i < x.length; i = i + 16) {
let olda = a;
let oldb = b;
let oldc = c;
let oldd = d;
a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
}
return Array(a, b, c, d);
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function md5_cmn(q, a, b, x, s, t) {
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
}
function md5_ff(a, b, c, d, x, s, t) {
return md5_cmn(b & c | ~b & d, a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t) {
return md5_cmn(b & d | c & ~d, a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t) {
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t) {
return md5_cmn(c ^ (b | ~d), a, b, x, s, t);
}
/*
* Calculate the HMAC-MD5, of a key and some data
*/
function core_hmac_md5(key, data) {
let bkey = str2binl(key);
if (bkey.length > 16) {
bkey = core_md5(bkey, key.length * chrsz);
}
let ipad = Array(16), opad = Array(16);
for (let i = 0; i < 16; i++) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
let hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
return core_md5(opad.concat(hash), 512 + 128);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y) {
let lsw = (x & 0xFFFF) + (y & 0xFFFF);
let msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return msw << 16 | lsw & 0xFFFF;
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bit_rol(num, cnt) {
return num << cnt | num >>> 32 - cnt;
}
/*
* Convert a string to an array of little-endian words
* If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
*/
function str2binl(str) {
let bin = Array();
let mask = (1 << chrsz) - 1;
for (let i = 0; i < str.length * chrsz; i = i + chrsz) {
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << i % 32;
}
return bin;
}
/*
* Convert an array of little-endian words to a string
*/
function binl2str(bin) {
let str = "";
let mask = (1 << chrsz) - 1;
for (let i = 0; i < bin.length * 32; i = i + chrsz) {
str = str + String.fromCharCode(bin[i >> 5] >>> i % 32 & mask);
}
return str;
}
/*
* Convert an array of little-endian words to a hex string.
*/
function binl2hex(binarray) {
let hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
let str = "";
for (let i = 0; i < binarray.length * 4; i++) {
str = str + (hex_tab.charAt(binarray[i >> 2] >> i % 4 * 8 + 4 & 0xF) +
hex_tab.charAt(binarray[i >> 2] >> i % 4 * 8 & 0xF));
}
return str;
}
/*
* Convert an array of little-endian words to a base-64 string
*/
function binl2b64(binarray) {
let tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let str = "";
for (let i = 0; i < binarray.length * 4; i = i + 3) {
let triplet = (binarray[i >> 2] >> 8 * (i % 4) & 0xFF) << 16 |
(binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4) & 0xFF) << 8 |
binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4) & 0xFF;
for (let j = 0; j < 4; j++) {
if (i * 8 + j * 6 > binarray.length * 32) {
str = str + b64pad;
} else {
str = str + tab.charAt(triplet >> 6 * (3 - j) & 0x3F);
}
}
}
return str;
}
/** x~x Tests et essais ------------------------------------------------ */
// /////////////////////////////////////////
// debug cartes capitan Roule 07/12/2016
// /////////////////////////////////
// essais : objet
// .mode : description
// .essais : tableau d'objets essai
// .mode : description
// .essais : tableau de cartes
// .noCarte : id de la carte
// .essais : tableau d'essais, [x, y, n, nb]
function AfficheEssais(essais, sMode) {
let eBigDiv = document.getElementById('ListeEssaiCapitan');
if (!eBigDiv) {
let insertPoint = getFooter();
eBigDiv = document.createElement('table');
eBigDiv.id = 'ListeEssaiCapitan';
insertBefore(insertPoint, document.createElement('p'));
insertTitle(insertPoint, 'Capitan : Liste des essais');
insertBefore(insertPoint, eBigDiv);
addTrEssais(eBigDiv, 'mode', 'carte', 'nombre d\'essais', true);
}
if (!essais) {
addTrEssais(eBigDiv, sMode, '', 'pas d\'essai', false);
return;
}
let carte;
for (carte in essais) {
addTrEssais(eBigDiv, sMode, carte, `${essais[carte]} essai(s)`, false);
}
if (carte === undefined) {
addTrEssais(eBigDiv, sMode, '', '0 essai', false);
}
}
function addTrEssais(eTable, sMode, sCarte, sText, bBold) {
let tr = appendTr(eTable);
let td = appendTd(tr);
appendText(td, sMode, bBold);
td = appendTd(tr);
appendText(td, sCarte, bBold);
td = appendTd(tr);
appendText(td, sText, bBold);
}
function getEssaiV1_0() {
try {
let prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
prefs = prefs.getBranch("mountyzilla.storage.capitan.");
let tabK, nK;
prefs.getChildList('', nK, tabK);
logMZ(`getEssaiV1_0, nb key : ${nK}`);
// logMZ('getEssaiV1_0, ' + nK);
return;
// return r;
} catch (exc) {
logMZ('getEssaiV1_0', exc);
}
}
function getEssaiV1_1() {
let locSto = window.localStorage;
logMZ(`getEssaiV1_1, nb key : ${locSto.length}`);
let r = [];
for (let i = 0; i < locSto.length; i++) {
let k = locSto.key(i);
// logMZ('getEssaiV1_1 key ' + k + ' => ' + locSto.getItem(k));
let t = k.split(/\./);
if (t[0] !== 'capitan') {
continue;
}
if (t[2] !== 'essai') {
continue;
}
let carte = `carte n°${t[1]}`;
if (r[carte]) {
r[carte]++;
} else {
r[carte] = 1;
}
// logMZ('getEssaiV1_1 r[' + carte + ']=' + r[carte]);
}
return r;
}
function showEssaiCartes() {
logMZ('début showEssai Tout_MZ');
let essais = getEssaiV1_0();
AfficheEssais(essais, 'V1.0');
essais = getEssaiV1_1();
AfficheEssais(essais, 'V1.1');
logMZ('fin showEssai Tout_MZ');
}
function testBoolLocalStorage() {
let b = true;
let key = 'MZ_essai_bool';
GM_setValue(key, b);
window.localStorage[key] = b;
let v = GM_getValue(key);
logMZ(`recup GM true => ${v}, ${typeof v}`);
v = window.localStorage.getItem(key);
logMZ(`recup localstorage true => ${v}, ${typeof v}`); // localStorage nous rend une chaine 'true' :(
b = false;
GM_setValue(key, b);
window.localStorage[key] = b;
v = GM_getValue(key);
logMZ(`recup GM false => ${v}, ${typeof v}`);
v = window.localStorage.getItem(key);
logMZ(`recup localstorage false => ${v}, ${typeof v}`);
let x = window.localStorage.getItem('lkjlkjerziurlijzer');
logMZ(`recup LocalStorage inconnu => ${typeof x}`); // object null
let y = GM_getValue('654654897894654654');
logMZ(`recup GM inconnu => ${typeof y}`); // undefined
logMZ(`égalité ? => ${x == y}`); // les deux sont "égaux" avec l'opérateur == (pas avec ===, bien sûr)
}
/* --------------------------------- Création liste trolligion --------------------------------- */
function export_trolligion() {
let txt = '';
try {
let tabDl = document.getElementsByTagName('dl');
if (!tabDl || !tabDl[0]) {
logMZ(`pas de dl`);
return;
}
let tabDieux = []; // chaque élément est un objet avec les propriétés suivantes
// nom : string
// rayonnement : entier
// grades : table d'objets (une occurence par grade)
// nom : string
// trolls : table d'objets (un par Trõll)
// id
// nom
// idguilde
// guilde
// race
// niveau
// ferveur
let currentDieu;
let currentGrade;
for (let iChild1 in tabDl[0].children) {
let eChild1 = tabDl[0].children[iChild1];
if (eChild1.tagName) {
switch (eChild1.tagName.toLowerCase()) {
case 'dd': // Trõll
let oTroll = {};
export_trolligion_analyse(oTroll, eChild1);
currentGrade.trolls.push(oTroll);
break;
case 'dt':
let tabH3 = eChild1.getElementsByTagName('h3');
if (tabH3 && tabH3[0]) { // changement de dieu
currentDieu = {
nom: tabH3[0].innerText || tabH3[0].textContent,
grades: []
};
txt = eChild1.innerText || eChild1.textContent;
let m = txt.match(/yon*ement *:* *(\d+)/);
if (m) {
currentDieu.rayonnement = parseInt(m[1]);
}
currentGrade = undefined;
tabDieux.push(currentDieu);
break;
}
let tabH4 = eChild1.getElementsByTagName('h4');
if (tabH4 && tabH4[0]) { // changement de grade
let grade;
txt = tabH4[0].innerText || tabH4[0].textContent;
let tabI = tabH4[0].getElementsByTagName('i');
if (tabI && tabI[0]) {
grade = tabI[0].innerText || tabI[0].textContent;
grade = grade.replace(/"/g, '');
let m = txt.match(/\((.*)\)/); // cas particulier Líhã dont les grades ont des catégories
if (m) {
grade = `${grade} (${m[1]})`;
}
} else {
grade = txt.replace(/"/g, '');
}
currentGrade = { nom: grade, trolls: [] };
currentDieu.grades.push(currentGrade);
break;
}
logMZ(`ignore tag dt ${eChild1.innerHTML}`);
break;
default:
logMZ(`ignore tag ${eChild1.tagName}`); // + ' ' + eChild1);
}
}
}
// logMZ('nb dieux = ' + tabDieux.length);
// logMZ(' + JSON.stringify(tabDieux));
txt = "Dieu\tRayonnement\tGrade\tidTroll\tTroll\tidGuilde\tGuilde\tRace\tNiveau\tFerveur\n";
let txt2 = "Dieu\tRayonnement\n"; // Roule 25/01/2017 ajout d'un tableau résumé par religion
for (let iDieu in tabDieux) {
let oDieu = tabDieux[iDieu];
for (let iGrade in oDieu.grades) {
let oGrade = oDieu.grades[iGrade];
for (let iTroll in oGrade.trolls) {
let oTroll = oGrade.trolls[iTroll];
let t = [oDieu.nom, oDieu.rayonnement,
oGrade.nom,
oTroll.id, oTroll.nom,
oTroll.idguilde, oTroll.guilde,
oTroll.race, oTroll.niveau,
oTroll.ferveur];
for (let iParam in t) {
if (t[iParam] === undefined) {
t[iParam] = '';
} // protection
t[iParam] = t[iParam].toString().replace(/[\n\r\t]/g, ' ').trim(); // plus de protection
}
txt = `${txt}${t.join("\t")}\n`;
}
}
let t = [oDieu.nom, oDieu.rayonnement];
for (let iParam in t) {
if (t[iParam] === undefined) {
t[iParam] = '';
} // protection
t[iParam] = t[iParam].toString().replace(/[\n\r\t]/g, ' ').trim(); // plus de protection
}
txt2 = `${txt2}${t.join("\t")}\n`;
}
txt = `${txt}\n${txt2}`;
} catch (exc) {
avertissement(`Échec durant l'export de trolligion`, null, null, exc);
}
try {
if (copyTextToClipboard(txt)) {
avertissement("Les données ont été copiées dans le presse-papier\n" +
"Collez dans Calc\nou, au pire, dans EXCEL®");
} else {
avertissement("Échec durant la copie vers le presse-papier");
}
} catch (exc) {
avertissement(`Échec durant la copie vers le presse-papier`, exc);
}
}
function export_trolligion_analyse(oTroll, eChild1) {
for (let iChild2 in eChild1.childNodes) { // childNodes pour obtenir les éléments texte aussi
let eChild2 = eChild1.childNodes[iChild2];
if (eChild2.nodeType === undefined) {
continue;
} // properties
// logMZ('eChild2 ' + iChild2 + ' ' + eChild2.nodeName);
switch (eChild2.nodeType) {
case 1: // ELEMENT_NODE:
switch (eChild2.nodeName.toLowerCase()) {
case 'a':
let m;
if (!eChild2.href) {
logMZ(`a sans href ${eChild2.outerHTML}`);
break;
}
m = eChild2.href.match(/EPV\((\d+) *,/);
if (m) {
oTroll.id = parseInt(m[1]);
oTroll.nom = (eChild2.innerText || eChild2.textContent).trim();
break;
}
m = eChild2.href.match(/EAV\((\d+) *,/);
if (m) {
let idGuilde = parseInt(m[1]);
if (idGuilde > 1) { // MH donne 1 comme idGuilde quand le Trõll n'est pas guildé
oTroll.idguilde = parseInt(m[1]);
oTroll.guilde = (eChild2.innerText || eChild2.textContent).trim();
}
break;
}
logMZ(`a non traité ${eChild2.outerHTML}`);
break;
case 'br': // ignore
case 'style': // ignore
case 'img': // ignore
break;
case 'div': // barre de vie
if (eChild2.classList.contains('barre-vie') && eChild2.style && eChild2.style.width) {
oTroll.ferveur = eChild2.style.width;
break;
}
// logMZ(eChild2.innerHTML);
export_trolligion_analyse(oTroll, eChild2);
// logMZ('troll ' + JSON.stringify(oTroll));
break;
default:
logMZ(`ignore élément tag ${eChild2.nodeName}`);
break;
}
break;
case 3: // TEXT_NODE:
let txt = eChild2.nodeValue.trim();
if (txt === '') {
break;
}
let m = txt.match(/(.*) *\((\d+)\)/);
if (m) {
oTroll.race = m[1].trim();
oTroll.niveau = parseInt(m[2]);
} else {
oTroll.race = txt;
}
break;
default: // ne devrait pas arriver
logMZ(`ignore élément type ${eChild2.nodeType}`);
break;
}
}
}
function do_trolligion() {
let divpopup = document.createElement('div');
divpopup.id = 'MZ_divCopier';
divpopup.style.position = 'fixed';
divpopup.style.top = '2px';
divpopup.style.left = '2px;';
divpopup.style.backgroundColor = 'rgba(255,255,255,0.5)';
divpopup.style.cursor = 'pointer';
divpopup.style.zIndex = 200;
divpopup.title = '[MZ] Cliquer ici pour copier les données';
divpopup.onclick = export_trolligion;
let img = createAltImage(`${URL_MZimg}copy_32.png`, 'Cliquer ici pour copier les données');
divpopup.appendChild(img);
document.body.appendChild(divpopup);
}
function do_memoPA() {
let t = document.body.innerText;
let m = t.match(/Il\s*me\s*reste\s*(\d+)\s*PA/i);
//debugMZ('do_memoPA_log t=' + t);
//debugMZ('do_memoPA_log m=' + JSON.stringify(m));
if (m && m.length > 1) {
let pa = parseInt(m[1], 10);
if (numTroll !== undefined && !isNaN(pa)) MY_setValue(numTroll + '.PA', pa);
}
}
function MZ_extern_param() {
if (!document.body.MZ_Params) {
return;
}
if (document.body.MZ_Params.INFOCARAC != undefined) {
MY_setValue('INFOCARAC', document.body.MZ_Params.INFOCARAC);
}
if (document.body.MZ_Params.PRINTSTACK != undefined) {
MY_setValue('PRINTSTACK', document.body.MZ_Params.PRINTSTACK);
}
if (document.body.MZ_Params.CONFIRMEDECALAGE != undefined) {
MY_setValue('CONFIRMEDECALAGE', document.body.MZ_Params.CONFIRMEDECALAGE);
}
if (document.body.MZ_Params.COMPTEAREBOURSDLA != undefined) {
MY_setValue('COMPTEAREBOURSDLA', document.body.MZ_Params.COMPTEAREBOURSDLA);
}
if (document.body.MZ_Params.COMPTEAREBOURSTITRE != undefined) {
MY_setValue('COMPTEAREBOURSTITRE', document.body.MZ_Params.COMPTEAREBOURSTITRE);
}
if (document.body.MZ_Params.COMPTEAREBOURSSUIVANTE != undefined) {
MY_setValue('COMPTEAREBOURSSUIVANTE', document.body.MZ_Params.COMPTEAREBOURSSUIVANTE);
}
if (document.body.MZ_Params.MZ_SuivantsOrdres != undefined) {
MY_setValue('MZ_SuivantsOrdres', document.body.MZ_Params.MZ_SuivantsOrdres);
}
if (document.body.MZ_Params.MZ_SuivantsCompress != undefined) {
MY_setValue('MZ_SuivantsCompress', document.body.MZ_Params.MZ_SuivantsCompress);
}
if (document.body.MZ_Params.MZ_SuivantsTresUnique != undefined) {
MY_setValue('MZ_SuivantsTresUnique', document.body.MZ_Params.MZ_SuivantsTresUnique);
}
}
function MZ_CompoTanieresPrepare(eTable) {
if (!eTable) {
eTable = document.getElementById('tabTresorInfo');
}
if (!eTable) {
debugMZ('MZ_CompoTanieresPrepare erreur, impossible de trouver tabTresorInfo');
return;
}
let eDiv = document.getElementById('MZ_CompoTanieres');
if (eDiv) {
debugMZ('MZ_CompoTanieresPrepare div MZ_CompoTanieres déjà là');
return;
}
let oInfo = MZ_AnalyseInfoHistoTresor(eTable);
if (oInfo.type != 'Composant') {
debugMZ(`MZ_CompoTanieresPrepare div MZ_CompoTanieres pas composant (${oInfo.type})`);
return;
}
debugMZ('MZ_CompoTanieresPrepare création div MZ_CompoTanieres');
let eNew = document.createElement('table');
eNew.id = 'MZ_CompoTanieres';
eNew.className = 'mh_tdborder';
eNew.style.width = '98%';
eNew.style.margin = 'auto';
let eTr = document.createElement('tr');
let eTd = document.createElement('td');
eTd.className = 'mh_tdpage';
eTd.style.cursor = 'pointer';
eTd.style.color = 'blue';
eTd.onclick = MZ_doSearchCompoTanieres;
eTd.appendChild(document.createTextNode(`[MZ] Voir mes compos de ${oInfo.monstre} en tanière`));
eTr.appendChild(eTd);
eNew.appendChild(eTr);
eTable.parentNode.insertBefore(eNew, eTable.nextSibling);
}
function MZ_doSearchCompoTanieres(event) {
let eTableTaniere = document.getElementById('MZ_CompoTanieres');
if (!eTableTaniere) {
logMZ('MZ_doSearchCompoTanieres, erreur, pas de MZ_CompoTanieres');
return;
}
let eTableMH = document.getElementById('tabTresorInfo');
if (!eTableMH) {
logMZ('MZ_doSearchCompoTanieres, erreur, impossible de trouver tabTresorInfo');
return;
}
let oInfo = MZ_AnalyseInfoHistoTresor(eTableMH);
if (oInfo.type != 'Composant') {
logMZ('MZ_doSearchCompoTanieres, erreur, pas sur un compo');
return;
}
let url = `/mountyhall/MH_Play/Play_a_Action.php?type=L&id=-5&sub=rech`;
let postData = `type=L&id=-5&sub=rech&as_type=Composant&as_nom_base=${escape(oInfo.monstre)}&as_Action=Action+en+cours...`;
let nbCall = 0;
if (!event) {
postData = `${postData}&as_composant_morceau=${escape(oInfo.composant)}`;
}
let oCompos = {};
let msgErreur, msgWarning;
// ajouter un compo à l'objet oCompos
let addCompoQualite = function(compo, qualite) {
let oCompo = oCompos[compo];
if (oCompo == undefined) {
oCompo = {};
oCompos[compo] = oCompo;
}
let qty = oCompo[qualite];
if (qty == undefined) qty = 0;
oCompo[qualite] = ++qty;
}
// affichage d'un titre
let displayTitre = function(titre, color) {
let eTr = document.createElement('tr');
let eTd = document.createElement('td');
eTd.className = 'mh_tdpage';
eTd.style.color = color;
eTd.colSpan = 6;
eTd.appendChild(document.createTextNode(`[MZ] ${titre}`));
eTr.appendChild(eTd);
eTableTaniere.appendChild(eTr);
}
// affichage du résultat
let displayResults = function() {
while (eTableTaniere.rows.length > 0) {
eTableTaniere.deleteRow(0);
}
if (msgErreur) displayTitre(msgErreur, 'red');
if (msgWarning) displayTitre(msgWarning, 'purple');
debugMZ(`MZ_doSearchCompoTanieres réponse OK ${JSON.stringify(oCompos)}`);
// tri par nom de compo
let tabTri = [];
let nTotal = 0;
for (let compo in oCompos) {
tabTri.push(compo);
oQualites = oCompos[compo];
for (let qualite in oQualites) nTotal += oQualites[qualite];
}
if (tabTri.length == 0 && !(msgErreur || msgWarning))
displayTitre(`Pas de composant de ${oInfo.monstre} en tanière`, 'red');
else if (tabTri.length > 0)
displayTitre(`Vous avez ${nTotal} composants de ${oInfo.monstre} en tanière`, 'blue');
if (!tabTri.includes(oInfo.composant)) {
tabTri.push(oInfo.composant);
}
tabTri.sort();
eTr = document.createElement('tr');
eTr.className = 'mh_tdtitre';
let tabQualite = ['', 'Très Bonne', 'Bonne', 'Moyenne', 'Mauvaise', 'Très Mauvaise'];
for (let qualite of tabQualite) {
let eTh = document.createElement('th');
eTh.appendChild(document.createTextNode(qualite));
if (qualite == '') {
eTh.style.width = '30%';
} else {
eTh.style.width = '14%';
}
eTh.style.border = 'solid black 1px';
eTr.appendChild(eTh);
}
eTableTaniere.appendChild(eTr);
for (let compo of tabTri) {
eTr = document.createElement('tr');
for (let qualite of tabQualite) {
eTd = document.createElement('td');
eTd.style.border = 'solid black 1px';
eTd.className = 'mh_tdpage';
if (oInfo.composant == compo && oInfo.qualite == qualite) {
eTd.style.background = 'white';
} else {
}
if (qualite == '') {
eTd.appendChild(document.createTextNode(compo));
} else if (oCompos[compo] && oCompos[compo][qualite]) {
eTd.appendChild(document.createTextNode(oCompos[compo][qualite]));
eTd.style.textAlign = 'right';
}
eTr.appendChild(eTd);
}
eTableTaniere.appendChild(eTr);
}
}
// fonction de traitement du retour du deuxième appel (qui reçoit du JSON avec la liste de compos
let callback2 = function (responseDetails) {
try {
if (responseDetails.status == 0) return;
let oReponse = JSON.parse(responseDetails.responseText);
//logMZ('compo taniere.onload2 ' + JSON.stringify(oReponse));
for (oCompoRep of oReponse) {
//console.log(JSON.stringify(oCompoRep));
let m = oCompoRep.value.nom.value.match(/> *(.*) d'une* (.*)de Qualité (.*) \[/i);
if (!m) {
logMZ(`MZ_doSearchCompoTanieres no match ${oCompoRep.value.nom.value}`);
continue;
}
addCompoQualite(m[1], m[3]);
}
displayResults();
} catch (exc) {
logMZ('compo taniere.onload2', exc);
}
};
// fonction de traitement du retour du premier appel (qui reçoit de l'HTML). Ne sert qu'à récupérer le code "cp"
let callback1 = function (responseDetails) {
try {
// logMZ('MZ_doSearchCompoTanieres readyState=' + responseDetails.readyState + ', error=' + responseDetails.error + ', status=' + responseDetails.status);
if (responseDetails.status == 0) return;
let eStockAppendRows = responseDetails.responseXML.getElementById('stock-append-rows');
if (eStockAppendRows && eStockAppendRows.value) {
let url2 = '/mountyhall/MH_PageUtils/Services/json_stock.php?cp=' + eStockAppendRows.value;
// modification de l'history pour gérer le referer de l'appel AJAX JSON
let oldURL = document.URL;
window.history.replaceState(null, '', `https://${window.location.host}/mountyhall/MH_Play/Play_a_Action.php`);
FF_XMLHttpRequest({
method: 'GET',
url: url2,
trace: `recherche en tanière compos phase 2 ${oInfo.monstre}`,
onload: callback2,
});
window.history.replaceState(null, '', oldURL);
return;
}
if (!eStockAppendRows) {
if (nbCall == 0) {
// Il faut le faire 2 fois pour récupérer le code cp
nbCall = 1;
FF_XMLHttpRequest({
method: 'POST',
HTML: true,
url: url,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: postData,
trace: `recherche en tanière compos phase 1.5 ${oInfo.monstre}`,
onload: callback1,
});
return;
}
logMZ('pas de stock-append-rows');
} else {
logMZ(`réponseeMH : eStockAppendRows.value vide`);
msgErreur = 'Erreur à la récupération de la liste';
displayResults();
}
// la suite ne devrait plus être utile au 01/11/2024
let eDivRecherches = responseDetails.responseXML.getElementById('recherches');
if (!eDivRecherches) {
logMZ('MZ_doSearchCompoTanieres réponse sans DIV recherches');
return;
}
let bFound = false;
let nTotal = 0;
for (let eDiv of eDivRecherches.children) {
if (eDiv.tagName != 'DIV') {
continue;
}
let oTable = eDiv.getElementsByTagName('table')[0];
if (!oTable) {
continue;
}
for (let oTr of oTable.rows) {
for (let oTd of oTr.cells) {
let tabA = oTd.getElementsByTagName('a');
if (!tabA[0]) {
continue;
}
if (tabA[0].href.indexOf('TresorHistory.php') <= 0) {
continue;
}
let m = oTd.textContent.match(/^(.*) d'une* (.*) de Qualité (.*) \[/i);
if (!m) {
debugMZ(`MZ_doSearchCompoTanieres no match ${oTd.textContent}`);
continue;
}
addCompoQualite(m[1], m[3]);
nTotal++;
bFound = true;
}
}
}
if (!bFound) {
msgErreur = 'Pas de ';
if (!event) {
msgErreur += oInfo.composant;
} else {
msgErreur = `${sMsg}composant`;
}
msgErreur = `${msgErreur} de ${oInfo.monstre} en tanière`;
} else if (nTotal < 100) {
if (!event) {
msgWarning = `Vous avez au moins 100 composants de ${oInfo.monstre} en tanière.`;
msgWarning = `${msgWarning} La recherche a été restreinte aux composants de type ${oInfo.composant}`;
}
} else if (!event) {
msgErreur = `Vous avez au moins 100 ${oInfo.composant} de ${oInfo.monstre}. MZ met les pouces.`;
} else {
MZ_doSearchCompoTanieres(false);
return;
}
displayResults();
} catch (exc) {
logMZ('compo taniere .onload1', exc);
}
};
FF_XMLHttpRequest({
method: 'POST',
HTML: true,
url: url,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: postData,
trace: `recherche en tanière compos phase 1 ${oInfo.monstre}`,
onload: callback1,
});
}
function MZ_AnalyseInfoHistoTresor(eTable, oRet) {
if (oRet == undefined) {
oRet = {};
}
for (let oTr of eTable.rows) {
if (oTr.cells[0] == undefined) {
// ça arrive
// debugMZ('MZ_AnalyseInfoHistoTresor pas de oTr.cells[0] => ' + JSON.stringify(oTr));
continue;
}
if (oTr.cells[0].className == 'titre2' || oTr.className == 'mh_tdtitre') {
let s = oTr.cells[0].textContent;
let m = s.match(/\] (.*) d'une* (.+) de Qualité (.*) \[/i);
if (m) {
debugMZ(`MZ_AnalyseInfoHistoTresor match titre => ${JSON.stringify(m)}`);
oRet.monstre = m[2];
oRet.composant = m[1];
oRet.qualite = m[3];
} else {
debugMZ(`MZ_AnalyseInfoHistoTresor no match titre ${s}, class=${oTr.cells[0].className}`);
}
continue;
}
if (oTr.cells.length < 2) {
for (let oT2 of oTr.cells[0].getElementsByTagName('table')) {
MZ_AnalyseInfoHistoTresor(oT2, oRet);
} // appel récursif
continue;
}
let c0 = oTr.cells[0].textContent;
// debugMZ('MZ_AnalyseInfoHistoTresor nb cell=' + oTr.cells.length + ' [' + c0 + '][' + oTr.cells[1].textContent + ']');
if (c0.match(/Type/i)) {
oRet.type = oTr.cells[1].textContent;
continue;
}
}
return oRet;
}
var MZ_hookCompoTanieresCounter;
function MZ_CompoTanieresCallback() {
let eTable = document.getElementById('tabTresorInfo');
if (!eTable) {
debugMZ(`MZ_CompoTanieresCallback pas de tabTresorInfo`);
if (MZ_hookCompoTanieresCounter-- > 0) {
window.setTimeout(MZ_CompoTanieresCallback, 100);
} else {
MZ_hookCompoTanieresCounter = undefined;
}
return;
}
MZ_hookCompoTanieresCounter = undefined;
MZ_CompoTanieresPrepare(eTable);
}
function MZdo_hookCompoTanieres() {
debugMZ('do_hookCompoTanieres');
let hookSetCallback = function () {
if (MZ_hookCompoTanieresCounter != undefined) {
MZ_hookCompoTanieresCounter = MZ_hookCompoTanieresCounter + 50;
return;
}
MZ_hookCompoTanieresCounter = 50;
window.setTimeout(MZ_CompoTanieresCallback, 100);
};
document.body.onclick = hookSetCallback;
document.body.onkeypress = hookSetCallback;
}
/* --------------------------------- Dispatch --------------------------------- */
// chargerScriptDev("libs");
// chargerScriptDev("ALWAYS"); // ALWAYS contient des aides au test (GOD-MODE ;)
// if (isDEV) testBoolLocalStorage();
/* Roule, test getPVsRestants
let pv = 'Inimaginables (supérieurs à 200)';
let pvminmax = pv.match(/\d+/g);
let oMinMaxPV = {min: pvminmax[0], max: pvminmax[1]};
logMZ('minmax=' + JSON.stringify(pvminmax) + ', oMinMaxPV=' + JSON.stringify(oMinMaxPV));
logMZ('ret getPVsRestants=' + JSON.stringify(getPVsRestants(pv, '±70%')));
logMZ('ret getPVsRestants=' + JSON.stringify(getPVsRestants(pv, '±70%', true)));
*/
var MZ_fo_tresor = isPageWithParam({ url: 'MH_Play/Play_a_Action', ids: ['t_fo_equip'] });
try {
// Détection de la page à traiter
if (isPage("MH_Play/PlayStart2")) {
replaceLinkMHtoMZ();
} else if (isPage("MH_Play/TurnStart")) {
updateNumTroll();
} else if (MZ_fo_ordres) {
do_ordresgowap();
} else if (isPage("MH_Play/Play_a_ActionResult")) {
debugMZ(`Play_a_ActionResult id=${document.body.id}`);
switch (document.body.id) {
case 'p_comptenceconnaissancedesmonstres':
do_cdmcomp();
break;
}
} else if (isPage("Messagerie/ViewMessageBot")) {
do_cdmbot();
} else if (isPage("MH_Play/Play_a_TalentResult")) {
do_cdmcomp();
} else if (isPageWithParam({ url: 'MH_Play/Play_a_Action', params: { type: 'A', id: -6, sub: 'diplomatie' } })) {
do_diplo();
} else if (isPage("MH_Play/Play_equipement")) {
do_equip();
} else if (isPage("MH_Play/Play_menu")) {
do_menu();
} else if (isPage("MH_Play/Options/Play_o_Interface") || isPage("installPack")) {
do_option();
// showEssaiCartes();
} else if (isPage("View/PJView_Events")) {
do_scizOverwriteEvents(); /* SCIZ */
} else if (isPage("View/PJView")) {
do_pjview();
} else if (isPage("MH_Taniere/TanierePJ_o_Stock") || isPage("MH_Comptoirs/Comptoir_o_Stock")) {
do_tancompo();
} else if (isPage("MH_Play/Play_vue")) {
do_vue();
do_scizEnhanceView(); /* SCIZ */
do_highlightSameXYN();
} else if (isPage("MH_Play/Play_news")) {
do_news();
} else if (isPage("MH_Play/Play_evenement")) {
do_scizOverwriteEvents(); /* SCIZ */
} else if (isPageWithParam({ url: 'MH_Play/Play_a_Action', params: { type: 'C', id: 12 } })) {
do_move();
} else if (isPageWithParam({ url: 'MH_Play/Play_a_Action', params: { type: 'A', id: 1 } })) {
do_move();
} else if (isPage("MH_Missions/Mission_Etape")) {
do_mission();
} else if (isPage("View/MonsterView")) {
do_infomonstre();
do_scizOverwriteEvents(); /* SCIZ */
} else if (isPage("MH_Play/Play_e_follo.php")) {
do_listegowap();
} else if (isPage("MH_Lieux/Lieu_Description.php")) {
do_lieuDescription();
} else if (isPage("MH_Lieux/Lieu_Teleport")) {
do_lieuTeleport();
} else if (MZ_fo_tresor) {
do_equipgowap();
} else if (isPage("MH_Play/Play_mouche")) {
do_mouches();
} else if (isPage("MH_Play/Play_BM")) {
do_malus();
} else if (isPage("MH_Play/Play_evenement")) {
do_myevent();
} else if (isPage("MH_Lieux/Lieu_DemanderEnchantement")) {
do_enchant();
} else if (isPage("MH_Lieux/Lieu_Enchanteur")) {
do_pre_enchant();
} else if (isPage("MH_Play/Play_e_enchantements")) {
do_lire_enchant_en_cours();
} else if (isPage("MH_Play/Actions") || isPage("Messagerie/ViewMessageBot")) { // 25/03/2024 MH_Play/Actions n'existe plus. À surveiller...
do_actions();
} else if (isPage('MH_Missions/Mission_Liste.php')) { // Roule 28/03/2016 je n'ai pas vu l'utilité et ça bloque... && MY_getValue(numTroll+'.MISSIONS')) {
do_mission_liste();
} else if (isPage('MH_Play/Play_action')) {
do_actions();
} else if (isPage("MH_Play/Play_profil") && !isPage('MH_Play/Play_profil2')) {
do_profil2();
} else if (isPage('MH_Play/Play_profil2')) {
do_profil2();
} else if (isPage('View/TrolligionView.php')) {
do_trolligion();
} else if (isPage('View/TresorHistory.php')) {
MZ_CompoTanieresPrepare();
} else if (MY_DEBUG) {
debugMZ(`page non traitée ${window.location}`);
}
if (isPage('MH_Play/Play_equipement.php') ||
isPage('MH_Play/Play_e_follo.php') ||
MZ_fo_tresor ||
isPage('MH_Taniere/TanierePJ_o_Stock.php') ||
isPage('MH_Comptoirs/Comptoir_Recherche.php')) {
MZdo_hookCompoTanieres();
}
if (document.body.dataset.MZ_Etat === undefined) { // si l'état a été positionné par quelqu'un d'autre, laisser tel quel
document.body.dataset.MZ_Etat = 1; // indiquer aux scripts tiers qu'on a fini la première initialisation
}
if (document.body.MZ_Callback_init !== undefined) {
for (let iCallback = 0; iCallback < document.body.MZ_Callback_init.length; iCallback++) {
document.body.MZ_Callback_init[iCallback]();
}
}
setTimeout(MZ_extern_param, 500);
} catch (exc) {
logMZ(`Catch général page ${window.location.pathname}`, exc);
}