ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/skills.C
(Generate patch)

Comparing deliantra/server/server/skills.C (file contents):
Revision 1.13 by root, Tue Dec 12 21:39:57 2006 UTC vs.
Revision 1.22 by root, Mon Jan 8 01:19:04 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
3 3
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2003 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2003 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
6 7
7 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
8 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
159 * already -b.t. 160 * already -b.t.
160 */ 161 */
161 162
162 if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) || QUERY_FLAG (tmp, FLAG_APPLIED) 163 if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) || QUERY_FLAG (tmp, FLAG_APPLIED)
163 || !(tmp->type) 164 || !(tmp->type)
164 || tmp->type == EXPERIENCE || tmp->type == SPELL 165 || tmp->type == SPELL
165 || QUERY_FLAG (tmp, FLAG_STARTEQUIP) || QUERY_FLAG (tmp, FLAG_NO_STEAL) || tmp->invisible) 166 || QUERY_FLAG (tmp, FLAG_STARTEQUIP) || QUERY_FLAG (tmp, FLAG_NO_STEAL) || tmp->invisible)
166 continue; 167 continue;
167 168
168 /* Okay, try stealing this item. Dependent on dexterity of thief, 169 /* Okay, try stealing this item. Dependent on dexterity of thief,
169 * skill level, see the adj_stealroll fctn for more detail. 170 * skill level, see the adj_stealroll fctn for more detail.
292 /* If player can't move onto the space, can't steal from it. */ 293 /* If player can't move onto the space, can't steal from it. */
293 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y))) 294 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y)))
294 return 0; 295 return 0;
295 296
296 /* Find the topmost object at this spot */ 297 /* Find the topmost object at this spot */
297 for (tmp = get_map_ob (m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above); 298 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above);
298 299
299 /* For all the stacked objects at this point, attempt a steal */ 300 /* For all the stacked objects at this point, attempt a steal */
300 for (; tmp != NULL; tmp = next) 301 for (; tmp != NULL; tmp = next)
301 { 302 {
302 next = tmp->below; 303 next = tmp->below;
318 return 0; 319 return 0;
319 320
320 /* no xp for stealing from pets (of players) */ 321 /* no xp for stealing from pets (of players) */
321 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && tmp->attack_movement == PETMOVE) 322 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && tmp->attack_movement == PETMOVE)
322 { 323 {
323 object *owner = get_owner (tmp); 324 object *owner = tmp->owner;
324 325
325 if (owner != NULL && owner->type == PLAYER) 326 if (owner != NULL && owner->type == PLAYER)
326 return 0; 327 return 0;
327 } 328 }
328 329
383 { 384 {
384 new_draw_info (NDI_UNIQUE, 0, pl, "There is no lock there."); 385 new_draw_info (NDI_UNIQUE, 0, pl, "There is no lock there.");
385 return 0; 386 return 0;
386 } 387 }
387 388
388 for (tmp = get_map_ob (pl->map, x, y); tmp; tmp = tmp->above) 389 for (tmp = GET_MAP_OB (pl->map, x, y); tmp; tmp = tmp->above)
389 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR) 390 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR)
390 break; 391 break;
391 392
392 if (!tmp) 393 if (!tmp)
393 { 394 {
494 * of jumping. 495 * of jumping.
495 */ 496 */
496static void 497static void
497stop_jump (object *pl, int dist, int spaces) 498stop_jump (object *pl, int dist, int spaces)
498{ 499{
499 fix_player (pl); 500 pl->update_stats ();
500 insert_ob_in_map (pl, pl->map, pl, 0); 501 pl->map->insert (pl, pl->x, pl->y, pl);
501} 502}
502
503 503
504static int 504static int
505attempt_jump (object *pl, int dir, int spaces, object *skill) 505attempt_jump (object *pl, int dir, int spaces, object *skill)
506{ 506{
507 object *tmp; 507 object *tmp;
543 new_draw_info (NDI_UNIQUE, 0, pl, "Your jump is blocked."); 543 new_draw_info (NDI_UNIQUE, 0, pl, "Your jump is blocked.");
544 stop_jump (pl, i, spaces); 544 stop_jump (pl, i, spaces);
545 return 0; 545 return 0;
546 } 546 }
547 547
548 for (tmp = get_map_ob (m, x, y); tmp; tmp = tmp->above) 548 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above)
549 { 549 {
550 /* Jump into creature */ 550 /* Jump into creature */
551 if (QUERY_FLAG (tmp, FLAG_MONSTER) || (tmp->type == PLAYER && (!QUERY_FLAG (tmp, FLAG_WIZ) || !tmp->contr->hidden))) 551 if (QUERY_FLAG (tmp, FLAG_MONSTER) || (tmp->type == PLAYER && (!QUERY_FLAG (tmp, FLAG_WIZ) || !tmp->contr->hidden)))
552 { 552 {
553 new_draw_info_format (NDI_UNIQUE, 0, pl, "You jump into %s%s.", tmp->type == PLAYER ? "" : "the ", &tmp->name); 553 new_draw_info_format (NDI_UNIQUE, 0, pl, "You jump into %s%s.", tmp->type == PLAYER ? "" : "the ", &tmp->name);
638 esrv_update_item (UPD_FLAGS, pl, tmp); 638 esrv_update_item (UPD_FLAGS, pl, tmp);
639 success += calc_skill_exp (pl, tmp, skill); 639 success += calc_skill_exp (pl, tmp, skill);
640 } 640 }
641 641
642 /* Check ground, too, but only objects the player could pick up */ 642 /* Check ground, too, but only objects the player could pick up */
643 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp; tmp = tmp->above) 643 for (tmp = GET_MAP_OB (pl->map, pl->x, pl->y); tmp; tmp = tmp->above)
644 if (can_pick (pl, tmp) && 644 if (can_pick (pl, tmp) &&
645 !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && 645 !QUERY_FLAG (tmp, FLAG_IDENTIFIED) &&
646 !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED) 646 !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED)
647 && (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) && tmp->item_power < skill->level) 647 && (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) && tmp->item_power < skill->level)
648 { 648 {
669 esrv_update_item (UPD_FLAGS, pl, tmp); 669 esrv_update_item (UPD_FLAGS, pl, tmp);
670 success += calc_skill_exp (pl, tmp, skill); 670 success += calc_skill_exp (pl, tmp, skill);
671 } 671 }
672 672
673 /* Check ground, too, but like above, only if the object can be picked up */ 673 /* Check ground, too, but like above, only if the object can be picked up */
674 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp; tmp = tmp->above) 674 for (tmp = GET_MAP_OB (pl->map, pl->x, pl->y); tmp; tmp = tmp->above)
675 if (can_pick (pl, tmp) && 675 if (can_pick (pl, tmp) &&
676 !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && (is_magical (tmp)) && tmp->item_power < skill->level) 676 !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && (is_magical (tmp)) && tmp->item_power < skill->level)
677 { 677 {
678 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); 678 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL);
679 esrv_update_item (UPD_FLAGS, pl, tmp); 679 esrv_update_item (UPD_FLAGS, pl, tmp);
734 734
735 for (tmp = pl->inv; tmp; tmp = tmp->below) 735 for (tmp = pl->inv; tmp; tmp = tmp->below)
736 success += do_skill_ident2 (tmp, pl, obj_class, skill); 736 success += do_skill_ident2 (tmp, pl, obj_class, skill);
737 /* check the ground */ 737 /* check the ground */
738 738
739 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp; tmp = tmp->above) 739 for (tmp = GET_MAP_OB (pl->map, pl->x, pl->y); tmp; tmp = tmp->above)
740 success += do_skill_ident2 (tmp, pl, obj_class, skill); 740 success += do_skill_ident2 (tmp, pl, obj_class, skill);
741 741
742 return success; 742 return success;
743} 743}
744 744
838 { 838 {
839 new_draw_info (NDI_UNIQUE, 0, pl, "There is nothing to orate to."); 839 new_draw_info (NDI_UNIQUE, 0, pl, "There is nothing to orate to.");
840 return 0; 840 return 0;
841 } 841 }
842 842
843 for (tmp = get_map_ob (m, x, y); tmp; tmp = tmp->above) 843 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above)
844 { 844 {
845 /* can't persuade players - return because there is nothing else 845 /* can't persuade players - return because there is nothing else
846 * on that space to charm. Same for multi space monsters and 846 * on that space to charm. Same for multi space monsters and
847 * special monsters - we don't allow them to be charmed, and there 847 * special monsters - we don't allow them to be charmed, and there
848 * is no reason to do further processing since they should be the 848 * is no reason to do further processing since they should be the
877 } 877 }
878 878
879 /* it's already allied! */ 879 /* it's already allied! */
880 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && (tmp->attack_movement == PETMOVE)) 880 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && (tmp->attack_movement == PETMOVE))
881 { 881 {
882 if (get_owner (tmp) == pl) 882 if (tmp->owner == pl)
883 { 883 {
884 new_draw_info (NDI_UNIQUE, 0, pl, "Your follower loves your speech.\n"); 884 new_draw_info (NDI_UNIQUE, 0, pl, "Your follower loves your speech.\n");
885 return 0; 885 return 0;
886 } 886 }
887 else if (skill->level > tmp->level) 887 else if (skill->level > tmp->level)
888 { 888 {
889 /* you steal the follower. Perhaps we should really look at the 889 /* you steal the follower. Perhaps we should really look at the
890 * level of the owner above? 890 * level of the owner above?
891 */ 891 */
892 set_owner (tmp, pl); 892 tmp->set_owner (pl);
893 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to follow you instead!\n", query_name (tmp)); 893 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to follow you instead!\n", query_name (tmp));
894 /* Abuse fix - don't give exp since this can otherwise 894 /* Abuse fix - don't give exp since this can otherwise
895 * be used by a couple players to gets lots of exp. 895 * be used by a couple players to gets lots of exp.
896 */ 896 */
897 return 0; 897 return 0;
908 /* Ok, got a 'sucker' lets try to make them a follower */ 908 /* Ok, got a 'sucker' lets try to make them a follower */
909 if (chance > 0 && tmp->level < (random_roll (0, chance - 1, pl, PREFER_HIGH) - 1)) 909 if (chance > 0 && tmp->level < (random_roll (0, chance - 1, pl, PREFER_HIGH) - 1))
910 { 910 {
911 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to become your follower.\n", query_name (tmp)); 911 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to become your follower.\n", query_name (tmp));
912 912
913 set_owner (tmp, pl); 913 tmp->set_owner (pl);
914 tmp->stats.exp = 0; 914 tmp->stats.exp = 0;
915 add_friendly_object (tmp); 915 add_friendly_object (tmp);
916 SET_FLAG (tmp, FLAG_FRIENDLY);
917 tmp->attack_movement = PETMOVE; 916 tmp->attack_movement = PETMOVE;
918 return calc_skill_exp (pl, tmp, skill); 917 return calc_skill_exp (pl, tmp, skill);
919 } 918 }
920 /* Charm failed. Creature may be angry now */ 919 /* Charm failed. Creature may be angry now */
921 else if ((skill->level + ((pl->stats.Cha - 10) / 2)) < random_roll (1, 2 * tmp->level, pl, PREFER_LOW)) 920 else if ((skill->level + ((pl->stats.Cha - 10) / 2)) < random_roll (1, 2 * tmp->level, pl, PREFER_LOW))
964 if (mflags & P_OUT_OF_MAP) 963 if (mflags & P_OUT_OF_MAP)
965 continue; 964 continue;
966 if (!(mflags & P_IS_ALIVE)) 965 if (!(mflags & P_IS_ALIVE))
967 continue; 966 continue;
968 967
969 for (tmp = get_map_ob (m, x, y); tmp; tmp = tmp->above) 968 for (tmp = GET_MAP_OB (m, x, y); tmp; tmp = tmp->above)
970 { 969 {
971 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 970 if (QUERY_FLAG (tmp, FLAG_MONSTER))
972 break; 971 break;
973 /* can't affect players */ 972 /* can't affect players */
974 if (tmp->type == PLAYER) 973 if (tmp->type == PLAYER)
1034 mflags = get_map_flags (m, &m, x, y, &x, &y); 1033 mflags = get_map_flags (m, &m, x, y, &x, &y);
1035 if (mflags & P_OUT_OF_MAP) 1034 if (mflags & P_OUT_OF_MAP)
1036 continue; 1035 continue;
1037 1036
1038 /* Check everything in the square for trapness */ 1037 /* Check everything in the square for trapness */
1039 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above) 1038 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above)
1040 { 1039 {
1041 1040
1042 /* And now we'd better do an inventory traversal of each 1041 /* And now we'd better do an inventory traversal of each
1043 * of these objects' inventory 1042 * of these objects' inventory
1044 * We can narrow this down a bit - no reason to search through 1043 * We can narrow this down a bit - no reason to search through
1097 mflags = get_map_flags (m, &m, x, y, &x, &y); 1096 mflags = get_map_flags (m, &m, x, y, &x, &y);
1098 if (mflags & P_OUT_OF_MAP) 1097 if (mflags & P_OUT_OF_MAP)
1099 continue; 1098 continue;
1100 1099
1101 /* Check everything in the square for trapness */ 1100 /* Check everything in the square for trapness */
1102 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above) 1101 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above)
1103 { 1102 {
1104 /* And now we'd better do an inventory traversal of each 1103 /* And now we'd better do an inventory traversal of each
1105 * of these objects inventory. Like above, only 1104 * of these objects inventory. Like above, only
1106 * do this for interesting objects. 1105 * do this for interesting objects.
1107 */ 1106 */
1272 1271
1273 strcat (buf, msg); 1272 strcat (buf, msg);
1274 strcat (buf, "\n"); /* new msg needs a LF */ 1273 strcat (buf, "\n"); /* new msg needs a LF */
1275 if (item->nrof > 1) 1274 if (item->nrof > 1)
1276 { 1275 {
1277 newBook = object::create (); 1276 newBook = item->clone ();
1278 item->copy_to (newBook);
1279 decrease_ob (item); 1277 decrease_ob (item);
1280 esrv_send_item (pl, item); 1278 esrv_send_item (pl, item);
1281 newBook->nrof = 1; 1279 newBook->nrof = 1;
1282 newBook->msg = buf; 1280 newBook->msg = buf;
1283 newBook = insert_ob_in_ob (newBook, pl); 1281 newBook = insert_ob_in_ob (newBook, pl);
1358 1356
1359 if (random_roll (0, chosen_spell->level * 4 - 1, pl, PREFER_LOW) < skill->level) 1357 if (random_roll (0, chosen_spell->level * 4 - 1, pl, PREFER_LOW) < skill->level)
1360 { 1358 {
1361 if (scroll->nrof > 1) 1359 if (scroll->nrof > 1)
1362 { 1360 {
1363 newscroll = object::create (); 1361 newscroll = scroll->clone ();
1364 scroll->copy_to (newscroll);
1365 decrease_ob (scroll); 1362 decrease_ob (scroll);
1366 newscroll->nrof = 1; 1363 newscroll->nrof = 1;
1367 } 1364 }
1368 else 1365 else
1369 { 1366 {
1386 } 1383 }
1387 1384
1388 if (newscroll->inv) 1385 if (newscroll->inv)
1389 newscroll->inv->destroy (); 1386 newscroll->inv->destroy ();
1390 1387
1391 tmp = object::create ();
1392 chosen_spell->copy_to (tmp); 1388 tmp = chosen_spell->clone ();
1393 insert_ob_in_ob (tmp, newscroll); 1389 insert_ob_in_ob (tmp, newscroll);
1394 1390
1395 /* Same code as from treasure.c - so they can better merge. 1391 /* Same code as from treasure.c - so they can better merge.
1396 * if players want to sell them, so be it. 1392 * if players want to sell them, so be it.
1397 */ 1393 */
1419 1415
1420 if (chosen_spell->level > skill->level || confused) 1416 if (chosen_spell->level > skill->level || confused)
1421 { /*backfire! */ 1417 { /*backfire! */
1422 new_draw_info (NDI_UNIQUE, 0, pl, "Ouch! Your attempt to write a new scroll strains your mind!"); 1418 new_draw_info (NDI_UNIQUE, 0, pl, "Ouch! Your attempt to write a new scroll strains your mind!");
1423 if (random_roll (0, 1, pl, PREFER_LOW) == 1) 1419 if (random_roll (0, 1, pl, PREFER_LOW) == 1)
1424 drain_specific_stat (pl, 4); 1420 pl->drain_specific_stat (4);
1425 else 1421 else
1426 { 1422 {
1427 confuse_player (pl, pl, 99); 1423 confuse_player (pl, pl, 99);
1428 return (-30 * chosen_spell->level); 1424 return (-30 * chosen_spell->level);
1429 } 1425 }
1434 confuse_player (pl, pl, 99); 1430 confuse_player (pl, pl, 99);
1435 } 1431 }
1436 else 1432 else
1437 new_draw_info (NDI_UNIQUE, 0, pl, "You fail to write a new scroll."); 1433 new_draw_info (NDI_UNIQUE, 0, pl, "You fail to write a new scroll.");
1438 } 1434 }
1435
1439 return 0; 1436 return 0;
1440} 1437}
1441 1438
1442/* write_on_item() - wrapper for write_note and write_scroll */ 1439/* write_on_item() - wrapper for write_note and write_scroll */
1443int 1440int
1593 */ 1590 */
1594 1591
1595static object * 1592static object *
1596make_throw_ob (object *orig) 1593make_throw_ob (object *orig)
1597{ 1594{
1598 object *toss_item;
1599
1600 if (!orig) 1595 if (!orig)
1601 return NULL; 1596 return NULL;
1602 1597
1603 toss_item = object::create ();
1604 if (QUERY_FLAG (orig, FLAG_APPLIED)) 1598 if (QUERY_FLAG (orig, FLAG_APPLIED))
1605 { 1599 {
1606 LOG (llevError, "BUG: make_throw_ob(): ob is applied\n"); 1600 LOG (llevError, "BUG: make_throw_ob(): ob is applied\n");
1607 /* insufficient workaround, but better than nothing */ 1601 /* insufficient workaround, but better than nothing */
1608 CLEAR_FLAG (orig, FLAG_APPLIED); 1602 CLEAR_FLAG (orig, FLAG_APPLIED);
1609 } 1603 }
1610 orig->copy_to (toss_item); 1604
1605 object *toss_item = orig->clone ();
1606
1611 toss_item->type = THROWN_OBJ; 1607 toss_item->type = THROWN_OBJ;
1612 CLEAR_FLAG (toss_item, FLAG_CHANGING); 1608 CLEAR_FLAG (toss_item, FLAG_CHANGING);
1613 toss_item->stats.dam = 0; /* default damage */ 1609 toss_item->stats.dam = 0; /* default damage */
1614 insert_ob_in_ob (orig, toss_item); 1610 insert_ob_in_ob (orig, toss_item);
1615 return toss_item; 1611 return toss_item;
1693 */ 1689 */
1694 mflags = get_map_flags (part->map, &m, part->x + freearr_x[dir], part->y + freearr_y[dir], &sx, &sy); 1690 mflags = get_map_flags (part->map, &m, part->x + freearr_x[dir], part->y + freearr_y[dir], &sx, &sy);
1695 1691
1696 if (!dir || (eff_str <= 1) || (mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, sx, sy) & MOVE_FLY_LOW)) 1692 if (!dir || (eff_str <= 1) || (mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, sx, sy) & MOVE_FLY_LOW))
1697 { 1693 {
1698
1699 /* bounces off 'wall', and drops to feet */ 1694 /* bounces off 'wall', and drops to feet */
1700 throw_ob->remove (); 1695 throw_ob->insert_at (part, op);
1701 throw_ob->x = part->x; 1696
1702 throw_ob->y = part->y;
1703 insert_ob_in_map (throw_ob, part->map, op, 0);
1704 if (op->type == PLAYER) 1697 if (op->type == PLAYER)
1705 { 1698 {
1706 if (eff_str <= 1) 1699 if (eff_str <= 1)
1707 {
1708 new_draw_info_format (NDI_UNIQUE, 0, op, "Your load is so heavy you drop %s to the ground.", query_name (throw_ob)); 1700 new_draw_info_format (NDI_UNIQUE, 0, op, "Your load is so heavy you drop %s to the ground.", query_name (throw_ob));
1709 }
1710 else if (!dir) 1701 else if (!dir)
1711 {
1712 new_draw_info_format (NDI_UNIQUE, 0, op, "You throw %s at the ground.", query_name (throw_ob)); 1702 new_draw_info_format (NDI_UNIQUE, 0, op, "You throw %s at the ground.", query_name (throw_ob));
1713 }
1714 else 1703 else
1715 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); 1704 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way.");
1716 } 1705 }
1706
1717 return 0; 1707 return 0;
1718 } /* if object can't be thrown */ 1708 } /* if object can't be thrown */
1719 1709
1720 left = throw_ob; /* these are throwing objects left to the player */ 1710 left = throw_ob; /* these are throwing objects left to the player */
1721 1711
1758 { 1748 {
1759 insert_ob_in_ob (throw_ob, op); 1749 insert_ob_in_ob (throw_ob, op);
1760 return 0; 1750 return 0;
1761 } 1751 }
1762 1752
1763 set_owner (throw_ob, op); 1753 throw_ob->set_owner (op);
1764 /* At some point in the attack code, the actual real object (op->inv) 1754 /* At some point in the attack code, the actual real object (op->inv)
1765 * becomes the hitter. As such, we need to make sure that has a proper 1755 * becomes the hitter. As such, we need to make sure that has a proper
1766 * owner value so exp goes to the right place. 1756 * owner value so exp goes to the right place.
1767 */ 1757 */
1768 set_owner (throw_ob->inv, op); 1758 throw_ob->inv->set_owner (op);
1769 throw_ob->direction = dir; 1759 throw_ob->direction = dir;
1770 throw_ob->x = part->x;
1771 throw_ob->y = part->y;
1772 1760
1773 /* the damage bonus from the force of the throw */ 1761 /* the damage bonus from the force of the throw */
1774 dam = (int) (str_factor * dam_bonus[eff_str]); 1762 dam = (int) (str_factor * dam_bonus[eff_str]);
1775 1763
1776 /* Now, lets adjust the properties of the thrown_ob. */ 1764 /* Now, lets adjust the properties of the thrown_ob. */
1777 1765
1778 /* how far to fly */ 1766 /* how far to fly */
1779 throw_ob->last_sp = (eff_str * 3) / 5; 1767 throw_ob->last_sp = (eff_str * 3) / 5;
1780 1768
1781 /* speed */ 1769 /* speed */
1782 throw_ob->speed = (speed_bonus[eff_str] + 1.0) / 1.5; 1770 throw_ob->set_speed (min (1.0, speed_bonus[eff_str] + 1.0) / 1.5); /* no faster than an arrow! */
1783 throw_ob->speed = MIN (1.0, throw_ob->speed); /* no faster than an arrow! */
1784 1771
1785 /* item damage. Eff_str and item weight influence damage done */ 1772 /* item damage. Eff_str and item weight influence damage done */
1786 weight_f = (throw_ob->weight / 2000) > MAX_STAT ? MAX_STAT : (throw_ob->weight / 2000); 1773 weight_f = (throw_ob->weight / 2000) > MAX_STAT ? MAX_STAT : (throw_ob->weight / 2000);
1787 throw_ob->stats.dam += (dam / 3) + dam_bonus[weight_f] + (throw_ob->weight / 15000) - 2; 1774 throw_ob->stats.dam += (dam / 3) + dam_bonus[weight_f] + (throw_ob->weight / 15000) - 2;
1788 1775
1789 /* chance of breaking. Proportional to force used and weight of item */ 1776 /* chance of breaking. Proportional to force used and weight of item */
1790 throw_ob->stats.food = (dam / 2) + (throw_ob->weight / 60000); 1777 throw_ob->stats.food = (dam / 2) + (throw_ob->weight / 60000);
1791 1778
1792 /* replace 25 with a call to clone.arch wc? messes up w/ NPC */ 1779 /* replace 25 with a call to clone.arch wc? messes up w/ NPC */
1793 throw_ob->stats.wc = 25 - dex_bonus[op->stats.Dex] - thaco_bonus[eff_str] - skill->level; 1780 throw_ob->stats.wc = 25 - dex_bonus[op->stats.Dex] - thaco_bonus[eff_str] - skill->level;
1794
1795 1781
1796 /* the properties of objects which are meant to be thrown (ie dart, 1782 /* the properties of objects which are meant to be thrown (ie dart,
1797 * throwing knife, etc) will differ from ordinary items. Lets tailor 1783 * throwing knife, etc) will differ from ordinary items. Lets tailor
1798 * this stuff in here. 1784 * this stuff in here.
1799 */ 1785 */
1813 if (throw_ob->material & M_LEATHER) 1799 if (throw_ob->material & M_LEATHER)
1814 { 1800 {
1815 throw_ob->stats.dam -= 1; 1801 throw_ob->stats.dam -= 1;
1816 throw_ob->stats.food -= 10; 1802 throw_ob->stats.food -= 10;
1817 } 1803 }
1804
1818 if (throw_ob->material & M_GLASS) 1805 if (throw_ob->material & M_GLASS)
1819 throw_ob->stats.food += 60; 1806 throw_ob->stats.food += 60;
1820 1807
1821 if (throw_ob->material & M_ORGANIC) 1808 if (throw_ob->material & M_ORGANIC)
1822 { 1809 {
1823 throw_ob->stats.dam -= 3; 1810 throw_ob->stats.dam -= 3;
1824 throw_ob->stats.food += 55; 1811 throw_ob->stats.food += 55;
1825 } 1812 }
1813
1826 if (throw_ob->material & M_PAPER || throw_ob->material & M_CLOTH) 1814 if (throw_ob->material & M_PAPER || throw_ob->material & M_CLOTH)
1827 { 1815 {
1828 throw_ob->stats.dam -= 5; 1816 throw_ob->stats.dam -= 5;
1829 throw_ob->speed *= 0.8; 1817 throw_ob->speed *= 0.8;
1830 throw_ob->stats.wc += 3; 1818 throw_ob->stats.wc += 3;
1831 throw_ob->stats.food -= 30; 1819 throw_ob->stats.food -= 30;
1832 } 1820 }
1821
1833 /* light obj have more wind resistance, fly slower */ 1822 /* light obj have more wind resistance, fly slower */
1834 if (throw_ob->weight > 500) 1823 if (throw_ob->weight > 500)
1835 throw_ob->speed *= 0.8; 1824 throw_ob->speed *= 0.8;
1825
1836 if (throw_ob->weight > 50) 1826 if (throw_ob->weight > 50)
1837 throw_ob->speed *= 0.5; 1827 throw_ob->speed *= 0.5;
1838
1839 } /* else tailor thrown object */ 1828 } /* else tailor thrown object */
1840 1829
1841 /* some limits, and safeties (needed?) */ 1830 /* some limits, and safeties (needed?) */
1842 if (throw_ob->stats.dam < 0) 1831 if (throw_ob->stats.dam < 0)
1843 throw_ob->stats.dam = 0; 1832 throw_ob->stats.dam = 0;
1863 * In short summary, a throw can take anywhere between speed 5 and 1852 * In short summary, a throw can take anywhere between speed 5 and
1864 * speed 0.5 1853 * speed 0.5
1865 */ 1854 */
1866 op->speed_left -= 50 / pause_f; 1855 op->speed_left -= 50 / pause_f;
1867 1856
1868 update_ob_speed (throw_ob);
1869 throw_ob->speed_left = 0; 1857 throw_ob->speed_left = 0;
1870 throw_ob->map = part->map; 1858 throw_ob->map = part->map;
1871 1859
1872 throw_ob->move_type = MOVE_FLY_LOW; 1860 throw_ob->move_type = MOVE_FLY_LOW;
1873 throw_ob->move_on = MOVE_FLY_LOW | MOVE_WALK; 1861 throw_ob->move_on = MOVE_FLY_LOW | MOVE_WALK;
1883 LOG (llevDebug, " pause_f=%d \n", pause_f); 1871 LOG (llevDebug, " pause_f=%d \n", pause_f);
1884 LOG (llevDebug, " %s stats: wc=%d dam=%d dist=%d spd=%f break=%d\n", 1872 LOG (llevDebug, " %s stats: wc=%d dam=%d dist=%d spd=%f break=%d\n",
1885 throw_ob->name, throw_ob->stats.wc, throw_ob->stats.dam, throw_ob->last_sp, throw_ob->speed, throw_ob->stats.food); 1873 throw_ob->name, throw_ob->stats.wc, throw_ob->stats.dam, throw_ob->last_sp, throw_ob->speed, throw_ob->stats.food);
1886 LOG (llevDebug, "inserting tossitem (%d) into map\n", throw_ob->count); 1874 LOG (llevDebug, "inserting tossitem (%d) into map\n", throw_ob->count);
1887#endif 1875#endif
1888 insert_ob_in_map (throw_ob, part->map, op, 0); 1876
1877 throw_ob->insert_at (part, op);
1889 1878
1890 if (!throw_ob->destroyed ()) 1879 if (!throw_ob->destroyed ())
1891 move_arrow (throw_ob); 1880 move_arrow (throw_ob);
1892 1881
1893 return 1; 1882 return 1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines