summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt5
-rw-r--r--db/exp.txt121
-rw-r--r--src/map/atcommand.c25
-rw-r--r--src/map/battle.c8
-rw-r--r--src/map/battle.h4
-rw-r--r--src/map/charcommand.c22
-rw-r--r--src/map/clif.c2
-rw-r--r--src/map/pc.c233
-rw-r--r--src/map/pc.h3
-rw-r--r--src/map/status.c2
10 files changed, 154 insertions, 271 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 67bc71080..644267529 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,11 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. EVERYTHING ELSE
GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
+2006/01/31
+ * Changed the exp table format. The new format allows specifying exp tables
+ for any particular class. Thanks to Playstester for converting the official
+ exp table to the new format. [Skotlex]
+ - UNTESTED: Report any problems asap.
2006/01/30
* Autoloot now uses the item's base drop chance rather than final drop rate
to determine if it should autoloot the item or not. [Skotlex]
diff --git a/db/exp.txt b/db/exp.txt
index b9cf53240..051b926b6 100644
--- a/db/exp.txt
+++ b/db/exp.txt
@@ -1,99 +1,22 @@
-9,9,9,9,10,10,10,10,30,144,30,11,60,288
-16,16,16,16,18,18,18,18,43,184,43,20,86,368
-25,25,25,25,28,28,28,28,58,284,58,31,116,568
-36,36,36,36,40,40,40,40,76,348,76,44,152,696
-77,77,77,77,85,85,85,91,116,603,116,100,232,1206
-112,112,112,112,123,123,123,151,180,887,180,166,360,1774
-153,153,153,153,168,168,168,205,220,1096,220,226,440,2192
-200,200,200,200,220,220,220,268,272,1598,272,295,544,3196
-253,253,253,253,278,278,278,340,336,2540,336,374,672,5080
-320,320,320,320,400,400,400,0,520,3676,520,0,1040,7352
-385,385,385,385,481,481,481,0,604,4290,604,0,1208,8580
-490,490,490,490,613,613,613,0,699,4946,699,0,1398,9892
-585,585,585,585,731,731,731,0,802,6679,802,0,1604,13358
-700,700,700,700,875,875,875,0,948,9492,948,0,1896,18984
-830,830,830,830,1038,1038,1038,0,1125,12770,1125,0,2250,31925
-970,970,970,970,1213,1213,1213,0,1668,14344,1668,0,3336,35860
-1120,1120,1120,1120,1400,1400,1400,0,1937,16005,1937,0,3874,40013
-1260,1260,1260,1260,1575,1575,1575,0,2226,20642,2226,0,4452,51605
-1420,1420,1420,1420,1775,1775,1775,0,3040,27434,3040,0,6080,68585
-1620,1620,1620,1620,2268,2268,2268,0,3988,35108,3988,0,7976,87770
-1860,1860,1860,1860,2604,2604,2604,0,5564,38577,5564,0,11128,96443
-1990,1990,1990,1990,2786,2786,2786,0,6272,42206,6272,0,12544,105515
-2240,2240,2240,2240,3136,3136,3136,0,7021,52708,7021,0,14042,131770
-2504,2504,2504,2504,3506,3506,3506,0,9114,66971,9114,0,18228,167428
-2950,2950,2950,2950,4130,4130,4130,0,11473,82688,11473,0,28683,206720
-3426,3426,3426,3426,4796,4796,4796,0,15290,89544,15290,0,38225,223860
-3934,3934,3934,3934,5508,5508,5508,0,16891,96669,16891,0,42228,241673
-4474,4474,4474,4474,6264,6264,6264,0,18570,117821,18570,0,46425,294553
-6889,6889,6889,6889,9645,9645,9645,0,23229,144921,23229,0,58073,362303
-7995,7995,7995,7995,12392,12392,12392,0,28359,174201,28359,0,70898,479053
-9174,9174,9174,9174,14220,14220,14220,0,36478,186677,36478,0,91195,513362
-10425,10425,10425,10425,16159,16159,16159,0,39716,199584,39716,0,99290,548856
-11748,11748,11748,11748,18209,18209,18209,0,43088,238617,43088,0,107720,656197
-13967,13967,13967,13967,21649,21649,21649,0,52417,286366,52417,0,131043,787507
-15775,15775,15775,15775,24451,24451,24451,0,62495,337147,62495,0,156238,927154
-17678,17678,17678,17678,27401,27401,27401,0,78160,358435,78160,0,195408,985696
-19677,19677,19677,19677,30499,30499,30499,0,84175,380376,84175,0,210430,1046034
-21773,21773,21773,21773,33748,33748,33748,0,90404,447685,90404,0,226010,1231134
-30543,30543,30543,30543,47342,47342,47342,0,107611,526989,107611,0,269028,1449220
-34212,34212,34212,34212,58160,58160,58160,0,125915,610246,125915,0,314788,1678177
-38065,38065,38065,38065,64711,64711,64711,0,153941,644736,153941,0,384853,1773024
-42102,42102,42102,42102,71573,71573,71573,0,191781,793535,191781,0,479453,2182221
-46323,46323,46323,46323,78749,78749,78749,0,204351,921810,204351,0,510878,2534978
-53026,53026,53026,53026,90144,90144,90144,0,248352,1106758,248352,0,620880,3043585
-58419,58419,58419,58419,99312,99312,99312,0,286212,1260955,286212,0,715530,3782865
-64041,64041,64041,64041,108870,108870,108870,0,386371,1487304,386371,0,965928,4461912
-69892,69892,69892,69892,118816,118816,118816,0,409795,1557657,409795,0,1024488,4672971
-75973,75973,75973,75973,129154,129154,129154,0,482092,1990632,482092,0,1205230,5971896
-102468,102468,102468,102468,174196,174196,174196,0,509596,2083386,509596,0,1273990,6250158
-115254,115254,115254,115254,213220,213220,213220,0,0,0,982092,0,0,6875174
-128692,128692,128692,128692,238080,238080,238080,0,0,0,992092,0,0,7562691
-142784,142784,142784,142784,264150,264150,264150,0,0,0,1002092,0,0,8318960
-157528,157528,157528,157528,291427,291427,291427,0,0,0,1012092,0,0,9150856
-178184,178184,178184,178184,329640,329640,329640,0,0,0,1022092,0,0,10065942
-196300,196300,196300,196300,363155,363155,363155,0,0,0,1032092,0,0,11877812
-215198,215198,215198,215198,398116,398116,398116,0,0,0,1042092,0,0,14015818
-234879,234879,234879,234879,434526,434526,434526,0,0,0,1052092,0,0,16538655
-255341,255341,255341,255341,472381,472381,472381,0,0,0,1062092,0,0,19515624
-330188,330188,330188,330188,610848,610848,610848,0,0,0,1072092,0,0,23028437
-365914,365914,365914,365914,731828,731828,731828,0,0,0,1082092,0,0,28094693
-403224,403224,403224,403224,806448,806448,806448,0,0,0,1092092,0,0,34275525
-442116,442116,442116,442116,884232,884232,884232,0,0,0,1102092,0,0,41816141
-482590,482590,482590,482590,965180,965180,965180,0,0,0,1112092,0,0,51015692
-536948,536948,536948,536948,1073896,1073896,1073896,0,0,0,1122092,0,0,62239144
-585191,585191,585191,585191,1170382,1170382,1170382,0,0,0,1132092,0,0,79666104
-635278,635278,635278,635278,1270556,1270556,1270556,0,0,0,1142092,0,0,101972614
-687211,687211,687211,687211,1374422,1374422,1374422,0,0,0,1152092,0,0,130524946
-740988,740988,740988,740988,1481976,1481976,1481976,0,0,0,1162092,0,0,167071930
-925400,925400,925400,925400,1850800,1850800,1850800,0,0,0,1172092,0,0,213852071
-1473746,1473746,1473746,1473746,3389616,3389616,3389616,0,0,0,1182092,0,0,0
-1594058,1594058,1594058,1594058,3666333,3666333,3666333,0,0,0,1192092,0,0,0
-1718928,1718928,1718928,1718928,3953534,3953534,3953534,0,0,0,1202092,0,0,0
-1848355,1848355,1848355,1848355,4251217,4251217,4251217,0,0,0,1212092,0,0,0
-1982340,1982340,1982340,1982340,4559382,4559382,4559382,0,0,0,1222092,0,0,0
-2230113,2230113,2230113,2230113,5129260,5129260,5129260,0,0,0,1232092,0,0,0
-2386162,2386162,2386162,2386162,5488173,5488173,5488173,0,0,0,1242092,0,0,0
-2547417,2547417,2547417,2547417,5859059,5859059,5859059,0,0,0,1252092,0,0,0
-2713878,2713878,2713878,2713878,6241919,6241919,6241919,0,0,0,1262092,0,0,0
-3206160,3206160,3206160,3206160,7374168,7374168,7374168,0,0,0,1272092,0,0,0
-3681024,3681024,3681024,3681024,9570662,9570662,9570662,0,0,0,1282092,0,0,0
-4022472,4022472,4022472,4022472,10458427,10458427,10458427,0,0,0,1292092,0,0,0
-4377024,4377024,4377024,4377024,11380262,11380262,11380262,0,0,0,1302092,0,0,0
-4744680,4744680,4744680,4744680,12336168,12336168,12336168,0,0,0,1312092,0,0,0
-5125440,5125440,5125440,5125440,13326144,13326144,13326144,0,0,0,1322092,0,0,0
-5767272,5767272,5767272,5767272,14994907,14994907,14994907,0,0,0,1332092,0,0,0
-6204000,6204000,6204000,6204000,16130400,16130400,16130400,0,0,0,1342092,0,0,0
-6655464,6655464,6655464,6655464,17304200,17304200,17304200,0,0,0,1352092,0,0,0
-7121664,7121664,7121664,7121664,18516326,18516326,18516326,0,0,0,1362092,0,0,0
-7602600,7602600,7602600,7602600,19766760,19766760,19766760,0,0,0,1372092,0,0,0
-9738720,9738720,9738720,9738720,29216160,29216160,29216160,0,0,0,1382092,0,0,0
-11649960,11649960,11649960,11649960,34949880,34949880,34949880,0,0,0,1392092,0,0,0
-13643520,13643520,13643520,13643520,40930560,40930560,40930560,0,0,0,1402092,0,0,0
-18339300,18339300,18339300,18339300,55017900,55017900,55017900,0,0,0,1412092,0,0,0
-23836800,23836800,23836800,23836800,71510400,71510400,71510400,0,0,0,1422092,0,0,0
-35658000,35658000,35658000,35658000,106974000,106974000,106974000,0,0,0,1432092,0,0,0
-48687000,48687000,48687000,48687000,146061000,146061000,146061000,0,0,0,1442092,0,0,0
-58135000,58135000,58135000,58135000,174405000,174405000,174405000,0,0,0,1452092,0,0,0
-99999999,99999999,99999999,99999999,343210000,343210000,343210000,0,0,0,1462092,0,0,0
-0,0,0,0,0,0,0,0,0,0,0,0,0,0
+//Experience tables format:
+//Max Level,Class list,Type (0 - Base Exp, 1 - Job Exp),Exp for Lv 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98
+//Base - Normal and Baby Jobs
+99,0:1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:23:24:25:26:4023:4024:4025:4026:4027:4028:4029:4030:4031:4032:4033:4034:4035:4036:4037:4038:4039:4040:4041:4042:4043:4044:4045:4046:4047:4048:4049,0,9,16,25,36,77,112,153,200,253,320,385,490,585,700,830,970,1120,1260,1420,1620,1860,1990,2240,2504,2950,3426,3934,4474,6889,7995,9174,10425,11748,13967,15775,17678,19677,21773,30543,34212,38065,42102,46323,53026,58419,64041,69892,75973,102468,115254,128692,142784,157528,178184,196300,215198,234879,255341,330188,365914,403224,442116,482590,536948,585191,635278,687211,740988,925400,1473746,1594058,1718928,1848355,1982340,2230113,2386162,2547417,2713878,3206160,3681024,4022472,4377024,4744680,5125440,5767272,6204000,6655464,7121664,7602600,9738720,11649960,13643520,18339300,23836800,35658000,48687000,58135000,99999999
+//Base - Adv Jobs
+99,4001:4002:4003:4004:4005:4006:4007:4008:4009:4010:4011:4012:4013:4014:4015:4016:4017:4018:4019:4020:4021:4022,0,10,18,28,40,85,123,168,220,278,400,481,613,731,875,1038,1213,1400,1575,1775,2268,2604,2786,3136,3506,4130,4796,5508,6264,9645,12392,14220,16159,18209,21649,24451,27401,30499,33748,47342,58160,64711,71573,78749,90144,99312,108870,118816,129154,174196,213220,238080,264150,291427,329640,363155,398116,434526,472381,610848,731828,806448,884232,965180,1073896,1170382,1270556,1374422,1481976,1850800,3389616,3666333,3953534,4251217,4559382,5129260,5488173,5859059,6241919,7374168,9570662,10458427,11380262,12336168,13326144,14994907,16130400,17304200,18516326,19766760,29216160,34949880,40930560,55017900,71510400,106974000,146061000,174405000,343210000
+//Job - Novice
+10,0:4023,1,10,18,28,40,91,151,205,268,340
+//Job - 1st Classes
+50,1:2:3:4:5:6:24:25:26:4024:4025:4026:4027:4028:4029:4046,1,30,43,58,76,116,180,220,272,336,520,604,699,802,948,1125,1668,1937,2226,3040,3988,5564,6272,7021,9114,11473,15290,16891,18570,23229,28359,36478,39716,43088,52417,62495,78160,84175,90404,107611,125915,153941,191781,204351,248352,286212,386371,409795,482092,509596
+//Job - 2nd Classes
+50,7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:4030:4031:4032:4033:4034:4035:4036:4037:4038:4039:4040:4041:4042:4032:4044:4049,1,144,184,284,348,603,887,1096,1598,2540,3676,4290,4946,6679,9492,12770,14344,16005,20642,27434,35108,38577,42206,52708,66971,82688,89544,96669,117821,144921,174201,186677,199584,238617,286366,337147,358435,380376,447685,526989,610246,644736,793535,921810,1106758,1260955,1487304,1557657,1990632,2083386
+//Job - Super Novice
+99,23:4045,1,30,43,58,76,116,180,220,272,336,520,604,699,802,948,1125,1668,1937,2226,3040,3988,5564,6272,7021,9114,11473,15290,16891,18570,23229,28359,36478,39716,43088,52417,62495,78160,84175,90404,107611,125915,153941,191781,204351,248352,286212,386371,409795,482092,509596,982092,992092,1002092,1012092,1022092,1032092,1042092,1052092,1062092,1072092,1082092,1092092,1102092,1112092,1122092,1132092,1142092,1152092,1162092,1172092,1182092,1192092,1202092,1212092,1222092,1232092,1242092,1252092,1262092,1272092,1282092,1292092,1302092,1312092,1322092,1332092,1342092,1352092,1362092,1372092,1382092,1392092,1402092,1412092,1422092,1432092,1442092,1452092,1462092
+//Job - Novice High
+10,4001,1,11,20,31,44,100,166,226,295,374
+//Job - Adv First Classes
+50,4002:4003:4004:4005:4006:4007,1,60,86,116,152,232,360,440,544,672,1040,1208,1398,1604,1896,2250,3336,3874,4452,6080,7976,11128,12544,14042,18228,28683,38225,42228,46425,58073,70898,91195,99290,107720,131043,156238,195408,210430,226010,269028,314788,384853,479453,510878,620880,715530,965928,1024488,1205230,1273990
+//Job - Adv Second Classes
+70,4008:4009:4010:4011:4012:4013:4014:4015:4016:4017:4018:4019:4020:4021:4022,1,288,368,568,696,1206,1774,2192,3196,5080,7352,8580,9892,13358,18984,31925,35860,40013,51605,68585,87770,96443,105515,131770,167428,206720,223860,241673,294553,362303,479053,513362,548856,656197,787507,927154,985696,1046034,1231134,1449220,1678177,1773024,2182221,2534978,3043585,3782865,4461912,4672971,5971896,6250158,6875174,7562691,8318960,9150856,10065942,11877812,14015818,16538655,19515624,23028437,28094693,34275525,41816141,51015692,62239144,79666104,101972614,130524946,167071930,213852071
+//Job - Star Gladiator
+50,4047:4048,1,27434,27434,27434,27434,27434,27434,27434,27434,27434,27434,27434,27434,27434,27434,27434,27434,27434,27434,54868,70216,77154,84412,105416,133942,165376,179088,193338,235642,289842,348402,373354,399168,477234,572732,674294,716870,760752,895370,1053978,1220492,1289472,1587070,1843620,2213516,2521910,2974608,3115314,3981264,4166772
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 6d2d3cc2b..36ca4cfc3 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -2676,12 +2676,12 @@ int atcommand_baselevelup(
}
if (level > 0) {
- if (sd->status.base_level == battle_config.max_base_level) { /* check for max level by Valaris */
+ if (sd->status.base_level == pc_maxbaselv(sd)) { /* check for max level by Valaris */
clif_displaymessage(fd, msg_table[47]); /* Base level can't go any higher. */
return -1;
} /* End Addition */
- if ((unsigned int)level > battle_config.max_base_level || (unsigned int)level > (battle_config.max_base_level - sd->status.base_level)) // fix positiv overflow
- level = battle_config.max_base_level - sd->status.base_level;
+ if (level > pc_maxbaselv(sd) || level > (pc_maxbaselv(sd) - sd->status.base_level)) // fix positiv overflow
+ level = pc_maxbaselv(sd) - sd->status.base_level;
for (i = 1; i <= level; i++)
sd->status.status_point += (sd->status.base_level + i + 14) / 5;
sd->status.base_level += level;
@@ -2697,7 +2697,7 @@ int atcommand_baselevelup(
clif_displaymessage(fd, msg_table[158]); /* Base level can't go any lower. */
return -1;
}
- if (level < -(int)battle_config.max_base_level || level < (1 - (int)sd->status.base_level)) /* fix negativ overflow */
+ if (level < -(int)pc_maxbaselv(sd) || level < (1 - (int)sd->status.base_level)) /* fix negativ overflow */
level = 1 - sd->status.base_level;
if (sd->status.status_point > 0) {
for (i = 0; i > level; i--)
@@ -2725,7 +2725,6 @@ int atcommand_joblevelup(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
- unsigned int up_level = battle_config.max_job_level;
int level=0;
nullpo_retr(-1, sd);
@@ -2735,21 +2734,13 @@ int atcommand_joblevelup(
clif_displaymessage(fd, "Please, enter a level adjustement (usage: @joblvup/@jlevel/@joblvlup <number of levels>).");
return -1;
}
-
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_NOVICE) //Novice
- up_level = 10;
- else if ((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE) //S. Novice
- up_level = battle_config.max_sn_level;
- else if (sd->class_&JOBL_UPPER && sd->class_&JOBL_2)
- up_level = battle_config.max_adv_level; //2nd Adv Class
-
if (level > 0) {
- if (sd->status.job_level == up_level) {
+ if (sd->status.job_level == pc_maxjoblv(sd)) {
clif_displaymessage(fd, msg_table[23]); // Job level can't go any higher.
return -1;
}
- if ((unsigned int)level > up_level || (unsigned int)level > (up_level - sd->status.job_level)) // fix positiv overflow
- level = up_level - sd->status.job_level;
+ if (level > pc_maxjoblv(sd) || level > (pc_maxjoblv(sd) - sd->status.job_level)) // fix positiv overflow
+ level = pc_maxjoblv(sd) - sd->status.job_level;
sd->status.job_level += level;
clif_updatestatus(sd, SP_JOBLEVEL);
clif_updatestatus(sd, SP_NEXTJOBEXP);
@@ -2763,7 +2754,7 @@ int atcommand_joblevelup(
clif_displaymessage(fd, msg_table[159]); // Job level can't go any lower.
return -1;
}
- if (level < -(int)up_level || level < (1 - (int)sd->status.job_level)) // fix negativ overflow
+ if (level < -(int)pc_maxjoblv(sd) || level < (1 - (int)sd->status.job_level)) // fix negativ overflow
level = 1 - sd->status.job_level;
sd->status.job_level += level;
clif_updatestatus(sd, SP_JOBLEVEL);
diff --git a/src/map/battle.c b/src/map/battle.c
index e46fdf8ca..4bfee43f0 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -3708,10 +3708,6 @@ static const struct battle_data_short {
{ "item_drop_treasure_max", &battle_config.item_drop_treasure_max },
{ "prevent_logout", &battle_config.prevent_logout }, // Added by RoVeRT
{ "alchemist_summon_reward", &battle_config.alchemist_summon_reward }, // [Valaris]
- { "max_base_level", &battle_config.max_base_level }, // [Valaris]
- { "max_job_level", &battle_config.max_job_level },
- { "max_advanced_job_level", &battle_config.max_adv_level },
- { "max_super_novice_level", &battle_config.max_sn_level },
{ "drops_by_luk", &battle_config.drops_by_luk }, // [Valaris]
{ "drops_by_luk2", &battle_config.drops_by_luk2 }, // [Skotlex]
{ "equip_natural_break_rate", &battle_config.equip_natural_break_rate },
@@ -4097,10 +4093,6 @@ void battle_set_defaults() {
battle_config.item_drop_treasure_min=1;
battle_config.item_drop_treasure_max=10000;
battle_config.prevent_logout = 10000; // Added by RoVeRT
- battle_config.max_base_level = 255; // Added by Valaris
- battle_config.max_job_level = 50;
- battle_config.max_adv_level = 70;
- battle_config.max_sn_level = 99;
battle_config.drops_by_luk = 0; // [Valaris]
battle_config.drops_by_luk2 = 0;
battle_config.equip_natural_break_rate = 1;
diff --git a/src/map/battle.h b/src/map/battle.h
index 175aa49c4..947b59a82 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -292,10 +292,6 @@ extern struct Battle_Config {
unsigned short prevent_logout; // Added by RoVeRT
unsigned short alchemist_summon_reward; // [Valaris]
- unsigned short max_base_level; //Max Base Level [Valaris]
- unsigned short max_job_level; //Max job level (normal classes) [Skotlex]
- unsigned short max_sn_level; //Max job level (super novice) [Skotlex]
- unsigned short max_adv_level; //Max job level (advanced classes) [Skotlex]
unsigned short drops_by_luk;
unsigned short drops_by_luk2;
unsigned short equip_natural_break_rate; //Base Natural break rate for attacks.
diff --git a/src/map/charcommand.c b/src/map/charcommand.c
index e2c97b15f..216a6f450 100644
--- a/src/map/charcommand.c
+++ b/src/map/charcommand.c
@@ -1258,12 +1258,12 @@ int charcommand_baselevel(
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change base level only lower or same gm level
if (level > 0) {
- if (pl_sd->status.base_level == battle_config.max_base_level) { // check for max level by Valaris
+ if (pl_sd->status.base_level == pc_maxbaselv(sd)) { // check for max level by Valaris
clif_displaymessage(fd, msg_table[91]); // Character's base level can't go any higher.
return 0;
} // End Addition
- if ((unsigned int)level > battle_config.max_base_level || (unsigned int)level > (battle_config.max_base_level - pl_sd->status.base_level)) // fix positiv overflow
- level = battle_config.max_base_level - pl_sd->status.base_level;
+ if (level > pc_maxbaselv(pl_sd) || level > (pc_maxbaselv(pl_sd)- pl_sd->status.base_level)) // fix positiv overflow
+ level = pc_maxbaselv(pl_sd) - pl_sd->status.base_level;
for (i = 1; i <= level; i++)
pl_sd->status.status_point += (pl_sd->status.base_level + i + 14) / 5;
pl_sd->status.base_level += level;
@@ -1279,7 +1279,7 @@ int charcommand_baselevel(
clif_displaymessage(fd, msg_table[193]); // Character's base level can't go any lower.
return -1;
}
- if (level < -(int)battle_config.max_base_level || level < (1 - (int)pl_sd->status.base_level)) // fix negativ overflow
+ if (level < -(int)pc_maxbaselv(pl_sd) || level < (1 - (int)pl_sd->status.base_level)) // fix negativ overflow
level = 1 - pl_sd->status.base_level;
if (pl_sd->status.status_point > 0) {
for (i = 0; i > level; i--)
@@ -1316,7 +1316,6 @@ int charcommand_joblevel(
const char* command, const char* message)
{
struct map_session_data *pl_sd;
- unsigned int max_level = battle_config.max_job_level;
char player[NAME_LENGTH];
int level = 0;
//転生や養子の場合の元の職業を算出する
@@ -1329,20 +1328,13 @@ int charcommand_joblevel(
if ((pl_sd = map_nick2sd(player)) != NULL) {
if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can change job level only lower or same gm level
- if ((pl_sd->class_&MAPID_UPPERMASK) == MAPID_NOVICE)
- max_level = 10; //Novice
- else if ((pl_sd->class_&MAPID_BASEMASK) == MAPID_NOVICE)
- max_level = battle_config.max_sn_level; //S. Novice
- else if (pl_sd->class_&JOBL_UPPER && pl_sd->class_&JOBL_2)
- max_level = battle_config.max_adv_level; //Adv. Class
-
if (level > 0) {
- if (pl_sd->status.job_level == max_level) {
+ if (pl_sd->status.job_level == pc_maxjoblv(pl_sd)) {
clif_displaymessage(fd, msg_table[67]); // Character's job level can't go any higher.
return -1;
}
- if (pl_sd->status.job_level + level > max_level)
- level = max_level - pl_sd->status.job_level;
+ if (pl_sd->status.job_level + level > pc_maxjoblv(pl_sd))
+ level = pc_maxjoblv(pl_sd) - pl_sd->status.job_level;
pl_sd->status.job_level += level;
clif_updatestatus(pl_sd, SP_JOBLEVEL);
clif_updatestatus(pl_sd, SP_NEXTJOBEXP);
diff --git a/src/map/clif.c b/src/map/clif.c
index d8195fb0a..7aafe9311 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -8814,7 +8814,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
pc_checkskill(sd,SG_STAR_COMFORT))
status_calc_pc(sd,0);
- if (pc_checkskill(sd, SG_DEVIL) && sd->status.job_level >= battle_config.max_job_level)
+ if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobafter(sd))
clif_status_load(&sd->bl, SI_DEVIL, 1); //blindness [Komurka]
map_foreachinarea(clif_getareachar,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,BL_ALL,sd);
diff --git a/src/map/pc.c b/src/map/pc.c
index afafbe4c8..3f0181118 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -41,7 +41,8 @@
#endif
#define PVP_CALCRANK_INTERVAL 1000 // PVP順位計算の間隔
-static int exp_table[14][MAX_LEVEL];
+static int exp_table[MAX_PC_CLASS][2][MAX_LEVEL];
+static int max_level[MAX_PC_CLASS][2];
static short statp[MAX_LEVEL];
// h-files are for declarations, not for implementations... [Shinomori]
@@ -4642,7 +4643,7 @@ int pc_checkjoblevelup(struct map_session_data *sd)
status_calc_pc(sd,0);
clif_misceffect(&sd->bl,1);
- if (pc_checkskill(sd, SG_DEVIL) && sd->status.job_level >= battle_config.max_job_level)
+ if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobafter(sd))
clif_status_change(&sd->bl,SI_DEVIL, 1); //Permanent blind effect from SG_DEVIL.
if (script_config.event_script_type == 0) {
@@ -4728,28 +4729,30 @@ int pc_gainexp(struct map_session_data *sd,int base_exp,int job_exp)
}
/*==========================================
+ * Returns max level for this character.
+ *------------------------------------------
+ */
+
+int pc_maxbaselv(struct map_session_data *sd) {
+ return max_level[sd->status.class_][0];
+};
+
+int pc_maxjoblv(struct map_session_data *sd) {
+ return max_level[sd->status.class_][1];
+};
+
+/*==========================================
* base level側必要??値計算
*------------------------------------------
*/
int pc_nextbaseexp(struct map_session_data *sd)
{
- int i =0;
-
nullpo_retr(0, sd);
- if(sd->status.base_level>=MAX_LEVEL || sd->status.base_level<=0)
+ if(sd->status.base_level>=pc_maxbaselv(sd) || sd->status.base_level<=0)
return 0;
- i = (sd->class_&JOBL_UPPER)?4:0; //4 is the base for upper, 0 for normal/baby ones.
-
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_NOVICE)
- ; //Add 0, it's novice.
- else if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE)
- i = 3; //Super Novice/Super Baby
- else
- i+= (sd->class_&JOBL_2)?2:1; //Add 2 for second classes, add 1 for first classes.
-
- return exp_table[i][sd->status.base_level-1];
+ return exp_table[sd->status.class_][0][sd->status.base_level-1];
}
/*==========================================
@@ -4758,27 +4761,11 @@ int pc_nextbaseexp(struct map_session_data *sd)
*/
int pc_nextjobexp(struct map_session_data *sd)
{
- int i;
-
nullpo_retr(0, sd);
- if(sd->status.job_level>=MAX_LEVEL || sd->status.job_level<=0)
+ if(sd->status.job_level>=pc_maxjoblv(sd) || sd->status.job_level<=0)
return 0;
-
- i = (sd->class_&JOBL_UPPER)?11:7; //11 is the base for upper, 7 for normal/baby ones.
-
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_NOVICE)
- ; //Add 0, it's novice.
- else if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE)
- i = 10; //Super Novice/Super Baby
- else if ((sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR) {
- i = 13; //Star Gladiator - slow JExp (as for 2nd class)
- if (sd->status.job_level >= battle_config.max_job_level)
- return 0; //Since SG aren't really an advanced class... [Skotlex]
- } else
- i+= (sd->class_&JOBL_2)?2:1; //Add 2 for second classes, add 1 for first classes.
-
- return exp_table[i][sd->status.job_level-1];
+ return exp_table[sd->status.class_][1][sd->status.job_level-1];
}
/*==========================================
@@ -4787,23 +4774,12 @@ int pc_nextjobexp(struct map_session_data *sd)
*/
int pc_nextbaseafter(struct map_session_data *sd)
{
- int i;
-
nullpo_retr(0, sd);
- if(sd->status.base_level>=MAX_LEVEL || sd->status.base_level<=0)
+ if(sd->status.base_level>=pc_maxbaselv(sd) || sd->status.base_level<=0)
return 0;
- i = (sd->class_&JOBL_UPPER)?4:0; //4 is the base for upper, 0 for normal/baby ones.
-
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_NOVICE)
- ; //Add 0, it's novice.
- else if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE)
- i = 3; //Super Novice/Super Baby
- else
- i+= (sd->class_&JOBL_2)?2:1; //Add 2 for second classes, add 1 for first classes.
-
- return exp_table[i][sd->status.base_level];
+ return exp_table[sd->status.class_][0][sd->status.base_level];
}
/*==========================================
@@ -4812,27 +4788,12 @@ int pc_nextbaseafter(struct map_session_data *sd)
*/
int pc_nextjobafter(struct map_session_data *sd)
{
- int i;
-
nullpo_retr(0, sd);
- if(sd->status.job_level>=MAX_LEVEL || sd->status.job_level<=0)
+ if(sd->status.job_level>=pc_maxjoblv(sd) || sd->status.job_level<=0)
return 0;
- i = (sd->class_&JOBL_UPPER)?11:7; //11 is the base for upper, 7 for normal/baby ones.
-
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_NOVICE)
- ; //Add 0, it's novice.
- else if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE)
- i = 10; //Super Novice/Super Baby
- else if ((sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR) {
- i = 13; //Star Gladiator - slow JExp (as for 2nd class)
- if (sd->status.job_level >= battle_config.max_job_level)
- return 0; //Since SG aren't really an advanced class... [Skotlex]
- } else
- i+= (sd->class_&JOBL_2)?2:1; //Add 2 for second classes, add 1 for first classes.
-
- return exp_table[i][sd->status.job_level];
+ return exp_table[sd->status.class_][1][sd->status.job_level];
}
/*==========================================
@@ -5236,7 +5197,7 @@ int pc_resetskill(struct map_session_data* sd)
int i, skill, inf2;
nullpo_retr(0, sd);
- if (pc_checkskill(sd, SG_DEVIL) && sd->status.job_level >= battle_config.max_job_level)
+ if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobafter(sd))
clif_status_load(&sd->bl, SI_DEVIL, 0); //Remove perma blindness due to skill-reset. [Skotlex]
for (i = 1; i < MAX_SKILL; i++) {
@@ -5553,7 +5514,8 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage)
mob_changestate(md,MS_WALK,0);
}
if(battle_config.mobs_level_up && md && md->state.state!=MS_DEAD &&
- md->level < battle_config.max_base_level && !md->guardian_data // Guardians should not level. [Skotlex]
+ md->level < pc_maxbaselv(sd) &&
+ !md->guardian_data // Guardians should not level. [Skotlex]
) { // monster level up [Valaris]
clif_misceffect(&md->bl,0);
md->level++;
@@ -5786,14 +5748,14 @@ int pc_readparam(struct map_session_data *sd,int type)
*/
int pc_setparam(struct map_session_data *sd,int type,int val)
{
- int i = 0,up_level = battle_config.max_job_level;
+ int i = 0;
nullpo_retr(0, sd);
switch(type){
case SP_BASELEVEL:
- if ((val+ sd->status.base_level) > battle_config.max_base_level) //Capping to max
- val = battle_config.max_base_level - sd->status.base_level;
+ if ((val+ sd->status.base_level) > pc_maxbaselv(sd)) //Capping to max
+ val = pc_maxbaselv(sd) - sd->status.base_level;
if (val > (int)sd->status.base_level) {
for (i = 1; i <= (val - (int)sd->status.base_level); i++)
sd->status.status_point += (sd->status.base_level + i + 14) / 5 ;
@@ -5808,14 +5770,8 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
pc_heal(sd, sd->status.max_hp, sd->status.max_sp);
break;
case SP_JOBLEVEL:
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_NOVICE)
- up_level = 10; //Novice & Baby Novice have 10 Job Levels only
- else if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) //Super Novice & Super Baby can go up to 99
- up_level = battle_config.max_sn_level;
- else if (sd->class_&JOBL_UPPER && sd->class_&JOBL_2) //3rd Job has 70 Job Levels
- up_level = battle_config.max_adv_level;
if (val >= (int)sd->status.job_level) {
- if (val > up_level) val = up_level;
+ if (val > pc_maxjoblv(sd)) val = pc_maxjoblv(sd);
sd->status.skill_point += (val-sd->status.job_level);
sd->status.job_level = val;
sd->status.job_exp = 0;
@@ -8049,6 +8005,35 @@ void pc_setstand(struct map_session_data *sd){
sd->state.dead_sit = 0;
}
+int pc_split_str(char *str,char **val,int num)
+{
+ int i;
+
+ for (i=0; i<num && str; i++){
+ val[i] = str;
+ str = strchr(str,',');
+ if (str && i<num-1) //Do not remove a trailing comma.
+ *str++=0;
+ }
+ return i;
+}
+
+int pc_split_atoi(char *str,int *val, char sep, int max)
+{
+ int i,j;
+ for (i=0; i<max; i++) {
+ if (!str) break;
+ val[i] = atoi(str);
+ str = strchr(str,sep);
+ if (str)
+ *str++=0;
+ }
+ //Zero up the remaining.
+ for(j=i; j < max; j++)
+ val[j] = 0;
+ return i;
+}
+
//
// 初期化物
//
@@ -8067,70 +8052,66 @@ int pc_readdb(void)
{
int i,j,k;
FILE *fp;
- char line[1024],*p;
+ char line[16000],*p;
// 必要??値?み?み
memset(exp_table,0,sizeof(exp_table));
+ memset(max_level,0,sizeof(max_level));
sprintf(line, "%s/exp.txt", db_path);
fp=fopen(line, "r");
if(fp==NULL){
ShowError("can't read %s\n", line);
return 1;
}
- i=0;
while(fgets(line, sizeof(line)-1, fp)){
- int bn,b1,b2,b3,b4,b5,b6,jn,j1,j2,j3,j4,j5,j6;
+ int jobs[MAX_PC_CLASS], job_count, job;
+ int type, max;
+ char *split[3];
if(line[0]=='/' && line[1]=='/')
continue;
- if(sscanf(line,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&bn,&b1,&b2,&b3,&b4,&b5,&b6,&jn,&j1,&j2,&j3,&j4,&j5,&j6)!=14)
+ if (pc_split_str(line,split,4) < 4)
continue;
- exp_table[0][i]=bn;
- exp_table[1][i]=b1;
- exp_table[2][i]=b2;
- exp_table[3][i]=b3;
- exp_table[4][i]=b4;
- exp_table[5][i]=b5;
- exp_table[6][i]=b6;
- exp_table[7][i]=jn;
- exp_table[8][i]=j1;
- exp_table[9][i]=j2;
- exp_table[10][i]=j3;
- exp_table[11][i]=j4;
- exp_table[12][i]=j5;
- exp_table[13][i]=j6;
- i++;
- }
- if (i > battle_config.max_base_level)
- { //Empty Base level columns
- for (j = battle_config.max_base_level-1; j < i && exp_table[0][j]>0; j++)
- {
- exp_table[0][j]=0;
- exp_table[1][j]=0;
- exp_table[2][j]=0;
- exp_table[3][j]=0;
- exp_table[4][j]=0;
- exp_table[5][j]=0;
- exp_table[6][j]=0;
- }
- }
- if (i > battle_config.max_sn_level)
- { //Empty SN job exp columns
- for (j = battle_config.max_sn_level-1; j < i && exp_table[10][j]>0; j++)
- exp_table[10][j]=0;
- }
- if (i > battle_config.max_adv_level)
- { //Empty Adv Jobs columns
- for (j = battle_config.max_adv_level-1; j < i && exp_table[13][j]>0; j++)
- exp_table[13][j]=0;
- }
- if (i > battle_config.max_job_level)
- { //Empty normal Job columns
- for (j = battle_config.max_job_level-1; j < i &&
- (exp_table[8][j]>0 || exp_table[9][j]>0 || exp_table[12][j]>0); j++)
- {
- exp_table[8][j]=0; //1st Job
- exp_table[9][j]=0; //2nd Job
- exp_table[12][j]=0; //Adv 1st Job
+
+ job_count = pc_split_atoi(split[1],jobs,':',MAX_PC_CLASS);
+ if (job_count < 1)
+ continue;
+ job = jobs[0];
+ if (!pcdb_checkid(job)) {
+ ShowError("pc_readdb: Invalid job ID %d.\n", job);
+ continue;
+ }
+ type = atoi(split[2]);
+ if (type < 0 || type > 1) {
+ ShowError("pc_readdb: Invalid type %d (must be 0 for base levels, 1 for job levels).\n", type);
+ continue;
+ }
+ max = atoi(split[0]);
+ if (max > MAX_LEVEL) {
+ ShowWarning("pc_readdb: Specified max level %d for job %d is beyond server's limit (%d).\n ", max, job, MAX_LEVEL);
+ max = MAX_LEVEL;
+ }
+ //We send one less and then one more because the last entry in the exp array should hold 0.
+ max_level[job][type] = pc_split_atoi(split[3], exp_table[job][type],',',max-1)+1;
+ //Reverse check in case the array has a bunch of trailing zeros... [Skotlex]
+ //The reasoning behind the -2 is this... if the max level is 5, then the array
+ //should look like this:
+ //0: x, 1: x, 2: x: 3: x 4: 0 <- last valid value is at 3.
+ while ((i = max_level[job][type]-2) >= 0 && exp_table[job][type][i] <= 0)
+ max_level[job][type]--;
+
+ if (max_level[job][type] < max) {
+ ShowError("pc_readdb: Specified max %d for job %d, but that job's exp table only goes up to level %d.\n", max, job, max_level[job][type]);
+ }
+// ShowDebug("%s - Class %d: %d\n", type?"Job":"Base", job, max_level[job][type]);
+ for (i = 1; i < job_count; i++) {
+ job = jobs[i];
+ if (!pcdb_checkid(job)) {
+ ShowError("pc_readdb: Invalid job ID %d.\n", job);
+ continue;
+ }
+ memcpy(exp_table[job][type], exp_table[jobs[0]][type], sizeof(exp_table[0][0]));
+ max_level[job][type] = max_level[jobs[0]][type];
+// ShowDebug("%s - Class %d: %d\n", type?"Job":"Base", job, max_level[job][type]);
}
}
fclose(fp);
diff --git a/src/map/pc.h b/src/map/pc.h
index e7a9c85c5..b05323100 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -116,6 +116,9 @@ int pc_stopattack(struct map_session_data*);
int pc_follow(struct map_session_data*, int); // [MouseJstr]
int pc_stop_following(struct map_session_data*);
+
+int pc_maxbaselv(struct map_session_data *sd);
+int pc_maxjoblv(struct map_session_data *sd);
int pc_checkbaselevelup(struct map_session_data *sd);
int pc_checkjoblevelup(struct map_session_data *sd);
int pc_gainexp(struct map_session_data*,int,int);
diff --git a/src/map/status.c b/src/map/status.c
index 53e6009e9..88e13fedf 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -1624,7 +1624,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
// Relative modifiers from passive skills
if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0)
sd->aspd_rate -= (skill/2);
- if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && sd->status.job_level >= battle_config.max_job_level)
+ if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobafter(sd))
sd->aspd_rate -= (skill*3);
if(pc_isriding(sd))