1. Hello!

    First of all, welcome to MapleLegends! You are currently viewing the forums as a guest, so you can only view the first post of every topic. We highly recommend registering so you can be part of our community.

    By registering to our forums you can introduce yourself and make your first friends, talk in the shoutbox, contribute, and much more!

    This process only takes a few minutes and you can always decide to lurk even after!

    - MapleLegends Administration-
  2. Experiencing disconnecting after inserting your login info? Make sure you are on the latest MapleLegends version. The current latest version is found by clicking here.
    Dismiss Notice

Magician Mage Wash Simulator Script

Discussion in 'Jobs' started by Tarnished, Jun 25, 2024.

  1. Tarnished
    Offline

    Tarnished Mr. Anchor

    263
    151
    251
    Jun 13, 2022
    Male
    8:16 AM
    Confessor, Tarnished, Hawthorn
    Hero
    200
    There's already tons of great spreadsheets out there already but I figured I'd share this script now that I have it. I'm not the biggest spreadsheet fan :/

    The script assumes some conditions:
    • You are already a mage (not beginner)
    • You already maxed the MAX MP skill
    • You will always wait for enough NX before leveling
    • You will always fresh wash 5x per lv
    • You will always stale wash MP->HP every level to avoid wasting MP gains
    • You always have average luck on stat gain
    • No weird stuff like fresh washing HP
    • 5 free AP on 3rd and 4th job
    • I've heard MP gain per Fresh wash is 38, not 28 per Nise's formula. Set BASE_MP_PER_FRESH_WASH to whichever number you believe in.
    How to Use:
    • Check if this link to online JavaScript editor still works: https://onecompiler.com/javascript/42hap7geu
    • If that link doesn't work, just copy paste the code below and run it with any Javascript editor
    • Edit your initial values in the "FILL THESE VALUES OUT WITH YOUR CHAR" section
    • Press Run
    • you should be able to see your final HP/MP and NX cost
    Use at your own risk

    Code:
    // ASSUMPTIONS:
    // - you are already a mage (not a beginner)
    // - you already maxed the MAX MP skill (i.e. don't use use this if you're starting from lv.8)
    // - you will never run out of NX
    // - you will fresh wash 5x every level
    // - you will stale wash every level until your MP is under the STALE_WASH_MP_THRESHOLD
    // - always average luck on stat gain
    
    // FILL THESE VALUES OUT WITH YOUR CHAR
    const BEGIN_LV = 65; //the level  you start washing
    const BEGIN_MP = 11320; //mp when you start washing
    const BEGIN_HP = 910; //hp when you start washing
    const BEGIN_BASE_INT = 333; //your current base INT
    const INT_FROM_GEAR = 59; 
    const TARGET_LV = 120; //level you end washing
    
    // Washing Constants for MAGE ==================
    const HP_PER_LV = 12; //avg
    const MP_PER_LV = 43; //avg
    const HP_PER_STALE_WASH = 6;
    const MP_LOSS_PER_WASH = 30;
    const BASE_MP_PER_FRESH_WASH = 38; // this differs from Nise's formula; I heard 38 is the real number, not 28
    const SECOND_JOB_ADV_BONUS_MP = 450; // minimum roll
    const MW_MULTIPLIER = 1.1; // MW20
    const STALE_WASH_MP_THRESHOLD = 29000;
    const APR_COST = 3100;
    
    function CalculateWash()
    {
        let lv = BEGIN_LV;
        let mp = BEGIN_MP;
        let hp = BEGIN_HP;
        let my_int = BEGIN_BASE_INT;
        let washes = 0;
    
        let GetTotalInt = () =>
        {
          return Math.trunc( my_int * MW_MULTIPLIER ) + INT_FROM_GEAR;
        }
    
        let LevelUp = ()=>
        {
          mp += Math.trunc( GetTotalInt() / 10 ) + MP_PER_LV;
          hp += HP_PER_LV;
          lv += 1;
         
          if(lv == 70 || lv == 120)
          {
            DoWashesOnLevel(); // free 5 AP from 3rd and 4th Job
          }
          if(lv == 10) // bonus MP from 1st adv
          {
            // Do nothing because calculator assumes you're already a mage
            // Should already be included in your BEGIN_MP
          }
          if(lv == 30) // bonus MP from mage 2nd job adv
          {
            mp += SECOND_JOB_ADV_BONUS_MP;
          }
        } 
    
        let FreshWash1x = () => 
        {
          mp += BASE_MP_PER_FRESH_WASH + Math.trunc( my_int / 10 );
          mp -= MP_LOSS_PER_WASH;
          my_int += 1;
         
          washes += 1;
        }
       
        let StaleWash1x = () => 
        {
          mp -= MP_LOSS_PER_WASH;
          hp += HP_PER_STALE_WASH;
         
          washes += 1;
        }
       
        let DoWashesOnLevel = () => 
        {
            while(mp > STALE_WASH_MP_THRESHOLD)
            {
              StaleWash1x();
            }
           
            FreshWash1x();
            FreshWash1x();
            FreshWash1x();
            FreshWash1x();
            FreshWash1x();
        }
    
        for(let i = BEGIN_LV; i < TARGET_LV; i++)
        {
            LevelUp();
           
            DoWashesOnLevel();
        }
    
        console.log("HP: ", hp);
        console.log("MP: ", mp);
        console.log("NX Cost: ", washes * APR_COST);
    }
    
    CalculateWash();
    
     
    Last edited: Jun 26, 2024
    • Great Work Great Work x 4
  2. redpotion
    Offline

    redpotion Mixed Golem

    168
    53
    178
    May 23, 2024
    Female
    8:16 AM
    Miko
    Priest
    100
    Very cool script!

    I took the liberty of adding a new constant, INT_FROM_GEAR_BY_LEVEL, and adjusted the script so you have the option of populating this new constant with gear upgrades you receive, by level.
    This way you can simulate the MP gains from a zhelm at level 50; a cape upgrade at level 65; HTP at 120; etc, without having to worry about averaging things out.

    All values are used additively; if, for example, you have a 5 INT ragged cape and upgrade to a 13 INT gaia cape at level 65, it should be represented like so:

    Code:
    [
        {level: 25, value: 5},
        {level: 65, value: 8}
    ];
    Insert disclaimers about minimal testing, etc etc.
    This adds a small amount of processing time since this calculation is run every single level, but the number of iterations is really small enough I don't see the need to bother optimising at all.

    Code:
    // ASSUMPTIONS:
    // - you are already a mage (not a beginner)
    // - you already maxed the MAX MP skill (i.e. don't use use this if you're starting from lv.8)
    // - you will never run out of NX
    // - you will fresh wash 5x every level
    // - you will stale wash every level until your MP is under the STALE_WASH_MP_THRESHOLD
    // - always average luck on stat gain
    
    // FILL THESE VALUES OUT WITH YOUR CHAR
    const BEGIN_LV = 65; //the level  you start washing
    const BEGIN_MP = 11320; //mp when you start washing
    const BEGIN_HP = 910; //hp when you start washing
    const BEGIN_BASE_INT = 333; //your current base INT
    const INT_FROM_GEAR = 59;
    const INT_FROM_GEAR_BY_LEVEL = [ // If populated, script ignores INT_FROM_GEAR and uses this instead. Example values are below; adjust (and uncomment) as needed.
        // {level: 50, value: 15},
        // {level: 65, value: 8},
        // {level: 120, value: 7}
    ];
    const TARGET_LV = 120; //level you end washing
    
    // Washing Constants for MAGE ==================
    const HP_PER_LV = 12; //avg
    const MP_PER_LV = 43; //avg
    const HP_PER_STALE_WASH = 6;
    const MP_LOSS_PER_WASH = 30;
    const BASE_MP_PER_FRESH_WASH = 38; // this differs from Nise's formula; I heard 38 is the real number, not 28
    const SECOND_JOB_ADV_BONUS_MP = 450; // minimum roll
    const MW_MULTIPLIER = 1.1; // MW20
    const STALE_WASH_MP_THRESHOLD = 29000;
    const APR_COST = 3100;
    
    function CalculateWash()
    {
        let lv = BEGIN_LV;
        let mp = BEGIN_MP;
        let hp = BEGIN_HP;
        let my_int = BEGIN_BASE_INT;
        let washes = 0;
        let washesBeforeStale = 0;
        let staleWashBeginningLevel = 0;
       
        let GetTotalInt = () =>
        {
          let intFromGear;
          if (INT_FROM_GEAR_BY_LEVEL.length) {
            intFromGear = INT_FROM_GEAR_BY_LEVEL.filter(e => e.level <= lv).reduce((lhs, rhs) => lhs + rhs.value, 0);
          }
          else {
            intFromGear = INT_FROM_GEAR;
          }
    
          return Math.trunc( my_int * MW_MULTIPLIER ) + intFromGear;
        }
    
        let LevelUp = ()=>
        {
          mp += Math.trunc( GetTotalInt() / 10 ) + MP_PER_LV;
          hp += HP_PER_LV;
          lv += 1;
         
          if(lv == 70 || lv == 120)
          {
            DoWashesOnLevel(); // free 5 AP from 3rd and 4th Job
          }
          if(lv == 10) // bonus MP from 1st adv
          {
            // Do nothing because calculator assumes you're already a mage
            // Should already be included in your BEGIN_MP
          }
          if(lv == 30) // bonus MP from mage 2nd job adv
          {
            mp += SECOND_JOB_ADV_BONUS_MP;
          }
        }
    
        let FreshWash1x = () =>
        {
          mp += BASE_MP_PER_FRESH_WASH + Math.trunc( my_int / 10 );
          mp -= MP_LOSS_PER_WASH;
          my_int += 1;
         
          washes += 1;
        }
       
        let StaleWash1x = () =>
        {
          if (washesBeforeStale === 0) {
            washesBeforeStale = washes;
            staleWashBeginningLevel = lv;
          }
         
          mp -= MP_LOSS_PER_WASH;
          hp += HP_PER_STALE_WASH;
         
          washes += 1;
        }
       
        let DoWashesOnLevel = () =>
        {
            while(mp > STALE_WASH_MP_THRESHOLD)
            {
              StaleWash1x();
            }
           
            FreshWash1x();
            FreshWash1x();
            FreshWash1x();
            FreshWash1x();
            FreshWash1x();
        }
    
        for(let i = BEGIN_LV; i < TARGET_LV; i++)
        {
            LevelUp();
           
            DoWashesOnLevel();
        }
    
        console.log("HP: ", hp);
        console.log("MP: ", mp);
        console.log(`Reached MP goal of ${STALE_WASH_MP_THRESHOLD} at level ${staleWashBeginningLevel} using ${washesBeforeStale} washes, costing ${washesBeforeStale * APR_COST} NX.`);
        console.log("Total NX Cost: ", washes * APR_COST);
    }
    
    CalculateWash();
    
    Edit: removed some console logging I had added and forgot to take out before posting
    Edit2: added calculations to determine the level at which the MP goal was reached, and the NX spent to get there.
    Edit3: Pulled in Tarnished's update for MP on 2nd job adv and HP per level
     
    Last edited: Jun 26, 2024
    • Great Work Great Work x 1
  3. redpotion
    Offline

    redpotion Mixed Golem

    168
    53
    178
    May 23, 2024
    Female
    8:16 AM
    Miko
    Priest
    100
    I added a feature from Krythan's sheets I really like: the calculation for "how much NX was spent to reach the MP goal".
     
    • Like Like x 1
  4. LeonardoJF
    Offline

    LeonardoJF Horntail

    3,343
    573
    500
    Jun 16, 2021
    Male
    Rio grande do Sul - BR
    12:16 PM
    ItzLeo
    Paladin
    200
    Favela
  5. OP
    OP
    Tarnished
    Offline

    Tarnished Mr. Anchor

    263
    151
    251
    Jun 13, 2022
    Male
    8:16 AM
    Confessor, Tarnished, Hawthorn
    Hero
    200
    • Updated to include free MP on 2nd job Adv
    • Fixed bug where natural HP gain from lvling wasn't included
     
    • Great Work Great Work x 1

Share This Page