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 (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2002 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
6 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * the terms of the Affero GNU General Public License as published by the |
9 | * the terms of the Affero GNU General Public License as published by the |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
11 | * option) any later version. |
11 | * option) any later version. |
… | |
… | |
33 | |
33 | |
34 | //#define TREASURE_VERBOSE |
34 | //#define TREASURE_VERBOSE |
35 | |
35 | |
36 | #include <global.h> |
36 | #include <global.h> |
37 | #include <treasure.h> |
37 | #include <treasure.h> |
38 | #include <loader.h> |
|
|
39 | |
38 | |
40 | extern char *spell_mapping[]; |
39 | extern char *spell_mapping[]; |
41 | |
40 | |
42 | static treasurelist *first_treasurelist; |
41 | static treasurelist *first_treasurelist; |
43 | |
42 | |
… | |
… | |
256 | return; |
255 | return; |
257 | } |
256 | } |
258 | |
257 | |
259 | op->expand_tail (); |
258 | op->expand_tail (); |
260 | |
259 | |
|
|
260 | if (!creator->is_on_map () |
261 | if (!creator->is_on_map () || op->blocked (creator->map, creator->x, creator->y)) |
261 | || (op->weight && op->blocked (creator->map, creator->x, creator->y))) |
262 | op->destroy (); |
262 | op->destroy (); |
263 | else |
263 | else |
264 | { |
264 | { |
265 | SET_FLAG (op, FLAG_OBJ_ORIGINAL); |
265 | op->flag [FLAG_OBJ_ORIGINAL] = true; |
266 | op->insert_at (creator, creator, INS_NO_MERGE | INS_NO_WALK_ON); |
266 | op->insert_at (creator, creator, INS_NO_MERGE | INS_NO_WALK_ON); |
267 | } |
267 | } |
268 | } |
268 | } |
269 | else |
269 | else |
270 | { |
270 | { |
271 | op = creator->insert (op); |
271 | op = creator->insert (op); |
272 | |
272 | |
273 | if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER)) |
273 | if ((flags & GT_APPLY) && creator->flag [FLAG_MONSTER]) |
274 | monster_check_apply (creator, op); |
274 | monster_check_apply (creator, op); |
275 | } |
275 | } |
276 | } |
276 | } |
277 | |
277 | |
278 | /* if there are change_xxx commands in the treasure, we include the changes |
278 | /* if there are change_xxx commands in the treasure, we include the changes |
… | |
… | |
612 | i = -i; |
612 | i = -i; |
613 | if (i > max_magic) |
613 | if (i > max_magic) |
614 | i = max_magic; |
614 | i = max_magic; |
615 | set_abs_magic (op, i); |
615 | set_abs_magic (op, i); |
616 | if (i < 0) |
616 | if (i < 0) |
617 | SET_FLAG (op, FLAG_CURSED); |
617 | op->set_flag (FLAG_CURSED); |
618 | } |
618 | } |
619 | |
619 | |
620 | /* |
620 | /* |
621 | * Randomly adds one magical ability to the given object. |
621 | * Randomly adds one magical ability to the given object. |
622 | * Modified for Partial Resistance in many ways: |
622 | * Modified for Partial Resistance in many ways: |
… | |
… | |
715 | break; |
715 | break; |
716 | } |
716 | } |
717 | case 20: |
717 | case 20: |
718 | if (op->type == AMULET) |
718 | if (op->type == AMULET) |
719 | { |
719 | { |
720 | SET_FLAG (op, FLAG_REFL_SPELL); |
720 | op->set_flag (FLAG_REFL_SPELL); |
721 | op->value *= 11; |
721 | op->value *= 11; |
722 | } |
722 | } |
723 | else |
723 | else |
724 | { |
724 | { |
725 | op->stats.hp = 1; /* regenerate hit points */ |
725 | op->stats.hp = 1; /* regenerate hit points */ |
… | |
… | |
728 | break; |
728 | break; |
729 | |
729 | |
730 | case 21: |
730 | case 21: |
731 | if (op->type == AMULET) |
731 | if (op->type == AMULET) |
732 | { |
732 | { |
733 | SET_FLAG (op, FLAG_REFL_MISSILE); |
733 | op->set_flag (FLAG_REFL_MISSILE); |
734 | op->value *= 9; |
734 | op->value *= 9; |
735 | } |
735 | } |
736 | else |
736 | else |
737 | { |
737 | { |
738 | op->stats.sp = 1; /* regenerate spell points */ |
738 | op->stats.sp = 1; /* regenerate spell points */ |
… | |
… | |
924 | case WEAPON: |
924 | case WEAPON: |
925 | case ARMOUR: |
925 | case ARMOUR: |
926 | case SHIELD: |
926 | case SHIELD: |
927 | case HELMET: |
927 | case HELMET: |
928 | case CLOAK: |
928 | case CLOAK: |
929 | if (QUERY_FLAG (op, FLAG_CURSED) && !(rndm (4))) |
929 | if (op->flag [FLAG_CURSED] && !(rndm (4))) |
930 | set_ring_bonus (op, -DICE2); |
930 | set_ring_bonus (op, -DICE2); |
931 | break; |
931 | break; |
932 | |
932 | |
933 | case BRACERS: |
933 | case BRACERS: |
934 | if (!rndm (QUERY_FLAG (op, FLAG_CURSED) ? 5 : 20)) |
934 | if (!rndm (op->flag [FLAG_CURSED] ? 5 : 20)) |
935 | { |
935 | { |
936 | set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2); |
936 | set_ring_bonus (op, op->flag [FLAG_CURSED] ? -DICE2 : DICE2); |
937 | if (!QUERY_FLAG (op, FLAG_CURSED)) |
937 | if (!op->flag [FLAG_CURSED]) |
938 | op->value *= 3; |
938 | op->value *= 3; |
939 | } |
939 | } |
940 | break; |
940 | break; |
941 | |
941 | |
942 | case POTION: |
942 | case POTION: |
… | |
… | |
972 | op->name = "potion"; |
972 | op->name = "potion"; |
973 | op->name_pl = "potions"; |
973 | op->name_pl = "potions"; |
974 | } |
974 | } |
975 | |
975 | |
976 | if (!(flags & GT_ONLY_GOOD) && rndm (2)) |
976 | if (!(flags & GT_ONLY_GOOD) && rndm (2)) |
977 | SET_FLAG (op, FLAG_CURSED); |
977 | op->set_flag (FLAG_CURSED); |
978 | |
978 | |
979 | break; |
979 | break; |
980 | } |
980 | } |
981 | |
981 | |
982 | case AMULET: |
982 | case AMULET: |
… | |
… | |
986 | case RING: |
986 | case RING: |
987 | if (!IS_ARCH (op->arch, ring) && !IS_ARCH (op->arch, amulet)) /* It's a special artifact! */ |
987 | if (!IS_ARCH (op->arch, ring) && !IS_ARCH (op->arch, amulet)) /* It's a special artifact! */ |
988 | break; |
988 | break; |
989 | |
989 | |
990 | if (!(flags & GT_ONLY_GOOD) && !(rndm (3))) |
990 | if (!(flags & GT_ONLY_GOOD) && !(rndm (3))) |
991 | SET_FLAG (op, FLAG_CURSED); |
991 | op->set_flag (FLAG_CURSED); |
992 | |
992 | |
993 | set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2); |
993 | set_ring_bonus (op, op->flag [FLAG_CURSED] ? -DICE2 : DICE2); |
994 | |
994 | |
995 | if (op->type != RING) /* Amulets have only one ability */ |
995 | if (op->type != RING) /* Amulets have only one ability */ |
996 | break; |
996 | break; |
997 | |
997 | |
998 | if (!(rndm (4))) |
998 | if (!(rndm (4))) |
999 | { |
999 | { |
1000 | int d = (rndm (2) || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2; |
1000 | int d = (rndm (2) || op->flag [FLAG_CURSED]) ? -DICE2 : DICE2; |
1001 | |
1001 | |
1002 | if (d > 0) |
1002 | if (d > 0) |
1003 | op->value *= 3; |
1003 | op->value *= 3; |
1004 | |
1004 | |
1005 | set_ring_bonus (op, d); |
1005 | set_ring_bonus (op, d); |
1006 | |
1006 | |
1007 | if (!(rndm (4))) |
1007 | if (!(rndm (4))) |
1008 | { |
1008 | { |
1009 | int d = (rndm (3) || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2; |
1009 | int d = (rndm (3) || op->flag [FLAG_CURSED]) ? -DICE2 : DICE2; |
1010 | |
1010 | |
1011 | if (d > 0) |
1011 | if (d > 0) |
1012 | op->value *= 5; |
1012 | op->value *= 5; |
1013 | set_ring_bonus (op, d); |
1013 | set_ring_bonus (op, d); |
1014 | } |
1014 | } |
… | |
… | |
1025 | * creator and/or map level we found it on. |
1025 | * creator and/or map level we found it on. |
1026 | */ |
1026 | */ |
1027 | if (!op->msg && rndm (10)) |
1027 | if (!op->msg && rndm (10)) |
1028 | { |
1028 | { |
1029 | /* set the book level properly */ |
1029 | /* set the book level properly */ |
1030 | if (creator->level == 0 || QUERY_FLAG (creator, FLAG_ALIVE)) |
1030 | if (creator->level == 0 || creator->flag [FLAG_ALIVE]) |
1031 | { |
1031 | { |
1032 | if (op->map && op->map->difficulty) |
1032 | if (op->map && op->map->difficulty) |
1033 | op->level = rndm (op->map->difficulty) + rndm (10) + 1; |
1033 | op->level = rndm (op->map->difficulty) + rndm (10) + 1; |
1034 | else |
1034 | else |
1035 | op->level = rndm (20) + 1; |
1035 | op->level = rndm (20) + 1; |
… | |
… | |
1048 | /* creator related stuff */ |
1048 | /* creator related stuff */ |
1049 | |
1049 | |
1050 | /* for library, chained books. Note that some monsters have no_pick |
1050 | /* for library, chained books. Note that some monsters have no_pick |
1051 | * set - we don't want to set no pick in that case. |
1051 | * set - we don't want to set no pick in that case. |
1052 | */ |
1052 | */ |
1053 | if (QUERY_FLAG (creator, FLAG_NO_PICK) && !QUERY_FLAG (creator, FLAG_MONSTER)) |
1053 | if (creator->flag [FLAG_NO_PICK] && !creator->flag [FLAG_MONSTER]) |
1054 | SET_FLAG (op, FLAG_NO_PICK); |
1054 | op->set_flag (FLAG_NO_PICK); |
1055 | if (creator->slaying && !op->slaying) /* for check_inv floors */ |
1055 | if (creator->slaying && !op->slaying) /* for check_inv floors */ |
1056 | op->slaying = creator->slaying; |
1056 | op->slaying = creator->slaying; |
1057 | break; |
1057 | break; |
1058 | |
1058 | |
1059 | case SPELLBOOK: |
1059 | case SPELLBOOK: |
… | |
… | |
1122 | break; |
1122 | break; |
1123 | } /* switch type */ |
1123 | } /* switch type */ |
1124 | |
1124 | |
1125 | if (flags & GT_STARTEQUIP) |
1125 | if (flags & GT_STARTEQUIP) |
1126 | { |
1126 | { |
1127 | if (op->nrof < 2 && op->type != CONTAINER && op->type != MONEY && !QUERY_FLAG (op, FLAG_IS_THROWN)) |
1127 | if (op->nrof < 2 && op->type != CONTAINER && op->type != MONEY && !op->flag [FLAG_IS_THROWN]) |
1128 | SET_FLAG (op, FLAG_STARTEQUIP); |
1128 | op->set_flag (FLAG_STARTEQUIP); |
1129 | else if (op->type != MONEY) |
1129 | else if (op->type != MONEY) |
1130 | op->value = 0; |
1130 | op->value = 0; |
1131 | } |
1131 | } |
1132 | |
1132 | |
1133 | if (!(flags & GT_ENVIRONMENT)) |
1133 | if (!(flags & GT_ENVIRONMENT)) |
… | |
… | |
1315 | op->path_repelled |= change->path_repelled; |
1315 | op->path_repelled |= change->path_repelled; |
1316 | op->path_denied |= change->path_denied; |
1316 | op->path_denied |= change->path_denied; |
1317 | op->move_type |= change->move_type; |
1317 | op->move_type |= change->move_type; |
1318 | op->stats.luck += change->stats.luck; |
1318 | op->stats.luck += change->stats.luck; |
1319 | |
1319 | |
1320 | if (QUERY_FLAG (change, FLAG_CURSED)) |
1320 | if (change->flag [FLAG_CURSED]) |
1321 | SET_FLAG (op, FLAG_CURSED); |
1321 | op->set_flag (FLAG_CURSED); |
1322 | if (QUERY_FLAG (change, FLAG_DAMNED)) |
1322 | if (change->flag [FLAG_DAMNED]) |
1323 | SET_FLAG (op, FLAG_DAMNED); |
1323 | op->set_flag (FLAG_DAMNED); |
1324 | if ((QUERY_FLAG (change, FLAG_CURSED) || QUERY_FLAG (change, FLAG_DAMNED)) && op->magic > 0) |
1324 | if ((change->flag [FLAG_CURSED] || change->flag [FLAG_DAMNED]) && op->magic > 0) |
1325 | set_abs_magic (op, -op->magic); |
1325 | set_abs_magic (op, -op->magic); |
1326 | |
1326 | |
1327 | if (QUERY_FLAG (change, FLAG_LIFESAVE)) |
1327 | if (change->flag [FLAG_LIFESAVE]) |
1328 | SET_FLAG (op, FLAG_LIFESAVE); |
1328 | op->set_flag (FLAG_LIFESAVE); |
1329 | if (QUERY_FLAG (change, FLAG_REFL_SPELL)) |
1329 | if (change->flag [FLAG_REFL_SPELL]) |
1330 | SET_FLAG (op, FLAG_REFL_SPELL); |
1330 | op->set_flag (FLAG_REFL_SPELL); |
1331 | if (QUERY_FLAG (change, FLAG_STEALTH)) |
1331 | if (change->flag [FLAG_STEALTH]) |
1332 | SET_FLAG (op, FLAG_STEALTH); |
1332 | op->set_flag (FLAG_STEALTH); |
1333 | if (QUERY_FLAG (change, FLAG_XRAYS)) |
1333 | if (change->flag [FLAG_XRAYS]) |
1334 | SET_FLAG (op, FLAG_XRAYS); |
1334 | op->set_flag (FLAG_XRAYS); |
1335 | if (QUERY_FLAG (change, FLAG_BLIND)) |
1335 | if (change->flag [FLAG_BLIND]) |
1336 | SET_FLAG (op, FLAG_BLIND); |
1336 | op->set_flag (FLAG_BLIND); |
1337 | if (QUERY_FLAG (change, FLAG_SEE_IN_DARK)) |
1337 | if (change->flag [FLAG_SEE_IN_DARK]) |
1338 | SET_FLAG (op, FLAG_SEE_IN_DARK); |
1338 | op->set_flag (FLAG_SEE_IN_DARK); |
1339 | if (QUERY_FLAG (change, FLAG_REFL_MISSILE)) |
1339 | if (change->flag [FLAG_REFL_MISSILE]) |
1340 | SET_FLAG (op, FLAG_REFL_MISSILE); |
1340 | op->set_flag (FLAG_REFL_MISSILE); |
1341 | if (QUERY_FLAG (change, FLAG_MAKE_INVIS)) |
1341 | if (change->flag [FLAG_MAKE_INVIS]) |
1342 | SET_FLAG (op, FLAG_MAKE_INVIS); |
1342 | op->set_flag (FLAG_MAKE_INVIS); |
1343 | |
1343 | |
1344 | if (QUERY_FLAG (change, FLAG_STAND_STILL)) |
1344 | if (change->flag [FLAG_STAND_STILL]) |
1345 | { |
1345 | { |
1346 | CLEAR_FLAG (op, FLAG_ANIMATE); |
1346 | op->clr_flag (FLAG_ANIMATE); |
1347 | /* so artifacts will join */ |
1347 | /* so artifacts will join */ |
1348 | if (!QUERY_FLAG (op, FLAG_ALIVE)) |
1348 | if (!op->flag [FLAG_ALIVE]) |
1349 | op->speed = 0.0; |
1349 | op->speed = 0.0; |
1350 | |
1350 | |
1351 | op->set_speed (op->speed); |
1351 | op->set_speed (op->speed); |
1352 | } |
1352 | } |
1353 | |
1353 | |
… | |
… | |
1370 | op->destroy_inv (false); |
1370 | op->destroy_inv (false); |
1371 | |
1371 | |
1372 | object *tmp = change->other_arch->instance (); |
1372 | object *tmp = change->other_arch->instance (); |
1373 | insert_ob_in_ob (tmp, op); |
1373 | insert_ob_in_ob (tmp, op); |
1374 | } |
1374 | } |
|
|
1375 | |
1375 | /* No harm setting this for potions/horns */ |
1376 | /* No harm setting this for potions/horns */ |
1376 | op->other_arch = change->other_arch; |
1377 | op->other_arch = change->other_arch; |
1377 | } |
1378 | } |
1378 | |
1379 | |
1379 | if (change->stats.hp < 0) |
1380 | if (change->stats.hp < 0) |
… | |
… | |
1526 | op->title = new_name; |
1527 | op->title = new_name; |
1527 | add_abilities (op, artifct); /* Give out the bonuses */ |
1528 | add_abilities (op, artifct); /* Give out the bonuses */ |
1528 | |
1529 | |
1529 | #if 0 /* Bit verbose, but keep it here until next time I need it... */ |
1530 | #if 0 /* Bit verbose, but keep it here until next time I need it... */ |
1530 | { |
1531 | { |
1531 | char identified = QUERY_FLAG (op, FLAG_IDENTIFIED); |
1532 | char identified = op->flag [FLAG_IDENTIFIED]; |
1532 | |
1533 | |
1533 | SET_FLAG (op, FLAG_IDENTIFIED); |
1534 | op->set_flag (FLAG_IDENTIFIED); |
1534 | LOG (llevDebug, "Generated artifact %s %s [%s]\n", op->name, op->title, describe_item (op, NULL)); |
1535 | LOG (llevDebug, "Generated artifact %s %s [%s]\n", op->name, op->title, describe_item (op, NULL)); |
1535 | if (!identified) |
1536 | if (!identified) |
1536 | CLEAR_FLAG (op, FLAG_IDENTIFIED); |
1537 | op->clr_flag (FLAG_IDENTIFIED); |
1537 | } |
1538 | } |
1538 | #endif |
1539 | #endif |
1539 | return; |
1540 | return; |
1540 | } |
1541 | } |
1541 | |
1542 | |
… | |
… | |
1652 | item->type = POISON; |
1653 | item->type = POISON; |
1653 | |
1654 | |
1654 | if (donor->attacktype & AT_ACID) |
1655 | if (donor->attacktype & AT_ACID) |
1655 | item->stats.hp = -1 * item->stats.food; |
1656 | item->stats.hp = -1 * item->stats.food; |
1656 | |
1657 | |
1657 | SET_FLAG (item, FLAG_NO_STEAL); |
1658 | item->set_flag (FLAG_NO_STEAL); |
1658 | } |
1659 | } |
1659 | } |
1660 | } |
1660 | |
1661 | |
1661 | static void |
1662 | static void |
1662 | free_treasurestruct (treasure *t) |
1663 | free_treasurestruct (treasure *t) |