|
Atrinik Server 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00030 #include <global.h> 00031 00037 uint64 new_levels[MAXLEVEL + 2] = 00038 { 00039 0, 0, 1500, 4000, 8000, 00040 16000, 32000, 64000, 125000, 250000, 00041 500000, 1100000, 2300000, 3600000, 5000000, 00042 6500000, 8100000, 9800000, 11600000, 13500000, 00043 15500000, 17600000, 19800000, 22100000, 24500000, 00044 27000000, 29600000, 32300000, 35100000, 38000000, 00045 41000000, 44100000, 47300000, 50600000, 54000000, 00046 57500000, 61100000, 64800000, 68600000, 72500000, 00047 76500000, 80600000, 84800000, 89100000, 93500000, 00048 98000000, 102600000, 107300000, 112100000, 117000000, 00049 122000000, 127100000, 132300000, 137600000, 143000000, 00050 148500000, 154100000, 159800000, 165600000, 171500000, 00051 177500000, 183600000, 189800000, 196100000, 202500000, 00052 209000000, 215600000, 222300000, 229100000, 236000000, 00053 243000000, 250100000, 257300000, 264600000, 272000000, 00054 280200000, 294800000, 310200000, 326300000, 343200000, 00055 361000000, 379700000, 399300000, 419900000, 441500000, 00056 464200000, 488100000, 513100000, 539400000, 567000000, 00057 596000000, 626400000, 658300000, 691900000, 727100000, 00058 764100000, 802900000, 843700000, 886500000, 931500000, 00059 978700000, 1028200000, 1080300000, 1134900000, 1192300000, 00060 1252500000, 1315800000, 1382200000, 1451900000, 1525100000, 00061 2100000000ULL, 4200000000ULL, 8400000000ULL, 16800000000ULL, 33600000000ULL, 00062 67200000000ULL, 134400000000ULL 00063 }; 00064 00067 _level_color level_color[201] = 00068 { 00069 {-2, -1, 0, 1, 2, 3}, 00070 {-1, 0, 1, 2, 3, 4}, 00071 {0, 1, 2, 3, 4, 5}, 00072 {1, 2, 3, 4, 5, 6}, 00073 {2, 3, 4, 5, 6, 7}, 00074 {3, 4, 5, 6, 7, 8}, 00075 {4, 5, 6, 7, 8, 9}, 00076 {5, 6, 7, 8, 9, 10}, 00077 {6, 7, 8, 9, 10, 11}, 00078 {7, 8, 9, 10, 11, 12}, 00079 {7, 9, 10, 11, 12, 14}, 00080 {8, 9, 11, 12, 13, 15}, 00081 {9, 10, 12, 13, 14, 16}, 00082 {9, 11, 13, 14, 15, 17}, 00083 {10, 11, 14, 15, 16, 18}, 00084 {11, 12, 15, 16, 17, 19}, 00085 {11, 13, 16, 17, 18, 20}, 00086 {12, 14, 17, 18, 19, 21}, 00087 {13, 15, 18, 19, 20, 22}, 00088 {14, 16, 19, 20, 21, 23}, 00089 {14, 17, 20, 21, 22, 24}, 00090 {15, 17, 21, 22, 24, 26}, 00091 {16, 18, 22, 23, 25, 27}, 00092 {16, 19, 23, 24, 26, 28}, 00093 {17, 19, 24, 25, 27, 30}, 00094 {18, 20, 25, 26, 28, 31}, 00095 {19, 21, 26, 27, 29, 32}, 00096 {19, 22, 27, 28, 30, 33}, 00097 {20, 23, 28, 29, 31, 35}, 00098 {21, 24, 29, 30, 32, 36}, 00099 {22, 25, 30, 31, 33, 37}, 00100 {22, 25, 31, 32, 34, 38}, 00101 {23, 26, 32, 33, 35, 39}, 00102 {24, 27, 32, 35, 37, 41}, 00103 {25, 28, 33, 36, 38, 42}, 00104 {25, 28, 34, 37, 39, 43}, 00105 {26, 29, 35, 38, 40, 44}, 00106 {27, 30, 36, 39, 41, 45}, 00107 {28, 31, 37, 40, 42, 46}, 00108 {28, 32, 38, 41, 44, 48}, 00109 {29, 33, 39, 42, 45, 49}, 00110 {30, 34, 40, 43, 46, 50}, 00111 {30, 34, 41, 44, 47, 52}, 00112 {31, 35, 42, 45, 48, 53}, 00113 {32, 36, 43, 46, 49, 54}, 00114 {33, 37, 44, 47, 50, 55}, 00115 {33, 37, 45, 48, 51, 57}, 00116 {34, 38, 46, 49, 52, 58}, 00117 {35, 39, 47, 50, 53, 59}, 00118 {36, 40, 48, 51, 54, 60}, 00119 {36, 41, 49, 52, 55, 61}, 00120 {37, 42, 50, 53, 56, 62}, 00121 {38, 43, 51, 54, 57, 63}, 00122 {38, 43, 52, 55, 58, 65}, 00123 {39, 44, 53, 56, 59, 66}, 00124 {40, 45, 54, 57, 60, 67}, 00125 {41, 46, 55, 58, 61, 68}, 00126 {41, 47, 56, 59, 63, 70}, 00127 {42, 48, 57, 60, 64, 71}, 00128 {43, 49, 58, 61, 65, 72}, 00129 {44, 50, 59, 62, 66, 73}, 00130 {44, 50, 60, 63, 67, 75}, 00131 {45, 51, 61, 64, 68, 76}, 00132 {46, 52, 62, 65, 69, 77}, 00133 {47, 53, 63, 66, 70, 78}, 00134 {47, 53, 64, 67, 71, 79}, 00135 {48, 54, 64, 69, 73, 81}, 00136 {49, 55, 65, 70, 74, 82}, 00137 {50, 56, 66, 71, 75, 83}, 00138 {50, 56, 67, 72, 76, 84}, 00139 {51, 57, 68, 73, 77, 85}, 00140 {52, 58, 69, 74, 78, 86}, 00141 {53, 59, 70, 75, 79, 87}, 00142 {53, 60, 71, 76, 80, 89}, 00143 {54, 61, 72, 77, 81, 90}, 00144 {55, 62, 73, 78, 82, 91}, 00145 {56, 63, 74, 79, 83, 92}, 00146 {56, 63, 75, 80, 85, 94}, 00147 {57, 64, 76, 81, 86, 95}, 00148 {58, 65, 77, 82, 87, 96}, 00149 {59, 66, 78, 83, 88, 97}, 00150 {59, 67, 79, 84, 89, 99}, 00151 {60, 68, 80, 85, 90, 100}, 00152 {61, 69, 81, 86, 91, 101}, 00153 {62, 70, 82, 87, 92, 102}, 00154 {62, 70, 83, 88, 93, 103}, 00155 {63, 71, 84, 89, 94, 104}, 00156 {64, 72, 85, 90, 95, 105}, 00157 {65, 73, 86, 91, 96, 106}, 00158 {65, 73, 87, 92, 97, 108}, 00159 {66, 74, 88, 93, 98, 109}, 00160 {67, 75, 89, 94, 99, 110}, 00161 {68, 76, 90, 95, 100, 111}, 00162 {69, 77, 91, 96, 101, 112}, 00163 {69, 78, 92, 97, 103, 114}, 00164 {70, 79, 93, 98, 104, 115}, 00165 {71, 80, 94, 99, 105, 116}, 00166 {72, 81, 95, 100, 106, 117}, 00167 {72, 81, 96, 101, 107, 119}, 00168 {73, 82, 96, 103, 109, 120}, 00169 {74, 83, 97, 104, 110, 121}, 00170 {75, 84, 98, 105, 111, 122}, 00171 {75, 84, 99, 106, 112, 124}, 00172 {76, 85, 100, 107, 113, 125}, 00173 {77, 86, 101, 108, 114, 126}, 00174 {78, 87, 102, 109, 115, 127}, 00175 {79, 88, 103, 110, 116, 128}, 00176 {79, 89, 104, 111, 117, 129}, 00177 {80, 90, 105, 112, 118, 130}, 00178 {81, 91, 106, 113, 119, 131}, 00179 {82, 92, 107, 114, 120, 132}, 00180 {82, 92, 108, 115, 121, 134}, 00181 {83, 93, 109, 116, 122, 135}, 00182 {84, 94, 110, 117, 123, 136}, 00183 {85, 95, 111, 118, 124, 137}, 00184 {86, 96, 112, 119, 125, 138}, 00185 {86, 96, 113, 120, 126, 140}, 00186 {87, 97, 114, 121, 127, 141}, 00187 {88, 98, 115, 122, 128, 142}, 00188 {89, 99, 116, 123, 129, 143}, 00189 {90, 100, 117, 124, 130, 144}, 00190 {90, 101, 118, 125, 132, 146}, 00191 {91, 102, 119, 126, 133, 147}, 00192 {92, 103, 120, 127, 134, 148}, 00193 {93, 104, 121, 128, 135, 149}, 00194 {94, 105, 122, 129, 136, 150}, 00195 {94, 105, 123, 130, 137, 151}, 00196 {95, 106, 124, 131, 138, 152}, 00197 {96, 107, 125, 132, 139, 153}, 00198 {97, 108, 126, 133, 140, 154}, 00199 {97, 109, 127, 134, 141, 156}, 00200 {98, 110, 128, 135, 142, 157}, 00201 {99, 110, 128, 137, 144, 158}, 00202 {100, 111, 129, 138, 145, 159}, 00203 {101, 112, 130, 139, 146, 160}, 00204 {101, 113, 131, 140, 147, 162}, 00205 {102, 114, 132, 141, 148, 163}, 00206 {103, 115, 133, 142, 149, 164}, 00207 {104, 116, 134, 143, 150, 165}, 00208 {105, 117, 135, 144, 151, 166}, 00209 {106, 118, 136, 145, 152, 167}, 00210 {106, 118, 137, 146, 153, 169}, 00211 {107, 119, 138, 147, 154, 170}, 00212 {108, 120, 139, 148, 155, 171}, 00213 {109, 121, 140, 149, 156, 172}, 00214 {110, 122, 141, 150, 157, 173}, 00215 {110, 122, 142, 151, 159, 175}, 00216 {111, 123, 143, 152, 160, 176}, 00217 {112, 124, 144, 153, 161, 177}, 00218 {113, 125, 145, 154, 162, 178}, 00219 {114, 126, 146, 155, 163, 179}, 00220 {114, 127, 147, 156, 164, 180}, 00221 {115, 128, 148, 157, 165, 181}, 00222 {116, 129, 149, 158, 166, 182}, 00223 {117, 130, 150, 159, 167, 183}, 00224 {118, 131, 151, 160, 168, 184}, 00225 {119, 132, 152, 161, 169, 185}, 00226 {119, 132, 153, 162, 170, 187}, 00227 {120, 133, 154, 163, 171, 188}, 00228 {121, 134, 155, 164, 172, 189}, 00229 {122, 135, 156, 165, 173, 190}, 00230 {123, 136, 157, 166, 174, 191}, 00231 {123, 137, 158, 167, 175, 193}, 00232 {124, 138, 159, 168, 176, 194}, 00233 {125, 139, 160, 169, 177, 195}, 00234 {126, 139, 160, 171, 179, 196}, 00235 {127, 140, 161, 172, 180, 197}, 00236 {128, 141, 162, 173, 181, 198}, 00237 {128, 142, 163, 174, 182, 200}, 00238 {129, 143, 164, 175, 183, 201}, 00239 {130, 144, 165, 176, 184, 202}, 00240 {131, 145, 166, 177, 185, 203}, 00241 {132, 146, 167, 178, 186, 204}, 00242 {133, 147, 168, 179, 187, 205}, 00243 {133, 147, 169, 180, 189, 207}, 00244 {134, 148, 170, 181, 190, 208}, 00245 {135, 149, 171, 182, 191, 209}, 00246 {136, 150, 172, 183, 192, 210}, 00247 {137, 151, 173, 184, 193, 211}, 00248 {138, 152, 174, 185, 194, 212}, 00249 {139, 153, 175, 186, 195, 213}, 00250 {139, 153, 176, 187, 196, 214}, 00251 {140, 154, 177, 188, 197, 215}, 00252 {141, 155, 178, 189, 198, 216}, 00253 {142, 156, 179, 190, 199, 217}, 00254 {143, 157, 180, 191, 200, 218}, 00255 {144, 158, 181, 192, 201, 219}, 00256 {144, 159, 182, 193, 202, 221}, 00257 {145, 160, 183, 194, 203, 222}, 00258 {146, 161, 184, 195, 204, 223}, 00259 {147, 162, 185, 196, 205, 224}, 00260 {148, 163, 186, 197, 206, 225}, 00261 {149, 164, 187, 198, 207, 226}, 00262 {150, 165, 188, 199, 208, 227}, 00263 {150, 165, 189, 200, 209, 229}, 00264 {151, 166, 190, 201, 210, 230}, 00265 {152, 167, 191, 202, 211, 231}, 00266 {153, 168, 192, 203, 212, 232}, 00267 {154, 169, 192, 205, 214, 233}, 00268 {155, 170, 193, 206, 215, 234}, 00269 {156, 171, 194, 207, 216, 235} 00270 }; 00271 00273 #define MAX_EXPERIENCE new_levels[MAXLEVEL] 00274 00275 #define MAX_EXP_IN_OBJ new_levels[MAXLEVEL] / (MAX_EXP_CAT - 1) 00276 00285 uint64 level_exp(int level, double expmul) 00286 { 00287 return (uint64) (expmul * (double) new_levels[level]); 00288 } 00289 00298 sint64 add_exp(object *op, sint64 exp, int skill_nr, int exact) 00299 { 00300 object *exp_ob = NULL, *exp_skill = NULL; 00301 00302 /* Sanity check */ 00303 if (!op) 00304 { 00305 LOG(llevBug, "add_exp(): Called for NULL object.\n"); 00306 return 0; 00307 } 00308 00309 /* No exp gain for monsters */ 00310 if (op->type != PLAYER) 00311 { 00312 return 0; 00313 } 00314 00315 if (skill_nr == CHOSEN_SKILL_NO) 00316 { 00317 LOG(llevDebug, "TODO: add_exp(): called for %s with exp %"FMT64". CHOSEN_SKILL_NO set. TODO: select skill.\n", query_name(op, NULL), exp); 00318 return 0; 00319 } 00320 00321 /* Now we grab the skill experience object from the player's shortcut 00322 * pointer array. */ 00323 exp_skill = CONTR(op)->skill_ptr[skill_nr]; 00324 00325 /* Sanity */ 00326 if (!exp_skill) 00327 { 00328 LOG(llevDebug, "add_exp(): called for %s with skill nr %d / %"FMT64" exp - object has not this skill.\n", query_name(op, NULL), skill_nr, exp); 00329 return 0; 00330 } 00331 00332 /* If we are full in this skill, there nothing is to do. */ 00333 if (exp_skill->level >= MAXLEVEL) 00334 { 00335 return 0; 00336 } 00337 00338 /* Mark the skills for update */ 00339 CONTR(op)->update_skills = 1; 00340 exp_ob = exp_skill->exp_obj; 00341 00342 if (!exp_ob) 00343 { 00344 LOG(llevBug, "add_exp() skill: %s - no exp_ob found!!\n", query_name(exp_skill, NULL)); 00345 return 0; 00346 } 00347 00348 /* General adjustments for playbalance */ 00349 if (!exact) 00350 { 00351 sint64 limit = (new_levels[exp_skill->level + 1] - new_levels[exp_skill->level]) / 4; 00352 00353 if (exp > limit) 00354 { 00355 exp = limit; 00356 } 00357 } 00358 00359 /* First we see what we can add to our skill */ 00360 exp = adjust_exp(op, exp_skill, exp); 00361 00362 /* Notify the player of the exp gain */ 00363 new_draw_info_format(0, COLOR_WHITE, op, "You got %"FMT64" exp in skill %s.", exp, skills[skill_nr].name); 00364 CONTR(op)->stat_exp_gained += exp; 00365 00366 /* adjust_exp() has adjusted the skill and all exp_obj and player 00367 * experience. Now let's check for level up in all categories. */ 00368 player_lvl_adj(op, exp_skill); 00369 player_lvl_adj(op, exp_ob); 00370 player_lvl_adj(op, NULL); 00371 00372 if (op->exp_obj) 00373 { 00374 op->exp_obj = NULL; 00375 } 00376 00377 /* The real experience we have added to our skill */ 00378 return exp; 00379 } 00380 00388 void player_lvl_adj(object *who, object *op) 00389 { 00390 char buf[MAX_BUF]; 00391 00392 /* When rolling stats */ 00393 if (!op) 00394 { 00395 op = who; 00396 } 00397 00398 /* No exp gain for indirect skills */ 00399 if (op->type == SKILL && !op->last_eat) 00400 { 00401 LOG(llevBug,"player_lvl_adj() called for indirect skill %s (who: %s)\n", query_name(op, NULL), who == NULL ? "<null>" : query_name(who, NULL)); 00402 return; 00403 } 00404 00405 if (op->level < MAXLEVEL && op->stats.exp >= (sint64) level_exp(op->level + 1, 1.0)) 00406 { 00407 op->level++; 00408 00409 /* Show the player some effects. */ 00410 if (op->type == SKILL && who && who->type == PLAYER && who->map) 00411 { 00412 object *effect_ob; 00413 00414 play_sound_player_only(CONTR(who), CMD_SOUND_EFFECT, "event01.ogg", 0, 0, 0, 0); 00415 00416 if (level_up_arch) 00417 { 00418 /* Prepare effect */ 00419 effect_ob = arch_to_object(level_up_arch); 00420 effect_ob->map = who->map; 00421 effect_ob->x = who->x; 00422 effect_ob->y = who->y; 00423 00424 if (!insert_ob_in_map(effect_ob, effect_ob->map, NULL, INS_NO_MERGE | INS_NO_WALK_ON)) 00425 { 00426 /* Something is wrong - remove object */ 00427 if (!QUERY_FLAG(effect_ob, FLAG_REMOVED)) 00428 { 00429 remove_ob(effect_ob); 00430 } 00431 } 00432 } 00433 } 00434 00435 if (who && who->type == PLAYER && op->type != EXPERIENCE && op->type != SKILL && who->level > 1) 00436 { 00437 if (who->level > 4) 00438 { 00439 CONTR(who)->levhp[who->level] = (char) rndm(1, who->arch->clone.stats.maxhp); 00440 } 00441 else if (who->level > 2) 00442 { 00443 CONTR(who)->levhp[who->level] = (char) rndm(1, who->arch->clone.stats.maxhp / 2) + (who->arch->clone.stats.maxhp / 2); 00444 } 00445 else 00446 { 00447 CONTR(who)->levhp[who->level] = (char) who->arch->clone.stats.maxhp; 00448 } 00449 } 00450 00451 if (op->level > 1 && op->type == EXPERIENCE) 00452 { 00453 if (who && who->type == PLAYER) 00454 { 00455 /* Mana */ 00456 if (op->stats.Pow) 00457 { 00458 if (op->level > 4) 00459 { 00460 CONTR(who)->levsp[op->level] = (char) rndm(1, who->arch->clone.stats.maxsp); 00461 } 00462 else 00463 { 00464 CONTR(who)->levsp[op->level] = (char) who->arch->clone.stats.maxsp; 00465 } 00466 } 00467 /* Grace */ 00468 else if (op->stats.Wis) 00469 { 00470 if (op->level > 4) 00471 { 00472 CONTR(who)->levgrace[op->level] = (char) rndm(1, who->arch->clone.stats.maxgrace); 00473 } 00474 else 00475 { 00476 CONTR(who)->levgrace[op->level] = (char) who->arch->clone.stats.maxgrace; 00477 } 00478 } 00479 } 00480 00481 if (who) 00482 { 00483 snprintf(buf, sizeof(buf), "You are now level %d in %s based skills.", op->level, op->name); 00484 new_draw_info(0, COLOR_RED, who, buf); 00485 } 00486 } 00487 else if (op->level > 1 && op->type == SKILL) 00488 { 00489 if (who) 00490 { 00491 /* If we leveled up praying or wizardry, we need to send a spell list update */ 00492 if (op->stats.sp == SK_PRAYING || op->stats.sp == SK_SPELL_CASTING) 00493 { 00494 send_spelllist_cmd(who, NULL, SPLIST_MODE_UPDATE); 00495 } 00496 00497 snprintf(buf, sizeof(buf), "You are now level %d in the skill %s.", op->level, op->name); 00498 new_draw_info(0, COLOR_RED, who, buf); 00499 } 00500 } 00501 else 00502 { 00503 if (who) 00504 { 00505 snprintf(buf, sizeof(buf), "You are now level %d.", op->level); 00506 new_draw_info(0, COLOR_RED, who, buf); 00507 } 00508 } 00509 00510 if (who) 00511 { 00512 fix_player(who); 00513 } 00514 00515 /* To increase more levels. */ 00516 player_lvl_adj(who, op); 00517 } 00518 else if (op->level > 1 && op->stats.exp < (sint64) level_exp(op->level, 1.0)) 00519 { 00520 op->level--; 00521 00522 if (who) 00523 { 00524 fix_player(who); 00525 } 00526 00527 if (op->type == EXPERIENCE) 00528 { 00529 if (who) 00530 { 00531 snprintf(buf, sizeof(buf), "-You are now level %d in %s based skills.", op->level, op->name); 00532 new_draw_info(0, COLOR_RED, who, buf); 00533 } 00534 } 00535 else if (op->type == SKILL) 00536 { 00537 if (who) 00538 { 00539 snprintf(buf, sizeof(buf), "-You are now level %d in the skill %s.", op->level, op->name); 00540 new_draw_info(0, COLOR_RED, who, buf); 00541 } 00542 } 00543 else 00544 { 00545 if (who) 00546 { 00547 snprintf(buf, sizeof(buf), "-You are now level %d.", op->level); 00548 new_draw_info(0, COLOR_RED, who, buf); 00549 } 00550 } 00551 00552 /* To decrease more levels. */ 00553 player_lvl_adj(who, op); 00554 } 00555 } 00556 00567 sint64 adjust_exp(object *pl, object *op, sint64 exp) 00568 { 00569 object *tmp; 00570 int i, sk_nr; 00571 sint64 sk_exp, pl_exp; 00572 00573 /* Be sure this is a skill object from a player. */ 00574 if (op->type != SKILL || !pl || pl->type != PLAYER) 00575 { 00576 LOG(llevBug, "adjust_exp() - called for non player or non skill: skill: %s -> player: %s\n", query_name(op, NULL), query_name(pl, NULL)); 00577 return 0; 00578 } 00579 00580 /* Add or sub the exp and cap it. Must be >= 0 and <= MAX_EXPERIENCE */ 00581 op->stats.exp += exp; 00582 00583 if (op->stats.exp < 0) 00584 { 00585 exp -= op->stats.exp; 00586 op->stats.exp = 0; 00587 } 00588 00589 if (op->stats.exp > (sint64) MAX_EXPERIENCE) 00590 { 00591 exp = exp - (op->stats.exp - MAX_EXPERIENCE); 00592 op->stats.exp = MAX_EXPERIENCE; 00593 } 00594 00595 /* Now we collect the experience of all skills which are in the same 00596 * experience object category. */ 00597 sk_nr = skills[op->stats.sp].category; 00598 sk_exp = 0; 00599 00600 for (tmp = pl->inv; tmp; tmp = tmp->below) 00601 { 00602 if (tmp->type == SKILL && skills[tmp->stats.sp].category == sk_nr && !QUERY_FLAG(tmp, FLAG_STAND_STILL)) 00603 { 00604 if (tmp->stats.exp > sk_exp) 00605 { 00606 sk_exp = tmp->stats.exp; 00607 } 00608 } 00609 } 00610 00611 /* Set the experience of the experience object to our best skill of 00612 * this group. */ 00613 op->exp_obj->stats.exp = sk_exp; 00614 00615 pl_exp = 0; 00616 00617 for (i = 0; i < MAX_EXP_CAT - 1; i++) 00618 { 00619 if (CONTR(pl)->last_skill_ob[i]->stats.exp > pl_exp && !QUERY_FLAG(CONTR(pl)->last_skill_ob[i], FLAG_STAND_STILL)) 00620 { 00621 pl_exp = CONTR(pl)->last_skill_ob[i]->stats.exp; 00622 } 00623 } 00624 00625 /* Set our player exp to highest category experience. */ 00626 pl->stats.exp = pl_exp; 00627 00628 return exp; 00629 } 00630 00637 void apply_death_exp_penalty(object *op) 00638 { 00639 object *tmp; 00640 float loss_p; 00641 sint64 lev_exp, loss_exp; 00642 00643 /* Mark the skills for update */ 00644 CONTR(op)->update_skills = 1; 00645 00646 for (tmp = op->inv; tmp; tmp = tmp->below) 00647 { 00648 /* Only adjust skills with level and a positive exp value, 00649 * negative exp has special meaning. */ 00650 if (tmp->type == SKILL && tmp->level && tmp->last_eat == 1) 00651 { 00652 /* Check there is experience we can drain. */ 00653 lev_exp = tmp->stats.exp - new_levels[tmp->level]; 00654 00655 /* Sanity check */ 00656 if (lev_exp < 0) 00657 { 00658 LOG(llevBug, "apply_death_exp_penalty(): Skill %s (%d %"FMT64") for player %s -> less exp as level need!\n", query_name(tmp, NULL), tmp->level, tmp->stats.exp, query_name(op, NULL)); 00659 } 00660 00661 if (!lev_exp) 00662 { 00663 continue; 00664 } 00665 00666 if (tmp->level < 2) 00667 { 00668 loss_exp = lev_exp - (int) ((float) lev_exp * 0.9); 00669 } 00670 else if (tmp->level < 3) 00671 { 00672 loss_exp = lev_exp - (int) ((float) lev_exp * 0.85); 00673 } 00674 else 00675 { 00676 loss_p = 0.927f - (((float) tmp->level / 5.0f) * 0.00337f); 00677 loss_exp = (new_levels[tmp->level + 1] - new_levels[tmp->level]) - (int) ((float) (new_levels[tmp->level + 1] - new_levels[tmp->level]) * loss_p); 00678 } 00679 00680 if (loss_exp < 0) 00681 { 00682 loss_exp = 0; 00683 } 00684 00685 if (loss_exp > lev_exp) 00686 { 00687 loss_exp = lev_exp; 00688 } 00689 00690 if (loss_exp > 0) 00691 { 00692 adjust_exp(op, tmp, -loss_exp); 00693 player_lvl_adj(op, tmp); 00694 } 00695 } 00696 } 00697 00698 for (tmp = op->inv; tmp; tmp = tmp->below) 00699 { 00700 /* Adjust experience object levels. */ 00701 if (tmp->type == EXPERIENCE && tmp->stats.exp) 00702 { 00703 player_lvl_adj(op, tmp); 00704 } 00705 } 00706 00707 /* Adjust the player level. */ 00708 player_lvl_adj(op, NULL); 00709 } 00710 00733 float calc_level_difference(int who_lvl, int op_lvl) 00734 { 00735 int r; 00736 float v, tmp = 1.0f; 00737 00738 /* Sanity checks */ 00739 if (who_lvl < 0 || who_lvl > 200 || op_lvl < 0 || op_lvl > 200) 00740 { 00741 LOG(llevBug, "calc_level_difference(): Level out of range! (%d - %d)\n", who_lvl, op_lvl); 00742 return 0.0f; 00743 } 00744 00745 /* Grey, no experience */ 00746 if (op_lvl < level_color[who_lvl].green) 00747 { 00748 return 0.0f; 00749 } 00750 00751 /* Yellow, blue or green */ 00752 if (who_lvl > op_lvl) 00753 { 00754 if (op_lvl >= level_color[who_lvl].yellow) 00755 { 00756 r = who_lvl - level_color[who_lvl].yellow; 00757 00758 if (r < 1) 00759 { 00760 r = 1; 00761 } 00762 00763 v = 0.2f / (float) r; 00764 tmp = 1.0f - (v * (float) (who_lvl - op_lvl)); 00765 } 00766 else if (op_lvl >= level_color[who_lvl].blue) 00767 { 00768 r = level_color[who_lvl].yellow - level_color[who_lvl].blue; 00769 00770 if (r < 1) 00771 { 00772 r = 1; 00773 } 00774 00775 v = 0.3f / (float) r; 00776 tmp = 0.4f + (v * (float) (op_lvl - level_color[who_lvl].blue + 1)); 00777 } 00778 /* Green */ 00779 else 00780 { 00781 r = level_color[who_lvl].blue - level_color[who_lvl].green; 00782 00783 if (r < 1) 00784 { 00785 r = 1; 00786 } 00787 00788 v = 0.05f / (float) r; 00789 tmp = 0.25f + (v * (float) (op_lvl - level_color[who_lvl].green + 1)); 00790 } 00791 } 00792 /* Yellow, orange, red, purple */ 00793 else if (who_lvl < op_lvl) 00794 { 00795 /* Still yellow */ 00796 if (op_lvl < level_color[who_lvl].orange) 00797 { 00798 r = level_color[who_lvl].orange - who_lvl - 1; 00799 00800 if (r < 1) 00801 { 00802 r = 1; 00803 } 00804 00805 v = 0.1f / (float) r; 00806 tmp = 1.0f + (v * (float) (op_lvl - who_lvl)); 00807 00808 } 00809 /* Orange */ 00810 else if (op_lvl < level_color[who_lvl].red) 00811 { 00812 r = level_color[who_lvl].red - who_lvl - 1; 00813 00814 if (r < 1) 00815 { 00816 r = 1; 00817 } 00818 00819 v = 0.2f / (float) r; 00820 tmp = 1.2f + (v * (float) (op_lvl - who_lvl)); 00821 } 00822 /* Red or purple */ 00823 else 00824 { 00825 r = (op_lvl + 1) - level_color[who_lvl].red; 00826 v = 0.1f * (float) r; 00827 tmp = 1.4f + v; 00828 } 00829 } 00830 00831 return tmp; 00832 } 00833 00838 uint64 calculate_total_exp(object *op) 00839 { 00840 uint64 exp = 0; 00841 int i; 00842 00843 for (i = 0; i < NROFSKILLS; i++) 00844 { 00845 if (CONTR(op)->skill_ptr[i]) 00846 { 00847 exp += CONTR(op)->skill_ptr[i]->stats.exp; 00848 } 00849 } 00850 00851 return exp; 00852 }
1.7.4