1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
|
|
4 | * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2001 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 2001 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * |
8 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * Deliantra is free software: you can redistribute it and/or modify it under |
… | |
… | |
305 | * Returns 0 if it was not able to work for some reason. |
306 | * Returns 0 if it was not able to work for some reason. |
306 | * |
307 | * |
307 | * Checks if weapon was prepared, if enough potions on the floor, ... |
308 | * Checks if weapon was prepared, if enough potions on the floor, ... |
308 | * |
309 | * |
309 | * We are hiding extra information about the weapon in the level and |
310 | * We are hiding extra information about the weapon in the level and |
310 | * last_eat numbers for an object. Hopefully this won't break anything ?? |
311 | * last_eat numbers for an object. Hopefully this won't break anything ?? |
311 | * level == max improve last_eat == current improve |
312 | * level == max improve last_eat == current improve |
312 | */ |
313 | */ |
313 | static int |
314 | static int |
314 | improve_weapon (object *op, object *improver, object *weapon) |
315 | improve_weapon (object *op, object *improver, object *weapon) |
315 | { |
316 | { |
… | |
… | |
340 | "powerful for you to use. Unready it if you " |
341 | "powerful for you to use. Unready it if you " |
341 | "really want to improve it."); |
342 | "really want to improve it."); |
342 | return 0; |
343 | return 0; |
343 | } |
344 | } |
344 | |
345 | |
345 | /* This just increases damage by 5 points, no matter what. No sacrifice |
346 | /* This just increases damage by 5 points, no matter what. No sacrifice |
346 | * is needed. Since stats.dam is now a 16 bit value and not 8 bit, |
347 | * is needed. Since stats.dam is now a 16 bit value and not 8 bit, |
347 | * don't put any maximum value on damage - the limit is how much the |
348 | * don't put any maximum value on damage - the limit is how much the |
348 | * weapon can be improved. |
349 | * weapon can be improved. |
349 | */ |
350 | */ |
350 | if (improver->stats.sp == IMPROVE_DAMAGE) |
351 | if (improver->stats.sp == IMPROVE_DAMAGE) |
351 | { |
352 | { |
352 | weapon->stats.dam += 5; |
353 | weapon->stats.dam += 5; |
353 | weapon->weight += 5000; /* 5 KG's */ |
354 | weapon->weight += 5000; /* 5 KG's */ |
… | |
… | |
476 | * the stats of a player w/ armour as well as a weapon |
477 | * the stats of a player w/ armour as well as a weapon |
477 | * will probably horribly unbalance the game. Magic enchanting |
478 | * will probably horribly unbalance the game. Magic enchanting |
478 | * depends on the level of the character - ie the plus |
479 | * depends on the level of the character - ie the plus |
479 | * value (magic) of the armour can never be increased beyond |
480 | * value (magic) of the armour can never be increased beyond |
480 | * the level of the character / 10 -- rounding upish, nor may |
481 | * the level of the character / 10 -- rounding upish, nor may |
481 | * the armour value of the piece of equipment exceed either |
482 | * the armour value of the piece of equipment exceed either |
482 | * the users level or 90) |
483 | * the users level or 90) |
483 | * Modified by MSW for partial resistance. Only support |
484 | * Modified by MSW for partial resistance. Only support |
484 | * changing of physical area right now. |
485 | * changing of physical area right now. |
485 | */ |
486 | */ |
486 | static int |
487 | static int |
… | |
… | |
667 | item->nrof *= nr; |
668 | item->nrof *= nr; |
668 | |
669 | |
669 | if (converter->flag [FLAG_PRECIOUS]) |
670 | if (converter->flag [FLAG_PRECIOUS]) |
670 | item->set_flag (FLAG_UNPAID); |
671 | item->set_flag (FLAG_UNPAID); |
671 | |
672 | |
672 | if (converter->is_in_shop ()) |
673 | if (converter->is_in_shop ()) |
673 | { |
674 | { |
674 | // converters on shop floors don't work anymore, bug lets check for it |
675 | // converters on shop floors don't work anymore, bug lets check for it |
675 | // and report in case someone still does it. |
676 | // and report in case someone still does it. |
676 | LOG (llevDebug, "ITEMBUG: broken converter, converters on shop floor don't work: %s\n", |
677 | LOG (llevDebug, "ITEMBUG: broken converter, converters on shop floor don't work: %s\n", |
677 | converter->debug_desc ()); |
678 | converter->debug_desc ()); |
… | |
… | |
680 | else if (price_in < sint64 (item->nrof) * item->value) |
681 | else if (price_in < sint64 (item->nrof) * item->value) |
681 | { |
682 | { |
682 | LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n", |
683 | LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n", |
683 | &converter->name, &converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name); |
684 | &converter->name, &converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name); |
684 | /** |
685 | /** |
685 | * elmex: we are going to let the game continue, as the mapcreator |
686 | * elmex: we are going to let the game continue, as the mapcreator |
686 | * hopefully had something in mind when doing this. |
687 | * hopefully had something in mind when doing this. |
687 | */ |
688 | */ |
688 | } |
689 | } |
689 | |
690 | |
690 | // elmex: only identify if we need to, for example so that generated money doesn't |
691 | // elmex: only identify if we need to, for example so that generated money doesn't |
… | |
… | |
696 | |
697 | |
697 | return 1; |
698 | return 1; |
698 | } |
699 | } |
699 | |
700 | |
700 | /** |
701 | /** |
701 | * Handle apply on containers. |
702 | * Handle apply on containers. |
702 | * By Eneq(@csd.uu.se). |
703 | * By Eneq(@csd.uu.se). |
703 | * Moved to own function and added many features [Tero.Haatanen@lut.fi] |
704 | * Moved to own function and added many features [Tero.Haatanen@lut.fi] |
704 | * added the alchemical cauldron to the code -b.t. |
705 | * added the alchemical cauldron to the code -b.t. |
705 | */ |
706 | */ |
706 | static int |
707 | static int |
… | |
… | |
868 | { |
869 | { |
869 | /* Somebody dropped an unpaid item, just move to an adjacent place. */ |
870 | /* Somebody dropped an unpaid item, just move to an adjacent place. */ |
870 | int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); |
871 | int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); |
871 | |
872 | |
872 | if (i != -1) |
873 | if (i != -1) |
873 | rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat); |
874 | rv = transfer_ob (op, op->x + DIRX (i), op->y + DIRY (i), 0, shop_mat); |
874 | |
875 | |
875 | return 0; |
876 | return 0; |
876 | } |
877 | } |
877 | |
878 | |
878 | /* Removed code that checked for multipart objects - it appears that |
879 | /* Removed code that checked for multipart objects - it appears that |
… | |
… | |
921 | if (i == -1) |
922 | if (i == -1) |
922 | LOG (llevError, "Internal shop-mat problem.\n"); |
923 | LOG (llevError, "Internal shop-mat problem.\n"); |
923 | else |
924 | else |
924 | { |
925 | { |
925 | op->remove (); |
926 | op->remove (); |
926 | op->x += freearr_x[i]; |
927 | op->x += DIRX (i); |
927 | op->y += freearr_y[i]; |
928 | op->y += DIRY (i); |
928 | rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL; |
929 | rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL; |
929 | } |
930 | } |
930 | } |
931 | } |
931 | |
932 | |
932 | op->clr_flag (FLAG_NO_APPLY); |
933 | op->clr_flag (FLAG_NO_APPLY); |
… | |
… | |
972 | } |
973 | } |
973 | |
974 | |
974 | /* Sign or magic mouth? Do we need to see it, or does it talk to us? |
975 | /* Sign or magic mouth? Do we need to see it, or does it talk to us? |
975 | * No way to know for sure. The presumption is basically that if |
976 | * No way to know for sure. The presumption is basically that if |
976 | * move_on is zero, it needs to be manually applied (doesn't talk |
977 | * move_on is zero, it needs to be manually applied (doesn't talk |
977 | * to us). |
978 | * to us). |
978 | */ |
979 | */ |
979 | if (op->flag [FLAG_BLIND] && !op->flag [FLAG_WIZ] && !sign->move_on) |
980 | if (op->flag [FLAG_BLIND] && !op->flag [FLAG_WIZ] && !sign->move_on) |
980 | { |
981 | { |
981 | op->failmsg ("You are unable to read while blind!"); |
982 | op->failmsg ("You are unable to read while blind!"); |
982 | return; |
983 | return; |
… | |
… | |
1019 | |
1020 | |
1020 | victim->play_sound (trap->sound ? trap->sound : sound_find ("fall_hole")); |
1021 | victim->play_sound (trap->sound ? trap->sound : sound_find ("fall_hole")); |
1021 | victim->statusmsg ("You fall through the hole!", NDI_RED); |
1022 | victim->statusmsg ("You fall through the hole!", NDI_RED); |
1022 | |
1023 | |
1023 | transfer_ob (victim, |
1024 | transfer_ob (victim, |
1024 | EXIT_X (trap) + freearr_x[dir], |
1025 | EXIT_X (trap) + DIRX (dir), |
1025 | EXIT_Y (trap) + freearr_y[dir], |
1026 | EXIT_Y (trap) + DIRY (dir), |
1026 | 0, victim); |
1027 | 0, victim); |
1027 | } |
1028 | } |
1028 | |
1029 | |
1029 | /** |
1030 | /** |
1030 | * Unapplies specified item. |
1031 | * Unapplies specified item. |
… | |
… | |
1286 | |
1287 | |
1287 | /* if we have an applied weapon/shield, and unapply it would free |
1288 | /* if we have an applied weapon/shield, and unapply it would free |
1288 | * enough slots to equip the new item, then just set "can |
1289 | * enough slots to equip the new item, then just set "can |
1289 | * apply unapply". We don't care about the logic below - if you have a |
1290 | * apply unapply". We don't care about the logic below - if you have a |
1290 | * shield equipped and try to equip another shield, there is only |
1291 | * shield equipped and try to equip another shield, there is only |
1291 | * one choice. However, the check for the number of body locations |
1292 | * one choice. However, the check for the number of body locations |
1292 | * does take into the account cases where what is being applied |
1293 | * does take into the account cases where what is being applied |
1293 | * may be two handed for example. |
1294 | * may be two handed for example. |
1294 | */ |
1295 | */ |
1295 | if (ws) |
1296 | if (ws) |
1296 | if ((who->slot[i].used - ws->slot[i].info + op->slot[i].info) >= 0) |
1297 | if ((who->slot[i].used - ws->slot[i].info + op->slot[i].info) >= 0) |
… | |
… | |
1315 | else if (tmp != tmp1) |
1316 | else if (tmp != tmp1) |
1316 | retval |= CAN_APPLY_UNAPPLY_MULT; |
1317 | retval |= CAN_APPLY_UNAPPLY_MULT; |
1317 | |
1318 | |
1318 | /* This object isn't using up all the slots, so there must |
1319 | /* This object isn't using up all the slots, so there must |
1319 | * be another. If so, and it the new item doesn't need all |
1320 | * be another. If so, and it the new item doesn't need all |
1320 | * the slots, the player then has a choice. |
1321 | * the slots, the player then has a choice. |
1321 | */ |
1322 | */ |
1322 | if ((who->slot[i].used - tmp1->slot[i].info != who->slot[i].info) |
1323 | if ((who->slot[i].used - tmp1->slot[i].info != who->slot[i].info) |
1323 | && abs (op->slot[i].info) < who->slot[i].info) |
1324 | && abs (op->slot[i].info) < who->slot[i].info) |
1324 | retval |= CAN_APPLY_UNAPPLY_CHOICE; |
1325 | retval |= CAN_APPLY_UNAPPLY_CHOICE; |
1325 | |
1326 | |
… | |
… | |
1472 | return 1; |
1473 | return 1; |
1473 | } |
1474 | } |
1474 | |
1475 | |
1475 | /* Ok. We are now at the state where we can apply the new object. |
1476 | /* Ok. We are now at the state where we can apply the new object. |
1476 | * Note that we don't have the checks for can_use_... |
1477 | * Note that we don't have the checks for can_use_... |
1477 | * below - that is already taken care of by can_apply_object. |
1478 | * below - that is already taken care of by can_apply_object. |
1478 | */ |
1479 | */ |
1479 | |
1480 | |
1480 | // split away all the other items from the stack, so only one item is left |
1481 | // split away all the other items from the stack, so only one item is left |
1481 | tmp = op->nrof > 1 ? op->split (op->nrof - 1) : 0; |
1482 | tmp = op->nrof > 1 ? op->split (op->nrof - 1) : 0; |
1482 | |
1483 | |
… | |
… | |
1670 | arch_flag = 1; |
1671 | arch_flag = 1; |
1671 | name_flag = 1; |
1672 | name_flag = 1; |
1672 | race_flag = 1; |
1673 | race_flag = 1; |
1673 | } |
1674 | } |
1674 | |
1675 | |
1675 | /* If the director has race set, only affect objects with a arch, |
1676 | /* If the director has race set, only affect objects with a arch, |
1676 | * name or race that matches. |
1677 | * name or race that matches. |
1677 | */ |
1678 | */ |
1678 | if ((op->race) && |
1679 | if ((op->race) && |
1679 | ((!(victim->arch && arch_flag && victim->arch->archname) || op->race != victim->arch->archname)) && |
1680 | ((!(victim->arch && arch_flag && victim->arch->archname) || op->race != victim->arch->archname)) && |
1680 | ((!(victim->name && name_flag) || op->race != victim->name)) && |
1681 | ((!(victim->name && name_flag) || op->race != victim->name)) && |
… | |
… | |
2016 | /* Only exits affect DMs. */ |
2017 | /* Only exits affect DMs. */ |
2017 | if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN) |
2018 | if (victim->flag [FLAG_WIZPASS] && trap->type != EXIT && trap->type != SIGN) |
2018 | return; |
2019 | return; |
2019 | |
2020 | |
2020 | /* move_apply() is the most likely candidate for causing unwanted and |
2021 | /* move_apply() is the most likely candidate for causing unwanted and |
2021 | * possibly unlimited recursion. |
2022 | * possibly unlimited recursion. |
2022 | */ |
2023 | */ |
2023 | |
2024 | |
2024 | /* The following was changed because it was causing perfectly correct |
2025 | /* The following was changed because it was causing perfectly correct |
2025 | * maps to fail. 1) it's not an error to recurse: |
2026 | * maps to fail. 1) it's not an error to recurse: |
2026 | * rune detonates, summoning monster. monster lands on nearby rune. |
2027 | * rune detonates, summoning monster. monster lands on nearby rune. |
2027 | * nearby rune detonates. This sort of recursion is expected and |
2028 | * nearby rune detonates. This sort of recursion is expected and |
2028 | * proper. This code was causing needless crashes. |
2029 | * proper. This code was causing needless crashes. |
2029 | */ |
2030 | */ |
2030 | if (recursion_depth >= 500) |
2031 | if (recursion_depth >= 500) |
2031 | { |
2032 | { |
2032 | LOG (llevDebug, "WARNING: move_apply(): aborting recursion " |
2033 | LOG (llevDebug, "WARNING: move_apply(): aborting recursion " |
2033 | "[trap arch %s, name %s; victim arch %s, name %s]\n", &trap->arch->archname, &trap->name, &victim->arch->archname, &victim->name); |
2034 | "[trap arch %s, name %s; victim arch %s, name %s]\n", &trap->arch->archname, &trap->name, &victim->arch->archname, &victim->name); |
… | |
… | |
2128 | } |
2129 | } |
2129 | |
2130 | |
2130 | for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab; ab = ab_next) |
2131 | for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab; ab = ab_next) |
2131 | { |
2132 | { |
2132 | /* need to set this up, since if we do transfer the object, |
2133 | /* need to set this up, since if we do transfer the object, |
2133 | * ab->above would be bogus |
2134 | * ab->above would be bogus |
2134 | */ |
2135 | */ |
2135 | ab_next = ab->above; |
2136 | ab_next = ab->above; |
2136 | |
2137 | |
2137 | if ((ab->move_type && trap->move_on) || ab->move_type == 0) |
2138 | if ((ab->move_type && trap->move_on) || ab->move_type == 0) |
2138 | { |
2139 | { |
… | |
… | |
2541 | * |
2542 | * |
2542 | * 2- The learner's skill level in literacy adjusts the chance to learn |
2543 | * 2- The learner's skill level in literacy adjusts the chance to learn |
2543 | * a spell. |
2544 | * a spell. |
2544 | * |
2545 | * |
2545 | * 3 -Automatically fail to learn if you read while confused |
2546 | * 3 -Automatically fail to learn if you read while confused |
2546 | * |
2547 | * |
2547 | * Overall, chances are the same but a player will find having a high |
2548 | * Overall, chances are the same but a player will find having a high |
2548 | * literacy rate very useful! -b.t. |
2549 | * literacy rate very useful! -b.t. |
2549 | */ |
2550 | */ |
2550 | if (op->flag [FLAG_CONFUSED]) |
2551 | if (op->flag [FLAG_CONFUSED]) |
2551 | { |
2552 | { |
2552 | op->failmsg ("In your confused state you flub the wording of the text!"); |
2553 | op->failmsg ("In your confused state you flub the wording of the text!"); |
2553 | scroll_failure (op, 0 - random_roll (0, spell->level, op, PREFER_LOW), max (spell->stats.sp, spell->stats.grace)); |
2554 | scroll_failure (op, 0 - random_roll (0, spell->level, op, PREFER_LOW), max (spell->stats.sp, spell->stats.grace)); |
… | |
… | |
3821 | else if (invtmp->arch |
3822 | else if (invtmp->arch |
3822 | && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS |
3823 | && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS |
3823 | && invtmp->has_random_items ()) |
3824 | && invtmp->has_random_items ()) |
3824 | { |
3825 | { |
3825 | create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); |
3826 | create_treasure (invtmp->randomitems, invtmp, 0, difficulty, 0); |
3826 | /* Need to clear this so that we never try to create |
3827 | /* Need to clear this so that we never try to create |
3827 | * treasure again for this object |
3828 | * treasure again for this object |
3828 | */ |
3829 | */ |
3829 | invtmp->randomitems = NULL; |
3830 | invtmp->randomitems = NULL; |
3830 | } |
3831 | } |
3831 | } |
3832 | } |