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

Comparing deliantra/server/server/apply.C (file contents):
Revision 1.22 by root, Sun Sep 10 15:59:57 2006 UTC vs.
Revision 1.31 by root, Sun Dec 3 20:26:35 2006 UTC

1
2/*
3 * static char *rcsid_apply_c =
4 * "$Id: apply.C,v 1.22 2006/09/10 15:59:57 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The authors can be reached via e-mail to crossfire-devel@real-time.com 21 The authors can be reached via e-mail to <crossfire@schmorp.de>
28*/ 22*/
29 23
30#include <global.h> 24#include <global.h>
31#include <living.h> 25#include <living.h>
32#include <spells.h> 26#include <spells.h>
232 drain_stat (op); 226 drain_stat (op);
233 fix_player (op); 227 fix_player (op);
234 decrease_ob (tmp); 228 decrease_ob (tmp);
235 return 1; 229 return 1;
236 } 230 }
237 if ((at = find_archetype (ARCH_DEPLETION)) == NULL) 231 if ((at = archetype::find (ARCH_DEPLETION)) == NULL)
238 { 232 {
239 LOG (llevError, "Could not find archetype depletion\n"); 233 LOG (llevError, "Could not find archetype depletion\n");
240 return 0; 234 return 0;
241 } 235 }
242 depl = present_arch_in_ob (at, op); 236 depl = present_arch_in_ob (at, op);
737 eat_item (op, improver->slaying, sacrifice_needed); 731 eat_item (op, improver->slaying, sacrifice_needed);
738 weapon->item_power++; 732 weapon->item_power++;
739 733
740 switch (improver->stats.sp) 734 switch (improver->stats.sp)
741 { 735 {
742 case IMPROVE_STR: 736 case IMPROVE_STR:
743 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Str), 1, "strength"); 737 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Str), 1, "strength");
744 case IMPROVE_DEX: 738 case IMPROVE_DEX:
745 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Dex), 1, "dexterity"); 739 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Dex), 1, "dexterity");
746 case IMPROVE_CON: 740 case IMPROVE_CON:
747 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Con), 1, "constitution"); 741 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Con), 1, "constitution");
748 case IMPROVE_WIS: 742 case IMPROVE_WIS:
749 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Wis), 1, "wisdom"); 743 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Wis), 1, "wisdom");
750 case IMPROVE_CHA: 744 case IMPROVE_CHA:
751 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Cha), 1, "charisma"); 745 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Cha), 1, "charisma");
752 case IMPROVE_INT: 746 case IMPROVE_INT:
753 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Int), 1, "intelligence"); 747 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Int), 1, "intelligence");
754 case IMPROVE_POW: 748 case IMPROVE_POW:
755 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Pow), 1, "power"); 749 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Pow), 1, "power");
756 default: 750 default:
757 new_draw_info (NDI_UNIQUE, 0, op, "Unknown improvement type."); 751 new_draw_info (NDI_UNIQUE, 0, op, "Unknown improvement type.");
758 } 752 }
759 LOG (llevError, "improve_weapon: Got to end of function\n"); 753 LOG (llevError, "improve_weapon: Got to end of function\n");
760 return 0; 754 return 0;
761} 755}
762 756
1315 else 1309 else
1316 { 1310 {
1317 altar->value = 1; /* works only once */ 1311 altar->value = 1; /* works only once */
1318 push_button (altar); 1312 push_button (altar);
1319 } 1313 }
1314
1320 return sacrifice == NULL; 1315 return !sacrifice;
1321 } 1316 }
1322 else 1317 else
1323 {
1324 return 0; 1318 return 0;
1325 }
1326} 1319}
1327
1328 1320
1329/** 1321/**
1330 * Handles 'movement' of shop mats. 1322 * Handles 'movement' of shop mats.
1331 * Returns 1 if 'op' was destroyed, 0 if not. 1323 * Returns 1 if 'op' was destroyed, 0 if not.
1332 * Largely re-written to not use nearly as many gotos, plus 1324 * Largely re-written to not use nearly as many gotos, plus
1349 * the shop. 1341 * the shop.
1350 */ 1342 */
1351 for (tmp = op->inv; tmp; tmp = next) 1343 for (tmp = op->inv; tmp; tmp = next)
1352 { 1344 {
1353 next = tmp->below; 1345 next = tmp->below;
1346
1354 if (QUERY_FLAG (tmp, FLAG_UNPAID)) 1347 if (QUERY_FLAG (tmp, FLAG_UNPAID))
1355 { 1348 {
1356 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); 1349 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9);
1357 1350
1358 remove_ob (tmp); 1351 remove_ob (tmp);
1352
1359 if (i == -1) 1353 if (i == -1)
1360 i = 0; 1354 i = 0;
1355
1361 tmp->map = op->map; 1356 tmp->map = op->map;
1362 tmp->x = op->x + freearr_x[i]; 1357 tmp->x = op->x + freearr_x[i];
1363 tmp->y = op->y + freearr_y[i]; 1358 tmp->y = op->y + freearr_y[i];
1364 insert_ob_in_map (tmp, op->map, op, 0); 1359 insert_ob_in_map (tmp, op->map, op, 0);
1365 } 1360 }
1377 1372
1378 /* Somebody dropped an unpaid item, just move to an adjacent place. */ 1373 /* Somebody dropped an unpaid item, just move to an adjacent place. */
1379 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); 1374 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
1380 1375
1381 if (i != -1) 1376 if (i != -1)
1382 {
1383 rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat); 1377 rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat);
1384 } 1378
1385 return 0; 1379 return 0;
1386 } 1380 }
1387 /* Removed code that checked for multipart objects - it appears that 1381 /* Removed code that checked for multipart objects - it appears that
1388 * the teleport function should be able to handle this just fine. 1382 * the teleport function should be able to handle this just fine.
1389 */ 1383 */
1390 rv = teleport (shop_mat, SHOP_MAT, op); 1384 rv = teleport (shop_mat, SHOP_MAT, op);
1391 } 1385 }
1392 /* immediate block below is only used for players */ 1386 else if (can_pay (op) && get_payment (op))
1393 else if (can_pay (op))
1394 { 1387 {
1395 get_payment (op, op->inv); 1388 /* this is only used for players */
1396 rv = teleport (shop_mat, SHOP_MAT, op); 1389 rv = teleport (shop_mat, SHOP_MAT, op);
1397 1390
1398 if (shop_mat->msg) 1391 if (shop_mat->msg)
1399 {
1400 new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg); 1392 new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg);
1401 }
1402 /* This check below is a bit simplistic - generally it should be correct, 1393 /* This check below is a bit simplistic - generally it should be correct,
1403 * but there is never a guarantee that the bottom space on the map is 1394 * but there is never a guarantee that the bottom space on the map is
1404 * actually the shop floor. 1395 * actually the shop floor.
1405 */ 1396 */
1406 else if (!rv && !is_in_shop (op)) 1397 else if (!rv && !is_in_shop (op))
1407 { 1398 {
1408 opinion = shopkeeper_approval (op->map, op); 1399 opinion = shopkeeper_approval (op->map, op);
1400
1409 if (opinion > 0.9) 1401 if (opinion > 0.9)
1410 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper gives you a friendly wave."); 1402 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper gives you a friendly wave.");
1411 else if (opinion > 0.75) 1403 else if (opinion > 0.75)
1412 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper waves to you."); 1404 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper waves to you.");
1413 else if (opinion > 0.5) 1405 else if (opinion > 0.5)
1420 { 1412 {
1421 /* if we get here, a player tried to leave a shop but was not able 1413 /* if we get here, a player tried to leave a shop but was not able
1422 * to afford the items he has. We try to move the player so that 1414 * to afford the items he has. We try to move the player so that
1423 * they are not on the mat anymore 1415 * they are not on the mat anymore
1424 */ 1416 */
1425
1426 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); 1417 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
1427 1418
1428 if (i == -1) 1419 if (i == -1)
1429 { 1420 {
1430 LOG (llevError, "Internal shop-mat problem.\n"); 1421 LOG (llevError, "Internal shop-mat problem.\n");
1435 op->x += freearr_x[i]; 1426 op->x += freearr_x[i];
1436 op->y += freearr_y[i]; 1427 op->y += freearr_y[i];
1437 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL; 1428 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL;
1438 } 1429 }
1439 } 1430 }
1431
1440 CLEAR_FLAG (op, FLAG_NO_APPLY); 1432 CLEAR_FLAG (op, FLAG_NO_APPLY);
1441 return rv; 1433 return rv;
1442} 1434}
1443 1435
1444/** 1436/**
1524 if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator))) 1516 if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator)))
1525 goto leave; 1517 goto leave;
1526 1518
1527 switch (trap->type) 1519 switch (trap->type)
1528 { 1520 {
1529 case PLAYERMOVER: 1521 case PLAYERMOVER:
1530 if (trap->attacktype && (trap->level || victim->type != PLAYER) && !should_director_abort (trap, victim)) 1522 if (trap->attacktype && (trap->level || victim->type != PLAYER) && !should_director_abort (trap, victim))
1523 {
1524 if (!trap->stats.maxsp)
1525 trap->stats.maxsp = 2;
1526
1527 /* Is this correct? From the docs, it doesn't look like it
1528 * should be divided by trap->speed
1529 */
1530 victim->speed_left = -FABS (trap->stats.maxsp * victim->speed / trap->speed);
1531
1532 /* Just put in some sanity check. I think there is a bug in the
1533 * above with some objects have zero speed, and thus the player
1534 * getting permanently paralyzed.
1535 */
1536 if (victim->speed_left < -50.0)
1537 victim->speed_left = -50.0;
1538 /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left); */
1539 }
1540 goto leave;
1541
1542 case SPINNER:
1543 if (victim->direction)
1544 {
1545 victim->direction = absdir (victim->direction - trap->stats.sp);
1546 update_turn_face (victim);
1547 }
1548 goto leave;
1549
1550 case DIRECTOR:
1551 if (victim->direction && !should_director_abort (trap, victim))
1552 {
1553 victim->direction = trap->stats.sp;
1554 update_turn_face (victim);
1555 }
1556 goto leave;
1557
1558 case BUTTON:
1559 case PEDESTAL:
1560 update_button (trap);
1561 goto leave;
1562
1563 case ALTAR:
1564 /* sacrifice victim on trap */
1565 apply_altar (trap, victim, originator);
1566 goto leave;
1567
1568 case THROWN_OBJ:
1569 if (trap->inv == NULL)
1570 goto leave;
1571 /* fallthrough */
1572
1573 case ARROW:
1574 /* bad bug: monster throw a object, make a step forwards, step on object ,
1575 * trigger this here and get hit by own missile - and will be own enemy.
1576 * Victim then is his own enemy and will start to kill herself (this is
1577 * removed) but we have not synced victim and his missile. To avoid senseless
1578 * action, we avoid hits here
1579 */
1580 if ((QUERY_FLAG (victim, FLAG_ALIVE) && trap->speed) && trap->owner != victim)
1581 hit_with_arrow (trap, victim);
1582 goto leave;
1583
1584 case SPELL_EFFECT:
1585 apply_spell_effect (trap, victim);
1586 goto leave;
1587
1588 case TRAPDOOR:
1589 {
1590 int max, sound_was_played;
1591 object *ab, *ab_next;
1592
1593 if (!trap->value)
1531 { 1594 {
1532 if (!trap->stats.maxsp) 1595 int tot;
1533 trap->stats.maxsp = 2;
1534 1596
1535 /* Is this correct? From the docs, it doesn't look like it 1597 for (ab = trap->above, tot = 0; ab != NULL; ab = ab->above)
1536 * should be divided by trap->speed 1598 if ((ab->move_type && trap->move_on) || ab->move_type == 0)
1599 tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying;
1600
1601 if (!(trap->value = (tot > trap->weight) ? 1 : 0))
1602 goto leave;
1603
1604 SET_ANIMATION (trap, trap->value);
1605 update_object (trap, UP_OBJ_FACE);
1606 }
1607
1608 for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab; ab = ab_next)
1609 {
1610 /* need to set this up, since if we do transfer the object,
1611 * ab->above would be bogus
1537 */ 1612 */
1538 victim->speed_left = -FABS (trap->stats.maxsp * victim->speed / trap->speed);
1539
1540 /* Just put in some sanity check. I think there is a bug in the
1541 * above with some objects have zero speed, and thus the player
1542 * getting permanently paralyzed.
1543 */
1544 if (victim->speed_left < -50.0)
1545 victim->speed_left = -50.0;
1546 /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left); */
1547 }
1548 goto leave;
1549
1550 case SPINNER:
1551 if (victim->direction)
1552 {
1553 victim->direction = absdir (victim->direction - trap->stats.sp);
1554 update_turn_face (victim);
1555 }
1556 goto leave;
1557
1558 case DIRECTOR:
1559 if (victim->direction && !should_director_abort (trap, victim))
1560 {
1561 victim->direction = trap->stats.sp;
1562 update_turn_face (victim);
1563 }
1564 goto leave;
1565
1566 case BUTTON:
1567 case PEDESTAL:
1568 update_button (trap);
1569 goto leave;
1570
1571 case ALTAR:
1572 /* sacrifice victim on trap */
1573 apply_altar (trap, victim, originator);
1574 goto leave;
1575
1576 case THROWN_OBJ:
1577 if (trap->inv == NULL)
1578 goto leave;
1579 /* fallthrough */
1580
1581 case ARROW:
1582
1583 /* bad bug: monster throw a object, make a step forwards, step on object ,
1584 * trigger this here and get hit by own missile - and will be own enemy.
1585 * Victim then is his own enemy and will start to kill herself (this is
1586 * removed) but we have not synced victim and his missile. To avoid senseless
1587 * action, we avoid hits here
1588 */
1589 if ((QUERY_FLAG (victim, FLAG_ALIVE) && trap->speed) && trap->owner != victim)
1590 hit_with_arrow (trap, victim);
1591 goto leave;
1592
1593 case SPELL_EFFECT:
1594 apply_spell_effect (trap, victim);
1595 goto leave;
1596
1597 case TRAPDOOR:
1598 {
1599 int max, sound_was_played;
1600 object *ab, *ab_next;
1601
1602 if (!trap->value)
1603 {
1604 int tot;
1605
1606 for (ab = trap->above, tot = 0; ab != NULL; ab = ab->above)
1607 if ((ab->move_type && trap->move_on) || ab->move_type == 0)
1608 tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying;
1609
1610 if (!(trap->value = (tot > trap->weight) ? 1 : 0))
1611 goto leave;
1612
1613 SET_ANIMATION (trap, trap->value);
1614 update_object (trap, UP_OBJ_FACE);
1615 }
1616
1617 for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab; ab = ab_next)
1618 {
1619 /* need to set this up, since if we do transfer the object,
1620 * ab->above would be bogus
1621 */
1622 ab_next = ab->above; 1613 ab_next = ab->above;
1623 1614
1624 if ((ab->move_type && trap->move_on) || ab->move_type == 0) 1615 if ((ab->move_type && trap->move_on) || ab->move_type == 0)
1625 {
1626 if (!sound_was_played)
1627 {
1628 play_sound_map (trap->map, trap->x, trap->y, SOUND_FALL_HOLE);
1629 sound_was_played = 1;
1630 }
1631 new_draw_info (NDI_UNIQUE, 0, ab, "You fall into a trapdoor!");
1632 transfer_ob (ab, (int) EXIT_X (trap), (int) EXIT_Y (trap), 0, ab);
1633 }
1634 }
1635 goto leave;
1636 }
1637
1638
1639 case CONVERTER:
1640 if (convert_item (victim, trap) < 0)
1641 {
1642 object *op;
1643
1644 new_draw_info_format (NDI_UNIQUE, 0, originator, "The %s seems to be broken!", query_name (trap));
1645
1646 op = get_archetype ("burnout");
1647 if (op != NULL)
1648 { 1616 {
1649 op->x = trap->x; 1617 if (!sound_was_played)
1650 op->y = trap->y; 1618 {
1651 insert_ob_in_map (op, trap->map, trap, 0); 1619 play_sound_map (trap->map, trap->x, trap->y, SOUND_FALL_HOLE);
1620 sound_was_played = 1;
1621 }
1622 new_draw_info (NDI_UNIQUE, 0, ab, "You fall into a trapdoor!");
1623 transfer_ob (ab, (int) EXIT_X (trap), (int) EXIT_Y (trap), 0, ab);
1652 } 1624 }
1653 } 1625 }
1654 goto leave; 1626 goto leave;
1627 }
1655 1628
1629
1630 case CONVERTER:
1631 if (convert_item (victim, trap) < 0)
1632 {
1633 object *op;
1634
1635 new_draw_info_format (NDI_UNIQUE, 0, originator, "The %s seems to be broken!", query_name (trap));
1636
1637 op = get_archetype ("burnout");
1638 if (op != NULL)
1639 {
1640 op->x = trap->x;
1641 op->y = trap->y;
1642 insert_ob_in_map (op, trap->map, trap, 0);
1643 }
1644 }
1645 goto leave;
1646
1656 case TRIGGER_BUTTON: 1647 case TRIGGER_BUTTON:
1657 case TRIGGER_PEDESTAL: 1648 case TRIGGER_PEDESTAL:
1658 case TRIGGER_ALTAR: 1649 case TRIGGER_ALTAR:
1659 check_trigger (trap, victim); 1650 check_trigger (trap, victim);
1651 goto leave;
1652
1653 case DEEP_SWAMP:
1654 walk_on_deep_swamp (trap, victim);
1655 goto leave;
1656
1657 case CHECK_INV:
1658 check_inv (victim, trap);
1659 goto leave;
1660
1661 case HOLE:
1662 /* Hole not open? */
1663 if (trap->stats.wc > 0)
1660 goto leave; 1664 goto leave;
1661 1665
1662 case DEEP_SWAMP: 1666 /* Is this a multipart monster and not the head? If so, return.
1663 walk_on_deep_swamp (trap, victim); 1667 * Processing will happen if the head runs into the pit
1668 */
1669 if (victim->head)
1664 goto leave; 1670 goto leave;
1665 1671
1666 case CHECK_INV:
1667 check_inv (victim, trap);
1668 goto leave;
1669
1670 case HOLE:
1671 /* Hole not open? */
1672 if (trap->stats.wc > 0)
1673 goto leave;
1674
1675 /* Is this a multipart monster and not the head? If so, return.
1676 * Processing will happen if the head runs into the pit
1677 */
1678 if (victim->head)
1679 goto leave;
1680
1681 play_sound_map (victim->map, victim->x, victim->y, SOUND_FALL_HOLE); 1672 play_sound_map (victim->map, victim->x, victim->y, SOUND_FALL_HOLE);
1682 new_draw_info (NDI_UNIQUE, 0, victim, "You fall through the hole!\n"); 1673 new_draw_info (NDI_UNIQUE, 0, victim, "You fall through the hole!\n");
1683 transfer_ob (victim, EXIT_X (trap), EXIT_Y (trap), 1, victim); 1674 transfer_ob (victim, EXIT_X (trap), EXIT_Y (trap), 1, victim);
1684 goto leave; 1675 goto leave;
1685 1676
1686 case EXIT: 1677 case EXIT:
1687 if (victim->type == PLAYER && EXIT_PATH (trap)) 1678 if (victim->type == PLAYER && EXIT_PATH (trap))
1688 { 1679 {
1689 /* Basically, don't show exits leading to random maps the 1680 /* Basically, don't show exits leading to random maps the
1690 * players output. 1681 * players output.
1691 */ 1682 */
1692 if (trap->msg && strncmp (EXIT_PATH (trap), "/!", 2) && strncmp (EXIT_PATH (trap), "/random/", 8)) 1683 if (trap->msg && strncmp (EXIT_PATH (trap), "/!", 2) && strncmp (EXIT_PATH (trap), "/random/", 8))
1693 new_draw_info (NDI_NAVY, 0, victim, trap->msg); 1684 new_draw_info (NDI_NAVY, 0, victim, trap->msg);
1694 enter_exit (victim, trap); 1685 enter_exit (victim, trap);
1695 } 1686 }
1696 goto leave; 1687 goto leave;
1697 1688
1698 case ENCOUNTER: 1689 case ENCOUNTER:
1699 /* may be some leftovers on this */ 1690 /* may be some leftovers on this */
1700 goto leave; 1691 goto leave;
1701 1692
1702 case SHOP_MAT: 1693 case SHOP_MAT:
1703 apply_shop_mat (trap, victim); 1694 apply_shop_mat (trap, victim);
1704 goto leave; 1695 goto leave;
1705 1696
1706 /* Drop a certain amount of gold, and have one item identified */ 1697 /* Drop a certain amount of gold, and have one item identified */
1707 case IDENTIFY_ALTAR: 1698 case IDENTIFY_ALTAR:
1708 apply_id_altar (victim, trap, originator); 1699 apply_id_altar (victim, trap, originator);
1709 goto leave; 1700 goto leave;
1710 1701
1711 case SIGN: 1702 case SIGN:
1712 if (victim->type != PLAYER && trap->stats.food > 0) 1703 if (victim->type != PLAYER && trap->stats.food > 0)
1713 goto leave; /* monsters musn't apply magic_mouths with counters */ 1704 goto leave; /* monsters musn't apply magic_mouths with counters */
1714 1705
1715 apply_sign (victim, trap, 1); 1706 apply_sign (victim, trap, 1);
1716 goto leave; 1707 goto leave;
1717 1708
1718 case CONTAINER: 1709 case CONTAINER:
1719 if (victim->type == PLAYER) 1710 if (victim->type == PLAYER)
1720 (void) esrv_apply_container (victim, trap); 1711 (void) esrv_apply_container (victim, trap);
1721 else 1712 else
1722 (void) apply_container (victim, trap); 1713 (void) apply_container (victim, trap);
1723 goto leave; 1714 goto leave;
1724 1715
1725 case RUNE: 1716 case RUNE:
1726 case TRAP: 1717 case TRAP:
1727 if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE)) 1718 if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE))
1728 { 1719 {
1729 spring_trap (trap, victim); 1720 spring_trap (trap, victim);
1730 } 1721 }
1731 goto leave; 1722 goto leave;
1732 1723
1733 default: 1724 default:
1734 LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not " 1725 LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not "
1735 "handled in move_apply()\n", &trap->name, &trap->arch->name, trap->type); 1726 "handled in move_apply()\n", &trap->name, &trap->arch->name, trap->type);
1736 goto leave; 1727 goto leave;
1737 } 1728 }
1738 1729
1739leave: 1730leave:
1740 recursion_depth--; 1731 recursion_depth--;
1741} 1732}
1818static void 1809static void
1819apply_skillscroll (object *op, object *tmp) 1810apply_skillscroll (object *op, object *tmp)
1820{ 1811{
1821 switch ((int) learn_skill (op, tmp)) 1812 switch ((int) learn_skill (op, tmp))
1822 { 1813 {
1823 case 0: 1814 case 0:
1824 new_draw_info (NDI_UNIQUE, 0, op, "You already possess the knowledge "); 1815 new_draw_info (NDI_UNIQUE, 0, op, "You already possess the knowledge ");
1825 new_draw_info_format (NDI_UNIQUE, 0, op, "held within the %s.\n", query_name (tmp)); 1816 new_draw_info_format (NDI_UNIQUE, 0, op, "held within the %s.\n", query_name (tmp));
1826 return; 1817 return;
1827 1818
1828 case 1: 1819 case 1:
1829 new_draw_info_format (NDI_UNIQUE, 0, op, "You succeed in learning %s", &tmp->skill); 1820 new_draw_info_format (NDI_UNIQUE, 0, op, "You succeed in learning %s", &tmp->skill);
1830 decrease_ob (tmp); 1821 decrease_ob (tmp);
1831 return; 1822 return;
1832 1823
1833 default: 1824 default:
1834 new_draw_info_format (NDI_UNIQUE, 0, op, "You fail to learn the knowledge of the %s.\n", query_name (tmp)); 1825 new_draw_info_format (NDI_UNIQUE, 0, op, "You fail to learn the knowledge of the %s.\n", query_name (tmp));
1835 decrease_ob (tmp); 1826 decrease_ob (tmp);
1836 return; 1827 return;
1837 } 1828 }
1838} 1829}
1839 1830
1840/** 1831/**
1841 * Actually makes op learn spell. 1832 * Actually makes op learn spell.
1951 { 1942 {
1952 LOG (llevError, "apply_spellbook: Book %s has no spell in it!\n", &tmp->name); 1943 LOG (llevError, "apply_spellbook: Book %s has no spell in it!\n", &tmp->name);
1953 new_draw_info (NDI_UNIQUE, 0, op, "The spellbook symbols make no sense."); 1944 new_draw_info (NDI_UNIQUE, 0, op, "The spellbook symbols make no sense.");
1954 return; 1945 return;
1955 } 1946 }
1947
1956 if (spell->level > (skop->level + 10)) 1948 if (spell->level > (skop->level + 10))
1957 { 1949 {
1958 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to decipher the strange symbols."); 1950 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to decipher the strange symbols.");
1959 return; 1951 return;
1960 } 1952 }
1982 } 1974 }
1983 1975
1984 if (spell->skill) 1976 if (spell->skill)
1985 { 1977 {
1986 spell_skill = find_skill_by_name (op, spell->skill); 1978 spell_skill = find_skill_by_name (op, spell->skill);
1979
1987 if (!spell_skill) 1980 if (!spell_skill)
1988 { 1981 {
1989 new_draw_info_format (NDI_UNIQUE, 0, op, "You lack the skill %s to use this spell", &spell->skill); 1982 new_draw_info_format (NDI_UNIQUE, 0, op, "You lack the skill %s to use this spell", &spell->skill);
1990 return; 1983 return;
1991 } 1984 }
1985
1992 if (spell_skill->level < spell->level) 1986 if (spell_skill->level < spell->level)
1993 { 1987 {
1994 new_draw_info_format (NDI_UNIQUE, 0, op, "You need to be level %d in %s to learn this spell.", spell->level, &spell->skill); 1988 new_draw_info_format (NDI_UNIQUE, 0, op, "You need to be level %d in %s to learn this spell.", spell->level, &spell->skill);
1995 return; 1989 return;
1996 } 1990 }
2089 */ 2083 */
2090static void 2084static void
2091apply_treasure (object *op, object *tmp) 2085apply_treasure (object *op, object *tmp)
2092{ 2086{
2093 object *treas; 2087 object *treas;
2094 tag_t tmp_tag = tmp->count, op_tag = op->count;
2095 2088
2096 2089
2097 /* Nice side effect of new treasure creation method is that the treasure 2090 /* Nice side effect of new treasure creation method is that the treasure
2098 * for the chest is done when the chest is created, and put into the chest 2091 * for the chest is done when the chest is created, and put into the chest
2099 * inventory. So that when the chest burns up, the items still exist. Also 2092 * inventory. So that when the chest burns up, the items still exist. Also
2124 /* If either player or container was destroyed, no need to do 2117 /* If either player or container was destroyed, no need to do
2125 * further processing. I think this should be enclused with 2118 * further processing. I think this should be enclused with
2126 * spring trap above, as I don't think there is otherwise 2119 * spring trap above, as I don't think there is otherwise
2127 * any way for the treasure chest or player to get killed 2120 * any way for the treasure chest or player to get killed
2128 */ 2121 */
2129 if (was_destroyed (op, op_tag) || was_destroyed (tmp, tmp_tag)) 2122 if (op->destroyed () || tmp->destroyed ())
2130 break; 2123 break;
2131 } 2124 }
2132 2125
2133 if (!was_destroyed (tmp, tmp_tag) && tmp->inv == NULL) 2126 if (!tmp->destroyed () && tmp->inv == NULL)
2134 decrease_ob (tmp); 2127 decrease_ob (tmp);
2135 2128
2136} 2129}
2137 2130
2138/** 2131/**
2466is_legal_2ways_exit (object *op, object *exit) 2459is_legal_2ways_exit (object *op, object *exit)
2467{ 2460{
2468 object *tmp; 2461 object *tmp;
2469 object *exit_owner; 2462 object *exit_owner;
2470 player *pp; 2463 player *pp;
2471 mapstruct *exitmap; 2464 maptile *exitmap;
2472 2465
2473 if (exit->stats.exp != 1) 2466 if (exit->stats.exp != 1)
2474 return 1; /*This is not a 2 way, so it is legal */ 2467 return 1; /*This is not a 2 way, so it is legal */
2475 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race) 2468 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race)
2476 return 0; /* This is a reset town portal */ 2469 return 0; /* This is a reset town portal */
2569 return RESULT_INT (0); 2562 return RESULT_INT (0);
2570 2563
2571 switch (tmp->type) 2564 switch (tmp->type)
2572 { 2565 {
2573 2566
2574 case CF_HANDLE: 2567 case CF_HANDLE:
2575 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2568 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2576 play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE); 2569 play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE);
2577 tmp->value = tmp->value ? 0 : 1; 2570 tmp->value = tmp->value ? 0 : 1;
2578 SET_ANIMATION (tmp, tmp->value); 2571 SET_ANIMATION (tmp, tmp->value);
2579 update_object (tmp, UP_OBJ_FACE); 2572 update_object (tmp, UP_OBJ_FACE);
2580 push_button (tmp); 2573 push_button (tmp);
2581 return 1; 2574 return 1;
2582 2575
2583 case TRIGGER: 2576 case TRIGGER:
2584 if (check_trigger (tmp, op)) 2577 if (check_trigger (tmp, op))
2585 { 2578 {
2586 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2579 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2587 play_sound_map (tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE); 2580 play_sound_map (tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE);
2588 } 2581 }
2589 else 2582 else
2590 { 2583 {
2591 new_draw_info (NDI_UNIQUE, 0, op, "The handle doesn't move."); 2584 new_draw_info (NDI_UNIQUE, 0, op, "The handle doesn't move.");
2592 } 2585 }
2593 return 1; 2586 return 1;
2594 2587
2595 case EXIT: 2588 case EXIT:
2596 if (op->type != PLAYER) 2589 if (op->type != PLAYER)
2590 return 0;
2591 if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp))
2592 {
2593 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s is closed.", query_name (tmp));
2594 }
2595 else
2596 {
2597 /* Don't display messages for random maps. */
2598 if (tmp->msg && strncmp (EXIT_PATH (tmp), "/!", 2) && strncmp (EXIT_PATH (tmp), "/random/", 8))
2599 new_draw_info (NDI_NAVY, 0, op, tmp->msg);
2600 enter_exit (op, tmp);
2601 }
2602 return 1;
2603
2604 case SIGN:
2605 apply_sign (op, tmp, 0);
2606 return 1;
2607
2608 case BOOK:
2609 if (op->type == PLAYER)
2610 {
2611 apply_book (op, tmp);
2612 return 1;
2613 }
2614 else
2615 {
2597 return 0; 2616 return 0;
2598 if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp))
2599 {
2600 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s is closed.", query_name (tmp));
2601 } 2617 }
2602 else
2603 {
2604 /* Don't display messages for random maps. */
2605 if (tmp->msg && strncmp (EXIT_PATH (tmp), "/!", 2) && strncmp (EXIT_PATH (tmp), "/random/", 8))
2606 new_draw_info (NDI_NAVY, 0, op, tmp->msg);
2607 enter_exit (op, tmp);
2608 }
2609 return 1;
2610 2618
2611 case SIGN: 2619 case SKILLSCROLL:
2612 apply_sign (op, tmp, 0);
2613 return 1;
2614
2615 case BOOK:
2616 if (op->type == PLAYER) 2620 if (op->type == PLAYER)
2617 { 2621 {
2618 apply_book (op, tmp);
2619 return 1;
2620 }
2621 else
2622 {
2623 return 0;
2624 }
2625
2626 case SKILLSCROLL:
2627 if (op->type == PLAYER)
2628 {
2629 apply_skillscroll (op, tmp); 2622 apply_skillscroll (op, tmp);
2630 return 1; 2623 return 1;
2631 } 2624 }
2632 return 0; 2625 return 0;
2633 2626
2634 case SPELLBOOK: 2627 case SPELLBOOK:
2635 if (op->type == PLAYER) 2628 if (op->type == PLAYER)
2636 { 2629 {
2637 apply_spellbook (op, tmp); 2630 apply_spellbook (op, tmp);
2638 return 1; 2631 return 1;
2639 } 2632 }
2640 return 0; 2633 return 0;
2641 2634
2642 case SCROLL: 2635 case SCROLL:
2643 apply_scroll (op, tmp, 0); 2636 apply_scroll (op, tmp, 0);
2644 return 1; 2637 return 1;
2645 2638
2646 case POTION: 2639 case POTION:
2647 (void) apply_potion (op, tmp); 2640 (void) apply_potion (op, tmp);
2648 return 1; 2641 return 1;
2649 2642
2650 /* Eneq(@csd.uu.se): Handle apply on containers. */ 2643 /* Eneq(@csd.uu.se): Handle apply on containers. */
2651 case CLOSE_CON: 2644 case CLOSE_CON:
2652 if (op->type == PLAYER) 2645 if (op->type == PLAYER)
2653 (void) esrv_apply_container (op, tmp->env); 2646 (void) esrv_apply_container (op, tmp->env);
2654 else 2647 else
2655 (void) apply_container (op, tmp->env); 2648 (void) apply_container (op, tmp->env);
2656 return 1; 2649 return 1;
2657 2650
2658 case CONTAINER: 2651 case CONTAINER:
2659 if (op->type == PLAYER) 2652 if (op->type == PLAYER)
2660 (void) esrv_apply_container (op, tmp); 2653 (void) esrv_apply_container (op, tmp);
2661 else 2654 else
2662 (void) apply_container (op, tmp); 2655 (void) apply_container (op, tmp);
2663 return 1; 2656 return 1;
2664 2657
2665 case TREASURE: 2658 case TREASURE:
2666 if (op->type == PLAYER) 2659 if (op->type == PLAYER)
2667 { 2660 {
2668 apply_treasure (op, tmp); 2661 apply_treasure (op, tmp);
2669 return 1; 2662 return 1;
2670 } 2663 }
2671 else 2664 else
2672 { 2665 {
2673 return 0; 2666 return 0;
2674 } 2667 }
2675 2668
2676 case WEAPON: 2669 case WEAPON:
2677 case ARMOUR: 2670 case ARMOUR:
2678 case BOOTS: 2671 case BOOTS:
2679 case GLOVES: 2672 case GLOVES:
2680 case AMULET: 2673 case AMULET:
2681 case GIRDLE: 2674 case GIRDLE:
2682 case BRACERS: 2675 case BRACERS:
2683 case SHIELD: 2676 case SHIELD:
2684 case HELMET: 2677 case HELMET:
2685 case RING: 2678 case RING:
2686 case CLOAK: 2679 case CLOAK:
2687 case WAND: 2680 case WAND:
2688 case ROD: 2681 case ROD:
2689 case HORN: 2682 case HORN:
2690 case SKILL: 2683 case SKILL:
2691 case BOW: 2684 case BOW:
2692 case LAMP: 2685 case LAMP:
2693 case BUILDER: 2686 case BUILDER:
2694 case SKILL_TOOL: 2687 case SKILL_TOOL:
2695 if (tmp->env != op) 2688 if (tmp->env != op)
2696 return 2; /* not in inventory */ 2689 return 2; /* not in inventory */
2697 (void) apply_special (op, tmp, aflag); 2690 (void) apply_special (op, tmp, aflag);
2698 return 1; 2691 return 1;
2699 2692
2700 case DRINK: 2693 case DRINK:
2701 case FOOD: 2694 case FOOD:
2702 case FLESH: 2695 case FLESH:
2703 apply_food (op, tmp); 2696 apply_food (op, tmp);
2704 return 1; 2697 return 1;
2705 2698
2706 case POISON: 2699 case POISON:
2707 apply_poison (op, tmp); 2700 apply_poison (op, tmp);
2708 return 1; 2701 return 1;
2709 2702
2710 case SAVEBED: 2703 case SAVEBED:
2711 if (op->type == PLAYER) 2704 if (op->type == PLAYER)
2712 { 2705 {
2713 apply_savebed (op); 2706 apply_savebed (op);
2714 return 1; 2707 return 1;
2715 } 2708 }
2716 else 2709 else
2717 { 2710 {
2718 return 0; 2711 return 0;
2719 } 2712 }
2720 2713
2721 case ARMOUR_IMPROVER: 2714 case ARMOUR_IMPROVER:
2722 if (op->type == PLAYER) 2715 if (op->type == PLAYER)
2723 { 2716 {
2724 apply_armour_improver (op, tmp); 2717 apply_armour_improver (op, tmp);
2725 return 1; 2718 return 1;
2726 } 2719 }
2727 else 2720 else
2728 { 2721 {
2729 return 0; 2722 return 0;
2730 } 2723 }
2731 2724
2732 case WEAPON_IMPROVER: 2725 case WEAPON_IMPROVER:
2733 (void) check_improve_weapon (op, tmp); 2726 (void) check_improve_weapon (op, tmp);
2734 return 1; 2727 return 1;
2735 2728
2736 case CLOCK: 2729 case CLOCK:
2737 if (op->type == PLAYER) 2730 if (op->type == PLAYER)
2738 { 2731 {
2739 char buf[MAX_BUF]; 2732 char buf[MAX_BUF];
2740 timeofday_t tod; 2733 timeofday_t tod;
2741 2734
2742 get_tod (&tod); 2735 get_tod (&tod);
2743 sprintf (buf, "It is %d minute%s past %d o'clock %s", 2736 sprintf (buf, "It is %d minute%s past %d o'clock %s",
2744 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"), 2737 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"),
2745 ((tod.hour % 14 == 0) ? 14 : ((tod.hour) % 14)), ((tod.hour >= 14) ? "pm" : "am")); 2738 ((tod.hour % 14 == 0) ? 14 : ((tod.hour) % 14)), ((tod.hour >= 14) ? "pm" : "am"));
2746 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0); 2739 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0);
2747 new_draw_info (NDI_UNIQUE, 0, op, buf); 2740 new_draw_info (NDI_UNIQUE, 0, op, buf);
2748 return 1; 2741 return 1;
2749 } 2742 }
2750 else 2743 else
2751 { 2744 {
2752 return 0; 2745 return 0;
2753 } 2746 }
2754 2747
2755 case MENU: 2748 case MENU:
2756 if (op->type == PLAYER) 2749 if (op->type == PLAYER)
2757 { 2750 {
2758 shop_listing (op); 2751 shop_listing (op);
2759 return 1; 2752 return 1;
2760 } 2753 }
2761 else 2754 else
2762 { 2755 {
2763 return 0; 2756 return 0;
2764 } 2757 }
2765 2758
2766 case POWER_CRYSTAL: 2759 case POWER_CRYSTAL:
2767 apply_power_crystal (op, tmp); /* see egoitem.c */ 2760 apply_power_crystal (op, tmp); /* see egoitem.c */
2768 return 1; 2761 return 1;
2769 2762
2770 case LIGHTER: /* for lighting torches/lanterns/etc */ 2763 case LIGHTER: /* for lighting torches/lanterns/etc */
2771 if (op->type == PLAYER) 2764 if (op->type == PLAYER)
2772 { 2765 {
2773 apply_lighter (op, tmp); 2766 apply_lighter (op, tmp);
2774 return 1; 2767 return 1;
2775 } 2768 }
2776 else 2769 else
2777 { 2770 {
2778 return 0; 2771 return 0;
2779 } 2772 }
2780 2773
2781 case ITEM_TRANSFORMER: 2774 case ITEM_TRANSFORMER:
2782 apply_item_transformer (op, tmp); 2775 apply_item_transformer (op, tmp);
2783 return 1; 2776 return 1;
2784 2777
2785 default: 2778 default:
2786 return 0; 2779 return 0;
2787 } 2780 }
2788} 2781}
2789 2782
2790 2783
2791/* quiet suppresses the "don't know how to apply" and "you must get it first" 2784/* quiet suppresses the "don't know how to apply" and "you must get it first"
2897 object *tmp2; 2890 object *tmp2;
2898 2891
2899 CLEAR_FLAG (op, FLAG_APPLIED); 2892 CLEAR_FLAG (op, FLAG_APPLIED);
2900 switch (op->type) 2893 switch (op->type)
2901 { 2894 {
2902 case WEAPON: 2895 case WEAPON:
2903 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwield %s.", query_name (op)); 2896 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwield %s.", query_name (op));
2904 2897
2905 (void) change_abil (who, op); 2898 (void) change_abil (who, op);
2906 if (QUERY_FLAG (who, FLAG_READY_WEAPON)) 2899 if (QUERY_FLAG (who, FLAG_READY_WEAPON))
2907 CLEAR_FLAG (who, FLAG_READY_WEAPON); 2900 CLEAR_FLAG (who, FLAG_READY_WEAPON);
2908 clear_skill (who); 2901 clear_skill (who);
2909 break; 2902 break;
2910 2903
2911 case SKILL: /* allows objects to impart skills */ 2904 case SKILL: /* allows objects to impart skills */
2912 case SKILL_TOOL: 2905 case SKILL_TOOL:
2913 if (op != who->chosen_skill) 2906 if (op != who->chosen_skill)
2914 { 2907 {
2915 LOG (llevError, "BUG: apply_special(): applied skill is not a chosen skill\n"); 2908 LOG (llevError, "BUG: apply_special(): applied skill is not a chosen skill\n");
2916 } 2909 }
2917 if (who->type == PLAYER) 2910 if (who->type == PLAYER)
2918 { 2911 {
2919 if (who->contr->shoottype == range_skill) 2912 if (who->contr->shoottype == range_skill)
2920 who->contr->shoottype = range_none;
2921 if (!op->invisible)
2922 {
2923 new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op));
2924 }
2925 else
2926 {
2927 new_draw_info_format (NDI_UNIQUE, 0, who, "You can no longer use the skill: %s.", &op->skill);
2928 }
2929 }
2930 (void) change_abil (who, op);
2931 who->chosen_skill = NULL;
2932 CLEAR_FLAG (who, FLAG_READY_SKILL);
2933 break;
2934
2935 case ARMOUR:
2936 case HELMET:
2937 case SHIELD:
2938 case RING:
2939 case BOOTS:
2940 case GLOVES:
2941 case AMULET:
2942 case GIRDLE:
2943 case BRACERS:
2944 case CLOAK:
2945 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwear %s.", query_name (op));
2946 (void) change_abil (who, op);
2947 break;
2948 case LAMP:
2949 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn off your %s.", &op->name);
2950 tmp2 = arch_to_object (op->other_arch);
2951 tmp2->x = op->x;
2952 tmp2->y = op->y;
2953 tmp2->map = op->map;
2954 tmp2->below = op->below;
2955 tmp2->above = op->above;
2956 tmp2->stats.food = op->stats.food;
2957 CLEAR_FLAG (tmp2, FLAG_APPLIED);
2958 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
2959 SET_FLAG (tmp2, FLAG_INV_LOCKED);
2960 if (who->type == PLAYER)
2961 esrv_del_item (who->contr, (tag_t) op->count);
2962 remove_ob (op);
2963 free_object (op);
2964 insert_ob_in_ob (tmp2, who);
2965 fix_player (who);
2966 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2967 {
2968 if (who->type == PLAYER)
2969 {
2970 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
2971 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
2972 }
2973 }
2974 if (who->type == PLAYER)
2975 esrv_send_item (who, tmp2);
2976 return 1; /* otherwise, an attempt to drop causes problems */
2977 break;
2978 case BOW:
2979 case WAND:
2980 case ROD:
2981 case HORN:
2982 clear_skill (who);
2983 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2984 if (who->type == PLAYER)
2985 {
2986 who->contr->shoottype = range_none; 2913 who->contr->shoottype = range_none;
2987 } 2914 if (!op->invisible)
2988 else
2989 { 2915 {
2990 if (op->type == BOW) 2916 new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op));
2991 CLEAR_FLAG (who, FLAG_READY_BOW); 2917 }
2992 else 2918 else
2993 CLEAR_FLAG (who, FLAG_READY_RANGE); 2919 {
2920 new_draw_info_format (NDI_UNIQUE, 0, who, "You can no longer use the skill: %s.", &op->skill);
2994 } 2921 }
2922 }
2923 (void) change_abil (who, op);
2924 who->chosen_skill = NULL;
2925 CLEAR_FLAG (who, FLAG_READY_SKILL);
2995 break; 2926 break;
2996 2927
2928 case ARMOUR:
2929 case HELMET:
2997 case BUILDER: 2930 case SHIELD:
2931 case RING:
2932 case BOOTS:
2933 case GLOVES:
2934 case AMULET:
2935 case GIRDLE:
2936 case BRACERS:
2937 case CLOAK:
2938 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwear %s.", query_name (op));
2939 (void) change_abil (who, op);
2940 break;
2941 case LAMP:
2942 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn off your %s.", &op->name);
2943 tmp2 = arch_to_object (op->other_arch);
2944 tmp2->x = op->x;
2945 tmp2->y = op->y;
2946 tmp2->map = op->map;
2947 tmp2->below = op->below;
2948 tmp2->above = op->above;
2949 tmp2->stats.food = op->stats.food;
2950 CLEAR_FLAG (tmp2, FLAG_APPLIED);
2951
2952 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
2953 SET_FLAG (tmp2, FLAG_INV_LOCKED);
2954
2955 if (who->type == PLAYER)
2956 esrv_del_item (who->contr, op->count);
2957
2958 remove_ob (op);
2959 free_object (op);
2960 insert_ob_in_ob (tmp2, who);
2961 fix_player (who);
2962 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2963 {
2964 if (who->type == PLAYER)
2965 {
2966 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
2967 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
2968 }
2969 }
2970 if (who->type == PLAYER)
2971 esrv_send_item (who, tmp2);
2972 return 1; /* otherwise, an attempt to drop causes problems */
2973 break;
2974 case BOW:
2975 case WAND:
2976 case ROD:
2977 case HORN:
2978 clear_skill (who);
2998 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op)); 2979 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2980 if (who->type == PLAYER)
2981 {
2999 who->contr->shoottype = range_none; 2982 who->contr->shoottype = range_none;
2983 }
2984 else
2985 {
2986 if (op->type == BOW)
2987 CLEAR_FLAG (who, FLAG_READY_BOW);
2988 else
2989 CLEAR_FLAG (who, FLAG_READY_RANGE);
2990 }
2991 break;
2992
2993 case BUILDER:
2994 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2995 who->contr->shoottype = range_none;
3000 who->contr->ranges[range_builder] = NULL; 2996 who->contr->ranges[range_builder] = NULL;
3001 break; 2997 break;
3002 2998
3003 default: 2999 default:
3004 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op)); 3000 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op));
3005 break; 3001 break;
3006 } 3002 }
3007 3003
3008 fix_player (who); 3004 fix_player (who);
3009 3005
3010 if (!(aflags & AP_NO_MERGE)) 3006 if (!(aflags & AP_NO_MERGE))
3011 { 3007 {
3012 object *tmp; 3008 object *tmp;
3013
3014 tag_t del_tag = op->count;
3015 3009
3016 tmp = merge_ob (op, NULL); 3010 tmp = merge_ob (op, NULL);
3017 if (who->type == PLAYER) 3011 if (who->type == PLAYER)
3018 { 3012 {
3019 if (tmp) 3013 if (tmp)
3020 { /* it was merged */ 3014 { /* it was merged */
3021 esrv_del_item (who->contr, del_tag); 3015 esrv_del_item (who->contr, op->count);
3022 op = tmp; 3016 op = tmp;
3023 } 3017 }
3018
3024 esrv_send_item (who, op); 3019 esrv_send_item (who, op);
3025 } 3020 }
3026 } 3021 }
3027 return 0; 3022 return 0;
3028} 3023}
3432 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op))) 3427 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op)))
3433 return RESULT_INT (0); 3428 return RESULT_INT (0);
3434 3429
3435 switch (op->type) 3430 switch (op->type)
3436 { 3431 {
3437 case WEAPON: 3432 case WEAPON:
3438 if (!check_weapon_power (who, op->last_eat)) 3433 if (!check_weapon_power (who, op->last_eat))
3439 { 3434 {
3440 new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use."); 3435 new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use.");
3441 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); 3436 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!.");
3442 if (tmp != NULL) 3437 if (tmp != NULL)
3443 (void) insert_ob_in_ob (tmp, who);
3444 return 1;
3445 }
3446 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3447 {
3448 /* if the weapon does not have the name as the character, can't use it. */
3449 /* (Ragnarok's sword attempted to be used by Foo: won't work) */
3450 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3451 if (tmp != NULL)
3452 (void) insert_ob_in_ob (tmp, who);
3453 return 1;
3454 }
3455 SET_FLAG (op, FLAG_APPLIED);
3456
3457 if (skop)
3458 change_skill (who, skop, 1);
3459 if (!QUERY_FLAG (who, FLAG_READY_WEAPON))
3460 SET_FLAG (who, FLAG_READY_WEAPON);
3461
3462 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op));
3463
3464 (void) change_abil (who, op);
3465 break;
3466
3467 case ARMOUR:
3468 case HELMET:
3469 case SHIELD:
3470 case BOOTS:
3471 case GLOVES:
3472 case GIRDLE:
3473 case BRACERS:
3474 case CLOAK:
3475 case RING:
3476 case AMULET:
3477 SET_FLAG (op, FLAG_APPLIED);
3478 new_draw_info_format (NDI_UNIQUE, 0, who, "You wear %s.", query_name (op));
3479 (void) change_abil (who, op);
3480 break;
3481 case LAMP:
3482 if (op->stats.food < 1)
3483 {
3484 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name);
3485 return 1;
3486 }
3487 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name);
3488 tmp2 = arch_to_object (op->other_arch);
3489 tmp2->stats.food = op->stats.food;
3490 SET_FLAG (tmp2, FLAG_APPLIED);
3491 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
3492 SET_FLAG (tmp2, FLAG_INV_LOCKED);
3493 insert_ob_in_ob (tmp2, who);
3494
3495 /* Remove the old lantern */
3496 if (who->type == PLAYER)
3497 esrv_del_item (who->contr, (tag_t) op->count);
3498 remove_ob (op);
3499 free_object (op);
3500
3501 /* insert the portion that was split off */
3502 if (tmp != NULL)
3503 {
3504 (void) insert_ob_in_ob (tmp, who); 3438 (void) insert_ob_in_ob (tmp, who);
3439 return 1;
3440 }
3441 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3442 {
3443 /* if the weapon does not have the name as the character, can't use it. */
3444 /* (Ragnarok's sword attempted to be used by Foo: won't work) */
3445 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3446 if (tmp != NULL)
3447 (void) insert_ob_in_ob (tmp, who);
3448 return 1;
3449 }
3450 SET_FLAG (op, FLAG_APPLIED);
3451
3452 if (skop)
3453 change_skill (who, skop, 1);
3454 if (!QUERY_FLAG (who, FLAG_READY_WEAPON))
3455 SET_FLAG (who, FLAG_READY_WEAPON);
3456
3457 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op));
3458
3459 (void) change_abil (who, op);
3460 break;
3461
3462 case ARMOUR:
3463 case HELMET:
3464 case SHIELD:
3465 case BOOTS:
3466 case GLOVES:
3467 case GIRDLE:
3468 case BRACERS:
3469 case CLOAK:
3470 case RING:
3471 case AMULET:
3472 SET_FLAG (op, FLAG_APPLIED);
3473 new_draw_info_format (NDI_UNIQUE, 0, who, "You wear %s.", query_name (op));
3474 (void) change_abil (who, op);
3475 break;
3476 case LAMP:
3477 if (op->stats.food < 1)
3478 {
3479 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name);
3480 return 1;
3481 }
3482 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name);
3483 tmp2 = arch_to_object (op->other_arch);
3484 tmp2->stats.food = op->stats.food;
3485 SET_FLAG (tmp2, FLAG_APPLIED);
3486 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
3487 SET_FLAG (tmp2, FLAG_INV_LOCKED);
3488 insert_ob_in_ob (tmp2, who);
3489
3490 /* Remove the old lantern */
3491 if (who->type == PLAYER)
3492 esrv_del_item (who->contr, op->count);
3493
3494 remove_ob (op);
3495 free_object (op);
3496
3497 /* insert the portion that was split off */
3498 if (tmp != NULL)
3499 {
3500 (void) insert_ob_in_ob (tmp, who);
3505 if (who->type == PLAYER) 3501 if (who->type == PLAYER)
3506 esrv_send_item (who, tmp); 3502 esrv_send_item (who, tmp);
3507 } 3503 }
3508 fix_player (who); 3504 fix_player (who);
3509 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 3505 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
3510 { 3506 {
3511 if (who->type == PLAYER) 3507 if (who->type == PLAYER)
3512 { 3508 {
3513 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); 3509 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
3514 SET_FLAG (tmp2, FLAG_KNOWN_CURSED); 3510 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
3515 } 3511 }
3516 } 3512 }
3517 if (who->type == PLAYER) 3513 if (who->type == PLAYER)
3518 esrv_send_item (who, tmp2); 3514 esrv_send_item (who, tmp2);
3519 return 0; 3515 return 0;
3520 break; 3516 break;
3521 3517
3522 /* this part is needed for skill-tools */ 3518 /* this part is needed for skill-tools */
3523 case SKILL: 3519 case SKILL:
3524 case SKILL_TOOL: 3520 case SKILL_TOOL:
3525 if (who->chosen_skill) 3521 if (who->chosen_skill)
3526 { 3522 {
3527 LOG (llevError, "BUG: apply_special(): can't apply two skills\n"); 3523 LOG (llevError, "BUG: apply_special(): can't apply two skills\n");
3528 return 1; 3524 return 1;
3529 } 3525 }
3530 if (who->type == PLAYER) 3526 if (who->type == PLAYER)
3531 { 3527 {
3532 who->contr->shoottype = range_skill; 3528 who->contr->shoottype = range_skill;
3533 who->contr->ranges[range_skill] = op; 3529 who->contr->ranges[range_skill] = op;
3534 if (!op->invisible) 3530 if (!op->invisible)
3535 { 3531 {
3536 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); 3532 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op));
3537 new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill); 3533 new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill);
3538 } 3534 }
3539 else 3535 else
3540 { 3536 {
3541 new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name); 3537 new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name);
3542 } 3538 }
3543 } 3539 }
3544 SET_FLAG (op, FLAG_APPLIED); 3540 SET_FLAG (op, FLAG_APPLIED);
3545 (void) change_abil (who, op); 3541 (void) change_abil (who, op);
3546 who->chosen_skill = op; 3542 who->chosen_skill = op;
3547 SET_FLAG (who, FLAG_READY_SKILL); 3543 SET_FLAG (who, FLAG_READY_SKILL);
3548 break; 3544 break;
3549 3545
3550 case BOW: 3546 case BOW:
3551 if (!check_weapon_power (who, op->last_eat)) 3547 if (!check_weapon_power (who, op->last_eat))
3552 { 3548 {
3553 new_draw_info (NDI_UNIQUE, 0, who, "That item is too powerful for you to use."); 3549 new_draw_info (NDI_UNIQUE, 0, who, "That item is too powerful for you to use.");
3554 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!."); 3550 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!.");
3555 if (tmp != NULL) 3551 if (tmp != NULL)
3556 (void) insert_ob_in_ob (tmp, who); 3552 (void) insert_ob_in_ob (tmp, who);
3557 return 1; 3553 return 1;
3558 } 3554 }
3559 if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) 3555 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3560 { 3556 {
3561 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); 3557 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3562 if (tmp != NULL) 3558 if (tmp != NULL)
3563 (void) insert_ob_in_ob (tmp, who); 3559 (void) insert_ob_in_ob (tmp, who);
3564 return 1; 3560 return 1;
3565 } 3561 }
3566 /*FALLTHROUGH*/ case WAND: 3562 /*FALLTHROUGH*/ case WAND:
3567 case ROD: 3563 case ROD:
3568 case HORN: 3564 case HORN:
3569 /* check for skill, alter player status */ 3565 /* check for skill, alter player status */
3570 SET_FLAG (op, FLAG_APPLIED); 3566 SET_FLAG (op, FLAG_APPLIED);
3571 if (skop) 3567 if (skop)
3572 change_skill (who, skop, 0); 3568 change_skill (who, skop, 0);
3573 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); 3569 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op));
3574 3570
3575 if (who->type == PLAYER) 3571 if (who->type == PLAYER)
3576 { 3572 {
3577 if (op->type == BOW) 3573 if (op->type == BOW)
3578 { 3574 {
3579 (void) change_abil (who, op); 3575 (void) change_abil (who, op);
3580 new_draw_info_format (NDI_UNIQUE, 0, who, 3576 new_draw_info_format (NDI_UNIQUE, 0, who,
3581 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op)); 3577 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op));
3582 who->contr->shoottype = range_bow; 3578 who->contr->shoottype = range_bow;
3583 } 3579 }
3584 else 3580 else
3585 { 3581 {
3586 who->contr->shoottype = range_misc; 3582 who->contr->shoottype = range_misc;
3587 } 3583 }
3588 } 3584 }
3589 else 3585 else
3590 { 3586 {
3591 if (op->type == BOW) 3587 if (op->type == BOW)
3592 SET_FLAG (who, FLAG_READY_BOW); 3588 SET_FLAG (who, FLAG_READY_BOW);
3593 else 3589 else
3594 SET_FLAG (who, FLAG_READY_RANGE); 3590 SET_FLAG (who, FLAG_READY_RANGE);
3595 } 3591 }
3596 break; 3592 break;
3597 3593
3598 case BUILDER: 3594 case BUILDER:
3599 if (who->contr->ranges[range_builder]) 3595 if (who->contr->ranges[range_builder])
3600 unapply_special (who, who->contr->ranges[range_builder], 0); 3596 unapply_special (who, who->contr->ranges[range_builder], 0);
3601 who->contr->shoottype = range_builder; 3597 who->contr->shoottype = range_builder;
3602 who->contr->ranges[range_builder] = op; 3598 who->contr->ranges[range_builder] = op;
3603 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op)); 3599 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op));
3604 break; 3600 break;
3605 3601
3606 default: 3602 default:
3607 new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op)); 3603 new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op));
3608 } /* end of switch op->type */ 3604 } /* end of switch op->type */
3609 3605
3610 SET_FLAG (op, FLAG_APPLIED); 3606 SET_FLAG (op, FLAG_APPLIED);
3611 3607
3612 if (tmp != NULL) 3608 if (tmp != NULL)
3659 object *tmp = NULL, *tmp2; 3655 object *tmp = NULL, *tmp2;
3660 int i; 3656 int i;
3661 3657
3662 switch (op->type) 3658 switch (op->type)
3663 { 3659 {
3664 case SHOP_FLOOR: 3660 case SHOP_FLOOR:
3665 if (!HAS_RANDOM_ITEMS (op)) 3661 if (!HAS_RANDOM_ITEMS (op))
3666 return 0; 3662 return 0;
3667 do 3663 do
3668 { 3664 {
3669 i = 10; /* let's give it 10 tries */ 3665 i = 10; /* let's give it 10 tries */
3670 while ((tmp = generate_treasure (op->randomitems, 3666 while ((tmp = generate_treasure (op->randomitems,
3671 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i); 3667 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i);
3672 if (tmp == NULL) 3668 if (tmp == NULL)
3673 return 0; 3669 return 0;
3674 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 3670 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
3675 { 3671 {
3676 free_object (tmp);
3677 tmp = NULL;
3678 }
3679 }
3680 while (!tmp);
3681 tmp->x = op->x;
3682 tmp->y = op->y;
3683 SET_FLAG (tmp, FLAG_UNPAID);
3684 insert_ob_in_map (tmp, op->map, NULL, 0);
3685 CLEAR_FLAG (op, FLAG_AUTO_APPLY);
3686 identify (tmp);
3687 break;
3688
3689 case TREASURE:
3690 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
3691 return 0;
3692 while ((op->stats.hp--) > 0)
3693 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0,
3694 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3695
3696 /* If we generated an object and put it in this object inventory,
3697 * move it to the parent object as the current object is about
3698 * to disappear. An example of this item is the random_* stuff
3699 * that is put inside other objects.
3700 */
3701 for (tmp = op->inv; tmp; tmp = tmp2)
3702 {
3703 tmp2 = tmp->below;
3704 remove_ob (tmp);
3705 if (op->env)
3706 insert_ob_in_ob (tmp, op->env);
3707 else
3708 free_object (tmp); 3672 free_object (tmp);
3673 tmp = NULL;
3709 } 3674 }
3675 }
3676 while (!tmp);
3677 tmp->x = op->x;
3678 tmp->y = op->y;
3679 SET_FLAG (tmp, FLAG_UNPAID);
3680 insert_ob_in_map (tmp, op->map, NULL, 0);
3681 CLEAR_FLAG (op, FLAG_AUTO_APPLY);
3682 identify (tmp);
3683 break;
3684
3685 case TREASURE:
3686 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
3687 return 0;
3688 while ((op->stats.hp--) > 0)
3689 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0,
3690 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3691
3692 /* If we generated an object and put it in this object inventory,
3693 * move it to the parent object as the current object is about
3694 * to disappear. An example of this item is the random_* stuff
3695 * that is put inside other objects.
3696 */
3697 for (tmp = op->inv; tmp; tmp = tmp2)
3698 {
3699 tmp2 = tmp->below;
3700 remove_ob (tmp);
3701 if (op->env)
3702 insert_ob_in_ob (tmp, op->env);
3703 else
3704 free_object (tmp);
3705 }
3710 remove_ob (op); 3706 remove_ob (op);
3711 free_object (op); 3707 free_object (op);
3712 break; 3708 break;
3713 } 3709 }
3714 return tmp ? 1 : 0; 3710 return tmp ? 1 : 0;
3715} 3711}
3716 3712
3717/** 3713/**
3719 * when an original map is loaded) and performs special actions for 3715 * when an original map is loaded) and performs special actions for
3720 * certain objects (most initialization of chests and creation of 3716 * certain objects (most initialization of chests and creation of
3721 * treasures and stuff). Calls auto_apply if appropriate. 3717 * treasures and stuff). Calls auto_apply if appropriate.
3722 */ 3718 */
3723void 3719void
3724fix_auto_apply (mapstruct *m) 3720fix_auto_apply (maptile *m)
3725{ 3721{
3726 object *tmp, *above = NULL; 3722 object *tmp, *above = NULL;
3727 int x, y; 3723 int x, y;
3728 3724
3729 if (m == NULL) 3725 if (m == NULL)
3917void 3913void
3918apply_lighter (object *who, object *lighter) 3914apply_lighter (object *who, object *lighter)
3919{ 3915{
3920 object *item; 3916 object *item;
3921 int is_player_env = 0; 3917 int is_player_env = 0;
3922 uint32 nrof;
3923 tag_t count;
3924 char item_name[MAX_BUF]; 3918 char item_name[MAX_BUF];
3925 3919
3926 item = find_marked_object (who); 3920 item = find_marked_object (who);
3927 if (item) 3921 if (item)
3928 { 3922 {
3941 esrv_send_item (who, lighter); 3935 esrv_send_item (who, lighter);
3942 oneLighter = insert_ob_in_ob (oneLighter, who); 3936 oneLighter = insert_ob_in_ob (oneLighter, who);
3943 esrv_send_item (who, oneLighter); 3937 esrv_send_item (who, oneLighter);
3944 } 3938 }
3945 else 3939 else
3946 {
3947 lighter->stats.food--; 3940 lighter->stats.food--;
3948 }
3949
3950 } 3941 }
3951 else if (lighter->last_eat) 3942 else if (lighter->last_eat)
3952 { /* no charges left in lighter */ 3943 { /* no charges left in lighter */
3953 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with a used up %s.", &item->name, &lighter->name); 3944 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with a used up %s.", &item->name, &lighter->name);
3954 return; 3945 return;
3955 } 3946 }
3956 /* Perhaps we should split what we are trying to light on fire? 3947 /* Perhaps we should split what we are trying to light on fire?
3957 * I can't see many times when you would want to light multiple 3948 * I can't see many times when you would want to light multiple
3958 * objects at once. 3949 * objects at once.
3959 */ 3950 */
3960 nrof = item->nrof;
3961 count = item->count;
3962 /* If the item is destroyed, we don't have a valid pointer to the 3951 /* If the item is destroyed, we don't have a valid pointer to the
3963 * name object, so make a copy so the message we print out makes 3952 * name object, so make a copy so the message we print out makes
3964 * some sense. 3953 * some sense.
3965 */ 3954 */
3966 strcpy (item_name, item->name); 3955 strcpy (item_name, item->name);
3969 3958
3970 save_throw_object (item, AT_FIRE, who); 3959 save_throw_object (item, AT_FIRE, who);
3971 /* Change to check count and not freed, since the object pointer 3960 /* Change to check count and not freed, since the object pointer
3972 * may have gotten recycled 3961 * may have gotten recycled
3973 */ 3962 */
3974 if ((nrof != item->nrof) || (count != item->count)) 3963 if (item->destroyed ())
3975 { 3964 {
3976 new_draw_info_format (NDI_UNIQUE, 0, who, "You light the %s with the %s.", &item_name, &lighter->name); 3965 new_draw_info_format (NDI_UNIQUE, 0, who, "You light the %s with the %s.", &item_name, &lighter->name);
3977 /* Need to update the player so that the players glow radius 3966 /* Need to update the player so that the players glow radius
3978 * gets changed. 3967 * gets changed.
3979 */ 3968 */
3980 if (is_player_env) 3969 if (is_player_env)
3981 fix_player (who); 3970 fix_player (who);
3982 } 3971 }
3983 else 3972 else
3984 {
3985 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with the %s and fail.", &item->name, &lighter->name); 3973 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with the %s and fail.", &item->name, &lighter->name);
3986 }
3987
3988 } 3974 }
3989 else /* nothing to light */ 3975 else /* nothing to light */
3990 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object."); 3976 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object.");
3991 3977
3992} 3978}
4053 for the race, put the excess stat some 4039 for the race, put the excess stat some
4054 where else. */ 4040 where else. */
4055 4041
4056 switch (change->type) 4042 switch (change->type)
4057 { 4043 {
4058 case CLASS: 4044 case CLASS:
4059 { 4045 {
4060 living *stats = &(pl->contr->orig_stats); 4046 living *stats = &(pl->contr->orig_stats);
4061 living *ns = &(change->stats); 4047 living *ns = &(change->stats);
4062 object *walk; 4048 object *walk;
4063 int flag_change_face = 1; 4049 int flag_change_face = 1;
4064 4050
4065 /* the following code assigns stats up to the stat max 4051 /* the following code assigns stats up to the stat max
4066 * for the race, and if the stat max is exceeded, 4052 * for the race, and if the stat max is exceeded,
4067 * tries to randomly reassign the excess stat 4053 * tries to randomly reassign the excess stat
4068 */ 4054 */
4069 int i, j; 4055 int i, j;
4070 4056
4071 for (i = 0; i < NUM_STATS; i++) 4057 for (i = 0; i < NUM_STATS; i++)
4072 { 4058 {
4073 sint8 stat = get_attr_value (stats, i); 4059 sint8 stat = get_attr_value (stats, i);
4074 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); 4060 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4075 4061
4076 stat += get_attr_value (ns, i); 4062 stat += get_attr_value (ns, i);
4077 if (stat > 20 + race_bonus) 4063 if (stat > 20 + race_bonus)
4078 { 4064 {
4079 excess_stat++; 4065 excess_stat++;
4080 stat = 20 + race_bonus; 4066 stat = 20 + race_bonus;
4081 } 4067 }
4082 set_attr_value (stats, i, stat); 4068 set_attr_value (stats, i, stat);
4083 } 4069 }
4084 4070
4085 for (j = 0; excess_stat > 0 && j < 100; j++) 4071 for (j = 0; excess_stat > 0 && j < 100; j++)
4086 { /* try 100 times to assign excess stats */ 4072 { /* try 100 times to assign excess stats */
4087 int i = rndm (0, 6); 4073 int i = rndm (0, 6);
4088 int stat = get_attr_value (stats, i); 4074 int stat = get_attr_value (stats, i);
4089 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); 4075 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4090 4076
4091 if (i == CHA) 4077 if (i == CHA)
4092 continue; /* exclude cha from this */ 4078 continue; /* exclude cha from this */
4093 if (stat < 20 + race_bonus) 4079 if (stat < 20 + race_bonus)
4094 { 4080 {
4095 change_attr_value (stats, i, 1); 4081 change_attr_value (stats, i, 1);
4096 excess_stat--; 4082 excess_stat--;
4097 } 4083 }
4098 } 4084 }
4099 4085
4100 /* insert the randomitems from the change's treasurelist into 4086 /* insert the randomitems from the change's treasurelist into
4101 * the player ref: player.c 4087 * the player ref: player.c
4102 */ 4088 */
4103 if (change->randomitems != NULL) 4089 if (change->randomitems != NULL)
4104 give_initial_items (pl, change->randomitems); 4090 give_initial_items (pl, change->randomitems);
4105 4091
4106 4092
4107 /* set up the face, for some races. */ 4093 /* set up the face, for some races. */
4108 4094
4109 /* first, look for the force object banning 4095 /* first, look for the force object banning
4110 * changing the face. Certain races never change face with class. 4096 * changing the face. Certain races never change face with class.
4111 */ 4097 */
4112 for (walk = pl->inv; walk != NULL; walk = walk->below) 4098 for (walk = pl->inv; walk != NULL; walk = walk->below)
4113 if (!strcmp (walk->name, "NOCLASSFACECHANGE")) 4099 if (!strcmp (walk->name, "NOCLASSFACECHANGE"))
4114 flag_change_face = 0; 4100 flag_change_face = 0;
4115 4101
4116 if (flag_change_face) 4102 if (flag_change_face)
4117 { 4103 {
4118 pl->animation_id = GET_ANIM_ID (change); 4104 pl->animation_id = GET_ANIM_ID (change);
4119 pl->face = change->face; 4105 pl->face = change->face;
4120 4106
4121 if (QUERY_FLAG (change, FLAG_ANIMATE)) 4107 if (QUERY_FLAG (change, FLAG_ANIMATE))
4122 SET_FLAG (pl, FLAG_ANIMATE); 4108 SET_FLAG (pl, FLAG_ANIMATE);
4123 else 4109 else
4124 CLEAR_FLAG (pl, FLAG_ANIMATE); 4110 CLEAR_FLAG (pl, FLAG_ANIMATE);
4125 } 4111 }
4126 4112
4127 /* check the special case of can't use weapons */ 4113 /* check the special case of can't use weapons */
4128 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */ 4114 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */
4129 if (!strcmp (change->name, "monk")) 4115 if (!strcmp (change->name, "monk"))
4130 CLEAR_FLAG (pl, FLAG_USE_WEAPON); 4116 CLEAR_FLAG (pl, FLAG_USE_WEAPON);
4131 4117
4132 break; 4118 break;
4133 } 4119 }
4134 } 4120 }
4135} 4121}
4136 4122
4137/** 4123/**
4138 * This handles items of type 'transformer'. 4124 * This handles items of type 'transformer'.
4212 if (!new_item) 4198 if (!new_item)
4213 { 4199 {
4214 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0)); 4200 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0));
4215 return; 4201 return;
4216 } 4202 }
4203
4217 new_item->nrof = yield; 4204 new_item->nrof = yield;
4218 new_draw_info_format (NDI_UNIQUE, 0, pl, "You %s the %s.", &transformer->slaying, query_base_name (marked, 0)); 4205 new_draw_info_format (NDI_UNIQUE, 0, pl, "You %s the %s.", &transformer->slaying, query_base_name (marked, 0));
4219 insert_ob_in_ob (new_item, pl); 4206 insert_ob_in_ob (new_item, pl);
4220 esrv_send_inventory (pl, pl); 4207 esrv_send_inventory (pl, pl);
4221 /* Eat up one item */ 4208 /* Eat up one item */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines