// The Mana World scripts. // Author: // The Mana World Team // Description: // Controls TMW rEvolt gameplay function script GameplayCore { /* Arguments killedrid → RID of the killed monster OR player (check for range) @defend → DEF used @weaponNew → Weapon switch detector @weaponAtk → Nº of Hits @weaponCrit → Nº of Crits @weaponMiss → Nº of Miss @weaponDef → Total DMG aborbed @weaponDodge → Nº of dodges @skillMMOId → Array of used skills ID @skillMMOLv → Array of used skills Level .@rg → Your attack range (only used if @weaponNew is false) .@mobLv → Level of opponent .@mobHp → Max HP of opponent .@mobAtk → DMG of opponent .@mobRng → Attack range of opponent .@boss → If opponent was a boss or not EXP_STR → Exp for STR stat (etc) */ // Build your own data .@rg = readbattleparam(getcharid(3), UDT_ATKRANGE); .@str = readparam(bStr); .@agi = readparam(bAgi); .@dex = readparam(bDex); .@vit = readparam(bVit); .@int = readparam(bInt); .@luk = readparam(bLuk); .@max = getbattleflag("max_parameter"); // Build the defeated opponent data (PC or MD) if (killedrid > 2000000 && killedrid < 2100000) { .@mobLv = readbattleparam(killedrid, UDT_LEVEL) * 7; // *ahem* PvP .@mobHp = readbattleparam(killedrid, UDT_MAXHP); .@mobAtk = readbattleparam(killedrid, UDT_ATKMIN); .@boss = false; } else { .@mobLv = getmonsterinfo(killedrid, MOB_LV); .@mobHp = getmonsterinfo(killedrid, MOB_MAXHP); .@mobAtk = getmonsterinfo(killedrid, MOB_ATK1); .@boss = getmonsterinfo(killedrid, MOB_MODE) & 32; // 32 = MD_BOSS } /* Grants STR */ if (.@str < .@max) callfunc("GC_strength", .@mobHp); /* Grants AGI */ if (.@agi < .@max) callfunc("GC_agility", .@mobLv); /* Grants DEX */ if (.@dex < .@max) callfunc("GC_dexterity", .@mobHp); /* Grants VIT */ if (.@vit < .@max) callfunc("GC_vitality", .@max); /* Grants INT */ if (.@int < .@max) callfunc("GC_intelligence", .@boss); /* Grants LUK */ if (.@luk < .@max) callfunc("GC_luck", .@mobLv, .@mobAtk); /* Grants hunting exp */ callfunc("GC_Hunt", .@mobLv); /* May grant mining or foraging exp */ callfunc("GC_Mine", killedrid); // Cleanup GameplayCore variables @defend = 0; @weaponId = 0; @weaponNew = 0; @weaponAtk = 0; @weaponCrit = 0; @weaponMiss = 0; @weaponDef = 0; @weaponDodge = 0; deletearray @skillMMOId; deletearray @skillMMOLv; return; } function script NEXT_Str { .@str = getarg(0, readparam(bStr)); .@nxt = 1200 + (.@str / 10 * 10); .@nxt = .@str * .@nxt * 125 / 10; // EXP_STR is already divided by 10 return .@nxt; } function script NEXT_Agi { .@agi = getarg(0, readparam(bAgi)); return .@agi * 132; // 120 × 11 ÷ 10 } function script NEXT_Vit { .@vit = getarg(0, readparam(bVit)); return 200 * .@vit * 115 / 100; // Variable is saved truncated, hence 200 } function script NEXT_Int { .@int = getarg(0, readparam(bInt)); return .@int * 150 / 10; } function script NEXT_Dex { .@dex = getarg(0, readparam(bDex)); return .@dex * 132; // 120 × 11 ÷ 10 } function script NEXT_Luk { .@luk = getarg(0, readparam(bLuk)); return .@luk * 62; // 20 * 1.75 } function script NEXT_Fora { .@stat = getarg(0, LVL_FORA); return .@stat * 92; } function script NEXT_Mine { .@stat = getarg(0, LVL_MINE); return .@stat * 92; } function script NEXT_Fish { .@stat = getarg(0, LVL_FISH); return .@stat * 24; } function script NEXT_Cook { .@stat = getarg(0, LVL_COOK); return .@stat * 26; } function script NEXT_Forg { .@stat = getarg(0, LVL_FORG); return .@stat * 96; } function script NEXT_Hunt { .@stat = getarg(0, LVL_HUNT); return .@stat * 221; } function script NEXT_Mf { .@stat = getarg(0, LVL_M_FIRE); return .@stat * 44; } function script NEXT_Mw { .@stat = getarg(0, LVL_M_WATER); return .@stat * 44; } function script NEXT_Mn { .@stat = getarg(0, LVL_M_NATURE); return .@stat * 44; } function script NEXT_Mh { .@stat = getarg(0, LVL_M_HARMONY); return .@stat * 44; } function script NEXT_Mc { .@stat = getarg(0, LVL_M_COMBAT); return .@stat * 44; } function script NEXT_Ms { .@stat = getarg(0, LVL_M_SUPPORT); return .@stat * 44; } function script GC_Hunt { EXP_HUNT+=(getarg(0)/10); if (EXP_HUNT > NEXT_Hunt()) { EXP_HUNT-=NEXT_Hunt(); LVL_HUNT+=1; } return; } function script GC_Mine { .@rc = getmonsterinfo(getarg(0), MOB_RACE); if (.@rc == RC_Forage) EXP_FORA+=1; else if (.@rc == RC_Mineral) EXP_MINE+=1; if (EXP_MINE > NEXT_Mine()) { EXP_MINE-= NEXT_Mine(); LVL_MINE+= 1; } if (EXP_FORA > NEXT_Fora()) { EXP_FORA-= NEXT_Fora(); LVL_FORA+= 1; } return; } /* *************************************************************************** */ /* Grants STR */ function script GC_strength { /* Rule: - Granted based on total damage inflicted - Not granted if weapon was changed - Not granted for ranged weapons - Not granted if skills were used - Rule: 1200 total damage inflicted × 1.25 × STR (FIXME) - Every 10 STR raises total damage in 10 - PS. Still "easy" - only 4 mi for max level */ .@mobHp = getarg(0); // Switched weapon if (@weaponNew) return; // Ranged weaponry .@rg = readbattleparam(getcharid(3), UDT_ATKRANGE); if (.@rg > 3) return; // FIXME: Used magic - But must discard physical skills =/ //if (getarraysize(@skillMMOId) > 0) // return; // Grant Strength Experience EXP_STR += .@mobHp / 11; // Verify for stat up .@nxt=NEXT_Str(); if (EXP_STR > .@nxt) { statusup2(bStr, 1); EXP_STR -= .@nxt; // FIXME: Use a color-coded special effect specialeffect(1, SELF, getcharid(3)); } return; } /* *************************************************************************** */ /* Grants AGI */ function script GC_agility { /* Rule: - Granted based on your own evasion - Every (50+agi*3) defense used counts as 1 evasion - Every (5+agi/10) hits also count as 1 evasion - Less is granted if overweight (roughly proportional) - Not granted if ? - Rule: 120 dodges × 1.10 × AGI */ .@mobLv = getarg(0); .@agi = readparam(bAgi); // Calculate .@exp = @weaponDodge; .@exp += @defend / (47 + .@agi * 3); .@exp += @weaponAtk / (5 + .@agi / 10); // Weight proportion .@rat = 100 * Weight / MaxWeight; .@rat = cap_value(100 - .@rat, 0, 90); .@exp = .@exp * rat / 90; // Brawling gives extra exp if (!@weaponNew && @weaponId < 1) .@exp += .@mobLv/10; // Grant Agility Experience EXP_AGI += .@exp; // Verify for stat up .@nxt = NEXT_Agi(); if (EXP_AGI > .@nxt) { statusup2(bAgi, 1); EXP_AGI -= .@nxt; // FIXME: Use a color-coded special effect specialeffect(1, SELF, getcharid(3)); } return; } /* *************************************************************************** */ /* Grants DEX */ function script GC_dexterity { /* Rule: - More misses grant more dex - If ranged, then every 500 damage = 0.1 miss (FIXME: Mobs don't have HP) - (TODO) Maybe also grant dex per hit...? - Less is granted for every critical - Not granted if ? - Rule: 12 misses × 1.10 × DEX */ .@mobHp = getarg(0); .@dex = readparam(bDex); .@rg = readbattleparam(getcharid(3), UDT_ATKRANGE); // Calculate .@exp = (@weaponMiss - @weaponCrit) * 5; // Reduced the bonus from (miss-crit) if (!@weaponNew && .@rg > 3) { .@exp += (.@mobHp / 100); // Increased bonus from Ranged Attacks } // Grant Dexterity Experience EXP_DEX += max(.@exp, 0); // Verify for stat up // Note each miss is counted as 5 misses .@nxt = NEXT_Dex(); if (EXP_DEX > .@nxt) { statusup2(bDex, 1); EXP_DEX -= .@nxt; // FIXME: Use a color-coded special effect specialeffect(1, SELF, getcharid(3)); } return; } /* *************************************************************************** */ /* Grants VIT */ function script GC_vitality { /* Rule: - Granted based on damage absorbed - Defended damage counts as 20% - Each dodge counts as (max_stat - vit) damage absorb - If weapon changed, only 70% is granted - Not granted if ? - Rule: 2000 damage × 1.15 × VIT [FIXME] */ .@max = getarg(0); .@vit = readparam(bVit); // Calculate .@exp = @weaponDef; .@exp += @defend * 2 / 10; .@exp += (.@max - .@vit) * @weaponDodge; // Weapon swap penalty if (@weaponNew) .@exp = .@exp * 7 / 10; .@exp = .@exp / 10; // Grant Vitality Experience EXP_VIT += .@exp; // Verify for stat up .@nxt = NEXT_Vit(); if (EXP_VIT > .@nxt) { statusup2(bVit, 1); EXP_VIT -= .@nxt; // FIXME: Use a color-coded special effect specialeffect(1, SELF, getcharid(3)); } return; } /* *************************************************************************** */ /* Grants INT */ function script GC_intelligence { /* Rule: - 1 point per every spell per every level - +1 point if target was a boss (always) - Not granted to utility spells (e.g. resync) - Each 7 points grants +1 DEX exp (even if melee) - The above rule is up to 1+(int/10) - Each attack reduces this in 2% - Rule: 10 spells × 1.5 × INT */ .@boss = getarg(0); .@int = readparam(bInt); // Calculate .@exp = (.@boss ? 1 : 0); setarray .@excl_sk, EVOL_SUPER_MENU, EVOL_MONSTER_IDENTIFY, EVOL_CRAFTING; // array_sum() would be neat, but... We need to remove "weeds" freeloop(true); for (.@i = 0; .@i < getarraysize(@skillMMOId); .@i++) { .@skillId = @skillMMOId[.@i]; .@skillLv = @skillMMOLv[.@i]; if (array_find(.@excl_sk, .@skillId) < 0) .@exp += .@skillLv; } freeloop(false); // Dex bonus must be handled now EXP_DEX += min(.@exp / 7, 1 + .@int / 10); // Penalty calculation for int .@exp -= .@exp * min(@weaponAtk, 50) / 50; // Grant Intel Experience EXP_INT += .@exp; // Verify for stat up .@nxt = NEXT_Int(); if (EXP_INT > .@nxt) { statusup2(bInt, 1); EXP_INT -= .@nxt; // FIXME: Use a color-coded special effect specialeffect(1, SELF, getcharid(3)); } return; } /* *************************************************************************** */ /* Grants LUK */ function script GC_luck { /* Rule: - Granted based on your criticals - Every 10 evasion counts as 1 crit - Every 10 levels of foe counts as 1 crit - Every (27 + luck) mob damage counts as 1 crit [FIXME] - Less is granted if ? - Not granted if ? - (Really should read drops, instead?) - Rule: 24 crits × 1.75 × LUK */ .@mobLv = getarg(0); .@mobAtk = getarg(1); .@luk = readparam(bLuk); // Calculate .@exp = @weaponCrit; .@exp += @weaponDodge / 10; .@exp += .@mobLv / 10; .@exp += .@mobAtk / (26 + .@luk); // Grant Luck Experience EXP_LUK += .@exp; // Verify for stat up .@nxt = NEXT_Luk(); if (EXP_LUK > .@nxt) { statusup2(bLuk, 1); EXP_LUK -= .@nxt; // FIXME: Use a color-coded special effect specialeffect(1, SELF, getcharid(3)); } return; }