1 | /* |
1 | /* |
2 | * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team |
4 | * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Crossfire TRT is free software: you can redistribute it and/or modify |
8 | * Deliantra is free software: you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation, either version 3 of the License, or |
10 | * the Free Software Foundation, either version 3 of the License, or |
11 | * (at your option) any later version. |
11 | * (at your option) any later version. |
12 | * |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
13 | * This program is distributed in the hope that it will be useful, |
… | |
… | |
16 | * GNU General Public License for more details. |
16 | * GNU General Public License for more details. |
17 | * |
17 | * |
18 | * You should have received a copy of the GNU General Public License |
18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | * |
20 | * |
21 | * The authors can be reached via e-mail to <crossfire@schmorp.de> |
21 | * The authors can be reached via e-mail to <support@deliantra.net> |
22 | */ |
22 | */ |
23 | |
23 | |
24 | #include <cmath> |
24 | #include <cmath> |
25 | |
25 | |
26 | #include <global.h> |
26 | #include <global.h> |
… | |
… | |
113 | { |
113 | { |
114 | if (operate_altar (altar, &money)) |
114 | if (operate_altar (altar, &money)) |
115 | { |
115 | { |
116 | identify (marked); |
116 | identify (marked); |
117 | |
117 | |
118 | buf.printf ("You have %s.", long_desc (marked, pl)); |
118 | buf.printf ("You have %s.\n\n", long_desc (marked, pl)); |
119 | if (marked->msg) |
119 | if (marked->msg) |
120 | buf << "The item has a story:\n" << marked->msg; |
120 | buf << "The item has a story:\n\n" << marked->msg << "\n\n"; |
121 | |
121 | |
122 | return !money; |
122 | return !money; |
123 | } |
123 | } |
124 | } |
124 | } |
125 | |
125 | |
… | |
… | |
129 | { |
129 | { |
130 | if (operate_altar (altar, &money)) |
130 | if (operate_altar (altar, &money)) |
131 | { |
131 | { |
132 | identify (id); |
132 | identify (id); |
133 | |
133 | |
134 | buf.printf ("You have %s.", long_desc (id, pl)); |
134 | buf.printf ("You have %s.\n\n", long_desc (id, pl)); |
135 | if (id->msg) |
135 | if (id->msg) |
136 | buf << "The item has a story:\n" << id->msg; |
136 | buf << "The item has a story:\n\n" << id->msg << "\n\n"; |
137 | |
137 | |
138 | /* If no more money, might as well quit now */ |
138 | /* If no more money, might as well quit now */ |
139 | if (!money || !check_altar_sacrifice (altar, money)) |
139 | if (!money || !check_altar_sacrifice (altar, money)) |
140 | break; |
140 | break; |
141 | } |
141 | } |
… | |
… | |
146 | } |
146 | } |
147 | } |
147 | } |
148 | } |
148 | } |
149 | |
149 | |
150 | if (buf.empty ()) |
150 | if (buf.empty ()) |
151 | buf << ("You have nothing that needs identifying"); |
151 | pl->failmsg ("You have nothing that needs identifying"); |
152 | |
152 | else |
153 | pl->contr->infobox ("Identify", buf); |
153 | pl->contr->infobox (MSG_CHANNEL ("identify"), buf); |
154 | |
154 | |
155 | return !money; |
155 | return !money; |
156 | } |
156 | } |
157 | |
157 | |
158 | /** |
158 | /** |
… | |
… | |
217 | |
217 | |
218 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
218 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
219 | { |
219 | { |
220 | op->drain_stat (); |
220 | op->drain_stat (); |
221 | op->update_stats (); |
221 | op->update_stats (); |
222 | decrease_ob (tmp); |
222 | tmp->decrease (); |
223 | return 1; |
223 | return 1; |
224 | } |
224 | } |
225 | |
225 | |
226 | if (!(at = archetype::find (ARCH_DEPLETION))) |
226 | if (!(at = archetype::find (ARCH_DEPLETION))) |
227 | { |
227 | { |
… | |
… | |
240 | op->update_stats (); |
240 | op->update_stats (); |
241 | } |
241 | } |
242 | else |
242 | else |
243 | op->statusmsg ("Your potion had no effect."); |
243 | op->statusmsg ("Your potion had no effect."); |
244 | |
244 | |
245 | decrease_ob (tmp); |
245 | tmp->decrease (); |
246 | return 1; |
246 | return 1; |
247 | } |
247 | } |
248 | |
248 | |
249 | /* improvement potion - only for players */ |
249 | /* improvement potion - only for players */ |
250 | if (op->type == PLAYER && (tmp->attacktype & AT_GODPOWER)) |
250 | if (op->type == PLAYER && (tmp->attacktype & AT_GODPOWER)) |
… | |
… | |
318 | } |
318 | } |
319 | else |
319 | else |
320 | op->statusmsg ("You are fortunate that you are so pathetic.", NDI_DK_ORANGE); |
320 | op->statusmsg ("You are fortunate that you are so pathetic.", NDI_DK_ORANGE); |
321 | } |
321 | } |
322 | |
322 | |
323 | decrease_ob (tmp); |
323 | tmp->decrease (); |
324 | return 1; |
324 | return 1; |
325 | } |
325 | } |
326 | |
326 | |
327 | |
327 | |
328 | /* A potion that casts a spell. Healing, restore spellpoint (power potion) |
328 | /* A potion that casts a spell. Healing, restore spellpoint (power potion) |
… | |
… | |
347 | insert_ob_in_map (fball, op->map, NULL, 0); |
347 | insert_ob_in_map (fball, op->map, NULL, 0); |
348 | } |
348 | } |
349 | else |
349 | else |
350 | cast_spell (op, tmp, op->facing, tmp->inv, NULL); |
350 | cast_spell (op, tmp, op->facing, tmp->inv, NULL); |
351 | |
351 | |
352 | decrease_ob (tmp); |
352 | tmp->decrease (); |
353 | |
353 | |
354 | /* if youre dead, no point in doing this... */ |
354 | /* if youre dead, no point in doing this... */ |
355 | if (!QUERY_FLAG (op, FLAG_REMOVED)) |
355 | if (!QUERY_FLAG (op, FLAG_REMOVED)) |
356 | op->update_stats (); |
356 | op->update_stats (); |
357 | |
357 | |
… | |
… | |
388 | force->speed_left = -1; |
388 | force->speed_left = -1; |
389 | force = insert_ob_in_ob (force, op); |
389 | force = insert_ob_in_ob (force, op); |
390 | CLEAR_FLAG (tmp, FLAG_APPLIED); |
390 | CLEAR_FLAG (tmp, FLAG_APPLIED); |
391 | SET_FLAG (force, FLAG_APPLIED); |
391 | SET_FLAG (force, FLAG_APPLIED); |
392 | change_abil (op, force); |
392 | change_abil (op, force); |
393 | decrease_ob (tmp); |
393 | tmp->decrease (); |
394 | return 1; |
394 | return 1; |
395 | } |
395 | } |
396 | |
396 | |
397 | /* Only thing left are the stat potions */ |
397 | /* Only thing left are the stat potions */ |
398 | if (op->type == PLAYER) |
398 | if (op->type == PLAYER) |
… | |
… | |
411 | * stat will not be raised by them. fix_player just clears |
411 | * stat will not be raised by them. fix_player just clears |
412 | * up all the stats. |
412 | * up all the stats. |
413 | */ |
413 | */ |
414 | CLEAR_FLAG (tmp, FLAG_APPLIED); |
414 | CLEAR_FLAG (tmp, FLAG_APPLIED); |
415 | op->update_stats (); |
415 | op->update_stats (); |
416 | decrease_ob (tmp); |
416 | op->decrease (); |
417 | return 1; |
417 | return 1; |
418 | } |
418 | } |
419 | |
419 | |
420 | /**************************************************************************** |
420 | /**************************************************************************** |
421 | * Weapon improvement code follows |
421 | * Weapon improvement code follows |
… | |
… | |
468 | { |
468 | { |
469 | if (strcmp (op->arch->archname, item) == 0) |
469 | if (strcmp (op->arch->archname, item) == 0) |
470 | { |
470 | { |
471 | if (op->nrof >= nrof) |
471 | if (op->nrof >= nrof) |
472 | { |
472 | { |
473 | decrease_ob_nr (op, nrof); |
473 | op->decrease (nrof); |
474 | return; |
474 | return; |
475 | } |
475 | } |
476 | else |
476 | else |
477 | { |
477 | { |
478 | decrease_ob_nr (op, op->nrof); |
478 | op->decrease (nrof); |
479 | nrof -= op->nrof; |
479 | nrof -= op->nrof; |
480 | } |
480 | } |
481 | |
481 | |
482 | op = prev; |
482 | op = prev; |
483 | } |
483 | } |
… | |
… | |
568 | static int |
568 | static int |
569 | improve_weapon_stat (object *op, object *improver, object *weapon, sint8 &stat, int sacrifice_count, const char *statname) |
569 | improve_weapon_stat (object *op, object *improver, object *weapon, sint8 &stat, int sacrifice_count, const char *statname) |
570 | { |
570 | { |
571 | stat += sacrifice_count; |
571 | stat += sacrifice_count; |
572 | weapon->last_eat++; |
572 | weapon->last_eat++; |
573 | decrease_ob (improver); |
573 | improver->decrease (); |
574 | |
574 | |
575 | /* So it updates the players stats and the window */ |
575 | /* So it updates the players stats and the window */ |
576 | op->update_stats (); |
576 | op->update_stats (); |
577 | |
577 | |
578 | op->statusmsg (format ( |
578 | op->statusmsg (format ( |
… | |
… | |
623 | if (i < NROFATTACKS || weapon->stats.hp || /* regeneration */ |
623 | if (i < NROFATTACKS || weapon->stats.hp || /* regeneration */ |
624 | (weapon->stats.sp && weapon->type == WEAPON) || /* sp regeneration */ |
624 | (weapon->stats.sp && weapon->type == WEAPON) || /* sp regeneration */ |
625 | weapon->stats.exp || /* speed */ |
625 | weapon->stats.exp || /* speed */ |
626 | weapon->stats.ac) /* AC - only taifu's I think */ |
626 | weapon->stats.ac) /* AC - only taifu's I think */ |
627 | { |
627 | { |
628 | op->failmsg ("You cannot prepare magic weapons."); |
628 | op->failmsg ("You cannot prepare magic weapons. " |
|
|
629 | "H<A weapon is considered magical if it changes regeneration, " |
|
|
630 | "speed or ac.>"); |
629 | return 0; |
631 | return 0; |
630 | } |
632 | } |
631 | |
633 | |
632 | sacrifice_count = check_sacrifice (op, improver); |
634 | sacrifice_count = check_sacrifice (op, improver); |
633 | if (sacrifice_count <= 0) |
635 | if (sacrifice_count <= 0) |
… | |
… | |
644 | |
646 | |
645 | sprintf (buf, "%s's %s", &op->name, &weapon->name); |
647 | sprintf (buf, "%s's %s", &op->name, &weapon->name); |
646 | weapon->name = weapon->name_pl = buf; |
648 | weapon->name = weapon->name_pl = buf; |
647 | weapon->nrof = 0; /* prevents preparing n weapons in the same |
649 | weapon->nrof = 0; /* prevents preparing n weapons in the same |
648 | slot at once! */ |
650 | slot at once! */ |
649 | decrease_ob (improver); |
651 | improver->decrease (); |
650 | weapon->last_eat = 0; |
652 | weapon->last_eat = 0; |
651 | return 1; |
653 | return 1; |
652 | } |
654 | } |
653 | |
655 | |
654 | |
656 | |
… | |
… | |
702 | weapon->weight += 5000; /* 5 KG's */ |
704 | weapon->weight += 5000; /* 5 KG's */ |
703 | op->statusmsg (format ("Damage has been increased by 5 to %d.", weapon->stats.dam)); |
705 | op->statusmsg (format ("Damage has been increased by 5 to %d.", weapon->stats.dam)); |
704 | weapon->last_eat++; |
706 | weapon->last_eat++; |
705 | |
707 | |
706 | weapon->item_power++; |
708 | weapon->item_power++; |
707 | decrease_ob (improver); |
709 | improver->decrease (); |
708 | return 1; |
710 | return 1; |
709 | } |
711 | } |
710 | |
712 | |
711 | if (improver->stats.sp == IMPROVE_WEIGHT) |
713 | if (improver->stats.sp == IMPROVE_WEIGHT) |
712 | { |
714 | { |
… | |
… | |
716 | weapon->weight = 1; |
718 | weapon->weight = 1; |
717 | |
719 | |
718 | op->statusmsg (format ("Weapon weight reduced to %6.1fkg.", (float) weapon->weight / 1000.0)); |
720 | op->statusmsg (format ("Weapon weight reduced to %6.1fkg.", (float) weapon->weight / 1000.0)); |
719 | weapon->last_eat++; |
721 | weapon->last_eat++; |
720 | weapon->item_power++; |
722 | weapon->item_power++; |
721 | decrease_ob (improver); |
723 | improver->decrease (); |
722 | return 1; |
724 | return 1; |
723 | } |
725 | } |
724 | if (improver->stats.sp == IMPROVE_ENCHANT) |
726 | if (improver->stats.sp == IMPROVE_ENCHANT) |
725 | { |
727 | { |
726 | weapon->magic++; |
728 | weapon->magic++; |
727 | weapon->last_eat++; |
729 | weapon->last_eat++; |
728 | op->statusmsg (format ("Weapon magic increased to %d.", weapon->magic)); |
730 | op->statusmsg (format ("Weapon magic increased to %d.", weapon->magic)); |
729 | decrease_ob (improver); |
731 | improver->decrease (); |
730 | weapon->item_power++; |
732 | weapon->item_power++; |
731 | return 1; |
733 | return 1; |
732 | } |
734 | } |
733 | |
735 | |
734 | sacrifice_needed = weapon->stats.Str + weapon->stats.Int + weapon->stats.Dex + |
736 | sacrifice_needed = weapon->stats.Str + weapon->stats.Int + weapon->stats.Dex + |
… | |
… | |
834 | if (armour->magic >= settings.armor_max_enchant) |
836 | if (armour->magic >= settings.armor_max_enchant) |
835 | { |
837 | { |
836 | op->failmsg ("This armour can not be enchanted any further!"); |
838 | op->failmsg ("This armour can not be enchanted any further!"); |
837 | return 0; |
839 | return 0; |
838 | } |
840 | } |
|
|
841 | |
839 | /* Dealing with random artifact armor is a lot trickier (in terms of value, weight, |
842 | /* Dealing with random artifact armor is a lot trickier (in terms of value, weight, |
840 | * etc), so take the easy way out and don't worry about it. |
843 | * etc), so take the easy way out and don't worry about it. |
841 | * Note - maybe add scrolls which make the random artifact versions (eg, armour |
844 | * Note - maybe add scrolls which make the random artifact versions (eg, armour |
842 | * of gnarg and what not?) |
845 | * of gnarg and what not?) |
843 | */ |
846 | */ |
… | |
… | |
845 | { |
848 | { |
846 | op->failmsg ("This armour will not accept further enchantment."); |
849 | op->failmsg ("This armour will not accept further enchantment."); |
847 | return 0; |
850 | return 0; |
848 | } |
851 | } |
849 | |
852 | |
850 | /* Split objects if needed. Can't insert tmp until the |
853 | /* Split objects if needed. Can't insert tmp until the |
851 | * end of this function - otherwise it will just re-merge. |
854 | * end of this function - otherwise it will just re-merge. |
852 | */ |
855 | */ |
853 | if (armour->nrof > 1) |
856 | if (armour->nrof > 1) |
854 | tmp = get_split_ob (armour, armour->nrof - 1); |
857 | tmp = get_split_ob (armour, armour->nrof - 1); |
855 | else |
858 | else |
… | |
… | |
902 | esrv_send_item (op, armour); |
905 | esrv_send_item (op, armour); |
903 | if (QUERY_FLAG (armour, FLAG_APPLIED)) |
906 | if (QUERY_FLAG (armour, FLAG_APPLIED)) |
904 | op->update_stats (); |
907 | op->update_stats (); |
905 | } |
908 | } |
906 | |
909 | |
907 | decrease_ob (improver); |
910 | improver->decrease (); |
908 | |
911 | |
909 | if (tmp) |
912 | if (tmp) |
910 | { |
913 | { |
911 | insert_ob_in_ob (tmp, op); |
914 | insert_ob_in_ob (tmp, op); |
912 | esrv_send_item (op, tmp); |
915 | esrv_send_item (op, tmp); |
… | |
… | |
916 | } |
919 | } |
917 | |
920 | |
918 | /* |
921 | /* |
919 | * convert_item() returns 1 if anything was converted, 0 if the item was not |
922 | * convert_item() returns 1 if anything was converted, 0 if the item was not |
920 | * what the converter wants, -1 if the converter is broken. |
923 | * what the converter wants, -1 if the converter is broken. |
921 | */ |
924 | * |
922 | #define CONV_FROM(xyz) xyz->slaying |
|
|
923 | #define CONV_TO(xyz) xyz->other_arch |
|
|
924 | #define CONV_NR(xyz) xyz->stats.sp |
|
|
925 | #define CONV_NEED(xyz) xyz->stats.food |
|
|
926 | |
|
|
927 | /* Takes one items and makes another. |
925 | * Takes one type of items and makes another. |
928 | * converter is the object that is doing the conversion. |
926 | * converter is the object that is doing the conversion. |
929 | * item is the object that triggered the converter - if it is not |
927 | * item is the object that triggered the converter - if it is not |
930 | * what the converter wants, this will not do anything. |
928 | * what the converter wants, this will not do anything. |
931 | */ |
929 | */ |
932 | int |
930 | static int |
933 | convert_item (object *item, object *converter) |
931 | convert_item (object *item, object *converter) |
934 | { |
932 | { |
935 | int nr = 0; |
|
|
936 | uint32 price_in; |
933 | sint64 nr, price_in; |
|
|
934 | |
|
|
935 | if (item->flag [FLAG_UNPAID]) |
|
|
936 | return 0; |
|
|
937 | |
|
|
938 | shstr conv_from = converter->slaying; |
|
|
939 | archetype *conv_to = converter->other_arch; |
|
|
940 | sint64 need = converter->stats.food; |
|
|
941 | sint64 give = converter->stats.sp; |
937 | |
942 | |
938 | /* We make some assumptions - we assume if it takes money as it type, |
943 | /* We make some assumptions - we assume if it takes money as it type, |
939 | * it wants some amount. We don't make change (ie, if something costs |
944 | * it wants some amount. We don't make change (ie, if something costs |
940 | * 3 gp and player drops a platinum, tough luck) |
945 | * 3 gp and player drops a platinum, tough luck) |
941 | */ |
946 | */ |
942 | if (CONV_FROM (converter) == shstr_money) |
947 | if (conv_from == shstr_money) |
943 | { |
948 | { |
944 | if (item->type != MONEY) |
949 | if (item->type != MONEY) |
945 | return 0; |
950 | return 0; |
946 | |
951 | |
947 | nr = (item->nrof * item->value) / CONV_NEED (converter); |
952 | nr = sint64 (item->nrof) * item->value / need; |
948 | if (!nr) |
953 | if (!nr) |
949 | return 0; |
954 | return 0; |
950 | |
955 | |
951 | converter->play_sound (sound_find ("shop_buy")); |
956 | converter->play_sound (sound_find ("shop_buy")); |
952 | |
957 | |
953 | int cost = nr * CONV_NEED (converter) / item->value; |
958 | sint64 cost = (nr * need + item->value - 1) / item->value; |
954 | /* take into account rounding errors */ |
|
|
955 | if (nr * CONV_NEED (converter) % item->value) |
|
|
956 | cost++; |
|
|
957 | |
959 | |
958 | decrease_ob_nr (item, cost); |
960 | item->decrease (cost); |
959 | |
961 | |
960 | price_in = cost * item->value; |
962 | price_in = cost * item->value; |
961 | } |
963 | } |
962 | else |
964 | else |
963 | { |
965 | { |
964 | if (item->type == PLAYER || CONV_FROM (converter) != item->arch->archname || |
966 | if (item->type == PLAYER |
965 | (CONV_NEED (converter) && CONV_NEED (converter) > (uint16) item->nrof)) |
967 | || conv_from != item->arch->archname |
|
|
968 | || (need && need > (uint16) item->nrof)) |
966 | return 0; |
969 | return 0; |
967 | |
970 | |
968 | converter->play_sound (sound_find ("convert_item")); |
971 | converter->play_sound (sound_find ("convert_item")); |
969 | |
972 | |
970 | if (CONV_NEED (converter)) |
973 | if (need) |
971 | { |
974 | { |
972 | nr = item->nrof / CONV_NEED (converter); |
975 | nr = sint64 (item->nrof) / need; |
973 | decrease_ob_nr (item, nr * CONV_NEED (converter)); |
976 | item->decrease (nr * need); |
974 | price_in = nr * CONV_NEED (converter) * item->value; |
977 | price_in = nr * need * item->value; |
975 | } |
978 | } |
976 | else |
979 | else |
977 | { |
980 | { |
978 | price_in = item->value; |
981 | price_in = item->value; |
979 | item->destroy (); |
982 | item->destroy (); |
… | |
… | |
996 | CLEAR_FLAG (item, FLAG_IS_A_TEMPLATE); |
999 | CLEAR_FLAG (item, FLAG_IS_A_TEMPLATE); |
997 | unflag_inv (item, FLAG_IS_A_TEMPLATE); |
1000 | unflag_inv (item, FLAG_IS_A_TEMPLATE); |
998 | } |
1001 | } |
999 | else |
1002 | else |
1000 | { |
1003 | { |
1001 | if (converter->other_arch == NULL) |
1004 | if (!conv_to) |
1002 | { |
1005 | { |
1003 | LOG (llevError, "move_creator: Converter doesn't have other arch set: %s (%s, %d, %d)\n", |
1006 | LOG (llevError, "move_creator: Converter doesn't have other arch set: %s (%s, %d, %d)\n", |
1004 | &converter->name, &converter->map->path, converter->x, converter->y); |
1007 | &converter->name, &converter->map->path, converter->x, converter->y); |
1005 | return -1; |
1008 | return -1; |
1006 | } |
1009 | } |
1007 | |
1010 | |
1008 | item = object_create_arch (converter->other_arch); |
1011 | item = object_create_arch (conv_to); |
1009 | fix_generated_item (item, converter, 0, 0, GT_MINIMAL); |
1012 | fix_generated_item (item, converter, 0, 0, GT_MINIMAL); |
1010 | } |
1013 | } |
1011 | |
1014 | |
1012 | if (CONV_NR (converter)) |
1015 | if (give) |
1013 | item->nrof = CONV_NR (converter); |
1016 | item->nrof = give; |
1014 | |
1017 | |
1015 | if (nr) |
1018 | if (nr) |
1016 | item->nrof *= nr; |
1019 | item->nrof *= nr; |
1017 | |
1020 | |
1018 | if (is_in_shop (converter)) |
1021 | if (is_in_shop (converter)) |
1019 | SET_FLAG (item, FLAG_UNPAID); |
1022 | SET_FLAG (item, FLAG_UNPAID); |
1020 | else if (price_in < item->nrof * item->value) |
1023 | else if (price_in < sint64 (item->nrof) * item->value) |
1021 | { |
1024 | { |
1022 | LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n", |
1025 | LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n", |
1023 | &converter->name, &converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name); |
1026 | &converter->name, &converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name); |
1024 | /** |
1027 | /** |
1025 | * elmex: we are going to let the game continue, as the mapcreator |
1028 | * elmex: we are going to let the game continue, as the mapcreator |
… | |
… | |
1310 | } |
1313 | } |
1311 | |
1314 | |
1312 | if (op->contr) |
1315 | if (op->contr) |
1313 | if (client *ns = op->contr->ns) |
1316 | if (client *ns = op->contr->ns) |
1314 | { |
1317 | { |
|
|
1318 | if (sign->sound) |
1315 | ns->play_sound (sign->sound); |
1319 | ns->play_sound (sign->sound); |
1316 | msgType = get_readable_message_type (sign); |
1320 | else if (autoapply) |
|
|
1321 | ns->play_sound (sound_find ("msg_voice")); |
1317 | |
1322 | |
1318 | if (ns->can_msg) |
1323 | if (ns->can_msg) |
1319 | ns->send_msg (NDI_NAVY, msgType->msgtype, &sign->msg); |
1324 | op->contr->infobox (MSG_CHANNEL ("examine"), format ("T<%s>\n\n\n\n%s", &sign->name, &sign->msg)); |
1320 | else |
1325 | else |
1321 | { |
1326 | { |
1322 | char newbuf[HUGE_BUF]; |
1327 | msgType = get_readable_message_type (sign); |
1323 | snprintf (newbuf, sizeof (newbuf), "%u %s", autoapply ? 1 : 0, &sign->msg); |
1328 | const char *somemsg = format ("%u %s", autoapply ? 1 : 0, &sign->msg); |
1324 | draw_ext_info (NDI_UNIQUE | NDI_NAVY, 0, op, msgType->message_type, msgType->message_subtype, newbuf, &sign->msg); |
1329 | draw_ext_info (NDI_UNIQUE | NDI_NAVY, 0, op, msgType->message_type, msgType->message_subtype, somemsg, &sign->msg); |
1325 | } |
1330 | } |
1326 | } |
1331 | } |
1327 | } |
1332 | } |
1328 | |
1333 | |
1329 | /** |
1334 | /** |
… | |
… | |
1443 | |
1448 | |
1444 | if (!trap->value) |
1449 | if (!trap->value) |
1445 | { |
1450 | { |
1446 | int tot; |
1451 | int tot; |
1447 | |
1452 | |
1448 | for (ab = trap->above, tot = 0; ab != NULL; ab = ab->above) |
1453 | for (ab = trap->above, tot = 0; ab; ab = ab->above) |
1449 | if ((ab->move_type && trap->move_on) || ab->move_type == 0) |
1454 | if ((ab->move_type && trap->move_on) || ab->move_type == 0) |
1450 | tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying; |
1455 | tot += ab->head_ ()->total_weight (); |
1451 | |
1456 | |
1452 | if (!(trap->value = (tot > trap->weight) ? 1 : 0)) |
1457 | if (!(trap->value = (tot > trap->weight) ? 1 : 0)) |
1453 | goto leave; |
1458 | goto leave; |
1454 | |
1459 | |
1455 | SET_ANIMATION (trap, trap->value); |
1460 | SET_ANIMATION (trap, trap->value); |
… | |
… | |
1524 | * players output. |
1529 | * players output. |
1525 | */ |
1530 | */ |
1526 | if (trap->msg && strncmp (EXIT_PATH (trap), "/!", 2)) |
1531 | if (trap->msg && strncmp (EXIT_PATH (trap), "/!", 2)) |
1527 | victim->statusmsg (trap->msg, NDI_NAVY); |
1532 | victim->statusmsg (trap->msg, NDI_NAVY); |
1528 | |
1533 | |
|
|
1534 | trap->play_sound (trap->sound); |
1529 | victim->enter_exit (trap); |
1535 | victim->enter_exit (trap); |
1530 | } |
1536 | } |
1531 | goto leave; |
1537 | goto leave; |
1532 | |
1538 | |
1533 | case ENCOUNTER: |
1539 | case ENCOUNTER: |
… | |
… | |
1600 | } |
1606 | } |
1601 | |
1607 | |
1602 | lev_diff = tmp->level - (skill_ob->level + 5); |
1608 | lev_diff = tmp->level - (skill_ob->level + 5); |
1603 | if (!QUERY_FLAG (op, FLAG_WIZ) && lev_diff > 0) |
1609 | if (!QUERY_FLAG (op, FLAG_WIZ) && lev_diff > 0) |
1604 | { |
1610 | { |
1605 | op->failmsg (lev_diff < 2 ? "This book is just barely beyond your comprehension." |
1611 | op->failmsg (lev_diff < 2 ? "This book is just barely beyond your comprehension." |
1606 | : lev_diff < 3 ? "This book is slightly beyond your comprehension." |
1612 | : lev_diff < 3 ? "This book is slightly beyond your comprehension." |
1607 | : lev_diff < 5 ? "This book is beyond your comprehension." |
1613 | : lev_diff < 5 ? "This book is beyond your comprehension." |
1608 | : lev_diff < 8 ? "This book is quite a bit beyond your comprehension." |
1614 | : lev_diff < 8 ? "This book is quite a bit beyond your comprehension." |
1609 | : lev_diff < 15 ? "This book is way beyond your comprehension." |
1615 | : lev_diff < 15 ? "This book is way beyond your comprehension." |
1610 | : "This book is totally beyond your comprehension."); |
1616 | : "This book is totally beyond your comprehension."); |
… | |
… | |
1614 | readable_message_type *msgType = get_readable_message_type (tmp); |
1620 | readable_message_type *msgType = get_readable_message_type (tmp); |
1615 | |
1621 | |
1616 | if (player *pl = op->contr) |
1622 | if (player *pl = op->contr) |
1617 | if (client *ns = pl->ns) |
1623 | if (client *ns = pl->ns) |
1618 | if (ns->can_msg) |
1624 | if (ns->can_msg) |
1619 | { |
1625 | pl->infobox (MSG_CHANNEL ("book"), format ("T<%s>\n\n\n\n%s", (char *)long_desc (tmp, op), &tmp->msg)); |
1620 | dynbuf_text buf; |
|
|
1621 | buf << long_desc (tmp, op) |
|
|
1622 | << "\n\n" |
|
|
1623 | << tmp->msg |
|
|
1624 | << '\0'; |
|
|
1625 | ns->send_msg (NDI_NAVY, msgType->msgtype, buf.linearise ()); |
|
|
1626 | } |
|
|
1627 | else |
1626 | else |
1628 | draw_ext_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, |
1627 | draw_ext_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, |
1629 | msgType->message_type, msgType->message_subtype, |
1628 | msgType->message_type, msgType->message_subtype, |
1630 | "You open the %s and start reading.\n%s", (char *)"%s\n%s", |
1629 | "You open the %s and start reading.\n%s", (char *)"%s\n%s", |
1631 | long_desc (tmp, op), &tmp->msg); |
1630 | long_desc (tmp, op), &tmp->msg); |
… | |
… | |
1665 | op->play_sound (sound_find ("generic_fail")); |
1664 | op->play_sound (sound_find ("generic_fail")); |
1666 | op->failmsg (format ("You already possess the knowledge held within the %s.", query_name (tmp))); |
1665 | op->failmsg (format ("You already possess the knowledge held within the %s.", query_name (tmp))); |
1667 | break; |
1666 | break; |
1668 | |
1667 | |
1669 | case 1: |
1668 | case 1: |
1670 | decrease_ob (tmp); |
1669 | tmp->decrease (); |
1671 | op->play_sound (sound_find ("skill_learn")); |
1670 | op->play_sound (sound_find ("skill_learn")); |
1672 | op->statusmsg (format ("You succeed in learning %s", &tmp->skill)); |
1671 | op->statusmsg (format ("You succeed in learning %s", &tmp->skill)); |
1673 | break; |
1672 | break; |
1674 | |
1673 | |
1675 | default: |
1674 | default: |
1676 | decrease_ob (tmp); |
1675 | tmp->decrease (); |
1677 | op->play_sound (sound_find ("generic_fail")); |
1676 | op->play_sound (sound_find ("generic_fail")); |
1678 | op->failmsg (format ("You fail to learn the knowledge of the %s.\n", query_name (tmp))); |
1677 | op->failmsg (format ("You fail to learn the knowledge of the %s.\n", query_name (tmp))); |
1679 | break; |
1678 | break; |
1680 | } |
1679 | } |
1681 | } |
1680 | } |
… | |
… | |
1872 | { |
1871 | { |
1873 | op->contr->play_sound (sound_find ("fumble_spell")); |
1872 | op->contr->play_sound (sound_find ("fumble_spell")); |
1874 | op->failmsg ("You fail to learn the spell. H<Wis (priests) or Int (wizards) governs the chance of learning a prayer or spell.>\n"); |
1873 | op->failmsg ("You fail to learn the spell. H<Wis (priests) or Int (wizards) governs the chance of learning a prayer or spell.>\n"); |
1875 | } |
1874 | } |
1876 | |
1875 | |
1877 | decrease_ob (tmp); |
1876 | tmp->decrease (); |
1878 | } |
1877 | } |
1879 | |
1878 | |
1880 | /** |
1879 | /** |
1881 | * Handles applying a spell scroll. |
1880 | * Handles applying a spell scroll. |
1882 | */ |
1881 | */ |
… | |
… | |
1921 | identify (tmp); |
1920 | identify (tmp); |
1922 | |
1921 | |
1923 | op->statusmsg (format ("The scroll of %s turns to dust.", &tmp->inv->name)); |
1922 | op->statusmsg (format ("The scroll of %s turns to dust.", &tmp->inv->name)); |
1924 | |
1923 | |
1925 | cast_spell (op, tmp, dir, tmp->inv, NULL); |
1924 | cast_spell (op, tmp, dir, tmp->inv, NULL); |
1926 | decrease_ob (tmp); |
1925 | tmp->decrease (); |
1927 | } |
1926 | } |
1928 | |
1927 | |
1929 | /** |
1928 | /** |
1930 | * Applies a treasure object - by default, chest. op |
1929 | * Applies a treasure object - by default, chest. op |
1931 | * is the person doing the applying, tmp is the treasure |
1930 | * is the person doing the applying, tmp is the treasure |
… | |
… | |
1943 | object *treas = tmp->inv; |
1942 | object *treas = tmp->inv; |
1944 | |
1943 | |
1945 | if (!treas) |
1944 | if (!treas) |
1946 | { |
1945 | { |
1947 | op->statusmsg ("The chest was empty."); |
1946 | op->statusmsg ("The chest was empty."); |
1948 | decrease_ob (tmp); |
1947 | tmp->decrease (); |
1949 | return; |
1948 | return; |
1950 | } |
1949 | } |
1951 | |
1950 | |
1952 | while (tmp->inv) |
1951 | while (tmp->inv) |
1953 | { |
1952 | { |
… | |
… | |
1969 | if (op->destroyed () || tmp->destroyed ()) |
1968 | if (op->destroyed () || tmp->destroyed ()) |
1970 | break; |
1969 | break; |
1971 | } |
1970 | } |
1972 | |
1971 | |
1973 | if (!tmp->destroyed () && !tmp->inv) |
1972 | if (!tmp->destroyed () && !tmp->inv) |
1974 | decrease_ob (tmp); |
1973 | tmp->decrease (); |
1975 | } |
1974 | } |
1976 | |
1975 | |
1977 | /** |
1976 | /** |
1978 | * op eats food. |
1977 | * op eats food. |
1979 | * If player, takes care of messages and dragon special food. |
1978 | * If player, takes care of messages and dragon special food. |
… | |
… | |
1998 | if (tmp->type == FOOD || tmp->type == FLESH) |
1997 | if (tmp->type == FOOD || tmp->type == FLESH) |
1999 | op->failmsg ("You feel full, but what a waste of food!"); |
1998 | op->failmsg ("You feel full, but what a waste of food!"); |
2000 | else |
1999 | else |
2001 | op->statusmsg ("Most of the drink goes down your face not your throat!"); |
2000 | op->statusmsg ("Most of the drink goes down your face not your throat!"); |
2002 | } |
2001 | } |
|
|
2002 | |
|
|
2003 | tmp->play_sound ( |
|
|
2004 | tmp->sound |
|
|
2005 | ? tmp->sound |
|
|
2006 | : tmp->type == DRINK |
|
|
2007 | ? sound_find ("eat_drink") |
|
|
2008 | : sound_find ("eat_food") |
|
|
2009 | ); |
2003 | |
2010 | |
2004 | if (!QUERY_FLAG (tmp, FLAG_CURSED)) |
2011 | if (!QUERY_FLAG (tmp, FLAG_CURSED)) |
2005 | { |
2012 | { |
2006 | const char *buf; |
2013 | const char *buf; |
2007 | |
2014 | |
… | |
… | |
2037 | eat_special_food (op, tmp); |
2044 | eat_special_food (op, tmp); |
2038 | } |
2045 | } |
2039 | } |
2046 | } |
2040 | |
2047 | |
2041 | handle_apply_yield (tmp); |
2048 | handle_apply_yield (tmp); |
2042 | decrease_ob (tmp); |
2049 | tmp->decrease (); |
2043 | } |
2050 | } |
2044 | |
2051 | |
2045 | /** |
2052 | /** |
2046 | * A dragon is eating some flesh. If the flesh contains resistances, |
2053 | * A dragon is eating some flesh. If the flesh contains resistances, |
2047 | * there is a chance for the dragon's skin to get improved. |
2054 | * there is a chance for the dragon's skin to get improved. |
… | |
… | |
2253 | hit_player (op, tmp->stats.hp, tmp, AT_POISON, 1); |
2260 | hit_player (op, tmp->stats.hp, tmp, AT_POISON, 1); |
2254 | } |
2261 | } |
2255 | |
2262 | |
2256 | op->stats.food -= op->stats.food / 4; |
2263 | op->stats.food -= op->stats.food / 4; |
2257 | handle_apply_yield (tmp); |
2264 | handle_apply_yield (tmp); |
2258 | decrease_ob (tmp); |
2265 | tmp->decrease (); |
2259 | } |
2266 | } |
2260 | |
2267 | |
2261 | /** |
2268 | /** |
2262 | * This function return true if the exit is not a 2 ways one or it is 2 ways, valid exit. |
2269 | * This function return true if the exit is not a 2 ways one or it is 2 ways, valid exit. |
2263 | * A valid 2 way exit means: |
2270 | * A valid 2 way exit means: |
… | |
… | |
2278 | |
2285 | |
2279 | #if 0 //TODO |
2286 | #if 0 //TODO |
2280 | if (!has_been_loaded (EXIT_PATH (exit)) && exit->race) |
2287 | if (!has_been_loaded (EXIT_PATH (exit)) && exit->race) |
2281 | return 0; /* This is a reset town portal */ |
2288 | return 0; /* This is a reset town portal */ |
2282 | #endif |
2289 | #endif |
|
|
2290 | |
|
|
2291 | LOG (llevError | logBacktrace, "sync map load due to %s\n", exit->debug_desc ()); |
2283 | |
2292 | |
2284 | maptile *exitmap = maptile::find_sync (EXIT_PATH (exit), exit->map); |
2293 | maptile *exitmap = maptile::find_sync (EXIT_PATH (exit), exit->map); |
2285 | |
2294 | |
2286 | if (exitmap) |
2295 | if (exitmap) |
2287 | { |
2296 | { |
… | |
… | |
2599 | if (op->env && (pl->move_type & MOVE_FLYING)) |
2608 | if (op->env && (pl->move_type & MOVE_FLYING)) |
2600 | { |
2609 | { |
2601 | /* player is flying and applying object not in inventory */ |
2610 | /* player is flying and applying object not in inventory */ |
2602 | if (!QUERY_FLAG (pl, FLAG_WIZ) && !(op->move_type & MOVE_FLYING)) |
2611 | if (!QUERY_FLAG (pl, FLAG_WIZ) && !(op->move_type & MOVE_FLYING)) |
2603 | { |
2612 | { |
2604 | op->failmsg ("But you are floating high above the ground! H<You have to stop levitating first, if you can.>"); |
2613 | pl->failmsg ("But you are floating high above the ground! H<You have to stop levitating first, if you can.>"); |
2605 | return 0; |
2614 | return 0; |
2606 | } |
2615 | } |
2607 | } |
2616 | } |
2608 | |
2617 | |
2609 | pl->contr->last_used = op; |
2618 | pl->contr->last_used = op; |
2610 | |
2619 | |
2611 | tmp = manual_apply (pl, op, aflag); |
2620 | tmp = manual_apply (pl, op, aflag); |
2612 | if (!quiet) |
2621 | if (!quiet) |
2613 | { |
2622 | { |
2614 | if (tmp == 0) |
2623 | if (tmp == 0) |
2615 | op->statusmsg (format ("I don't know how to apply the %s.", query_name (op))); |
2624 | pl->statusmsg (format ("I don't know how to apply the %s.", query_name (op))); |
2616 | else if (tmp == 2) |
2625 | else if (tmp == 2) |
2617 | op->failmsg ("You must get it first!\n"); |
2626 | pl->failmsg ("You must get it first!\n"); |
2618 | } |
2627 | } |
2619 | |
2628 | |
2620 | return tmp; |
2629 | return tmp; |
2621 | } |
2630 | } |
2622 | |
2631 | |
… | |
… | |
4092 | pl->statusmsg (format ("You %s the %s.", &transformer->slaying, query_base_name (marked, 0))); |
4101 | pl->statusmsg (format ("You %s the %s.", &transformer->slaying, query_base_name (marked, 0))); |
4093 | |
4102 | |
4094 | insert_ob_in_ob (new_item, pl); |
4103 | insert_ob_in_ob (new_item, pl); |
4095 | esrv_send_inventory (pl, pl); |
4104 | esrv_send_inventory (pl, pl); |
4096 | /* Eat up one item */ |
4105 | /* Eat up one item */ |
4097 | decrease_ob_nr (marked, 1); |
4106 | marked->decrease (); |
4098 | |
4107 | |
4099 | /* Eat one transformer if needed */ |
4108 | /* Eat one transformer if needed */ |
4100 | if (transformer->stats.food) |
4109 | if (transformer->stats.food) |
4101 | if (--transformer->stats.food == 0) |
4110 | if (--transformer->stats.food == 0) |
4102 | decrease_ob_nr (transformer, 1); |
4111 | transformer->decrease (); |
4103 | } |
4112 | } |
4104 | |
4113 | |