Skip to content

Instantly share code, notes, and snippets.

@ShrimpManiac
Forked from ThatMapleDev/Magician.md
Created May 8, 2026 05:34
Show Gist options
  • Select an option

  • Save ShrimpManiac/c20cd33de30e05c84767c89aa6af9376 to your computer and use it in GitHub Desktop.

Select an option

Save ShrimpManiac/c20cd33de30e05c84767c89aa6af9376 to your computer and use it in GitHub Desktop.

Magic Damage Formula - v40 Reverse Engineering

Overview

This document contains the 100% IDA-verified magic damage formula for MapleStory v40, reverse engineered from sub_515307 (CalcMagicDamagePerHit).


Formula

BaseDamage = (INT × 0.5 + (Magic × 0.058)² + MagicInterp × 3.3) × EffectiveSkillMAD × 0.01
FinalDamage = Floor(BaseDamage) - DefenseSub

Variables

Variable Description Source
INT Character's INT stat GetSecureValue(a4+15)
Magic INT + MATK (total magic power) GetSecureValue(a5+96) + GetSecureValue(a5+108)
MagicInterp Interpolated magic (min to max via RNG) See Mastery Interpolation
EffectiveSkillMAD SkillMAD × AmpMultiplier Amp is integrated into skill damage
DefenseSub Monster defense reduction Interpolated MDD × [0.5, 0.6]

IDA Constants

Address Name Value Usage
0x6295C8 dbl_6295C8 0.5 INT coefficient
0x62BD30 dbl_62BD30 0.058 Magic quadratic coefficient
0x62BD28 dbl_62BD28 3.3 Magic linear coefficient
0x62B6D0 dbl_62B6D0 0.01 Skill scale factor
0x62BD08 dbl_62BD08 5.0 Mastery calculation
0x62BD18 dbl_62BD18 10.0 Mastery base value
0x62BD00 dbl_62BD00 0.009 Mastery scale
0x62BC80 dbl_62BC80 99999.0 Damage cap
0x62BCE8 dbl_62BCE8 1e-7 RNG normalization

Mastery Interpolation

The mastery factor determines the minimum damage range:

// IDA Line 103
v52 = (skillMastery × 5.0 + 10.0) × 0.009
Skill Mastery v52 Result Min Damage %
0 0.09 9%
10 0.54 54%
20 0.99 99%

Interpolation Logic (Lines 220-238)

v35 = Magic;           // Start at max
v59 = Magic × v52;     // Calculate min

if (v59 < v35) {
    Swap(v35, v59);    // v35=min, v59=max
}

v35 = v35 + (v59 - v35) × rngFactor;  // Interpolate

Multi-Hit RNG Pattern (Critical)

CalcMagicDamagePerHit pre-generates 7 random values ONCE at the start, then cycles through them for all hits:

// Lines 76-84: Pre-generate 7 randoms
uint v51[7];
v62 = 0;
do {
    v51[v62++] = CRand32::Random();
} while (v62 < 7);

// In the hit loop (for each hit):
accRandom = v51[v62 % 7]; v62++;   // Accuracy
dmgRandom = v51[v62 % 7]; v62++;   // Damage
defRandom = v51[v62 % 7]; v62++;   // Defense

Multi-Hit Example (Magic Claw - 2 hits)

Hit Acc Index Dmg Index Def Index
1 0 1 2
2 3 4 5

Elemental Amplification

Amp is integrated INTO the skill damage, not applied after defense:

EffectiveSkillMAD = SkillMAD × (AmpY / 100)
// Example: 55 × 1.35 = 74.25

Important: The amp multiplier uses the skill's y property (e.g., y=135 → 1.35×)


Complete Implementation

// IDA Constants
const double INT_COEFF = 0.5;           // dbl_6295C8
const double MAGIC_QUAD_COEFF = 0.058;  // dbl_62BD30
const double MAGIC_LINEAR_COEFF = 3.3;  // dbl_62BD28
const double SKILL_SCALE = 0.01;        // dbl_62B6D0
const double MASTERY_MULT = 5.0;        // dbl_62BD08
const double MASTERY_ADD = 10.0;        // dbl_62BD18
const double MASTERY_SCALE = 0.009;     // dbl_62BD00

public int CalculateMagicDamage(
    int intStat, int matk, int skillMastery, int skillMad, 
    double ampMultiplier, double dmgRngFactor)
{
    int totalMagic = intStat + matk;
    
    // Step 1: Calculate mastery factor (IDA line 103)
    double v52 = (skillMastery * MASTERY_MULT + MASTERY_ADD) * MASTERY_SCALE;
    
    // Step 2: Interpolate Magic stat (IDA lines 220-238)
    double v35 = totalMagic;
    double v59 = v35 * v52;
    
    if (v59 < v35) {
        (v35, v59) = (v59, v35);  // Swap for min/max
    }
    
    v35 = v35 + (v59 - v35) * dmgRngFactor;  // Interpolate
    
    // Step 3: Apply formula (IDA lines 240-242)
    // Amp is integrated into skillMad
    double effectiveSkillMad = skillMad * ampMultiplier;
    
    double intTerm = intStat * INT_COEFF;
    double quadTerm = Math.Pow(totalMagic * MAGIC_QUAD_COEFF, 2);
    double linearTerm = v35 * MAGIC_LINEAR_COEFF;
    
    double damage = (intTerm + quadTerm + linearTerm) * effectiveSkillMad * SKILL_SCALE;
    
    return (int)Math.Floor(damage);
}

Key Discoveries

Finding Description
v64 = INT Initially assumed to be LUK, but GetSecureValue(a4+15) returns INT
Skill Mastery Read from skill data offset 268, not a fixed 60%
Amp Integration Applied inside formula, NOT after defense subtraction
7 Random Cycle All hits share the same 7 pre-generated randoms, cycled with modulo 7
Mastery Formula (mastery × 5 + 10) × 0.009 converts skill mastery to interpolation factor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment