Atrinik Server  4.0
exp.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
30 #include <global.h>
31 #include <arch.h>
32 #include <exp.h>
33 #include <player.h>
34 
38 uint64_t new_levels[MAXLEVEL + 2] = {
39  0, 0, 2000, 4000, 8000, 16000, 32000, 64000, 125000, 250000, 500000,
40  900000, 1400000, 2000000, 2600000,
41  3300000, 4100000, 4900000, 5700000, 6600000, 7500000,
42  8500000, 9500000, 10600000, 11800000, 13000000,
43  14300000, 15600000, 17000000, 18500000, 20000000,
44  21700000, 23400000, 25200000, 27000000, 29000000,
45  31100000, 33300000, 35600000, 38000000, 40500000,
46  43200000, 46000000, 48900000, 52000000, 55200000,
47  58600000, 62100000, 65900000, 69800000, 73900000,
48  78200000, 82700000, 87500000, 92500000, 97800000,
49  103300000, 109100000, 115200000, 121500000, 128200000,
50  135300000, 142700000, 150400000, 158600000, 167100000,
51  176100000, 185600000, 195500000, 205900000, 216800000,
52  228300000, 240300000, 252900000, 266200000, 280200000,
53  294800000, 310200000, 326300000, 343200000, 361000000,
54  379700000, 399300000, 419900000, 441500000, 464200000,
55  488100000, 513100000, 539400000, 567000000, 596000000,
56  626400000, 658300000, 691900000, 727100000, 764100000,
57  802900000, 843700000, 886500000, 931500000, 978700000,
58  1028200000, 1080300000, 1134900000, 1192300000, 1252500000,
59  1315800000, 1382200000, 1451900000, 1525100000, 2100000000ULL,
60  4200000000ULL, 8400000000ULL, 16800000000ULL,
61  33600000000ULL, 67200000000ULL, 134400000000ULL
62 };
63 
68  {-2, -1, 0, 1, 2, 3},
69  {-1, 0, 1, 2, 3, 4},
70  {0, 1, 2, 3, 4, 5},
71  {1, 2, 3, 4, 5, 6},
72  {2, 3, 4, 5, 6, 7},
73  {3, 4, 5, 6, 7, 8},
74  {4, 5, 6, 7, 8, 9},
75  {5, 6, 7, 8, 9, 10},
76  {6, 7, 8, 9, 10, 11},
77  {7, 8, 9, 10, 11, 12},
78  {7, 9, 10, 11, 12, 14},
79  {8, 9, 11, 12, 13, 15},
80  {9, 10, 12, 13, 14, 16},
81  {9, 11, 13, 14, 15, 17},
82  {10, 11, 14, 15, 16, 18},
83  {11, 12, 15, 16, 17, 19},
84  {11, 13, 16, 17, 18, 20},
85  {12, 14, 17, 18, 19, 21},
86  {13, 15, 18, 19, 20, 22},
87  {14, 16, 19, 20, 21, 23},
88  {14, 17, 20, 21, 22, 24},
89  {15, 17, 21, 22, 24, 26},
90  {16, 18, 22, 23, 25, 27},
91  {16, 19, 23, 24, 26, 28},
92  {17, 19, 24, 25, 27, 30},
93  {18, 20, 25, 26, 28, 31},
94  {19, 21, 26, 27, 29, 32},
95  {19, 22, 27, 28, 30, 33},
96  {20, 23, 28, 29, 31, 35},
97  {21, 24, 29, 30, 32, 36},
98  {22, 25, 30, 31, 33, 37},
99  {22, 25, 31, 32, 34, 38},
100  {23, 26, 32, 33, 35, 39},
101  {24, 27, 32, 35, 37, 41},
102  {25, 28, 33, 36, 38, 42},
103  {25, 28, 34, 37, 39, 43},
104  {26, 29, 35, 38, 40, 44},
105  {27, 30, 36, 39, 41, 45},
106  {28, 31, 37, 40, 42, 46},
107  {28, 32, 38, 41, 44, 48},
108  {29, 33, 39, 42, 45, 49},
109  {30, 34, 40, 43, 46, 50},
110  {30, 34, 41, 44, 47, 52},
111  {31, 35, 42, 45, 48, 53},
112  {32, 36, 43, 46, 49, 54},
113  {33, 37, 44, 47, 50, 55},
114  {33, 37, 45, 48, 51, 57},
115  {34, 38, 46, 49, 52, 58},
116  {35, 39, 47, 50, 53, 59},
117  {36, 40, 48, 51, 54, 60},
118  {36, 41, 49, 52, 55, 61},
119  {37, 42, 50, 53, 56, 62},
120  {38, 43, 51, 54, 57, 63},
121  {38, 43, 52, 55, 58, 65},
122  {39, 44, 53, 56, 59, 66},
123  {40, 45, 54, 57, 60, 67},
124  {41, 46, 55, 58, 61, 68},
125  {41, 47, 56, 59, 63, 70},
126  {42, 48, 57, 60, 64, 71},
127  {43, 49, 58, 61, 65, 72},
128  {44, 50, 59, 62, 66, 73},
129  {44, 50, 60, 63, 67, 75},
130  {45, 51, 61, 64, 68, 76},
131  {46, 52, 62, 65, 69, 77},
132  {47, 53, 63, 66, 70, 78},
133  {47, 53, 64, 67, 71, 79},
134  {48, 54, 64, 69, 73, 81},
135  {49, 55, 65, 70, 74, 82},
136  {50, 56, 66, 71, 75, 83},
137  {50, 56, 67, 72, 76, 84},
138  {51, 57, 68, 73, 77, 85},
139  {52, 58, 69, 74, 78, 86},
140  {53, 59, 70, 75, 79, 87},
141  {53, 60, 71, 76, 80, 89},
142  {54, 61, 72, 77, 81, 90},
143  {55, 62, 73, 78, 82, 91},
144  {56, 63, 74, 79, 83, 92},
145  {56, 63, 75, 80, 85, 94},
146  {57, 64, 76, 81, 86, 95},
147  {58, 65, 77, 82, 87, 96},
148  {59, 66, 78, 83, 88, 97},
149  {59, 67, 79, 84, 89, 99},
150  {60, 68, 80, 85, 90, 100},
151  {61, 69, 81, 86, 91, 101},
152  {62, 70, 82, 87, 92, 102},
153  {62, 70, 83, 88, 93, 103},
154  {63, 71, 84, 89, 94, 104},
155  {64, 72, 85, 90, 95, 105},
156  {65, 73, 86, 91, 96, 106},
157  {65, 73, 87, 92, 97, 108},
158  {66, 74, 88, 93, 98, 109},
159  {67, 75, 89, 94, 99, 110},
160  {68, 76, 90, 95, 100, 111},
161  {69, 77, 91, 96, 101, 112},
162  {69, 78, 92, 97, 103, 114},
163  {70, 79, 93, 98, 104, 115},
164  {71, 80, 94, 99, 105, 116},
165  {72, 81, 95, 100, 106, 117},
166  {72, 81, 96, 101, 107, 119},
167  {73, 82, 96, 103, 109, 120},
168  {74, 83, 97, 104, 110, 121},
169  {75, 84, 98, 105, 111, 122},
170  {75, 84, 99, 106, 112, 124},
171  {76, 85, 100, 107, 113, 125},
172  {77, 86, 101, 108, 114, 126},
173  {78, 87, 102, 109, 115, 127},
174  {79, 88, 103, 110, 116, 128},
175  {79, 89, 104, 111, 117, 129},
176  {80, 90, 105, 112, 118, 130},
177  {81, 91, 106, 113, 119, 131},
178  {82, 92, 107, 114, 120, 132},
179  {82, 92, 108, 115, 121, 134},
180  {83, 93, 109, 116, 122, 135},
181  {84, 94, 110, 117, 123, 136},
182  {85, 95, 111, 118, 124, 137},
183  {86, 96, 112, 119, 125, 138},
184  {86, 96, 113, 120, 126, 140},
185  {87, 97, 114, 121, 127, 141},
186  {88, 98, 115, 122, 128, 142},
187  {89, 99, 116, 123, 129, 143},
188  {90, 100, 117, 124, 130, 144},
189  {90, 101, 118, 125, 132, 146},
190  {91, 102, 119, 126, 133, 147},
191  {92, 103, 120, 127, 134, 148},
192  {93, 104, 121, 128, 135, 149},
193  {94, 105, 122, 129, 136, 150},
194  {94, 105, 123, 130, 137, 151},
195  {95, 106, 124, 131, 138, 152},
196  {96, 107, 125, 132, 139, 153},
197  {97, 108, 126, 133, 140, 154},
198  {97, 109, 127, 134, 141, 156},
199  {98, 110, 128, 135, 142, 157},
200  {99, 110, 128, 137, 144, 158},
201  {100, 111, 129, 138, 145, 159},
202  {101, 112, 130, 139, 146, 160},
203  {101, 113, 131, 140, 147, 162},
204  {102, 114, 132, 141, 148, 163},
205  {103, 115, 133, 142, 149, 164},
206  {104, 116, 134, 143, 150, 165},
207  {105, 117, 135, 144, 151, 166},
208  {106, 118, 136, 145, 152, 167},
209  {106, 118, 137, 146, 153, 169},
210  {107, 119, 138, 147, 154, 170},
211  {108, 120, 139, 148, 155, 171},
212  {109, 121, 140, 149, 156, 172},
213  {110, 122, 141, 150, 157, 173},
214  {110, 122, 142, 151, 159, 175},
215  {111, 123, 143, 152, 160, 176},
216  {112, 124, 144, 153, 161, 177},
217  {113, 125, 145, 154, 162, 178},
218  {114, 126, 146, 155, 163, 179},
219  {114, 127, 147, 156, 164, 180},
220  {115, 128, 148, 157, 165, 181},
221  {116, 129, 149, 158, 166, 182},
222  {117, 130, 150, 159, 167, 183},
223  {118, 131, 151, 160, 168, 184},
224  {119, 132, 152, 161, 169, 185},
225  {119, 132, 153, 162, 170, 187},
226  {120, 133, 154, 163, 171, 188},
227  {121, 134, 155, 164, 172, 189},
228  {122, 135, 156, 165, 173, 190},
229  {123, 136, 157, 166, 174, 191},
230  {123, 137, 158, 167, 175, 193},
231  {124, 138, 159, 168, 176, 194},
232  {125, 139, 160, 169, 177, 195},
233  {126, 139, 160, 171, 179, 196},
234  {127, 140, 161, 172, 180, 197},
235  {128, 141, 162, 173, 181, 198},
236  {128, 142, 163, 174, 182, 200},
237  {129, 143, 164, 175, 183, 201},
238  {130, 144, 165, 176, 184, 202},
239  {131, 145, 166, 177, 185, 203},
240  {132, 146, 167, 178, 186, 204},
241  {133, 147, 168, 179, 187, 205},
242  {133, 147, 169, 180, 189, 207},
243  {134, 148, 170, 181, 190, 208},
244  {135, 149, 171, 182, 191, 209},
245  {136, 150, 172, 183, 192, 210},
246  {137, 151, 173, 184, 193, 211},
247  {138, 152, 174, 185, 194, 212},
248  {139, 153, 175, 186, 195, 213},
249  {139, 153, 176, 187, 196, 214},
250  {140, 154, 177, 188, 197, 215},
251  {141, 155, 178, 189, 198, 216},
252  {142, 156, 179, 190, 199, 217},
253  {143, 157, 180, 191, 200, 218},
254  {144, 158, 181, 192, 201, 219},
255  {144, 159, 182, 193, 202, 221},
256  {145, 160, 183, 194, 203, 222},
257  {146, 161, 184, 195, 204, 223},
258  {147, 162, 185, 196, 205, 224},
259  {148, 163, 186, 197, 206, 225},
260  {149, 164, 187, 198, 207, 226},
261  {150, 165, 188, 199, 208, 227},
262  {150, 165, 189, 200, 209, 229},
263  {151, 166, 190, 201, 210, 230},
264  {152, 167, 191, 202, 211, 231},
265  {153, 168, 192, 203, 212, 232},
266  {154, 169, 192, 205, 214, 233},
267  {155, 170, 193, 206, 215, 234},
268  {156, 171, 194, 207, 216, 235}
269 };
270 
283 uint64_t
284 level_exp (int level, double expmul)
285 {
286  return (uint64_t) (expmul * (double) new_levels[level]);
287 }
288 
303 int64_t
304 add_exp (object *op, int64_t exp_gain, int skill_nr, int exact)
305 {
306  object *exp_skill;
307 
308  /* Sanity check */
309  if (!op) {
310  return 0;
311  }
312 
313  /* No exp gain for monsters */
314  if (op->type != PLAYER) {
315  return 0;
316  }
317 
318  if (skill_nr == CHOSEN_SKILL_NO) {
319  return 0;
320  }
321 
322  /* No experience to gain/lose, nothing to do. */
323  if (exp_gain == 0) {
324  return 0;
325  }
326 
327  /* Now we grab the skill experience object from the player's shortcut
328  * pointer array. */
329  exp_skill = CONTR(op)->skill_ptr[skill_nr];
330 
331  /* Sanity */
332  if (!exp_skill) {
333  return 0;
334  }
335 
336  /* Can't add experience to maxed out skill, and can't subtract
337  * experience if the skill doesn't have any experience left. */
338  if ((exp_gain > 0 && exp_skill->level >= MAXLEVEL) || (exp_gain < 0 && exp_skill->stats.exp == 0)) {
339  return 0;
340  }
341 
342  /* General adjustments for playbalance */
343  if (!exact) {
344  int64_t limit;
345 
346  limit = (new_levels[exp_skill->level + 1] - new_levels[exp_skill->level]) / 4;
347 
348  if (exp_gain > limit) {
349  exp_gain = limit;
350  }
351  }
352 
353  exp_skill->stats.exp += exp_gain;
354 
355  if (exp_skill->stats.exp > (int64_t) MAX_EXPERIENCE) {
356  exp_gain = exp_gain - (exp_skill->stats.exp - MAX_EXPERIENCE);
357  exp_skill->stats.exp = MAX_EXPERIENCE;
358  } else if (exp_skill->stats.exp < 0) {
359  exp_gain += exp_skill->stats.exp;
360  exp_skill->stats.exp = 0;
361  }
362 
363  if (exp_gain > 0) {
364  if (!QUERY_FLAG(exp_skill, FLAG_STAND_STILL)) {
365  op->stats.exp += exp_gain;
366 
367  if (op->stats.exp >= (int64_t) MAX_EXPERIENCE) {
368  op->stats.exp = MAX_EXPERIENCE;
369  }
370  }
371 
372  CONTR(op)->stat_exp_gained += exp_gain;
373  } else if (exp_gain < 0) {
374  link_player_skills(op);
375  CONTR(op)->stat_exp_lost += -exp_gain;
376  }
377 
378  /* Notify the player of the exp gain/loss. */
379  if (exp_gain > 0) {
380  draw_info_format(COLOR_WHITE, op, "You got %"PRId64 " exp in skill %s.", exp_gain, skills[skill_nr].name);
381  } else {
382  draw_info_format(COLOR_WHITE, op, "You lost %"PRId64 " exp in skill %s.", -exp_gain, skills[skill_nr].name);
383  }
384 
385  if (exp_lvl_adj(op, exp_skill) + exp_lvl_adj(op, NULL) != 0) {
386  play_sound_player_only(CONTR(op), CMD_SOUND_EFFECT, "event01.ogg", 0, 0, 0, 0);
387  living_update(op);
388 
389  /* Show the player some effects. */
390  if (op->map != NULL) {
391  object *effect_ob;
392 
393  /* Prepare effect */
394  effect_ob = arch_to_object(arches[ARCH_LEVEL_UP]);
395  effect_ob->map = op->map;
396  effect_ob->x = op->x;
397  effect_ob->y = op->y;
398 
399  object_insert_map(effect_ob, effect_ob->map, NULL, INS_NO_MERGE | INS_NO_WALK_ON);
400  }
401  }
402 
403  esrv_update_item(UPD_EXTRA, exp_skill);
404 
405  return exp_gain;
406 }
407 
421 int
422 exp_lvl_adj (object *who, object *op)
423 {
424  if (who == NULL) {
425  return 0;
426  }
427 
428  if (op == NULL) {
429  op = who;
430  }
431 
432  if (op->type == SKILL && op->level == 0) {
433  return 0;
434  }
435 
436  if (op->level < MAXLEVEL && op->stats.exp >= (int64_t) level_exp(op->level + 1, 1.0)) {
437  op->level++;
438 
439  if (op->level > 1 && op->type == SKILL) {
440  draw_info_format(COLOR_RED, who, "You are now level %d in the skill %s.", op->level, op->name);
441  } else {
442  draw_info_format(COLOR_RED, who, "You are now level %d.", op->level);
443  }
444 
445  /* To increase more levels. */
446  return exp_lvl_adj(who, op) + 1;
447  } else if (op->level > 1 && op->stats.exp < (int64_t) level_exp(op->level, 1.0)) {
448  op->level--;
449 
450  if (op->type == SKILL) {
451  draw_info_format(COLOR_RED, who, "-You are now level %d in the skill %s.", op->level, op->name);
452  } else {
453  draw_info_format(COLOR_RED, who, "-You are now level %d.", op->level);
454  }
455 
456  /* To decrease more levels. */
457  return exp_lvl_adj(who, op) + 1;
458  }
459 
460  return 0;
461 }
462 
489 float
490 calc_level_difference (int who_lvl, int op_lvl)
491 {
492  int r;
493  float v, tmp = 1.0f;
494 
495  /* Sanity checks */
496  if (who_lvl < 0 || who_lvl > 200 || op_lvl < 0 || op_lvl > 200) {
497  return 0.0f;
498  }
499 
500  /* Grey, no experience */
501  if (op_lvl < level_color[who_lvl].green) {
502  return 0.0f;
503  }
504 
505  /* Yellow, blue or green */
506  if (who_lvl > op_lvl) {
507  if (op_lvl >= level_color[who_lvl].yellow) {
508  r = who_lvl - level_color[who_lvl].yellow;
509 
510  if (r < 1) {
511  r = 1;
512  }
513 
514  v = 0.2f / (float) r;
515  tmp = 1.0f - (v * (float) (who_lvl - op_lvl));
516  } else if (op_lvl >= level_color[who_lvl].blue) {
517  r = level_color[who_lvl].yellow - level_color[who_lvl].blue;
518 
519  if (r < 1) {
520  r = 1;
521  }
522 
523  v = 0.3f / (float) r;
524  tmp = 0.4f + (v * (float) (op_lvl - level_color[who_lvl].blue + 1));
525  } else {
526  /* Green */
527 
528  r = level_color[who_lvl].blue - level_color[who_lvl].green;
529 
530  if (r < 1) {
531  r = 1;
532  }
533 
534  v = 0.05f / (float) r;
535  tmp = 0.25f + (v * (float) (op_lvl - level_color[who_lvl].green + 1));
536  }
537  } else if (who_lvl < op_lvl) {
538  /* Yellow, orange, red, purple */
539 
540  /* Still yellow */
541  if (op_lvl < level_color[who_lvl].orange) {
542  r = level_color[who_lvl].orange - who_lvl - 1;
543 
544  if (r < 1) {
545  r = 1;
546  }
547 
548  v = 0.1f / (float) r;
549  tmp = 1.0f + (v * (float) (op_lvl - who_lvl));
550 
551  } else if (op_lvl < level_color[who_lvl].red) {
552  /* Orange */
553 
554  r = level_color[who_lvl].red - who_lvl - 1;
555 
556  if (r < 1) {
557  r = 1;
558  }
559 
560  v = 0.2f / (float) r;
561  tmp = 1.2f + (v * (float) (op_lvl - who_lvl));
562  } else {
563  /* Red or purple */
564 
565  r = (op_lvl + 1) - level_color[who_lvl].red;
566  v = 0.1f * (float) r;
567  tmp = 1.4f + v;
568  }
569  }
570 
571  return tmp;
572 }
int64_t add_exp(object *op, int64_t exp_gain, int skill_nr, int exact)
Definition: exp.c:304
static const char *const stats[]
Definition: stats.c:38
int blue
Definition: exp.h:43
int yellow
Definition: exp.h:46
int64_t exp
Definition: living.h:69
#define PLAYER
Definition: define.h:122
#define QUERY_FLAG(xyz, p)
Definition: define.h:761
uint64_t new_levels[MAXLEVEL+2]
Definition: exp.c:38
#define FLAG_STAND_STILL
Definition: define.h:1133
int16_t y
Definition: object.h:276
archetype_t * arches[ARCH_MAX]
Definition: arch.c:45
int exp_lvl_adj(object *who, object *op)
Definition: exp.c:422
struct mapdef * map
Definition: object.h:139
void play_sound_player_only(player *pl, int type, const char *filename, int x, int y, int loop, int volume)
Definition: sounds.c:66
uint64_t level_exp(int level, double expmul)
Definition: exp.c:284
const char * name
Definition: object.h:168
object * arch_to_object(archetype_t *at)
Definition: arch.c:446
#define INS_NO_WALK_ON
Definition: object.h:570
int orange
Definition: exp.h:49
int red
Definition: exp.h:52
void link_player_skills(object *pl)
Definition: skill_util.c:287
int16_t x
Definition: object.h:273
object * object_insert_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1741
#define MAXLEVEL
Definition: global.h:221
#define CHOSEN_SKILL_NO
Definition: define.h:78
int green
Definition: exp.h:40
#define INS_NO_MERGE
Definition: object.h:564
living stats
Definition: object.h:481
void esrv_update_item(int flags, object *op)
Definition: item.c:639
#define SKILL
Definition: define.h:246
uint8_t type
Definition: object.h:360
int living_update(object *op)
Definition: living.c:1661
#define MAX_EXPERIENCE
Definition: global.h:224
float calc_level_difference(int who_lvl, int op_lvl)
Definition: exp.c:490
skill_struct skills[NROFSKILLS]
Definition: skillist.h:62
int8_t level
Definition: object.h:347
The 'level_up' archetype.
Definition: arch.h:58