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.43 by root, Tue Dec 19 05:12:52 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>
212 CLEAR_FLAG (tmp, FLAG_APPLIED); 206 CLEAR_FLAG (tmp, FLAG_APPLIED);
213 return 0; 207 return 0;
214 } 208 }
215 209
216 if (op->type == PLAYER) 210 if (op->type == PLAYER)
217 {
218 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 211 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
219 identify (tmp); 212 identify (tmp);
220 }
221 213
222 handle_apply_yield (tmp); 214 handle_apply_yield (tmp);
223 215
224 /* Potion of restoration - only for players */ 216 /* Potion of restoration - only for players */
225 if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE)) 217 if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE))
232 drain_stat (op); 224 drain_stat (op);
233 fix_player (op); 225 fix_player (op);
234 decrease_ob (tmp); 226 decrease_ob (tmp);
235 return 1; 227 return 1;
236 } 228 }
229
237 if ((at = find_archetype (ARCH_DEPLETION)) == NULL) 230 if ((at = archetype::find (ARCH_DEPLETION)) == NULL)
238 { 231 {
239 LOG (llevError, "Could not find archetype depletion\n"); 232 LOG (llevError, "Could not find archetype depletion\n");
240 return 0; 233 return 0;
241 } 234 }
242 depl = present_arch_in_ob (at, op); 235 depl = present_arch_in_ob (at, op);
236
243 if (depl != NULL) 237 if (depl != NULL)
244 { 238 {
245 for (i = 0; i < NUM_STATS; i++) 239 for (i = 0; i < NUM_STATS; i++)
246 if (get_attr_value (&depl->stats, i)) 240 if (get_attr_value (&depl->stats, i))
247 {
248 new_draw_info (NDI_UNIQUE, 0, op, restore_msg[i]); 241 new_draw_info (NDI_UNIQUE, 0, op, restore_msg[i]);
249 } 242
250 remove_ob (depl); 243 depl->destroy ();
251 free_object (depl);
252 fix_player (op); 244 fix_player (op);
253 } 245 }
254 else 246 else
255 new_draw_info (NDI_UNIQUE, 0, op, "You potion had no effect."); 247 new_draw_info (NDI_UNIQUE, 0, op, "You potion had no effect.");
256 248
259 } 251 }
260 252
261 /* improvement potion - only for players */ 253 /* improvement potion - only for players */
262 if (op->type == PLAYER && tmp->attacktype & AT_GODPOWER) 254 if (op->type == PLAYER && tmp->attacktype & AT_GODPOWER)
263 { 255 {
264
265 for (i = 1; i < MIN (11, op->level); i++) 256 for (i = 1; i < MIN (11, op->level); i++)
266 { 257 {
267 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 258 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
268 { 259 {
269 if (op->contr->levhp[i] != 1) 260 if (op->contr->levhp[i] != 1)
299 op->contr->levgrace[i] = 3; 290 op->contr->levgrace[i] = 3;
300 break; 291 break;
301 } 292 }
302 } 293 }
303 } 294 }
295
304 /* Just makes checking easier */ 296 /* Just makes checking easier */
305 if (i < MIN (11, op->level)) 297 if (i < MIN (11, op->level))
306 got_one = 1; 298 got_one = 1;
299
307 if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED)) 300 if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED))
308 { 301 {
309 if (got_one) 302 if (got_one)
310 { 303 {
311 fix_player (op); 304 fix_player (op);
324 new_draw_info (NDI_UNIQUE, 0, op, "The Gods are angry and punish you."); 317 new_draw_info (NDI_UNIQUE, 0, op, "The Gods are angry and punish you.");
325 } 318 }
326 else 319 else
327 new_draw_info (NDI_UNIQUE, 0, op, "You are fortunate that you are so pathetic."); 320 new_draw_info (NDI_UNIQUE, 0, op, "You are fortunate that you are so pathetic.");
328 } 321 }
322
329 decrease_ob (tmp); 323 decrease_ob (tmp);
330 return 1; 324 return 1;
331 } 325 }
332 326
333 327
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
958 price_in = nr * CONV_NEED (converter) * item->value; 952 price_in = nr * CONV_NEED (converter) * item->value;
959 } 953 }
960 else 954 else
961 { 955 {
962 price_in = item->value; 956 price_in = item->value;
963 remove_ob (item); 957 item->destroy ();
964 free_object (item);
965 } 958 }
966 } 959 }
967 960
968 if (converter->inv != NULL) 961 if (converter->inv != NULL)
969 { 962 {
1033 if (op->type != PLAYER) 1026 if (op->type != PLAYER)
1034 return 0; /* This might change */ 1027 return 0; /* This might change */
1035 1028
1036 if (sack == NULL || sack->type != CONTAINER) 1029 if (sack == NULL || sack->type != CONTAINER)
1037 { 1030 {
1038 LOG (llevError, "apply_container: %s is not container!\n", &sack->name); 1031 LOG (llevError, "apply_container: %s is not container!\n", sack ? &sack->name : "[nullobject]");
1039 return 0; 1032 return 0;
1040 } 1033 }
1041 op->contr->last_used = NULL; 1034
1042 op->contr->last_used_id = 0; 1035 op->contr->last_used = 0;
1043 1036
1044 if (sack->env != op) 1037 if (sack->env != op)
1045 { 1038 {
1046 if (sack->other_arch == NULL || sack->env != NULL) 1039 if (sack->other_arch == NULL || sack->env != NULL)
1047 { 1040 {
1048 new_draw_info (NDI_UNIQUE, 0, op, "You must get it first."); 1041 new_draw_info (NDI_UNIQUE, 0, op, "You must get it first.");
1049 return 1; 1042 return 1;
1050 } 1043 }
1044
1051 /* It's on the ground, the problems begin */ 1045 /* It's on the ground, the problems begin */
1052 if (op->container != sack) 1046 if (op->container != sack)
1053 { 1047 {
1054 /* it's closed OR some player has opened it */ 1048 /* it's closed OR some player has opened it */
1055 if (QUERY_FLAG (sack, FLAG_APPLIED)) 1049 if (QUERY_FLAG (sack, FLAG_APPLIED))
1082 } 1076 }
1083 else 1077 else
1084 { 1078 {
1085 sack->move_off = 0; 1079 sack->move_off = 0;
1086 tmp = sack->inv; 1080 tmp = sack->inv;
1081
1087 if (tmp && tmp->type == CLOSE_CON) 1082 if (tmp && tmp->type == CLOSE_CON)
1088 { 1083 tmp->destroy ();
1089 remove_ob (tmp);
1090 free_object (tmp);
1091 }
1092 } 1084 }
1093 } 1085 }
1094 } 1086 }
1095 1087
1096 if (QUERY_FLAG (sack, FLAG_APPLIED)) 1088 if (QUERY_FLAG (sack, FLAG_APPLIED))
1152 apply_container (op, sack); 1144 apply_container (op, sack);
1153 return 1; 1145 return 1;
1154 } 1146 }
1155 } 1147 }
1156 } 1148 }
1149
1157 new_draw_info (NDI_UNIQUE, 0, op, buf); 1150 new_draw_info (NDI_UNIQUE, 0, op, buf);
1151
1158 if (op->contr) 1152 if (op->contr)
1159 op->contr->socket.update_look = 1; 1153 op->contr->socket->floorbox_update ();
1154
1160 return 1; 1155 return 1;
1161} 1156}
1162 1157
1163/** 1158/**
1164 * Eneq(@csd.uu.se): Handle apply on containers. This is for containers 1159 * Eneq(@csd.uu.se): Handle apply on containers. This is for containers
1182 if (op->type != PLAYER) 1177 if (op->type != PLAYER)
1183 return 0; /* This might change */ 1178 return 0; /* This might change */
1184 1179
1185 if (sack == NULL || sack->type != CONTAINER) 1180 if (sack == NULL || sack->type != CONTAINER)
1186 { 1181 {
1187 LOG (llevError, "esrv_apply_container: %s is not container!\n", &sack->name); 1182 LOG (llevError, "esrv_apply_container: %s is not container!\n", sack ? &sack->name : "[nullobject]");
1188 return 0; 1183 return 0;
1189 } 1184 }
1190 1185
1191 /* If we have a currently open container, then it needs to be closed in all cases 1186 /* If we have a currently open container, then it needs to be closed in all cases
1192 * if we are opening this one up. We then fall through if appropriate for 1187 * if we are opening this one up. We then fall through if appropriate for
1315 else 1310 else
1316 { 1311 {
1317 altar->value = 1; /* works only once */ 1312 altar->value = 1; /* works only once */
1318 push_button (altar); 1313 push_button (altar);
1319 } 1314 }
1315
1320 return sacrifice == NULL; 1316 return !sacrifice;
1321 } 1317 }
1322 else 1318 else
1323 {
1324 return 0; 1319 return 0;
1325 }
1326} 1320}
1327
1328 1321
1329/** 1322/**
1330 * Handles 'movement' of shop mats. 1323 * Handles 'movement' of shop mats.
1331 * Returns 1 if 'op' was destroyed, 0 if not. 1324 * Returns 1 if 'op' was destroyed, 0 if not.
1332 * Largely re-written to not use nearly as many gotos, plus 1325 * Largely re-written to not use nearly as many gotos, plus
1349 * the shop. 1342 * the shop.
1350 */ 1343 */
1351 for (tmp = op->inv; tmp; tmp = next) 1344 for (tmp = op->inv; tmp; tmp = next)
1352 { 1345 {
1353 next = tmp->below; 1346 next = tmp->below;
1347
1354 if (QUERY_FLAG (tmp, FLAG_UNPAID)) 1348 if (QUERY_FLAG (tmp, FLAG_UNPAID))
1355 { 1349 {
1356 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); 1350 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9);
1357 1351
1358 remove_ob (tmp); 1352 tmp->remove ();
1353
1359 if (i == -1) 1354 if (i == -1)
1360 i = 0; 1355 i = 0;
1356
1361 tmp->map = op->map; 1357 tmp->map = op->map;
1362 tmp->x = op->x + freearr_x[i]; 1358 tmp->x = op->x + freearr_x[i];
1363 tmp->y = op->y + freearr_y[i]; 1359 tmp->y = op->y + freearr_y[i];
1364 insert_ob_in_map (tmp, op->map, op, 0); 1360 insert_ob_in_map (tmp, op->map, op, 0);
1365 } 1361 }
1377 1373
1378 /* Somebody dropped an unpaid item, just move to an adjacent place. */ 1374 /* 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); 1375 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
1380 1376
1381 if (i != -1) 1377 if (i != -1)
1382 {
1383 rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat); 1378 rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat);
1384 } 1379
1385 return 0; 1380 return 0;
1386 } 1381 }
1387 /* Removed code that checked for multipart objects - it appears that 1382 /* Removed code that checked for multipart objects - it appears that
1388 * the teleport function should be able to handle this just fine. 1383 * the teleport function should be able to handle this just fine.
1389 */ 1384 */
1390 rv = teleport (shop_mat, SHOP_MAT, op); 1385 rv = teleport (shop_mat, SHOP_MAT, op);
1391 } 1386 }
1392 /* immediate block below is only used for players */ 1387 else if (can_pay (op) && get_payment (op))
1393 else if (can_pay (op))
1394 { 1388 {
1395 get_payment (op, op->inv); 1389 /* this is only used for players */
1396 rv = teleport (shop_mat, SHOP_MAT, op); 1390 rv = teleport (shop_mat, SHOP_MAT, op);
1397 1391
1398 if (shop_mat->msg) 1392 if (shop_mat->msg)
1399 {
1400 new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg); 1393 new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg);
1401 }
1402 /* This check below is a bit simplistic - generally it should be correct, 1394 /* 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 1395 * but there is never a guarantee that the bottom space on the map is
1404 * actually the shop floor. 1396 * actually the shop floor.
1405 */ 1397 */
1406 else if (!rv && !is_in_shop (op)) 1398 else if (!rv && !is_in_shop (op))
1407 { 1399 {
1408 opinion = shopkeeper_approval (op->map, op); 1400 opinion = shopkeeper_approval (op->map, op);
1401
1409 if (opinion > 0.9) 1402 if (opinion > 0.9)
1410 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper gives you a friendly wave."); 1403 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper gives you a friendly wave.");
1411 else if (opinion > 0.75) 1404 else if (opinion > 0.75)
1412 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper waves to you."); 1405 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper waves to you.");
1413 else if (opinion > 0.5) 1406 else if (opinion > 0.5)
1420 { 1413 {
1421 /* if we get here, a player tried to leave a shop but was not able 1414 /* 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 1415 * to afford the items he has. We try to move the player so that
1423 * they are not on the mat anymore 1416 * they are not on the mat anymore
1424 */ 1417 */
1425
1426 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); 1418 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
1427 1419
1428 if (i == -1) 1420 if (i == -1)
1429 { 1421 {
1430 LOG (llevError, "Internal shop-mat problem.\n"); 1422 LOG (llevError, "Internal shop-mat problem.\n");
1431 } 1423 }
1432 else 1424 else
1433 { 1425 {
1434 remove_ob (op); 1426 op->remove ();
1435 op->x += freearr_x[i]; 1427 op->x += freearr_x[i];
1436 op->y += freearr_y[i]; 1428 op->y += freearr_y[i];
1437 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL; 1429 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL;
1438 } 1430 }
1439 } 1431 }
1432
1440 CLEAR_FLAG (op, FLAG_NO_APPLY); 1433 CLEAR_FLAG (op, FLAG_NO_APPLY);
1441 return rv; 1434 return rv;
1442} 1435}
1443 1436
1444/** 1437/**
1524 if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator))) 1517 if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator)))
1525 goto leave; 1518 goto leave;
1526 1519
1527 switch (trap->type) 1520 switch (trap->type)
1528 { 1521 {
1529 case PLAYERMOVER: 1522 case PLAYERMOVER:
1530 if (trap->attacktype && (trap->level || victim->type != PLAYER) && !should_director_abort (trap, victim)) 1523 if (trap->attacktype && (trap->level || victim->type != PLAYER) && !should_director_abort (trap, victim))
1524 {
1525 if (!trap->stats.maxsp)
1526 trap->stats.maxsp = 2;
1527
1528 /* Is this correct? From the docs, it doesn't look like it
1529 * should be divided by trap->speed
1530 */
1531 victim->speed_left = -FABS (trap->stats.maxsp * victim->speed / trap->speed);
1532
1533 /* Just put in some sanity check. I think there is a bug in the
1534 * above with some objects have zero speed, and thus the player
1535 * getting permanently paralyzed.
1536 */
1537 if (victim->speed_left < -50.0)
1538 victim->speed_left = -50.0;
1539 /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left); */
1540 }
1541 goto leave;
1542
1543 case SPINNER:
1544 if (victim->direction)
1545 {
1546 victim->direction = absdir (victim->direction - trap->stats.sp);
1547 update_turn_face (victim);
1548 }
1549 goto leave;
1550
1551 case DIRECTOR:
1552 if (victim->direction && !should_director_abort (trap, victim))
1553 {
1554 victim->direction = trap->stats.sp;
1555 update_turn_face (victim);
1556 }
1557 goto leave;
1558
1559 case BUTTON:
1560 case PEDESTAL:
1561 update_button (trap);
1562 goto leave;
1563
1564 case ALTAR:
1565 /* sacrifice victim on trap */
1566 apply_altar (trap, victim, originator);
1567 goto leave;
1568
1569 case THROWN_OBJ:
1570 if (trap->inv == NULL)
1571 goto leave;
1572 /* fallthrough */
1573
1574 case ARROW:
1575 /* bad bug: monster throw a object, make a step forwards, step on object ,
1576 * trigger this here and get hit by own missile - and will be own enemy.
1577 * Victim then is his own enemy and will start to kill herself (this is
1578 * removed) but we have not synced victim and his missile. To avoid senseless
1579 * action, we avoid hits here
1580 */
1581 if ((QUERY_FLAG (victim, FLAG_ALIVE) && trap->speed) && trap->owner != victim)
1582 hit_with_arrow (trap, victim);
1583 goto leave;
1584
1585 case SPELL_EFFECT:
1586 apply_spell_effect (trap, victim);
1587 goto leave;
1588
1589 case TRAPDOOR:
1590 {
1591 int max, sound_was_played;
1592 object *ab, *ab_next;
1593
1594 if (!trap->value)
1531 { 1595 {
1532 if (!trap->stats.maxsp) 1596 int tot;
1533 trap->stats.maxsp = 2;
1534 1597
1535 /* Is this correct? From the docs, it doesn't look like it 1598 for (ab = trap->above, tot = 0; ab != NULL; ab = ab->above)
1536 * should be divided by trap->speed 1599 if ((ab->move_type && trap->move_on) || ab->move_type == 0)
1600 tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying;
1601
1602 if (!(trap->value = (tot > trap->weight) ? 1 : 0))
1603 goto leave;
1604
1605 SET_ANIMATION (trap, trap->value);
1606 update_object (trap, UP_OBJ_FACE);
1607 }
1608
1609 for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab; ab = ab_next)
1610 {
1611 /* need to set this up, since if we do transfer the object,
1612 * ab->above would be bogus
1537 */ 1613 */
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; 1614 ab_next = ab->above;
1623 1615
1624 if ((ab->move_type && trap->move_on) || ab->move_type == 0) 1616 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 { 1617 {
1649 op->x = trap->x; 1618 if (!sound_was_played)
1650 op->y = trap->y; 1619 {
1651 insert_ob_in_map (op, trap->map, trap, 0); 1620 play_sound_map (trap->map, trap->x, trap->y, SOUND_FALL_HOLE);
1621 sound_was_played = 1;
1622 }
1623 new_draw_info (NDI_UNIQUE, 0, ab, "You fall into a trapdoor!");
1624 transfer_ob (ab, (int) EXIT_X (trap), (int) EXIT_Y (trap), 0, ab);
1652 } 1625 }
1653 } 1626 }
1654 goto leave; 1627 goto leave;
1628 }
1655 1629
1630
1631 case CONVERTER:
1632 if (convert_item (victim, trap) < 0)
1633 {
1634 object *op;
1635
1636 new_draw_info_format (NDI_UNIQUE, 0, originator, "The %s seems to be broken!", query_name (trap));
1637
1638 op = get_archetype ("burnout");
1639 if (op != NULL)
1640 {
1641 op->x = trap->x;
1642 op->y = trap->y;
1643 insert_ob_in_map (op, trap->map, trap, 0);
1644 }
1645 }
1646 goto leave;
1647
1656 case TRIGGER_BUTTON: 1648 case TRIGGER_BUTTON:
1657 case TRIGGER_PEDESTAL: 1649 case TRIGGER_PEDESTAL:
1658 case TRIGGER_ALTAR: 1650 case TRIGGER_ALTAR:
1659 check_trigger (trap, victim); 1651 check_trigger (trap, victim);
1652 goto leave;
1653
1654 case DEEP_SWAMP:
1655 walk_on_deep_swamp (trap, victim);
1656 goto leave;
1657
1658 case CHECK_INV:
1659 check_inv (victim, trap);
1660 goto leave;
1661
1662 case HOLE:
1663 /* Hole not open? */
1664 if (trap->stats.wc > 0)
1660 goto leave; 1665 goto leave;
1661 1666
1662 case DEEP_SWAMP: 1667 /* Is this a multipart monster and not the head? If so, return.
1663 walk_on_deep_swamp (trap, victim); 1668 * Processing will happen if the head runs into the pit
1669 */
1670 if (victim->head)
1664 goto leave; 1671 goto leave;
1665 1672
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); 1673 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"); 1674 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); 1675 transfer_ob (victim, EXIT_X (trap), EXIT_Y (trap), 1, victim);
1684 goto leave; 1676 goto leave;
1685 1677
1686 case EXIT: 1678 case EXIT:
1687 if (victim->type == PLAYER && EXIT_PATH (trap)) 1679 if (victim->type == PLAYER && EXIT_PATH (trap))
1688 { 1680 {
1689 /* Basically, don't show exits leading to random maps the 1681 /* Basically, don't show exits leading to random maps the
1690 * players output. 1682 * players output.
1691 */ 1683 */
1692 if (trap->msg && strncmp (EXIT_PATH (trap), "/!", 2) && strncmp (EXIT_PATH (trap), "/random/", 8)) 1684 if (trap->msg && strncmp (EXIT_PATH (trap), "/!", 2) && strncmp (EXIT_PATH (trap), "/random/", 8))
1693 new_draw_info (NDI_NAVY, 0, victim, trap->msg); 1685 new_draw_info (NDI_NAVY, 0, victim, trap->msg);
1694 enter_exit (victim, trap); 1686 enter_exit (victim, trap);
1695 } 1687 }
1696 goto leave; 1688 goto leave;
1697 1689
1698 case ENCOUNTER: 1690 case ENCOUNTER:
1699 /* may be some leftovers on this */ 1691 /* may be some leftovers on this */
1700 goto leave; 1692 goto leave;
1701 1693
1702 case SHOP_MAT: 1694 case SHOP_MAT:
1703 apply_shop_mat (trap, victim); 1695 apply_shop_mat (trap, victim);
1704 goto leave; 1696 goto leave;
1705 1697
1706 /* Drop a certain amount of gold, and have one item identified */ 1698 /* Drop a certain amount of gold, and have one item identified */
1707 case IDENTIFY_ALTAR: 1699 case IDENTIFY_ALTAR:
1708 apply_id_altar (victim, trap, originator); 1700 apply_id_altar (victim, trap, originator);
1709 goto leave; 1701 goto leave;
1710 1702
1711 case SIGN: 1703 case SIGN:
1712 if (victim->type != PLAYER && trap->stats.food > 0) 1704 if (victim->type != PLAYER && trap->stats.food > 0)
1713 goto leave; /* monsters musn't apply magic_mouths with counters */ 1705 goto leave; /* monsters musn't apply magic_mouths with counters */
1714 1706
1715 apply_sign (victim, trap, 1); 1707 apply_sign (victim, trap, 1);
1716 goto leave; 1708 goto leave;
1717 1709
1718 case CONTAINER: 1710 case CONTAINER:
1719 if (victim->type == PLAYER) 1711 if (victim->type == PLAYER)
1720 (void) esrv_apply_container (victim, trap); 1712 (void) esrv_apply_container (victim, trap);
1721 else 1713 else
1722 (void) apply_container (victim, trap); 1714 (void) apply_container (victim, trap);
1723 goto leave; 1715 goto leave;
1724 1716
1725 case RUNE: 1717 case RUNE:
1726 case TRAP: 1718 case TRAP:
1727 if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE)) 1719 if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE))
1728 { 1720 {
1729 spring_trap (trap, victim); 1721 spring_trap (trap, victim);
1730 } 1722 }
1731 goto leave; 1723 goto leave;
1732 1724
1733 default: 1725 default:
1734 LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not " 1726 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); 1727 "handled in move_apply()\n", &trap->name, &trap->arch->name, trap->type);
1736 goto leave; 1728 goto leave;
1737 } 1729 }
1738 1730
1739leave: 1731leave:
1740 recursion_depth--; 1732 recursion_depth--;
1741} 1733}
1798 1790
1799 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1791 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1800 { 1792 {
1801 /*exp_gain *= 2; because they just identified it too */ 1793 /*exp_gain *= 2; because they just identified it too */
1802 SET_FLAG (tmp, FLAG_IDENTIFIED); 1794 SET_FLAG (tmp, FLAG_IDENTIFIED);
1795
1803 /* If in a container, update how it looks */ 1796 /* If in a container, update how it looks */
1804 if (tmp->env) 1797 if (tmp->env)
1805 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1798 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1806 else 1799 else
1807 op->contr->socket.update_look = 1; 1800 op->contr->socket->floorbox_update ();
1808 } 1801 }
1802
1809 change_exp (op, exp_gain, skill_ob->skill, 0); 1803 change_exp (op, exp_gain, skill_ob->skill, 0);
1810 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT); /* so no more xp gained from this book */ 1804 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT); /* so no more xp gained from this book */
1811 } 1805 }
1812} 1806}
1813 1807
1818static void 1812static void
1819apply_skillscroll (object *op, object *tmp) 1813apply_skillscroll (object *op, object *tmp)
1820{ 1814{
1821 switch ((int) learn_skill (op, tmp)) 1815 switch ((int) learn_skill (op, tmp))
1822 { 1816 {
1823 case 0: 1817 case 0:
1824 new_draw_info (NDI_UNIQUE, 0, op, "You already possess the knowledge "); 1818 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)); 1819 new_draw_info_format (NDI_UNIQUE, 0, op, "held within the %s.\n", query_name (tmp));
1826 return; 1820 return;
1827 1821
1828 case 1: 1822 case 1:
1829 new_draw_info_format (NDI_UNIQUE, 0, op, "You succeed in learning %s", &tmp->skill); 1823 new_draw_info_format (NDI_UNIQUE, 0, op, "You succeed in learning %s", &tmp->skill);
1830 decrease_ob (tmp); 1824 decrease_ob (tmp);
1831 return; 1825 return;
1832 1826
1833 default: 1827 default:
1834 new_draw_info_format (NDI_UNIQUE, 0, op, "You fail to learn the knowledge of the %s.\n", query_name (tmp)); 1828 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); 1829 decrease_ob (tmp);
1836 return; 1830 return;
1837 } 1831 }
1838} 1832}
1839 1833
1840/** 1834/**
1841 * Actually makes op learn spell. 1835 * Actually makes op learn spell.
1862 } 1856 }
1863 return; 1857 return;
1864 } 1858 }
1865 1859
1866 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0); 1860 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0);
1867 tmp = get_object (); 1861 tmp = spell->clone ();
1868 copy_object (spell, tmp);
1869 insert_ob_in_ob (tmp, op); 1862 insert_ob_in_ob (tmp, op);
1870 1863
1871 if (special_prayer) 1864 if (special_prayer)
1872 {
1873 SET_FLAG (tmp, FLAG_STARTEQUIP); 1865 SET_FLAG (tmp, FLAG_STARTEQUIP);
1874 }
1875 1866
1876 esrv_add_spells (op->contr, tmp); 1867 esrv_add_spells (op->contr, tmp);
1877} 1868}
1878 1869
1879/** 1870/**
1896 } 1887 }
1897 1888
1898 new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You lose knowledge of %s.", spell); 1889 new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You lose knowledge of %s.", spell);
1899 player_unready_range_ob (op->contr, spob); 1890 player_unready_range_ob (op->contr, spob);
1900 esrv_remove_spell (op->contr, spob); 1891 esrv_remove_spell (op->contr, spob);
1901 remove_ob (spob); 1892 spob->destroy ();
1902 free_object (spob);
1903} 1893}
1904 1894
1905/** 1895/**
1906 * Handles player applying a spellbook. 1896 * Handles player applying a spellbook.
1907 * Checks whether player has knowledge of required skill, doesn't already know the spell, 1897 * Checks whether player has knowledge of required skill, doesn't already know the spell,
1945 new_draw_info (NDI_UNIQUE, 0, op, "You can't read! Your attempt fails."); 1935 new_draw_info (NDI_UNIQUE, 0, op, "You can't read! Your attempt fails.");
1946 return; 1936 return;
1947 } 1937 }
1948 1938
1949 spell = tmp->inv; 1939 spell = tmp->inv;
1940
1950 if (!spell) 1941 if (!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 }
1956 if (spell->level > (skop->level + 10)) 1947
1948 if (skop->level < int (sqrtf (spell->level) * 1.5f))
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, "It is too hard to read at your level: You are unable to decipher the strange symbols.");
1959 return; 1951 return;
1960 } 1952 }
1961 1953
1962 new_draw_info_format (NDI_UNIQUE, 0, op, "The spellbook contains the %s level spell %s.", get_levelnumber (spell->level), &spell->name); 1954 new_draw_info_format (NDI_UNIQUE, 0, op, "The spellbook contains the %s level spell %s.", get_levelnumber (spell->level), &spell->name);
1963 1955
1964 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1956 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1965 { 1957 {
1966 identify (tmp); 1958 identify (tmp);
1959
1967 if (tmp->env) 1960 if (tmp->env)
1968 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1961 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1969 else 1962 else
1970 op->contr->socket.update_look = 1; 1963 op->contr->socket->floorbox_update ();
1971 } 1964 }
1972 1965
1973 /* I removed the check for special_prayer_mark here - it didn't make 1966 /* I removed the check for special_prayer_mark here - it didn't make
1974 * a lot of sense - special prayers are not found in spellbooks, and 1967 * a lot of sense - special prayers are not found in spellbooks, and
1975 * if the player doesn't know the spell, doesn't make a lot of sense that 1968 * if the player doesn't know the spell, doesn't make a lot of sense that
1982 } 1975 }
1983 1976
1984 if (spell->skill) 1977 if (spell->skill)
1985 { 1978 {
1986 spell_skill = find_skill_by_name (op, spell->skill); 1979 spell_skill = find_skill_by_name (op, spell->skill);
1980
1987 if (!spell_skill) 1981 if (!spell_skill)
1988 { 1982 {
1989 new_draw_info_format (NDI_UNIQUE, 0, op, "You lack the skill %s to use this spell", &spell->skill); 1983 new_draw_info_format (NDI_UNIQUE, 0, op, "You lack the skill %s to use this spell", &spell->skill);
1990 return; 1984 return;
1991 } 1985 }
1986
1992 if (spell_skill->level < spell->level) 1987 if (spell_skill->level < spell->level)
1993 { 1988 {
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); 1989 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; 1990 return;
1996 } 1991 }
2089 */ 2084 */
2090static void 2085static void
2091apply_treasure (object *op, object *tmp) 2086apply_treasure (object *op, object *tmp)
2092{ 2087{
2093 object *treas; 2088 object *treas;
2094 tag_t tmp_tag = tmp->count, op_tag = op->count;
2095 2089
2096 2090
2097 /* Nice side effect of new treasure creation method is that the treasure 2091 /* 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 2092 * 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 2093 * inventory. So that when the chest burns up, the items still exist. Also
2110 } 2104 }
2111 while (tmp->inv) 2105 while (tmp->inv)
2112 { 2106 {
2113 treas = tmp->inv; 2107 treas = tmp->inv;
2114 2108
2115 remove_ob (treas); 2109 treas->remove ();
2116 new_draw_info_format (NDI_UNIQUE, 0, op, "You find %s in the chest.", query_name (treas)); 2110 new_draw_info_format (NDI_UNIQUE, 0, op, "You find %s in the chest.", query_name (treas));
2117 2111
2118 treas->x = op->x; 2112 treas->x = op->x;
2119 treas->y = op->y; 2113 treas->y = op->y;
2120 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR); 2114 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR);
2121 2115
2122 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && QUERY_FLAG (op, FLAG_ALIVE)) 2116 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && QUERY_FLAG (op, FLAG_ALIVE))
2123 spring_trap (treas, op); 2117 spring_trap (treas, op);
2118
2124 /* If either player or container was destroyed, no need to do 2119 /* If either player or container was destroyed, no need to do
2125 * further processing. I think this should be enclused with 2120 * further processing. I think this should be enclused with
2126 * spring trap above, as I don't think there is otherwise 2121 * spring trap above, as I don't think there is otherwise
2127 * any way for the treasure chest or player to get killed 2122 * any way for the treasure chest or player to get killed
2128 */ 2123 */
2129 if (was_destroyed (op, op_tag) || was_destroyed (tmp, tmp_tag)) 2124 if (op->destroyed () || tmp->destroyed ())
2130 break; 2125 break;
2131 } 2126 }
2132 2127
2133 if (!was_destroyed (tmp, tmp_tag) && tmp->inv == NULL) 2128 if (!tmp->destroyed () && tmp->inv == NULL)
2134 decrease_ob (tmp); 2129 decrease_ob (tmp);
2135 2130
2136} 2131}
2137 2132
2138/** 2133/**
2375 } 2370 }
2376#endif 2371#endif
2377 INVOKE_PLAYER (LOGOUT, pl->contr); 2372 INVOKE_PLAYER (LOGOUT, pl->contr);
2378 /* Need to call terminate_all_pets() before we remove the player ob */ 2373 /* Need to call terminate_all_pets() before we remove the player ob */
2379 terminate_all_pets (pl); 2374 terminate_all_pets (pl);
2380 remove_ob (pl); 2375 pl->remove ();
2381 pl->direction = 0; 2376 pl->direction = 0;
2382 new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, pl, "%s leaves the game.", &pl->name); 2377 new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, pl, "%s leaves the game.", &pl->name);
2383 2378
2384 /* update respawn position */ 2379 /* update respawn position */
2385 strcpy (pl->contr->savebed_map, pl->map->path); 2380 strcpy (pl->contr->savebed_map, pl->map->path);
2466is_legal_2ways_exit (object *op, object *exit) 2461is_legal_2ways_exit (object *op, object *exit)
2467{ 2462{
2468 object *tmp; 2463 object *tmp;
2469 object *exit_owner; 2464 object *exit_owner;
2470 player *pp; 2465 player *pp;
2471 mapstruct *exitmap; 2466 maptile *exitmap;
2472 2467
2473 if (exit->stats.exp != 1) 2468 if (exit->stats.exp != 1)
2474 return 1; /*This is not a 2 way, so it is legal */ 2469 return 1; /*This is not a 2 way, so it is legal */
2475 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race) 2470 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race)
2476 return 0; /* This is a reset town portal */ 2471 return 0; /* This is a reset town portal */
2569 return RESULT_INT (0); 2564 return RESULT_INT (0);
2570 2565
2571 switch (tmp->type) 2566 switch (tmp->type)
2572 { 2567 {
2573 2568
2574 case CF_HANDLE: 2569 case CF_HANDLE:
2575 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2570 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2576 play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE); 2571 play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE);
2577 tmp->value = tmp->value ? 0 : 1; 2572 tmp->value = tmp->value ? 0 : 1;
2578 SET_ANIMATION (tmp, tmp->value); 2573 SET_ANIMATION (tmp, tmp->value);
2579 update_object (tmp, UP_OBJ_FACE); 2574 update_object (tmp, UP_OBJ_FACE);
2580 push_button (tmp); 2575 push_button (tmp);
2581 return 1; 2576 return 1;
2582 2577
2583 case TRIGGER: 2578 case TRIGGER:
2584 if (check_trigger (tmp, op)) 2579 if (check_trigger (tmp, op))
2585 { 2580 {
2586 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2581 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2587 play_sound_map (tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE); 2582 play_sound_map (tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE);
2588 } 2583 }
2589 else 2584 else
2590 { 2585 {
2591 new_draw_info (NDI_UNIQUE, 0, op, "The handle doesn't move."); 2586 new_draw_info (NDI_UNIQUE, 0, op, "The handle doesn't move.");
2592 } 2587 }
2593 return 1; 2588 return 1;
2594 2589
2595 case EXIT: 2590 case EXIT:
2596 if (op->type != PLAYER) 2591 if (op->type != PLAYER)
2592 return 0;
2593 if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp))
2594 {
2595 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s is closed.", query_name (tmp));
2596 }
2597 else
2598 {
2599 /* Don't display messages for random maps. */
2600 if (tmp->msg && strncmp (EXIT_PATH (tmp), "/!", 2) && strncmp (EXIT_PATH (tmp), "/random/", 8))
2601 new_draw_info (NDI_NAVY, 0, op, tmp->msg);
2602 enter_exit (op, tmp);
2603 }
2604 return 1;
2605
2606 case SIGN:
2607 apply_sign (op, tmp, 0);
2608 return 1;
2609
2610 case BOOK:
2611 if (op->type == PLAYER)
2612 {
2613 apply_book (op, tmp);
2614 return 1;
2615 }
2616 else
2617 {
2597 return 0; 2618 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 } 2619 }
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 2620
2611 case SIGN: 2621 case SKILLSCROLL:
2612 apply_sign (op, tmp, 0);
2613 return 1;
2614
2615 case BOOK:
2616 if (op->type == PLAYER) 2622 if (op->type == PLAYER)
2617 { 2623 {
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); 2624 apply_skillscroll (op, tmp);
2630 return 1; 2625 return 1;
2631 } 2626 }
2632 return 0; 2627 return 0;
2633 2628
2634 case SPELLBOOK: 2629 case SPELLBOOK:
2635 if (op->type == PLAYER) 2630 if (op->type == PLAYER)
2636 { 2631 {
2637 apply_spellbook (op, tmp); 2632 apply_spellbook (op, tmp);
2638 return 1; 2633 return 1;
2639 } 2634 }
2640 return 0; 2635 return 0;
2641 2636
2642 case SCROLL: 2637 case SCROLL:
2643 apply_scroll (op, tmp, 0); 2638 apply_scroll (op, tmp, 0);
2644 return 1; 2639 return 1;
2645 2640
2646 case POTION: 2641 case POTION:
2647 (void) apply_potion (op, tmp); 2642 (void) apply_potion (op, tmp);
2648 return 1; 2643 return 1;
2649 2644
2650 /* Eneq(@csd.uu.se): Handle apply on containers. */ 2645 /* Eneq(@csd.uu.se): Handle apply on containers. */
2651 case CLOSE_CON: 2646 case CLOSE_CON:
2652 if (op->type == PLAYER) 2647 if (op->type == PLAYER)
2653 (void) esrv_apply_container (op, tmp->env); 2648 (void) esrv_apply_container (op, tmp->env);
2654 else 2649 else
2655 (void) apply_container (op, tmp->env); 2650 (void) apply_container (op, tmp->env);
2656 return 1; 2651 return 1;
2657 2652
2658 case CONTAINER: 2653 case CONTAINER:
2659 if (op->type == PLAYER) 2654 if (op->type == PLAYER)
2660 (void) esrv_apply_container (op, tmp); 2655 (void) esrv_apply_container (op, tmp);
2661 else 2656 else
2662 (void) apply_container (op, tmp); 2657 (void) apply_container (op, tmp);
2663 return 1; 2658 return 1;
2664 2659
2665 case TREASURE: 2660 case TREASURE:
2666 if (op->type == PLAYER) 2661 if (op->type == PLAYER)
2667 { 2662 {
2668 apply_treasure (op, tmp); 2663 apply_treasure (op, tmp);
2669 return 1; 2664 return 1;
2670 } 2665 }
2671 else 2666 else
2672 { 2667 {
2673 return 0; 2668 return 0;
2674 } 2669 }
2675 2670
2676 case WEAPON: 2671 case WEAPON:
2677 case ARMOUR: 2672 case ARMOUR:
2678 case BOOTS: 2673 case BOOTS:
2679 case GLOVES: 2674 case GLOVES:
2680 case AMULET: 2675 case AMULET:
2681 case GIRDLE: 2676 case GIRDLE:
2682 case BRACERS: 2677 case BRACERS:
2683 case SHIELD: 2678 case SHIELD:
2684 case HELMET: 2679 case HELMET:
2685 case RING: 2680 case RING:
2686 case CLOAK: 2681 case CLOAK:
2687 case WAND: 2682 case WAND:
2688 case ROD: 2683 case ROD:
2689 case HORN: 2684 case HORN:
2690 case SKILL: 2685 case SKILL:
2691 case BOW: 2686 case BOW:
2692 case LAMP: 2687 case LAMP:
2693 case BUILDER: 2688 case BUILDER:
2694 case SKILL_TOOL: 2689 case SKILL_TOOL:
2695 if (tmp->env != op) 2690 if (tmp->env != op)
2696 return 2; /* not in inventory */ 2691 return 2; /* not in inventory */
2697 (void) apply_special (op, tmp, aflag); 2692 (void) apply_special (op, tmp, aflag);
2698 return 1; 2693 return 1;
2699 2694
2700 case DRINK: 2695 case DRINK:
2701 case FOOD: 2696 case FOOD:
2702 case FLESH: 2697 case FLESH:
2703 apply_food (op, tmp); 2698 apply_food (op, tmp);
2704 return 1; 2699 return 1;
2705 2700
2706 case POISON: 2701 case POISON:
2707 apply_poison (op, tmp); 2702 apply_poison (op, tmp);
2708 return 1; 2703 return 1;
2709 2704
2710 case SAVEBED: 2705 case SAVEBED:
2711 if (op->type == PLAYER) 2706 if (op->type == PLAYER)
2712 { 2707 {
2713 apply_savebed (op); 2708 apply_savebed (op);
2714 return 1; 2709 return 1;
2715 } 2710 }
2716 else 2711 else
2717 { 2712 {
2718 return 0; 2713 return 0;
2719 } 2714 }
2720 2715
2721 case ARMOUR_IMPROVER: 2716 case ARMOUR_IMPROVER:
2722 if (op->type == PLAYER) 2717 if (op->type == PLAYER)
2723 { 2718 {
2724 apply_armour_improver (op, tmp); 2719 apply_armour_improver (op, tmp);
2725 return 1; 2720 return 1;
2726 } 2721 }
2727 else 2722 else
2728 { 2723 {
2729 return 0; 2724 return 0;
2730 } 2725 }
2731 2726
2732 case WEAPON_IMPROVER: 2727 case WEAPON_IMPROVER:
2733 (void) check_improve_weapon (op, tmp); 2728 (void) check_improve_weapon (op, tmp);
2734 return 1; 2729 return 1;
2735 2730
2736 case CLOCK: 2731 case CLOCK:
2737 if (op->type == PLAYER) 2732 if (op->type == PLAYER)
2738 { 2733 {
2739 char buf[MAX_BUF]; 2734 char buf[MAX_BUF];
2740 timeofday_t tod; 2735 timeofday_t tod;
2741 2736
2742 get_tod (&tod); 2737 get_tod (&tod);
2743 sprintf (buf, "It is %d minute%s past %d o'clock %s", 2738 sprintf (buf, "It is %d minute%s past %d o'clock %s",
2744 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"), 2739 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"),
2745 ((tod.hour % 14 == 0) ? 14 : ((tod.hour) % 14)), ((tod.hour >= 14) ? "pm" : "am")); 2740 ((tod.hour % 14 == 0) ? 14 : ((tod.hour) % 14)), ((tod.hour >= 14) ? "pm" : "am"));
2746 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0); 2741 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0);
2747 new_draw_info (NDI_UNIQUE, 0, op, buf); 2742 new_draw_info (NDI_UNIQUE, 0, op, buf);
2748 return 1; 2743 return 1;
2749 } 2744 }
2750 else 2745 else
2751 { 2746 {
2752 return 0; 2747 return 0;
2753 } 2748 }
2754 2749
2755 case MENU: 2750 case MENU:
2756 if (op->type == PLAYER) 2751 if (op->type == PLAYER)
2757 { 2752 {
2758 shop_listing (op); 2753 shop_listing (op);
2759 return 1; 2754 return 1;
2760 } 2755 }
2761 else 2756 else
2762 { 2757 {
2763 return 0; 2758 return 0;
2764 } 2759 }
2765 2760
2766 case POWER_CRYSTAL: 2761 case POWER_CRYSTAL:
2767 apply_power_crystal (op, tmp); /* see egoitem.c */ 2762 apply_power_crystal (op, tmp); /* see egoitem.c */
2768 return 1; 2763 return 1;
2769 2764
2770 case LIGHTER: /* for lighting torches/lanterns/etc */ 2765 case LIGHTER: /* for lighting torches/lanterns/etc */
2771 if (op->type == PLAYER) 2766 if (op->type == PLAYER)
2772 { 2767 {
2773 apply_lighter (op, tmp); 2768 apply_lighter (op, tmp);
2774 return 1; 2769 return 1;
2775 } 2770 }
2776 else 2771 else
2777 { 2772 {
2778 return 0; 2773 return 0;
2779 } 2774 }
2780 2775
2781 case ITEM_TRANSFORMER: 2776 case ITEM_TRANSFORMER:
2782 apply_item_transformer (op, tmp); 2777 apply_item_transformer (op, tmp);
2783 return 1; 2778 return 1;
2784 2779
2785 default: 2780 default:
2786 return 0; 2781 return 0;
2787 } 2782 }
2788} 2783}
2789 2784
2790 2785
2791/* quiet suppresses the "don't know how to apply" and "you must get it first" 2786/* quiet suppresses the "don't know how to apply" and "you must get it first"
2815 if (op->type != PLAYER && QUERY_FLAG (op, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ)) 2810 if (op->type != PLAYER && QUERY_FLAG (op, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ))
2816 { 2811 {
2817 play_sound_map (pl->map, pl->x, pl->y, SOUND_OB_EVAPORATE); 2812 play_sound_map (pl->map, pl->x, pl->y, SOUND_OB_EVAPORATE);
2818 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff " "of smoke!"); 2813 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff " "of smoke!");
2819 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion."); 2814 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion.");
2820 remove_ob (op); 2815 op->destroy ();
2821 free_object (op);
2822 return 1; 2816 return 1;
2823 } 2817 }
2824 2818
2825 pl->contr->last_used = op; 2819 pl->contr->last_used = op;
2826 pl->contr->last_used_id = op->count;
2827 2820
2828 tmp = manual_apply (pl, op, aflag); 2821 tmp = manual_apply (pl, op, aflag);
2829 if (!quiet) 2822 if (!quiet)
2830 { 2823 {
2831 if (tmp == 0) 2824 if (tmp == 0)
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 op->destroy ();
2959 insert_ob_in_ob (tmp2, who);
2960 fix_player (who);
2961 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2962 {
2963 if (who->type == PLAYER)
2964 {
2965 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
2966 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
2967 }
2968 }
2969 if (who->type == PLAYER)
2970 esrv_send_item (who, tmp2);
2971 return 1; /* otherwise, an attempt to drop causes problems */
2972 break;
2973 case BOW:
2974 case WAND:
2975 case ROD:
2976 case HORN:
2977 clear_skill (who);
2998 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op)); 2978 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2979 if (who->type == PLAYER)
2980 {
2999 who->contr->shoottype = range_none; 2981 who->contr->shoottype = range_none;
2982 }
2983 else
2984 {
2985 if (op->type == BOW)
2986 CLEAR_FLAG (who, FLAG_READY_BOW);
2987 else
2988 CLEAR_FLAG (who, FLAG_READY_RANGE);
2989 }
2990 break;
2991
2992 case BUILDER:
2993 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2994 who->contr->shoottype = range_none;
3000 who->contr->ranges[range_builder] = NULL; 2995 who->contr->ranges[range_builder] = NULL;
3001 break; 2996 break;
3002 2997
3003 default: 2998 default:
3004 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op)); 2999 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op));
3005 break; 3000 break;
3006 } 3001 }
3007 3002
3008 fix_player (who); 3003 fix_player (who);
3009 3004
3010 if (!(aflags & AP_NO_MERGE)) 3005 if (!(aflags & AP_NO_MERGE))
3011 { 3006 {
3012 object *tmp; 3007 object *tmp;
3013
3014 tag_t del_tag = op->count;
3015 3008
3016 tmp = merge_ob (op, NULL); 3009 tmp = merge_ob (op, NULL);
3017 if (who->type == PLAYER) 3010 if (who->type == PLAYER)
3018 { 3011 {
3019 if (tmp) 3012 if (tmp)
3020 { /* it was merged */ 3013 { /* it was merged */
3021 esrv_del_item (who->contr, del_tag); 3014 esrv_del_item (who->contr, op->count);
3022 op = tmp; 3015 op = tmp;
3023 } 3016 }
3017
3024 esrv_send_item (who, op); 3018 esrv_send_item (who, op);
3025 } 3019 }
3026 } 3020 }
3027 return 0; 3021 return 0;
3028} 3022}
3432 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op))) 3426 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op)))
3433 return RESULT_INT (0); 3427 return RESULT_INT (0);
3434 3428
3435 switch (op->type) 3429 switch (op->type)
3436 { 3430 {
3437 case WEAPON: 3431 case WEAPON:
3438 if (!check_weapon_power (who, op->last_eat)) 3432 if (!check_weapon_power (who, op->last_eat))
3439 { 3433 {
3440 new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use."); 3434 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!."); 3435 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!.");
3442 if (tmp != NULL) 3436 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); 3437 (void) insert_ob_in_ob (tmp, who);
3438 return 1;
3439 }
3440 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3441 {
3442 /* if the weapon does not have the name as the character, can't use it. */
3443 /* (Ragnarok's sword attempted to be used by Foo: won't work) */
3444 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3445 if (tmp != NULL)
3446 (void) insert_ob_in_ob (tmp, who);
3447 return 1;
3448 }
3449 SET_FLAG (op, FLAG_APPLIED);
3450
3451 if (skop)
3452 change_skill (who, skop, 1);
3453 if (!QUERY_FLAG (who, FLAG_READY_WEAPON))
3454 SET_FLAG (who, FLAG_READY_WEAPON);
3455
3456 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op));
3457
3458 (void) change_abil (who, op);
3459 break;
3460
3461 case ARMOUR:
3462 case HELMET:
3463 case SHIELD:
3464 case BOOTS:
3465 case GLOVES:
3466 case GIRDLE:
3467 case BRACERS:
3468 case CLOAK:
3469 case RING:
3470 case AMULET:
3471 SET_FLAG (op, FLAG_APPLIED);
3472 new_draw_info_format (NDI_UNIQUE, 0, who, "You wear %s.", query_name (op));
3473 (void) change_abil (who, op);
3474 break;
3475 case LAMP:
3476 if (op->stats.food < 1)
3477 {
3478 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name);
3479 return 1;
3480 }
3481 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name);
3482 tmp2 = arch_to_object (op->other_arch);
3483 tmp2->stats.food = op->stats.food;
3484 SET_FLAG (tmp2, FLAG_APPLIED);
3485 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
3486 SET_FLAG (tmp2, FLAG_INV_LOCKED);
3487 insert_ob_in_ob (tmp2, who);
3488
3489 /* Remove the old lantern */
3490 if (who->type == PLAYER)
3491 esrv_del_item (who->contr, op->count);
3492
3493 op->destroy ();
3494
3495 /* insert the portion that was split off */
3496 if (tmp != NULL)
3497 {
3498 (void) insert_ob_in_ob (tmp, who);
3505 if (who->type == PLAYER) 3499 if (who->type == PLAYER)
3506 esrv_send_item (who, tmp); 3500 esrv_send_item (who, tmp);
3507 } 3501 }
3508 fix_player (who); 3502 fix_player (who);
3509 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 3503 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
3510 { 3504 {
3511 if (who->type == PLAYER) 3505 if (who->type == PLAYER)
3512 { 3506 {
3513 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); 3507 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
3514 SET_FLAG (tmp2, FLAG_KNOWN_CURSED); 3508 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
3515 } 3509 }
3516 } 3510 }
3517 if (who->type == PLAYER) 3511 if (who->type == PLAYER)
3518 esrv_send_item (who, tmp2); 3512 esrv_send_item (who, tmp2);
3519 return 0; 3513 return 0;
3520 break; 3514 break;
3521 3515
3522 /* this part is needed for skill-tools */ 3516 /* this part is needed for skill-tools */
3523 case SKILL: 3517 case SKILL:
3524 case SKILL_TOOL: 3518 case SKILL_TOOL:
3525 if (who->chosen_skill) 3519 if (who->chosen_skill)
3526 { 3520 {
3527 LOG (llevError, "BUG: apply_special(): can't apply two skills\n"); 3521 LOG (llevError, "BUG: apply_special(): can't apply two skills\n");
3528 return 1; 3522 return 1;
3529 } 3523 }
3530 if (who->type == PLAYER) 3524 if (who->type == PLAYER)
3531 { 3525 {
3532 who->contr->shoottype = range_skill; 3526 who->contr->shoottype = range_skill;
3533 who->contr->ranges[range_skill] = op; 3527 who->contr->ranges[range_skill] = op;
3534 if (!op->invisible) 3528 if (!op->invisible)
3535 { 3529 {
3536 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); 3530 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); 3531 new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill);
3538 } 3532 }
3539 else 3533 else
3540 { 3534 {
3541 new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name); 3535 new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name);
3542 } 3536 }
3543 } 3537 }
3544 SET_FLAG (op, FLAG_APPLIED); 3538 SET_FLAG (op, FLAG_APPLIED);
3545 (void) change_abil (who, op); 3539 (void) change_abil (who, op);
3546 who->chosen_skill = op; 3540 who->chosen_skill = op;
3547 SET_FLAG (who, FLAG_READY_SKILL); 3541 SET_FLAG (who, FLAG_READY_SKILL);
3548 break; 3542 break;
3549 3543
3550 case BOW: 3544 case BOW:
3551 if (!check_weapon_power (who, op->last_eat)) 3545 if (!check_weapon_power (who, op->last_eat))
3552 { 3546 {
3553 new_draw_info (NDI_UNIQUE, 0, who, "That item is too powerful for you to use."); 3547 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!."); 3548 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!.");
3555 if (tmp != NULL) 3549 if (tmp != NULL)
3556 (void) insert_ob_in_ob (tmp, who); 3550 (void) insert_ob_in_ob (tmp, who);
3557 return 1; 3551 return 1;
3558 } 3552 }
3559 if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) 3553 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3560 { 3554 {
3561 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); 3555 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3562 if (tmp != NULL) 3556 if (tmp != NULL)
3563 (void) insert_ob_in_ob (tmp, who); 3557 (void) insert_ob_in_ob (tmp, who);
3564 return 1; 3558 return 1;
3565 } 3559 }
3566 /*FALLTHROUGH*/ case WAND: 3560 /*FALLTHROUGH*/ case WAND:
3567 case ROD: 3561 case ROD:
3568 case HORN: 3562 case HORN:
3569 /* check for skill, alter player status */ 3563 /* check for skill, alter player status */
3570 SET_FLAG (op, FLAG_APPLIED); 3564 SET_FLAG (op, FLAG_APPLIED);
3571 if (skop) 3565 if (skop)
3572 change_skill (who, skop, 0); 3566 change_skill (who, skop, 0);
3573 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); 3567 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op));
3574 3568
3575 if (who->type == PLAYER) 3569 if (who->type == PLAYER)
3576 { 3570 {
3577 if (op->type == BOW) 3571 if (op->type == BOW)
3578 { 3572 {
3579 (void) change_abil (who, op); 3573 (void) change_abil (who, op);
3580 new_draw_info_format (NDI_UNIQUE, 0, who, 3574 new_draw_info_format (NDI_UNIQUE, 0, who,
3581 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op)); 3575 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op));
3582 who->contr->shoottype = range_bow; 3576 who->contr->shoottype = range_bow;
3583 } 3577 }
3584 else 3578 else
3585 { 3579 {
3586 who->contr->shoottype = range_misc; 3580 who->contr->shoottype = range_misc;
3587 } 3581 }
3588 } 3582 }
3589 else 3583 else
3590 { 3584 {
3591 if (op->type == BOW) 3585 if (op->type == BOW)
3592 SET_FLAG (who, FLAG_READY_BOW); 3586 SET_FLAG (who, FLAG_READY_BOW);
3593 else 3587 else
3594 SET_FLAG (who, FLAG_READY_RANGE); 3588 SET_FLAG (who, FLAG_READY_RANGE);
3595 } 3589 }
3596 break; 3590 break;
3597 3591
3598 case BUILDER: 3592 case BUILDER:
3599 if (who->contr->ranges[range_builder]) 3593 if (who->contr->ranges[range_builder])
3600 unapply_special (who, who->contr->ranges[range_builder], 0); 3594 unapply_special (who, who->contr->ranges[range_builder], 0);
3601 who->contr->shoottype = range_builder; 3595 who->contr->shoottype = range_builder;
3602 who->contr->ranges[range_builder] = op; 3596 who->contr->ranges[range_builder] = op;
3603 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op)); 3597 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op));
3604 break; 3598 break;
3605 3599
3606 default: 3600 default:
3607 new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op)); 3601 new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op));
3608 } /* end of switch op->type */ 3602 } /* end of switch op->type */
3609 3603
3610 SET_FLAG (op, FLAG_APPLIED); 3604 SET_FLAG (op, FLAG_APPLIED);
3611 3605
3612 if (tmp != NULL) 3606 if (tmp != NULL)
3659 object *tmp = NULL, *tmp2; 3653 object *tmp = NULL, *tmp2;
3660 int i; 3654 int i;
3661 3655
3662 switch (op->type) 3656 switch (op->type)
3663 { 3657 {
3664 case SHOP_FLOOR: 3658 case SHOP_FLOOR:
3665 if (!HAS_RANDOM_ITEMS (op)) 3659 if (!op->has_random_items ())
3666 return 0; 3660 return 0;
3661
3667 do 3662 do
3668 { 3663 {
3669 i = 10; /* let's give it 10 tries */ 3664 i = 10; /* let's give it 10 tries */
3670 while ((tmp = generate_treasure (op->randomitems, 3665 while ((tmp = generate_treasure (op->randomitems,
3671 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i); 3666 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i);
3672 if (tmp == NULL) 3667 if (tmp == NULL)
3673 return 0; 3668 return 0;
3674 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 3669 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
3675 { 3670 {
3676 free_object (tmp); 3671 tmp->destroy ();
3677 tmp = NULL; 3672 tmp = NULL;
3678 } 3673 }
3679 } 3674 }
3680 while (!tmp); 3675 while (!tmp);
3676
3681 tmp->x = op->x; 3677 tmp->x = op->x;
3682 tmp->y = op->y; 3678 tmp->y = op->y;
3683 SET_FLAG (tmp, FLAG_UNPAID); 3679 SET_FLAG (tmp, FLAG_UNPAID);
3684 insert_ob_in_map (tmp, op->map, NULL, 0); 3680 insert_ob_in_map (tmp, op->map, NULL, 0);
3685 CLEAR_FLAG (op, FLAG_AUTO_APPLY); 3681 CLEAR_FLAG (op, FLAG_AUTO_APPLY);
3686 identify (tmp); 3682 identify (tmp);
3687 break; 3683 break;
3688 3684
3689 case TREASURE: 3685 case TREASURE:
3690 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 3686 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
3691 return 0; 3687 return 0;
3688
3692 while ((op->stats.hp--) > 0) 3689 while ((op->stats.hp--) > 0)
3693 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0, 3690 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); 3691 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3695 3692
3696 /* If we generated an object and put it in this object inventory, 3693 /* 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 3694 * move it to the parent object as the current object is about
3698 * to disappear. An example of this item is the random_* stuff 3695 * to disappear. An example of this item is the random_* stuff
3699 * that is put inside other objects. 3696 * that is put inside other objects.
3700 */ 3697 */
3701 for (tmp = op->inv; tmp; tmp = tmp2) 3698 for (tmp = op->inv; tmp; tmp = tmp2)
3702 { 3699 {
3703 tmp2 = tmp->below; 3700 tmp2 = tmp->below;
3704 remove_ob (tmp); 3701 tmp->remove ();
3702
3705 if (op->env) 3703 if (op->env)
3706 insert_ob_in_ob (tmp, op->env); 3704 insert_ob_in_ob (tmp, op->env);
3707 else 3705 else
3708 free_object (tmp); 3706 tmp->destroy ();
3709 } 3707 }
3710 remove_ob (op); 3708
3711 free_object (op); 3709 op->destroy ();
3712 break; 3710 break;
3713 } 3711 }
3714 return tmp ? 1 : 0; 3712 return tmp ? 1 : 0;
3715} 3713}
3716 3714
3717/** 3715/**
3719 * when an original map is loaded) and performs special actions for 3717 * when an original map is loaded) and performs special actions for
3720 * certain objects (most initialization of chests and creation of 3718 * certain objects (most initialization of chests and creation of
3721 * treasures and stuff). Calls auto_apply if appropriate. 3719 * treasures and stuff). Calls auto_apply if appropriate.
3722 */ 3720 */
3723void 3721void
3724fix_auto_apply (mapstruct *m) 3722fix_auto_apply (maptile *m)
3725{ 3723{
3726 object *tmp, *above = NULL; 3724 object *tmp, *above = NULL;
3727 int x, y; 3725 int x, y;
3728 3726
3729 if (m == NULL) 3727 if (m == NULL)
3743 { 3741 {
3744 invnext = invtmp->below; 3742 invnext = invtmp->below;
3745 3743
3746 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY)) 3744 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY))
3747 auto_apply (invtmp); 3745 auto_apply (invtmp);
3748 else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS (invtmp)) 3746 else if (invtmp->type == TREASURE && invtmp->has_random_items ())
3749 { 3747 {
3750 while ((invtmp->stats.hp--) > 0) 3748 while ((invtmp->stats.hp--) > 0)
3751 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3749 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3752 3750
3753 invtmp->randomitems = NULL; 3751 invtmp->randomitems = NULL;
3754 } 3752 }
3755 else if (invtmp && invtmp->arch 3753 else if (invtmp && invtmp->arch
3756 && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS && HAS_RANDOM_ITEMS (invtmp)) 3754 && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS && invtmp->has_random_items ())
3757 { 3755 {
3758 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3756 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3759 /* Need to clear this so that we never try to create 3757 /* Need to clear this so that we never try to create
3760 * treasure again for this object 3758 * treasure again for this object
3761 */ 3759 */
3778 3776
3779 } 3777 }
3780 3778
3781 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY)) 3779 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY))
3782 auto_apply (tmp); 3780 auto_apply (tmp);
3783 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && HAS_RANDOM_ITEMS (tmp)) 3781 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && tmp->has_random_items ())
3784 { 3782 {
3785 while ((tmp->stats.hp--) > 0) 3783 while ((tmp->stats.hp--) > 0)
3786 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0); 3784 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0);
3787 tmp->randomitems = NULL; 3785 tmp->randomitems = NULL;
3788 } 3786 }
3803 * This is a problem for the above objects, because they have counters 3801 * This is a problem for the above objects, because they have counters
3804 * which say how many times to make the treasure. 3802 * which say how many times to make the treasure.
3805 */ 3803 */
3806 else if (tmp && tmp->arch && tmp->type != PLAYER 3804 else if (tmp && tmp->arch && tmp->type != PLAYER
3807 && tmp->type != TREASURE && tmp->type != SPELL 3805 && tmp->type != TREASURE && tmp->type != SPELL
3808 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && HAS_RANDOM_ITEMS (tmp)) 3806 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && tmp->has_random_items ())
3809 { 3807 {
3810 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0); 3808 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0);
3811 tmp->randomitems = NULL; 3809 tmp->randomitems = NULL;
3812 } 3810 }
3813 } 3811 }
3864 SET_FLAG (force, FLAG_APPLIED); 3862 SET_FLAG (force, FLAG_APPLIED);
3865 change_abil (who, force); 3863 change_abil (who, force);
3866 insert_ob_in_ob (force, who); 3864 insert_ob_in_ob (force, who);
3867 } 3865 }
3868 else 3866 else
3869 { 3867 force->destroy ();
3870 free_object (force);
3871 }
3872 3868
3873 /* check for hp, sp change */ 3869 /* check for hp, sp change */
3874 if (food->stats.hp != 0) 3870 if (food->stats.hp != 0)
3875 { 3871 {
3876 if (QUERY_FLAG (food, FLAG_CURSED)) 3872 if (QUERY_FLAG (food, FLAG_CURSED))
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 {
3930 { /* lighter gets used up */ 3924 { /* lighter gets used up */
3931 /* Split multiple lighters if they're being used up. Otherwise * 3925 /* Split multiple lighters if they're being used up. Otherwise *
3932 * one charge from each would be used up. --DAMN */ 3926 * one charge from each would be used up. --DAMN */
3933 if (lighter->nrof > 1) 3927 if (lighter->nrof > 1)
3934 { 3928 {
3935 object *oneLighter = get_object (); 3929 object *oneLighter = lighter->clone ();
3936 3930
3937 copy_object (lighter, oneLighter);
3938 lighter->nrof -= 1; 3931 lighter->nrof -= 1;
3939 oneLighter->nrof = 1; 3932 oneLighter->nrof = 1;
3940 oneLighter->stats.food--; 3933 oneLighter->stats.food--;
3941 esrv_send_item (who, lighter); 3934 esrv_send_item (who, lighter);
3942 oneLighter = insert_ob_in_ob (oneLighter, who); 3935 oneLighter = insert_ob_in_ob (oneLighter, who);
3943 esrv_send_item (who, oneLighter); 3936 esrv_send_item (who, oneLighter);
3944 } 3937 }
3945 else 3938 else
3946 {
3947 lighter->stats.food--; 3939 lighter->stats.food--;
3948 }
3949
3950 } 3940 }
3951 else if (lighter->last_eat) 3941 else if (lighter->last_eat)
3952 { /* no charges left in lighter */ 3942 { /* 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); 3943 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; 3944 return;
3955 } 3945 }
3956 /* Perhaps we should split what we are trying to light on fire? 3946 /* 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 3947 * I can't see many times when you would want to light multiple
3958 * objects at once. 3948 * objects at once.
3959 */ 3949 */
3960 nrof = item->nrof;
3961 count = item->count;
3962 /* If the item is destroyed, we don't have a valid pointer to the 3950 /* 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 3951 * name object, so make a copy so the message we print out makes
3964 * some sense. 3952 * some sense.
3965 */ 3953 */
3966 strcpy (item_name, item->name); 3954 strcpy (item_name, item->name);
3969 3957
3970 save_throw_object (item, AT_FIRE, who); 3958 save_throw_object (item, AT_FIRE, who);
3971 /* Change to check count and not freed, since the object pointer 3959 /* Change to check count and not freed, since the object pointer
3972 * may have gotten recycled 3960 * may have gotten recycled
3973 */ 3961 */
3974 if ((nrof != item->nrof) || (count != item->count)) 3962 if (item->destroyed ())
3975 { 3963 {
3976 new_draw_info_format (NDI_UNIQUE, 0, who, "You light the %s with the %s.", &item_name, &lighter->name); 3964 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 3965 /* Need to update the player so that the players glow radius
3978 * gets changed. 3966 * gets changed.
3979 */ 3967 */
3980 if (is_player_env) 3968 if (is_player_env)
3981 fix_player (who); 3969 fix_player (who);
3982 } 3970 }
3983 else 3971 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); 3972 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 } 3973 }
3989 else /* nothing to light */ 3974 else /* nothing to light */
3990 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object."); 3975 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object.");
3991 3976
3992} 3977}
4006 object *tmp; 3991 object *tmp;
4007 3992
4008 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!."); 3993 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!.");
4009 tmp = get_archetype (SPELL_WONDER); 3994 tmp = get_archetype (SPELL_WONDER);
4010 cast_wonder (op, op, 0, tmp); 3995 cast_wonder (op, op, 0, tmp);
4011 free_object (tmp); 3996 tmp->destroy ();
4012 } 3997 }
4013 else if (failure <= -15 && failure > -35) 3998 else if (failure <= -15 && failure > -35)
4014 { /* drain mana */ 3999 { /* drain mana */
4015 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!."); 4000 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!.");
4016 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW); 4001 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW);
4039 object *tmp; 4024 object *tmp;
4040 4025
4041 tmp = get_archetype (LOOSE_MANA); 4026 tmp = get_archetype (LOOSE_MANA);
4042 cast_magic_storm (op, tmp, power); 4027 cast_magic_storm (op, tmp, power);
4043 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!"); 4028 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!");
4044 free_object (tmp); 4029 tmp->destroy ();
4045 } 4030 }
4046 } 4031 }
4047} 4032}
4048 4033
4049void 4034void
4053 for the race, put the excess stat some 4038 for the race, put the excess stat some
4054 where else. */ 4039 where else. */
4055 4040
4056 switch (change->type) 4041 switch (change->type)
4057 { 4042 {
4058 case CLASS: 4043 case CLASS:
4059 { 4044 {
4060 living *stats = &(pl->contr->orig_stats); 4045 living *stats = &(pl->contr->orig_stats);
4061 living *ns = &(change->stats); 4046 living *ns = &(change->stats);
4062 object *walk; 4047 object *walk;
4063 int flag_change_face = 1; 4048 int flag_change_face = 1;
4064 4049
4065 /* the following code assigns stats up to the stat max 4050 /* the following code assigns stats up to the stat max
4066 * for the race, and if the stat max is exceeded, 4051 * for the race, and if the stat max is exceeded,
4067 * tries to randomly reassign the excess stat 4052 * tries to randomly reassign the excess stat
4068 */ 4053 */
4069 int i, j; 4054 int i, j;
4070 4055
4071 for (i = 0; i < NUM_STATS; i++) 4056 for (i = 0; i < NUM_STATS; i++)
4072 { 4057 {
4073 sint8 stat = get_attr_value (stats, i); 4058 sint8 stat = get_attr_value (stats, i);
4074 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); 4059 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4075 4060
4076 stat += get_attr_value (ns, i); 4061 stat += get_attr_value (ns, i);
4077 if (stat > 20 + race_bonus) 4062 if (stat > 20 + race_bonus)
4078 { 4063 {
4079 excess_stat++; 4064 excess_stat++;
4080 stat = 20 + race_bonus; 4065 stat = 20 + race_bonus;
4081 } 4066 }
4082 set_attr_value (stats, i, stat); 4067 set_attr_value (stats, i, stat);
4083 } 4068 }
4084 4069
4085 for (j = 0; excess_stat > 0 && j < 100; j++) 4070 for (j = 0; excess_stat > 0 && j < 100; j++)
4086 { /* try 100 times to assign excess stats */ 4071 { /* try 100 times to assign excess stats */
4087 int i = rndm (0, 6); 4072 int i = rndm (0, 6);
4088 int stat = get_attr_value (stats, i); 4073 int stat = get_attr_value (stats, i);
4089 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); 4074 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4090 4075
4091 if (i == CHA) 4076 if (i == CHA)
4092 continue; /* exclude cha from this */ 4077 continue; /* exclude cha from this */
4093 if (stat < 20 + race_bonus) 4078 if (stat < 20 + race_bonus)
4094 { 4079 {
4095 change_attr_value (stats, i, 1); 4080 change_attr_value (stats, i, 1);
4096 excess_stat--; 4081 excess_stat--;
4097 } 4082 }
4098 } 4083 }
4099 4084
4100 /* insert the randomitems from the change's treasurelist into 4085 /* insert the randomitems from the change's treasurelist into
4101 * the player ref: player.c 4086 * the player ref: player.c
4102 */ 4087 */
4103 if (change->randomitems != NULL) 4088 if (change->randomitems != NULL)
4104 give_initial_items (pl, change->randomitems); 4089 give_initial_items (pl, change->randomitems);
4105 4090
4106 4091
4107 /* set up the face, for some races. */ 4092 /* set up the face, for some races. */
4108 4093
4109 /* first, look for the force object banning 4094 /* first, look for the force object banning
4110 * changing the face. Certain races never change face with class. 4095 * changing the face. Certain races never change face with class.
4111 */ 4096 */
4112 for (walk = pl->inv; walk != NULL; walk = walk->below) 4097 for (walk = pl->inv; walk != NULL; walk = walk->below)
4113 if (!strcmp (walk->name, "NOCLASSFACECHANGE")) 4098 if (!strcmp (walk->name, "NOCLASSFACECHANGE"))
4114 flag_change_face = 0; 4099 flag_change_face = 0;
4115 4100
4116 if (flag_change_face) 4101 if (flag_change_face)
4117 { 4102 {
4118 pl->animation_id = GET_ANIM_ID (change); 4103 pl->animation_id = GET_ANIM_ID (change);
4119 pl->face = change->face; 4104 pl->face = change->face;
4120 4105
4121 if (QUERY_FLAG (change, FLAG_ANIMATE)) 4106 if (QUERY_FLAG (change, FLAG_ANIMATE))
4122 SET_FLAG (pl, FLAG_ANIMATE); 4107 SET_FLAG (pl, FLAG_ANIMATE);
4123 else 4108 else
4124 CLEAR_FLAG (pl, FLAG_ANIMATE); 4109 CLEAR_FLAG (pl, FLAG_ANIMATE);
4125 } 4110 }
4126 4111
4127 /* check the special case of can't use weapons */ 4112 /* check the special case of can't use weapons */
4128 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */ 4113 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */
4129 if (!strcmp (change->name, "monk")) 4114 if (!strcmp (change->name, "monk"))
4130 CLEAR_FLAG (pl, FLAG_USE_WEAPON); 4115 CLEAR_FLAG (pl, FLAG_USE_WEAPON);
4131 4116
4132 break; 4117 break;
4133 } 4118 }
4134 } 4119 }
4135} 4120}
4136 4121
4137/** 4122/**
4138 * This handles items of type 'transformer'. 4123 * This handles items of type 'transformer'.
4212 if (!new_item) 4197 if (!new_item)
4213 { 4198 {
4214 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0)); 4199 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0));
4215 return; 4200 return;
4216 } 4201 }
4202
4217 new_item->nrof = yield; 4203 new_item->nrof = yield;
4218 new_draw_info_format (NDI_UNIQUE, 0, pl, "You %s the %s.", &transformer->slaying, query_base_name (marked, 0)); 4204 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); 4205 insert_ob_in_ob (new_item, pl);
4220 esrv_send_inventory (pl, pl); 4206 esrv_send_inventory (pl, pl);
4221 /* Eat up one item */ 4207 /* Eat up one item */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines