« MediaWiki:Common.js » : différence entre les versions

De Nephilim Wiki
Aucun résumé des modifications
Balise : Révocation manuelle
Aucun résumé des modifications
Balise : Révoqué
Ligne 75 : Ligne 75 :
     window.addEventListener( 'load', initDoubleScroll );
     window.addEventListener( 'load', initDoubleScroll );
   }
   }
}() );
/* ============================================
  CALCULATEUR DE RÉSOLUTION — Nephilim 5e
  À ajouter dans MediaWiki:Common.js
  ============================================ */
( function () {
    'use strict';
    // Ne s'active que si le calculateur est présent sur la page
    var calc = document.querySelector( '.neph-calc' );
    if ( !calc ) {
        return;
    }
    // Raccourci pour trouver les éléments par data-neph ou data-neph-out
    function input( name ) {
        return calc.querySelector( '[data-neph="' + name + '"]' );
    }
    function output( name ) {
        return calc.querySelector( '[data-neph-out="' + name + '"]' );
    }
    function val( name ) {
        var el = input( name );
        return el ? ( parseInt( el.value, 10 ) || 0 ) : 0;
    }
    // Recalcule les scores à chaque changement de select
    function compute() {
        var vecu = val( 'vecu' );
        var approche = val( 'approche' );
        var metamorphe = val( 'metamorphe' );
        var bonus = val( 'bonus' );
        var malus = val( 'malus' );
        var brut = vecu + approche + metamorphe;
        var net = Math.max( 0, brut + bonus - malus );
        var seuil = Math.min( net * 10, 100 );
        output( 'scoreBrut' ).textContent = brut;
        output( 'scoreNet' ).textContent = net;
        output( 'seuil' ).textContent = seuil + '%';
        // Masquer le résultat précédent
        var panel = output( 'resultPanel' );
        panel.className = 'neph-calc-result';
        output( 'resetWrap' ).className = 'neph-calc-reset-wrap';
        output( 'marginBar' ).style.display = 'none';
        output( 'marginFill' ).style.width = '0';
    }
    // Résout l'action
    function resolve() {
        var net = Math.max( 0, val( 'vecu' ) + val( 'approche' ) + val( 'metamorphe' ) + val( 'bonus' ) - val( 'malus' ) );
        var seuil = Math.min( net * 10, 100 );
        var jetEl = input( 'jet' );
        var jetInput = jetEl.value.trim();
        if ( jetInput === '' ) {
            jetEl.focus();
            return;
        }
        var jetVal = parseInt( jetInput, 10 );
        var isMaladresse = ( jetInput === '00' || jetInput === '000' || jetVal === 0 || jetVal === 100 );
        if ( isMaladresse ) {
            jetVal = 100;
        }
        var panel = output( 'resultPanel' );
        var verdict = output( 'resultVerdict' );
        var detail = output( 'resultDetail' );
        var marginText = output( 'resultMargin' );
        var marginBar = output( 'marginBar' );
        var marginFill = output( 'marginFill' );
        var resetWrap = output( 'resetWrap' );
        // Reset classes
        panel.className = 'neph-calc-result neph-visible';
        marginBar.style.display = 'none';
        marginFill.style.width = '0';
        if ( isMaladresse ) {
            panel.className += ' neph-maladresse';
            verdict.textContent = '\u2620 Maladresse !';
            detail.textContent = 'Échec critique \u2014 le sort s\'acharne sur le Nephilim.';
            marginText.textContent = '';
        } else if ( jetVal <= seuil ) {
            // Réussite
            var dizaines = Math.floor( jetVal / 10 );
            var bonusMarge = Math.max( 0, net - 10 );
            var marge = dizaines + bonusMarge;
            panel.className += ' neph-success';
            verdict.textContent = '\u2726 Réussite';
            detail.textContent = 'Jet de ' + jetVal + ' \u2264 seuil de ' + seuil + '%';
            var margeLabel = '';
            if ( marge <= 1 ) { margeLabel = 'Réussite de justesse'; }
            else if ( marge <= 3 ) { margeLabel = 'Réussite convenable'; }
            else if ( marge <= 5 ) { margeLabel = 'Belle réussite'; }
            else if ( marge <= 7 ) { margeLabel = 'Réussite remarquable'; }
            else if ( marge <= 9 ) { margeLabel = 'Réussite mémorable'; }
            else { margeLabel = 'Réussite extraordinaire'; }
            var margeText = 'Marge de réussite : ' + marge;
            if ( bonusMarge > 0 ) {
                margeText += ' (' + dizaines + ' + ' + bonusMarge + ' bonus)';
            }
            margeText += ' \u2014 ' + margeLabel;
            marginText.textContent = margeText;
            marginBar.style.display = 'block';
            var pct = Math.min( 100, Math.round( ( marge / 15 ) * 100 ) );
            setTimeout( function () {
                marginFill.style.width = pct + '%';
            }, 50 );
        } else {
            // Échec
            panel.className += ' neph-failure';
            verdict.textContent = '\u2715 Échec';
            detail.textContent = 'Jet de ' + jetVal + ' > seuil de ' + seuil + '%';
            marginText.textContent = '';
        }
        resetWrap.className = 'neph-calc-reset-wrap neph-visible';
    }
    // Réinitialise tout
    function resetAll() {
        [ 'vecu', 'approche', 'metamorphe', 'bonus', 'malus' ].forEach( function ( name ) {
            var el = input( name );
            if ( el ) { el.value = '0'; }
        } );
        var jetEl = input( 'jet' );
        if ( jetEl ) { jetEl.value = ''; }
        compute();
    }
    // Attacher les événements aux selects
    var selects = calc.querySelectorAll( '.neph-calc-select' );
    for ( var i = 0; i < selects.length; i++ ) {
        selects[ i ].addEventListener( 'change', compute );
    }
    // Bouton Résoudre
    var btnResolve = calc.querySelector( '[data-neph-action="resolve"]' );
    if ( btnResolve ) {
        btnResolve.addEventListener( 'click', resolve );
    }
    // Bouton Réinitialiser
    var btnReset = calc.querySelector( '[data-neph-action="reset"]' );
    if ( btnReset ) {
        btnReset.addEventListener( 'click', resetAll );
    }
    // Entrée dans le champ dé → résoudre
    var jetEl = input( 'jet' );
    if ( jetEl ) {
        jetEl.addEventListener( 'keydown', function ( e ) {
            if ( e.key === 'Enter' ) {
                resolve();
            }
        } );
    }


}() );
}() );

Version du 8 mars 2026 à 22:38

/* Tout JavaScript présent ici sera exécuté par tous les utilisateurs à chaque chargement de page. */

/* ============================================================
   NEPHILIM — Double scrollbar (haut + bas) pour tableaux
   À copier dans MediaWiki:Common.js
   
   Fonctionne avec les paires :
     <div class="neph-scroll-top"><div class="neph-scroll-top-spacer"></div></div>
     <div class="neph-scroll-table"> ... </div>
   ============================================================ */

( function () {
  'use strict';

  function initDoubleScroll() {
    // Cherche toutes les paires top + table
    var tops = document.querySelectorAll( '.neph-scroll-top' );

    tops.forEach( function ( topDiv ) {
      // Le conteneur de tableau est l'élément frère suivant
      var tableDiv = topDiv.nextElementSibling;
      if ( !tableDiv || !tableDiv.classList.contains( 'neph-scroll-table' ) ) {
        return;
      }

      // Trouve ou crée le spacer dans la barre haute
      var spacer = topDiv.querySelector( '.neph-scroll-top-spacer' );
      if ( !spacer ) {
        spacer = document.createElement( 'div' );
        spacer.className = 'neph-scroll-top-spacer';
        topDiv.appendChild( spacer );
      }

      // Synchronise la largeur du spacer avec le contenu du tableau
      function syncWidth() {
        spacer.style.width = tableDiv.scrollWidth + 'px';
      }

      syncWidth();

      // Re-synchronise si la fenêtre change de taille
      window.addEventListener( 'resize', syncWidth );

      // Observe aussi les changements de contenu (chargement tardif, etc.)
      if ( typeof ResizeObserver !== 'undefined' ) {
        var ro = new ResizeObserver( syncWidth );
        ro.observe( tableDiv );
      }

      // --- Synchronisation bidirectionnelle du scroll ---
      var syncing = false;

      topDiv.addEventListener( 'scroll', function () {
        if ( !syncing ) {
          syncing = true;
          tableDiv.scrollLeft = topDiv.scrollLeft;
          syncing = false;
        }
      } );

      tableDiv.addEventListener( 'scroll', function () {
        if ( !syncing ) {
          syncing = true;
          topDiv.scrollLeft = tableDiv.scrollLeft;
          syncing = false;
        }
      } );
    } );
  }

  // Lance après le chargement complet de la page
  if ( document.readyState === 'complete' ) {
    initDoubleScroll();
  } else {
    window.addEventListener( 'load', initDoubleScroll );
  }

}() );

/* ============================================
   CALCULATEUR DE RÉSOLUTION — Nephilim 5e
   À ajouter dans MediaWiki:Common.js
   ============================================ */
( function () {
    'use strict';

    // Ne s'active que si le calculateur est présent sur la page
    var calc = document.querySelector( '.neph-calc' );
    if ( !calc ) {
        return;
    }

    // Raccourci pour trouver les éléments par data-neph ou data-neph-out
    function input( name ) {
        return calc.querySelector( '[data-neph="' + name + '"]' );
    }
    function output( name ) {
        return calc.querySelector( '[data-neph-out="' + name + '"]' );
    }
    function val( name ) {
        var el = input( name );
        return el ? ( parseInt( el.value, 10 ) || 0 ) : 0;
    }

    // Recalcule les scores à chaque changement de select
    function compute() {
        var vecu = val( 'vecu' );
        var approche = val( 'approche' );
        var metamorphe = val( 'metamorphe' );
        var bonus = val( 'bonus' );
        var malus = val( 'malus' );

        var brut = vecu + approche + metamorphe;
        var net = Math.max( 0, brut + bonus - malus );
        var seuil = Math.min( net * 10, 100 );

        output( 'scoreBrut' ).textContent = brut;
        output( 'scoreNet' ).textContent = net;
        output( 'seuil' ).textContent = seuil + '%';

        // Masquer le résultat précédent
        var panel = output( 'resultPanel' );
        panel.className = 'neph-calc-result';
        output( 'resetWrap' ).className = 'neph-calc-reset-wrap';
        output( 'marginBar' ).style.display = 'none';
        output( 'marginFill' ).style.width = '0';
    }

    // Résout l'action
    function resolve() {
        var net = Math.max( 0, val( 'vecu' ) + val( 'approche' ) + val( 'metamorphe' ) + val( 'bonus' ) - val( 'malus' ) );
        var seuil = Math.min( net * 10, 100 );
        var jetEl = input( 'jet' );
        var jetInput = jetEl.value.trim();

        if ( jetInput === '' ) {
            jetEl.focus();
            return;
        }

        var jetVal = parseInt( jetInput, 10 );
        var isMaladresse = ( jetInput === '00' || jetInput === '000' || jetVal === 0 || jetVal === 100 );

        if ( isMaladresse ) {
            jetVal = 100;
        }

        var panel = output( 'resultPanel' );
        var verdict = output( 'resultVerdict' );
        var detail = output( 'resultDetail' );
        var marginText = output( 'resultMargin' );
        var marginBar = output( 'marginBar' );
        var marginFill = output( 'marginFill' );
        var resetWrap = output( 'resetWrap' );

        // Reset classes
        panel.className = 'neph-calc-result neph-visible';
        marginBar.style.display = 'none';
        marginFill.style.width = '0';

        if ( isMaladresse ) {
            panel.className += ' neph-maladresse';
            verdict.textContent = '\u2620 Maladresse !';
            detail.textContent = 'Échec critique \u2014 le sort s\'acharne sur le Nephilim.';
            marginText.textContent = '';
        } else if ( jetVal <= seuil ) {
            // Réussite
            var dizaines = Math.floor( jetVal / 10 );
            var bonusMarge = Math.max( 0, net - 10 );
            var marge = dizaines + bonusMarge;

            panel.className += ' neph-success';
            verdict.textContent = '\u2726 Réussite';
            detail.textContent = 'Jet de ' + jetVal + ' \u2264 seuil de ' + seuil + '%';

            var margeLabel = '';
            if ( marge <= 1 ) { margeLabel = 'Réussite de justesse'; }
            else if ( marge <= 3 ) { margeLabel = 'Réussite convenable'; }
            else if ( marge <= 5 ) { margeLabel = 'Belle réussite'; }
            else if ( marge <= 7 ) { margeLabel = 'Réussite remarquable'; }
            else if ( marge <= 9 ) { margeLabel = 'Réussite mémorable'; }
            else { margeLabel = 'Réussite extraordinaire'; }

            var margeText = 'Marge de réussite : ' + marge;
            if ( bonusMarge > 0 ) {
                margeText += ' (' + dizaines + ' + ' + bonusMarge + ' bonus)';
            }
            margeText += ' \u2014 ' + margeLabel;
            marginText.textContent = margeText;

            marginBar.style.display = 'block';
            var pct = Math.min( 100, Math.round( ( marge / 15 ) * 100 ) );
            setTimeout( function () {
                marginFill.style.width = pct + '%';
            }, 50 );
        } else {
            // Échec
            panel.className += ' neph-failure';
            verdict.textContent = '\u2715 Échec';
            detail.textContent = 'Jet de ' + jetVal + ' > seuil de ' + seuil + '%';
            marginText.textContent = '';
        }

        resetWrap.className = 'neph-calc-reset-wrap neph-visible';
    }

    // Réinitialise tout
    function resetAll() {
        [ 'vecu', 'approche', 'metamorphe', 'bonus', 'malus' ].forEach( function ( name ) {
            var el = input( name );
            if ( el ) { el.value = '0'; }
        } );
        var jetEl = input( 'jet' );
        if ( jetEl ) { jetEl.value = ''; }
        compute();
    }

    // Attacher les événements aux selects
    var selects = calc.querySelectorAll( '.neph-calc-select' );
    for ( var i = 0; i < selects.length; i++ ) {
        selects[ i ].addEventListener( 'change', compute );
    }

    // Bouton Résoudre
    var btnResolve = calc.querySelector( '[data-neph-action="resolve"]' );
    if ( btnResolve ) {
        btnResolve.addEventListener( 'click', resolve );
    }

    // Bouton Réinitialiser
    var btnReset = calc.querySelector( '[data-neph-action="reset"]' );
    if ( btnReset ) {
        btnReset.addEventListener( 'click', resetAll );
    }

    // Entrée dans le champ dé → résoudre
    var jetEl = input( 'jet' );
    if ( jetEl ) {
        jetEl.addEventListener( 'keydown', function ( e ) {
            if ( e.key === 'Enter' ) {
                resolve();
            }
        } );
    }

}() );