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.23 by root, Mon Sep 11 11:46:52 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.23 2006/09/11 11:46:52 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/**
1707 apply_id_altar (victim, trap, originator); 1700 apply_id_altar (victim, trap, originator);
1708 goto leave; 1701 goto leave;
1709 1702
1710 case SIGN: 1703 case SIGN:
1711 if (victim->type != PLAYER && trap->stats.food > 0) 1704 if (victim->type != PLAYER && trap->stats.food > 0)
1712 goto leave; /* monsters musn't apply magic_mouths with counters */ 1705 goto leave; /* monsters musn't apply magic_mouths with counters */
1713 1706
1714 apply_sign (victim, trap, 1); 1707 apply_sign (victim, trap, 1);
1715 goto leave; 1708 goto leave;
1716 1709
1717 case CONTAINER: 1710 case CONTAINER:
1797 1790
1798 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1791 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1799 { 1792 {
1800 /*exp_gain *= 2; because they just identified it too */ 1793 /*exp_gain *= 2; because they just identified it too */
1801 SET_FLAG (tmp, FLAG_IDENTIFIED); 1794 SET_FLAG (tmp, FLAG_IDENTIFIED);
1795
1802 /* If in a container, update how it looks */ 1796 /* If in a container, update how it looks */
1803 if (tmp->env) 1797 if (tmp->env)
1804 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1798 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1805 else 1799 else
1806 op->contr->socket.update_look = 1; 1800 op->contr->socket->floorbox_update ();
1807 } 1801 }
1802
1808 change_exp (op, exp_gain, skill_ob->skill, 0); 1803 change_exp (op, exp_gain, skill_ob->skill, 0);
1809 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 */
1810 } 1805 }
1811} 1806}
1812 1807
1817static void 1812static void
1818apply_skillscroll (object *op, object *tmp) 1813apply_skillscroll (object *op, object *tmp)
1819{ 1814{
1820 switch ((int) learn_skill (op, tmp)) 1815 switch ((int) learn_skill (op, tmp))
1821 { 1816 {
1822 case 0: 1817 case 0:
1823 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 ");
1824 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));
1825 return; 1820 return;
1826 1821
1827 case 1: 1822 case 1:
1828 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);
1829 decrease_ob (tmp); 1824 decrease_ob (tmp);
1830 return; 1825 return;
1831 1826
1832 default: 1827 default:
1833 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));
1834 decrease_ob (tmp); 1829 decrease_ob (tmp);
1835 return; 1830 return;
1836 } 1831 }
1837} 1832}
1838 1833
1839/** 1834/**
1840 * Actually makes op learn spell. 1835 * Actually makes op learn spell.
1861 } 1856 }
1862 return; 1857 return;
1863 } 1858 }
1864 1859
1865 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0); 1860 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0);
1866 tmp = get_object (); 1861 tmp = spell->clone ();
1867 copy_object (spell, tmp);
1868 insert_ob_in_ob (tmp, op); 1862 insert_ob_in_ob (tmp, op);
1869 1863
1870 if (special_prayer) 1864 if (special_prayer)
1871 {
1872 SET_FLAG (tmp, FLAG_STARTEQUIP); 1865 SET_FLAG (tmp, FLAG_STARTEQUIP);
1873 }
1874 1866
1875 esrv_add_spells (op->contr, tmp); 1867 esrv_add_spells (op->contr, tmp);
1876} 1868}
1877 1869
1878/** 1870/**
1895 } 1887 }
1896 1888
1897 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);
1898 player_unready_range_ob (op->contr, spob); 1890 player_unready_range_ob (op->contr, spob);
1899 esrv_remove_spell (op->contr, spob); 1891 esrv_remove_spell (op->contr, spob);
1900 remove_ob (spob); 1892 spob->destroy ();
1901 free_object (spob);
1902} 1893}
1903 1894
1904/** 1895/**
1905 * Handles player applying a spellbook. 1896 * Handles player applying a spellbook.
1906 * 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,
1944 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.");
1945 return; 1936 return;
1946 } 1937 }
1947 1938
1948 spell = tmp->inv; 1939 spell = tmp->inv;
1940
1949 if (!spell) 1941 if (!spell)
1950 { 1942 {
1951 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);
1952 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.");
1953 return; 1945 return;
1954 } 1946 }
1955 if (spell->level > (skop->level + 10)) 1947
1948 if (skop->level < int (sqrtf (spell->level) * 1.5f))
1956 { 1949 {
1957 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.");
1958 return; 1951 return;
1959 } 1952 }
1960 1953
1961 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);
1962 1955
1963 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1956 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1964 { 1957 {
1965 identify (tmp); 1958 identify (tmp);
1959
1966 if (tmp->env) 1960 if (tmp->env)
1967 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1961 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1968 else 1962 else
1969 op->contr->socket.update_look = 1; 1963 op->contr->socket->floorbox_update ();
1970 } 1964 }
1971 1965
1972 /* 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
1973 * 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
1974 * 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
1981 } 1975 }
1982 1976
1983 if (spell->skill) 1977 if (spell->skill)
1984 { 1978 {
1985 spell_skill = find_skill_by_name (op, spell->skill); 1979 spell_skill = find_skill_by_name (op, spell->skill);
1980
1986 if (!spell_skill) 1981 if (!spell_skill)
1987 { 1982 {
1988 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);
1989 return; 1984 return;
1990 } 1985 }
1986
1991 if (spell_skill->level < spell->level) 1987 if (spell_skill->level < spell->level)
1992 { 1988 {
1993 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);
1994 return; 1990 return;
1995 } 1991 }
2088 */ 2084 */
2089static void 2085static void
2090apply_treasure (object *op, object *tmp) 2086apply_treasure (object *op, object *tmp)
2091{ 2087{
2092 object *treas; 2088 object *treas;
2093 tag_t tmp_tag = tmp->count, op_tag = op->count;
2094 2089
2095 2090
2096 /* 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
2097 * 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
2098 * 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
2109 } 2104 }
2110 while (tmp->inv) 2105 while (tmp->inv)
2111 { 2106 {
2112 treas = tmp->inv; 2107 treas = tmp->inv;
2113 2108
2114 remove_ob (treas); 2109 treas->remove ();
2115 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));
2116 2111
2117 treas->x = op->x; 2112 treas->x = op->x;
2118 treas->y = op->y; 2113 treas->y = op->y;
2119 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);
2120 2115
2121 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))
2122 spring_trap (treas, op); 2117 spring_trap (treas, op);
2118
2123 /* If either player or container was destroyed, no need to do 2119 /* If either player or container was destroyed, no need to do
2124 * further processing. I think this should be enclused with 2120 * further processing. I think this should be enclused with
2125 * spring trap above, as I don't think there is otherwise 2121 * spring trap above, as I don't think there is otherwise
2126 * any way for the treasure chest or player to get killed 2122 * any way for the treasure chest or player to get killed
2127 */ 2123 */
2128 if (was_destroyed (op, op_tag) || was_destroyed (tmp, tmp_tag)) 2124 if (op->destroyed () || tmp->destroyed ())
2129 break; 2125 break;
2130 } 2126 }
2131 2127
2132 if (!was_destroyed (tmp, tmp_tag) && tmp->inv == NULL) 2128 if (!tmp->destroyed () && tmp->inv == NULL)
2133 decrease_ob (tmp); 2129 decrease_ob (tmp);
2134 2130
2135} 2131}
2136 2132
2137/** 2133/**
2374 } 2370 }
2375#endif 2371#endif
2376 INVOKE_PLAYER (LOGOUT, pl->contr); 2372 INVOKE_PLAYER (LOGOUT, pl->contr);
2377 /* 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 */
2378 terminate_all_pets (pl); 2374 terminate_all_pets (pl);
2379 remove_ob (pl); 2375 pl->remove ();
2380 pl->direction = 0; 2376 pl->direction = 0;
2381 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);
2382 2378
2383 /* update respawn position */ 2379 /* update respawn position */
2384 strcpy (pl->contr->savebed_map, pl->map->path); 2380 strcpy (pl->contr->savebed_map, pl->map->path);
2465is_legal_2ways_exit (object *op, object *exit) 2461is_legal_2ways_exit (object *op, object *exit)
2466{ 2462{
2467 object *tmp; 2463 object *tmp;
2468 object *exit_owner; 2464 object *exit_owner;
2469 player *pp; 2465 player *pp;
2470 mapstruct *exitmap; 2466 maptile *exitmap;
2471 2467
2472 if (exit->stats.exp != 1) 2468 if (exit->stats.exp != 1)
2473 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 */
2474 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race) 2470 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race)
2475 return 0; /* This is a reset town portal */ 2471 return 0; /* This is a reset town portal */
2568 return RESULT_INT (0); 2564 return RESULT_INT (0);
2569 2565
2570 switch (tmp->type) 2566 switch (tmp->type)
2571 { 2567 {
2572 2568
2573 case CF_HANDLE: 2569 case CF_HANDLE:
2574 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2570 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2575 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);
2576 tmp->value = tmp->value ? 0 : 1; 2572 tmp->value = tmp->value ? 0 : 1;
2577 SET_ANIMATION (tmp, tmp->value); 2573 SET_ANIMATION (tmp, tmp->value);
2578 update_object (tmp, UP_OBJ_FACE); 2574 update_object (tmp, UP_OBJ_FACE);
2579 push_button (tmp); 2575 push_button (tmp);
2580 return 1; 2576 return 1;
2581 2577
2582 case TRIGGER: 2578 case TRIGGER:
2583 if (check_trigger (tmp, op)) 2579 if (check_trigger (tmp, op))
2584 { 2580 {
2585 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2581 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2586 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);
2587 } 2583 }
2588 else 2584 else
2589 { 2585 {
2590 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.");
2591 } 2587 }
2592 return 1; 2588 return 1;
2593 2589
2594 case EXIT: 2590 case EXIT:
2595 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 {
2596 return 0; 2618 return 0;
2597 if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp))
2598 {
2599 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s is closed.", query_name (tmp));
2600 } 2619 }
2601 else
2602 {
2603 /* Don't display messages for random maps. */
2604 if (tmp->msg && strncmp (EXIT_PATH (tmp), "/!", 2) && strncmp (EXIT_PATH (tmp), "/random/", 8))
2605 new_draw_info (NDI_NAVY, 0, op, tmp->msg);
2606 enter_exit (op, tmp);
2607 }
2608 return 1;
2609 2620
2610 case SIGN: 2621 case SKILLSCROLL:
2611 apply_sign (op, tmp, 0);
2612 return 1;
2613
2614 case BOOK:
2615 if (op->type == PLAYER) 2622 if (op->type == PLAYER)
2616 { 2623 {
2617 apply_book (op, tmp);
2618 return 1;
2619 }
2620 else
2621 {
2622 return 0;
2623 }
2624
2625 case SKILLSCROLL:
2626 if (op->type == PLAYER)
2627 {
2628 apply_skillscroll (op, tmp); 2624 apply_skillscroll (op, tmp);
2629 return 1; 2625 return 1;
2630 } 2626 }
2631 return 0; 2627 return 0;
2632 2628
2633 case SPELLBOOK: 2629 case SPELLBOOK:
2634 if (op->type == PLAYER) 2630 if (op->type == PLAYER)
2635 { 2631 {
2636 apply_spellbook (op, tmp); 2632 apply_spellbook (op, tmp);
2637 return 1; 2633 return 1;
2638 } 2634 }
2639 return 0; 2635 return 0;
2640 2636
2641 case SCROLL: 2637 case SCROLL:
2642 apply_scroll (op, tmp, 0); 2638 apply_scroll (op, tmp, 0);
2643 return 1; 2639 return 1;
2644 2640
2645 case POTION: 2641 case POTION:
2646 (void) apply_potion (op, tmp); 2642 (void) apply_potion (op, tmp);
2647 return 1; 2643 return 1;
2648 2644
2649 /* Eneq(@csd.uu.se): Handle apply on containers. */ 2645 /* Eneq(@csd.uu.se): Handle apply on containers. */
2650 case CLOSE_CON: 2646 case CLOSE_CON:
2651 if (op->type == PLAYER) 2647 if (op->type == PLAYER)
2652 (void) esrv_apply_container (op, tmp->env); 2648 (void) esrv_apply_container (op, tmp->env);
2653 else 2649 else
2654 (void) apply_container (op, tmp->env); 2650 (void) apply_container (op, tmp->env);
2655 return 1; 2651 return 1;
2656 2652
2657 case CONTAINER: 2653 case CONTAINER:
2658 if (op->type == PLAYER) 2654 if (op->type == PLAYER)
2659 (void) esrv_apply_container (op, tmp); 2655 (void) esrv_apply_container (op, tmp);
2660 else 2656 else
2661 (void) apply_container (op, tmp); 2657 (void) apply_container (op, tmp);
2662 return 1; 2658 return 1;
2663 2659
2664 case TREASURE: 2660 case TREASURE:
2665 if (op->type == PLAYER) 2661 if (op->type == PLAYER)
2666 { 2662 {
2667 apply_treasure (op, tmp); 2663 apply_treasure (op, tmp);
2668 return 1; 2664 return 1;
2669 } 2665 }
2670 else 2666 else
2671 { 2667 {
2672 return 0; 2668 return 0;
2673 } 2669 }
2674 2670
2675 case WEAPON: 2671 case WEAPON:
2676 case ARMOUR: 2672 case ARMOUR:
2677 case BOOTS: 2673 case BOOTS:
2678 case GLOVES: 2674 case GLOVES:
2679 case AMULET: 2675 case AMULET:
2680 case GIRDLE: 2676 case GIRDLE:
2681 case BRACERS: 2677 case BRACERS:
2682 case SHIELD: 2678 case SHIELD:
2683 case HELMET: 2679 case HELMET:
2684 case RING: 2680 case RING:
2685 case CLOAK: 2681 case CLOAK:
2686 case WAND: 2682 case WAND:
2687 case ROD: 2683 case ROD:
2688 case HORN: 2684 case HORN:
2689 case SKILL: 2685 case SKILL:
2690 case BOW: 2686 case BOW:
2691 case LAMP: 2687 case LAMP:
2692 case BUILDER: 2688 case BUILDER:
2693 case SKILL_TOOL: 2689 case SKILL_TOOL:
2694 if (tmp->env != op) 2690 if (tmp->env != op)
2695 return 2; /* not in inventory */ 2691 return 2; /* not in inventory */
2696 (void) apply_special (op, tmp, aflag); 2692 (void) apply_special (op, tmp, aflag);
2697 return 1; 2693 return 1;
2698 2694
2699 case DRINK: 2695 case DRINK:
2700 case FOOD: 2696 case FOOD:
2701 case FLESH: 2697 case FLESH:
2702 apply_food (op, tmp); 2698 apply_food (op, tmp);
2703 return 1; 2699 return 1;
2704 2700
2705 case POISON: 2701 case POISON:
2706 apply_poison (op, tmp); 2702 apply_poison (op, tmp);
2707 return 1; 2703 return 1;
2708 2704
2709 case SAVEBED: 2705 case SAVEBED:
2710 if (op->type == PLAYER) 2706 if (op->type == PLAYER)
2711 { 2707 {
2712 apply_savebed (op); 2708 apply_savebed (op);
2713 return 1; 2709 return 1;
2714 } 2710 }
2715 else 2711 else
2716 { 2712 {
2717 return 0; 2713 return 0;
2718 } 2714 }
2719 2715
2720 case ARMOUR_IMPROVER: 2716 case ARMOUR_IMPROVER:
2721 if (op->type == PLAYER) 2717 if (op->type == PLAYER)
2722 { 2718 {
2723 apply_armour_improver (op, tmp); 2719 apply_armour_improver (op, tmp);
2724 return 1; 2720 return 1;
2725 } 2721 }
2726 else 2722 else
2727 { 2723 {
2728 return 0; 2724 return 0;
2729 } 2725 }
2730 2726
2731 case WEAPON_IMPROVER: 2727 case WEAPON_IMPROVER:
2732 (void) check_improve_weapon (op, tmp); 2728 (void) check_improve_weapon (op, tmp);
2733 return 1; 2729 return 1;
2734 2730
2735 case CLOCK: 2731 case CLOCK:
2736 if (op->type == PLAYER) 2732 if (op->type == PLAYER)
2737 { 2733 {
2738 char buf[MAX_BUF]; 2734 char buf[MAX_BUF];
2739 timeofday_t tod; 2735 timeofday_t tod;
2740 2736
2741 get_tod (&tod); 2737 get_tod (&tod);
2742 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",
2743 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"), 2739 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"),
2744 ((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"));
2745 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0); 2741 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0);
2746 new_draw_info (NDI_UNIQUE, 0, op, buf); 2742 new_draw_info (NDI_UNIQUE, 0, op, buf);
2747 return 1; 2743 return 1;
2748 } 2744 }
2749 else 2745 else
2750 { 2746 {
2751 return 0; 2747 return 0;
2752 } 2748 }
2753 2749
2754 case MENU: 2750 case MENU:
2755 if (op->type == PLAYER) 2751 if (op->type == PLAYER)
2756 { 2752 {
2757 shop_listing (op); 2753 shop_listing (op);
2758 return 1; 2754 return 1;
2759 } 2755 }
2760 else 2756 else
2761 { 2757 {
2762 return 0; 2758 return 0;
2763 } 2759 }
2764 2760
2765 case POWER_CRYSTAL: 2761 case POWER_CRYSTAL:
2766 apply_power_crystal (op, tmp); /* see egoitem.c */ 2762 apply_power_crystal (op, tmp); /* see egoitem.c */
2767 return 1; 2763 return 1;
2768 2764
2769 case LIGHTER: /* for lighting torches/lanterns/etc */ 2765 case LIGHTER: /* for lighting torches/lanterns/etc */
2770 if (op->type == PLAYER) 2766 if (op->type == PLAYER)
2771 { 2767 {
2772 apply_lighter (op, tmp); 2768 apply_lighter (op, tmp);
2773 return 1; 2769 return 1;
2774 } 2770 }
2775 else 2771 else
2776 { 2772 {
2777 return 0; 2773 return 0;
2778 } 2774 }
2779 2775
2780 case ITEM_TRANSFORMER: 2776 case ITEM_TRANSFORMER:
2781 apply_item_transformer (op, tmp); 2777 apply_item_transformer (op, tmp);
2782 return 1; 2778 return 1;
2783 2779
2784 default: 2780 default:
2785 return 0; 2781 return 0;
2786 } 2782 }
2787} 2783}
2788 2784
2789 2785
2790/* 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"
2814 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))
2815 { 2811 {
2816 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);
2817 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!");
2818 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.");
2819 remove_ob (op); 2815 op->destroy ();
2820 free_object (op);
2821 return 1; 2816 return 1;
2822 } 2817 }
2823 2818
2824 pl->contr->last_used = op; 2819 pl->contr->last_used = op;
2825 pl->contr->last_used_id = op->count;
2826 2820
2827 tmp = manual_apply (pl, op, aflag); 2821 tmp = manual_apply (pl, op, aflag);
2828 if (!quiet) 2822 if (!quiet)
2829 { 2823 {
2830 if (tmp == 0) 2824 if (tmp == 0)
2896 object *tmp2; 2890 object *tmp2;
2897 2891
2898 CLEAR_FLAG (op, FLAG_APPLIED); 2892 CLEAR_FLAG (op, FLAG_APPLIED);
2899 switch (op->type) 2893 switch (op->type)
2900 { 2894 {
2901 case WEAPON: 2895 case WEAPON:
2902 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));
2903 2897
2904 (void) change_abil (who, op); 2898 (void) change_abil (who, op);
2905 if (QUERY_FLAG (who, FLAG_READY_WEAPON)) 2899 if (QUERY_FLAG (who, FLAG_READY_WEAPON))
2906 CLEAR_FLAG (who, FLAG_READY_WEAPON); 2900 CLEAR_FLAG (who, FLAG_READY_WEAPON);
2907 clear_skill (who); 2901 clear_skill (who);
2908 break; 2902 break;
2909 2903
2910 case SKILL: /* allows objects to impart skills */ 2904 case SKILL: /* allows objects to impart skills */
2911 case SKILL_TOOL: 2905 case SKILL_TOOL:
2912 if (op != who->chosen_skill) 2906 if (op != who->chosen_skill)
2913 { 2907 {
2914 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");
2915 } 2909 }
2916 if (who->type == PLAYER) 2910 if (who->type == PLAYER)
2917 { 2911 {
2918 if (who->contr->shoottype == range_skill) 2912 if (who->contr->shoottype == range_skill)
2919 who->contr->shoottype = range_none;
2920 if (!op->invisible)
2921 {
2922 new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op));
2923 }
2924 else
2925 {
2926 new_draw_info_format (NDI_UNIQUE, 0, who, "You can no longer use the skill: %s.", &op->skill);
2927 }
2928 }
2929 (void) change_abil (who, op);
2930 who->chosen_skill = NULL;
2931 CLEAR_FLAG (who, FLAG_READY_SKILL);
2932 break;
2933
2934 case ARMOUR:
2935 case HELMET:
2936 case SHIELD:
2937 case RING:
2938 case BOOTS:
2939 case GLOVES:
2940 case AMULET:
2941 case GIRDLE:
2942 case BRACERS:
2943 case CLOAK:
2944 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwear %s.", query_name (op));
2945 (void) change_abil (who, op);
2946 break;
2947 case LAMP:
2948 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn off your %s.", &op->name);
2949 tmp2 = arch_to_object (op->other_arch);
2950 tmp2->x = op->x;
2951 tmp2->y = op->y;
2952 tmp2->map = op->map;
2953 tmp2->below = op->below;
2954 tmp2->above = op->above;
2955 tmp2->stats.food = op->stats.food;
2956 CLEAR_FLAG (tmp2, FLAG_APPLIED);
2957 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
2958 SET_FLAG (tmp2, FLAG_INV_LOCKED);
2959 if (who->type == PLAYER)
2960 esrv_del_item (who->contr, (tag_t) op->count);
2961 remove_ob (op);
2962 free_object (op);
2963 insert_ob_in_ob (tmp2, who);
2964 fix_player (who);
2965 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2966 {
2967 if (who->type == PLAYER)
2968 {
2969 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
2970 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
2971 }
2972 }
2973 if (who->type == PLAYER)
2974 esrv_send_item (who, tmp2);
2975 return 1; /* otherwise, an attempt to drop causes problems */
2976 break;
2977 case BOW:
2978 case WAND:
2979 case ROD:
2980 case HORN:
2981 clear_skill (who);
2982 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2983 if (who->type == PLAYER)
2984 {
2985 who->contr->shoottype = range_none; 2913 who->contr->shoottype = range_none;
2986 } 2914 if (!op->invisible)
2987 else
2988 { 2915 {
2989 if (op->type == BOW) 2916 new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op));
2990 CLEAR_FLAG (who, FLAG_READY_BOW); 2917 }
2991 else 2918 else
2992 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);
2993 } 2921 }
2922 }
2923 (void) change_abil (who, op);
2924 who->chosen_skill = NULL;
2925 CLEAR_FLAG (who, FLAG_READY_SKILL);
2994 break; 2926 break;
2995 2927
2928 case ARMOUR:
2929 case HELMET:
2996 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);
2997 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 {
2998 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;
2999 who->contr->ranges[range_builder] = NULL; 2995 who->contr->ranges[range_builder] = NULL;
3000 break; 2996 break;
3001 2997
3002 default: 2998 default:
3003 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));
3004 break; 3000 break;
3005 } 3001 }
3006 3002
3007 fix_player (who); 3003 fix_player (who);
3008 3004
3009 if (!(aflags & AP_NO_MERGE)) 3005 if (!(aflags & AP_NO_MERGE))
3010 { 3006 {
3011 object *tmp; 3007 object *tmp;
3012
3013 tag_t del_tag = op->count;
3014 3008
3015 tmp = merge_ob (op, NULL); 3009 tmp = merge_ob (op, NULL);
3016 if (who->type == PLAYER) 3010 if (who->type == PLAYER)
3017 { 3011 {
3018 if (tmp) 3012 if (tmp)
3019 { /* it was merged */ 3013 { /* it was merged */
3020 esrv_del_item (who->contr, del_tag); 3014 esrv_del_item (who->contr, op->count);
3021 op = tmp; 3015 op = tmp;
3022 } 3016 }
3017
3023 esrv_send_item (who, op); 3018 esrv_send_item (who, op);
3024 } 3019 }
3025 } 3020 }
3026 return 0; 3021 return 0;
3027} 3022}
3431 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)))
3432 return RESULT_INT (0); 3427 return RESULT_INT (0);
3433 3428
3434 switch (op->type) 3429 switch (op->type)
3435 { 3430 {
3436 case WEAPON: 3431 case WEAPON:
3437 if (!check_weapon_power (who, op->last_eat)) 3432 if (!check_weapon_power (who, op->last_eat))
3438 { 3433 {
3439 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.");
3440 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!.");
3441 if (tmp != NULL) 3436 if (tmp != NULL)
3442 (void) insert_ob_in_ob (tmp, who);
3443 return 1;
3444 }
3445 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3446 {
3447 /* if the weapon does not have the name as the character, can't use it. */
3448 /* (Ragnarok's sword attempted to be used by Foo: won't work) */
3449 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3450 if (tmp != NULL)
3451 (void) insert_ob_in_ob (tmp, who);
3452 return 1;
3453 }
3454 SET_FLAG (op, FLAG_APPLIED);
3455
3456 if (skop)
3457 change_skill (who, skop, 1);
3458 if (!QUERY_FLAG (who, FLAG_READY_WEAPON))
3459 SET_FLAG (who, FLAG_READY_WEAPON);
3460
3461 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op));
3462
3463 (void) change_abil (who, op);
3464 break;
3465
3466 case ARMOUR:
3467 case HELMET:
3468 case SHIELD:
3469 case BOOTS:
3470 case GLOVES:
3471 case GIRDLE:
3472 case BRACERS:
3473 case CLOAK:
3474 case RING:
3475 case AMULET:
3476 SET_FLAG (op, FLAG_APPLIED);
3477 new_draw_info_format (NDI_UNIQUE, 0, who, "You wear %s.", query_name (op));
3478 (void) change_abil (who, op);
3479 break;
3480 case LAMP:
3481 if (op->stats.food < 1)
3482 {
3483 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name);
3484 return 1;
3485 }
3486 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name);
3487 tmp2 = arch_to_object (op->other_arch);
3488 tmp2->stats.food = op->stats.food;
3489 SET_FLAG (tmp2, FLAG_APPLIED);
3490 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
3491 SET_FLAG (tmp2, FLAG_INV_LOCKED);
3492 insert_ob_in_ob (tmp2, who);
3493
3494 /* Remove the old lantern */
3495 if (who->type == PLAYER)
3496 esrv_del_item (who->contr, (tag_t) op->count);
3497 remove_ob (op);
3498 free_object (op);
3499
3500 /* insert the portion that was split off */
3501 if (tmp != NULL)
3502 {
3503 (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);
3504 if (who->type == PLAYER) 3499 if (who->type == PLAYER)
3505 esrv_send_item (who, tmp); 3500 esrv_send_item (who, tmp);
3506 } 3501 }
3507 fix_player (who); 3502 fix_player (who);
3508 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 3503 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
3509 { 3504 {
3510 if (who->type == PLAYER) 3505 if (who->type == PLAYER)
3511 { 3506 {
3512 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!");
3513 SET_FLAG (tmp2, FLAG_KNOWN_CURSED); 3508 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
3514 } 3509 }
3515 } 3510 }
3516 if (who->type == PLAYER) 3511 if (who->type == PLAYER)
3517 esrv_send_item (who, tmp2); 3512 esrv_send_item (who, tmp2);
3518 return 0; 3513 return 0;
3519 break; 3514 break;
3520 3515
3521 /* this part is needed for skill-tools */ 3516 /* this part is needed for skill-tools */
3522 case SKILL: 3517 case SKILL:
3523 case SKILL_TOOL: 3518 case SKILL_TOOL:
3524 if (who->chosen_skill) 3519 if (who->chosen_skill)
3525 { 3520 {
3526 LOG (llevError, "BUG: apply_special(): can't apply two skills\n"); 3521 LOG (llevError, "BUG: apply_special(): can't apply two skills\n");
3527 return 1; 3522 return 1;
3528 } 3523 }
3529 if (who->type == PLAYER) 3524 if (who->type == PLAYER)
3530 { 3525 {
3531 who->contr->shoottype = range_skill; 3526 who->contr->shoottype = range_skill;
3532 who->contr->ranges[range_skill] = op; 3527 who->contr->ranges[range_skill] = op;
3533 if (!op->invisible) 3528 if (!op->invisible)
3534 { 3529 {
3535 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));
3536 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);
3537 } 3532 }
3538 else 3533 else
3539 { 3534 {
3540 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);
3541 } 3536 }
3542 } 3537 }
3543 SET_FLAG (op, FLAG_APPLIED); 3538 SET_FLAG (op, FLAG_APPLIED);
3544 (void) change_abil (who, op); 3539 (void) change_abil (who, op);
3545 who->chosen_skill = op; 3540 who->chosen_skill = op;
3546 SET_FLAG (who, FLAG_READY_SKILL); 3541 SET_FLAG (who, FLAG_READY_SKILL);
3547 break; 3542 break;
3548 3543
3549 case BOW: 3544 case BOW:
3550 if (!check_weapon_power (who, op->last_eat)) 3545 if (!check_weapon_power (who, op->last_eat))
3551 { 3546 {
3552 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.");
3553 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!.");
3554 if (tmp != NULL) 3549 if (tmp != NULL)
3555 (void) insert_ob_in_ob (tmp, who); 3550 (void) insert_ob_in_ob (tmp, who);
3556 return 1; 3551 return 1;
3557 } 3552 }
3558 if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) 3553 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3559 { 3554 {
3560 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.");
3561 if (tmp != NULL) 3556 if (tmp != NULL)
3562 (void) insert_ob_in_ob (tmp, who); 3557 (void) insert_ob_in_ob (tmp, who);
3563 return 1; 3558 return 1;
3564 } 3559 }
3565 /*FALLTHROUGH*/ case WAND: 3560 /*FALLTHROUGH*/ case WAND:
3566 case ROD: 3561 case ROD:
3567 case HORN: 3562 case HORN:
3568 /* check for skill, alter player status */ 3563 /* check for skill, alter player status */
3569 SET_FLAG (op, FLAG_APPLIED); 3564 SET_FLAG (op, FLAG_APPLIED);
3570 if (skop) 3565 if (skop)
3571 change_skill (who, skop, 0); 3566 change_skill (who, skop, 0);
3572 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));
3573 3568
3574 if (who->type == PLAYER) 3569 if (who->type == PLAYER)
3575 { 3570 {
3576 if (op->type == BOW) 3571 if (op->type == BOW)
3577 { 3572 {
3578 (void) change_abil (who, op); 3573 (void) change_abil (who, op);
3579 new_draw_info_format (NDI_UNIQUE, 0, who, 3574 new_draw_info_format (NDI_UNIQUE, 0, who,
3580 "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));
3581 who->contr->shoottype = range_bow; 3576 who->contr->shoottype = range_bow;
3582 } 3577 }
3583 else 3578 else
3584 { 3579 {
3585 who->contr->shoottype = range_misc; 3580 who->contr->shoottype = range_misc;
3586 } 3581 }
3587 } 3582 }
3588 else 3583 else
3589 { 3584 {
3590 if (op->type == BOW) 3585 if (op->type == BOW)
3591 SET_FLAG (who, FLAG_READY_BOW); 3586 SET_FLAG (who, FLAG_READY_BOW);
3592 else 3587 else
3593 SET_FLAG (who, FLAG_READY_RANGE); 3588 SET_FLAG (who, FLAG_READY_RANGE);
3594 } 3589 }
3595 break; 3590 break;
3596 3591
3597 case BUILDER: 3592 case BUILDER:
3598 if (who->contr->ranges[range_builder]) 3593 if (who->contr->ranges[range_builder])
3599 unapply_special (who, who->contr->ranges[range_builder], 0); 3594 unapply_special (who, who->contr->ranges[range_builder], 0);
3600 who->contr->shoottype = range_builder; 3595 who->contr->shoottype = range_builder;
3601 who->contr->ranges[range_builder] = op; 3596 who->contr->ranges[range_builder] = op;
3602 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));
3603 break; 3598 break;
3604 3599
3605 default: 3600 default:
3606 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));
3607 } /* end of switch op->type */ 3602 } /* end of switch op->type */
3608 3603
3609 SET_FLAG (op, FLAG_APPLIED); 3604 SET_FLAG (op, FLAG_APPLIED);
3610 3605
3611 if (tmp != NULL) 3606 if (tmp != NULL)
3658 object *tmp = NULL, *tmp2; 3653 object *tmp = NULL, *tmp2;
3659 int i; 3654 int i;
3660 3655
3661 switch (op->type) 3656 switch (op->type)
3662 { 3657 {
3663 case SHOP_FLOOR: 3658 case SHOP_FLOOR:
3664 if (!HAS_RANDOM_ITEMS (op)) 3659 if (!op->has_random_items ())
3665 return 0; 3660 return 0;
3661
3666 do 3662 do
3667 { 3663 {
3668 i = 10; /* let's give it 10 tries */ 3664 i = 10; /* let's give it 10 tries */
3669 while ((tmp = generate_treasure (op->randomitems, 3665 while ((tmp = generate_treasure (op->randomitems,
3670 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);
3671 if (tmp == NULL) 3667 if (tmp == NULL)
3672 return 0; 3668 return 0;
3673 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 3669 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
3674 { 3670 {
3675 free_object (tmp); 3671 tmp->destroy ();
3676 tmp = NULL; 3672 tmp = NULL;
3677 } 3673 }
3678 } 3674 }
3679 while (!tmp); 3675 while (!tmp);
3676
3680 tmp->x = op->x; 3677 tmp->x = op->x;
3681 tmp->y = op->y; 3678 tmp->y = op->y;
3682 SET_FLAG (tmp, FLAG_UNPAID); 3679 SET_FLAG (tmp, FLAG_UNPAID);
3683 insert_ob_in_map (tmp, op->map, NULL, 0); 3680 insert_ob_in_map (tmp, op->map, NULL, 0);
3684 CLEAR_FLAG (op, FLAG_AUTO_APPLY); 3681 CLEAR_FLAG (op, FLAG_AUTO_APPLY);
3685 identify (tmp); 3682 identify (tmp);
3686 break; 3683 break;
3687 3684
3688 case TREASURE: 3685 case TREASURE:
3689 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 3686 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
3690 return 0; 3687 return 0;
3688
3691 while ((op->stats.hp--) > 0) 3689 while ((op->stats.hp--) > 0)
3692 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0, 3690 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0,
3693 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);
3694 3692
3695 /* 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,
3696 * 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
3697 * to disappear. An example of this item is the random_* stuff 3695 * to disappear. An example of this item is the random_* stuff
3698 * that is put inside other objects. 3696 * that is put inside other objects.
3699 */ 3697 */
3700 for (tmp = op->inv; tmp; tmp = tmp2) 3698 for (tmp = op->inv; tmp; tmp = tmp2)
3701 { 3699 {
3702 tmp2 = tmp->below; 3700 tmp2 = tmp->below;
3703 remove_ob (tmp); 3701 tmp->remove ();
3702
3704 if (op->env) 3703 if (op->env)
3705 insert_ob_in_ob (tmp, op->env); 3704 insert_ob_in_ob (tmp, op->env);
3706 else 3705 else
3707 free_object (tmp); 3706 tmp->destroy ();
3708 } 3707 }
3709 remove_ob (op); 3708
3710 free_object (op); 3709 op->destroy ();
3711 break; 3710 break;
3712 } 3711 }
3713 return tmp ? 1 : 0; 3712 return tmp ? 1 : 0;
3714} 3713}
3715 3714
3716/** 3715/**
3718 * when an original map is loaded) and performs special actions for 3717 * when an original map is loaded) and performs special actions for
3719 * certain objects (most initialization of chests and creation of 3718 * certain objects (most initialization of chests and creation of
3720 * treasures and stuff). Calls auto_apply if appropriate. 3719 * treasures and stuff). Calls auto_apply if appropriate.
3721 */ 3720 */
3722void 3721void
3723fix_auto_apply (mapstruct *m) 3722fix_auto_apply (maptile *m)
3724{ 3723{
3725 object *tmp, *above = NULL; 3724 object *tmp, *above = NULL;
3726 int x, y; 3725 int x, y;
3727 3726
3728 if (m == NULL) 3727 if (m == NULL)
3742 { 3741 {
3743 invnext = invtmp->below; 3742 invnext = invtmp->below;
3744 3743
3745 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY)) 3744 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY))
3746 auto_apply (invtmp); 3745 auto_apply (invtmp);
3747 else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS (invtmp)) 3746 else if (invtmp->type == TREASURE && invtmp->has_random_items ())
3748 { 3747 {
3749 while ((invtmp->stats.hp--) > 0) 3748 while ((invtmp->stats.hp--) > 0)
3750 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3749 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3751 3750
3752 invtmp->randomitems = NULL; 3751 invtmp->randomitems = NULL;
3753 } 3752 }
3754 else if (invtmp && invtmp->arch 3753 else if (invtmp && invtmp->arch
3755 && 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 ())
3756 { 3755 {
3757 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3756 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3758 /* Need to clear this so that we never try to create 3757 /* Need to clear this so that we never try to create
3759 * treasure again for this object 3758 * treasure again for this object
3760 */ 3759 */
3777 3776
3778 } 3777 }
3779 3778
3780 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY)) 3779 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY))
3781 auto_apply (tmp); 3780 auto_apply (tmp);
3782 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 ())
3783 { 3782 {
3784 while ((tmp->stats.hp--) > 0) 3783 while ((tmp->stats.hp--) > 0)
3785 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0); 3784 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0);
3786 tmp->randomitems = NULL; 3785 tmp->randomitems = NULL;
3787 } 3786 }
3802 * 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
3803 * which say how many times to make the treasure. 3802 * which say how many times to make the treasure.
3804 */ 3803 */
3805 else if (tmp && tmp->arch && tmp->type != PLAYER 3804 else if (tmp && tmp->arch && tmp->type != PLAYER
3806 && tmp->type != TREASURE && tmp->type != SPELL 3805 && tmp->type != TREASURE && tmp->type != SPELL
3807 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && HAS_RANDOM_ITEMS (tmp)) 3806 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && tmp->has_random_items ())
3808 { 3807 {
3809 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0); 3808 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0);
3810 tmp->randomitems = NULL; 3809 tmp->randomitems = NULL;
3811 } 3810 }
3812 } 3811 }
3863 SET_FLAG (force, FLAG_APPLIED); 3862 SET_FLAG (force, FLAG_APPLIED);
3864 change_abil (who, force); 3863 change_abil (who, force);
3865 insert_ob_in_ob (force, who); 3864 insert_ob_in_ob (force, who);
3866 } 3865 }
3867 else 3866 else
3868 { 3867 force->destroy ();
3869 free_object (force);
3870 }
3871 3868
3872 /* check for hp, sp change */ 3869 /* check for hp, sp change */
3873 if (food->stats.hp != 0) 3870 if (food->stats.hp != 0)
3874 { 3871 {
3875 if (QUERY_FLAG (food, FLAG_CURSED)) 3872 if (QUERY_FLAG (food, FLAG_CURSED))
3916void 3913void
3917apply_lighter (object *who, object *lighter) 3914apply_lighter (object *who, object *lighter)
3918{ 3915{
3919 object *item; 3916 object *item;
3920 int is_player_env = 0; 3917 int is_player_env = 0;
3921 uint32 nrof;
3922 tag_t count;
3923 char item_name[MAX_BUF]; 3918 char item_name[MAX_BUF];
3924 3919
3925 item = find_marked_object (who); 3920 item = find_marked_object (who);
3926 if (item) 3921 if (item)
3927 { 3922 {
3929 { /* lighter gets used up */ 3924 { /* lighter gets used up */
3930 /* Split multiple lighters if they're being used up. Otherwise * 3925 /* Split multiple lighters if they're being used up. Otherwise *
3931 * one charge from each would be used up. --DAMN */ 3926 * one charge from each would be used up. --DAMN */
3932 if (lighter->nrof > 1) 3927 if (lighter->nrof > 1)
3933 { 3928 {
3934 object *oneLighter = get_object (); 3929 object *oneLighter = lighter->clone ();
3935 3930
3936 copy_object (lighter, oneLighter);
3937 lighter->nrof -= 1; 3931 lighter->nrof -= 1;
3938 oneLighter->nrof = 1; 3932 oneLighter->nrof = 1;
3939 oneLighter->stats.food--; 3933 oneLighter->stats.food--;
3940 esrv_send_item (who, lighter); 3934 esrv_send_item (who, lighter);
3941 oneLighter = insert_ob_in_ob (oneLighter, who); 3935 oneLighter = insert_ob_in_ob (oneLighter, who);
3942 esrv_send_item (who, oneLighter); 3936 esrv_send_item (who, oneLighter);
3943 } 3937 }
3944 else 3938 else
3945 {
3946 lighter->stats.food--; 3939 lighter->stats.food--;
3947 }
3948
3949 } 3940 }
3950 else if (lighter->last_eat) 3941 else if (lighter->last_eat)
3951 { /* no charges left in lighter */ 3942 { /* no charges left in lighter */
3952 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);
3953 return; 3944 return;
3954 } 3945 }
3955 /* 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?
3956 * 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
3957 * objects at once. 3948 * objects at once.
3958 */ 3949 */
3959 nrof = item->nrof;
3960 count = item->count;
3961 /* 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
3962 * 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
3963 * some sense. 3952 * some sense.
3964 */ 3953 */
3965 strcpy (item_name, item->name); 3954 strcpy (item_name, item->name);
3968 3957
3969 save_throw_object (item, AT_FIRE, who); 3958 save_throw_object (item, AT_FIRE, who);
3970 /* Change to check count and not freed, since the object pointer 3959 /* Change to check count and not freed, since the object pointer
3971 * may have gotten recycled 3960 * may have gotten recycled
3972 */ 3961 */
3973 if ((nrof != item->nrof) || (count != item->count)) 3962 if (item->destroyed ())
3974 { 3963 {
3975 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);
3976 /* Need to update the player so that the players glow radius 3965 /* Need to update the player so that the players glow radius
3977 * gets changed. 3966 * gets changed.
3978 */ 3967 */
3979 if (is_player_env) 3968 if (is_player_env)
3980 fix_player (who); 3969 fix_player (who);
3981 } 3970 }
3982 else 3971 else
3983 {
3984 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);
3985 }
3986
3987 } 3973 }
3988 else /* nothing to light */ 3974 else /* nothing to light */
3989 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.");
3990 3976
3991} 3977}
4005 object *tmp; 3991 object *tmp;
4006 3992
4007 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!."); 3993 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!.");
4008 tmp = get_archetype (SPELL_WONDER); 3994 tmp = get_archetype (SPELL_WONDER);
4009 cast_wonder (op, op, 0, tmp); 3995 cast_wonder (op, op, 0, tmp);
4010 free_object (tmp); 3996 tmp->destroy ();
4011 } 3997 }
4012 else if (failure <= -15 && failure > -35) 3998 else if (failure <= -15 && failure > -35)
4013 { /* drain mana */ 3999 { /* drain mana */
4014 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!."); 4000 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!.");
4015 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW); 4001 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW);
4038 object *tmp; 4024 object *tmp;
4039 4025
4040 tmp = get_archetype (LOOSE_MANA); 4026 tmp = get_archetype (LOOSE_MANA);
4041 cast_magic_storm (op, tmp, power); 4027 cast_magic_storm (op, tmp, power);
4042 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!"); 4028 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!");
4043 free_object (tmp); 4029 tmp->destroy ();
4044 } 4030 }
4045 } 4031 }
4046} 4032}
4047 4033
4048void 4034void
4052 for the race, put the excess stat some 4038 for the race, put the excess stat some
4053 where else. */ 4039 where else. */
4054 4040
4055 switch (change->type) 4041 switch (change->type)
4056 { 4042 {
4057 case CLASS: 4043 case CLASS:
4058 { 4044 {
4059 living *stats = &(pl->contr->orig_stats); 4045 living *stats = &(pl->contr->orig_stats);
4060 living *ns = &(change->stats); 4046 living *ns = &(change->stats);
4061 object *walk; 4047 object *walk;
4062 int flag_change_face = 1; 4048 int flag_change_face = 1;
4063 4049
4064 /* the following code assigns stats up to the stat max 4050 /* the following code assigns stats up to the stat max
4065 * for the race, and if the stat max is exceeded, 4051 * for the race, and if the stat max is exceeded,
4066 * tries to randomly reassign the excess stat 4052 * tries to randomly reassign the excess stat
4067 */ 4053 */
4068 int i, j; 4054 int i, j;
4069 4055
4070 for (i = 0; i < NUM_STATS; i++) 4056 for (i = 0; i < NUM_STATS; i++)
4071 { 4057 {
4072 sint8 stat = get_attr_value (stats, i); 4058 sint8 stat = get_attr_value (stats, i);
4073 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); 4059 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4074 4060
4075 stat += get_attr_value (ns, i); 4061 stat += get_attr_value (ns, i);
4076 if (stat > 20 + race_bonus) 4062 if (stat > 20 + race_bonus)
4077 { 4063 {
4078 excess_stat++; 4064 excess_stat++;
4079 stat = 20 + race_bonus; 4065 stat = 20 + race_bonus;
4080 } 4066 }
4081 set_attr_value (stats, i, stat); 4067 set_attr_value (stats, i, stat);
4082 } 4068 }
4083 4069
4084 for (j = 0; excess_stat > 0 && j < 100; j++) 4070 for (j = 0; excess_stat > 0 && j < 100; j++)
4085 { /* try 100 times to assign excess stats */ 4071 { /* try 100 times to assign excess stats */
4086 int i = rndm (0, 6); 4072 int i = rndm (0, 6);
4087 int stat = get_attr_value (stats, i); 4073 int stat = get_attr_value (stats, i);
4088 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); 4074 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4089 4075
4090 if (i == CHA) 4076 if (i == CHA)
4091 continue; /* exclude cha from this */ 4077 continue; /* exclude cha from this */
4092 if (stat < 20 + race_bonus) 4078 if (stat < 20 + race_bonus)
4093 { 4079 {
4094 change_attr_value (stats, i, 1); 4080 change_attr_value (stats, i, 1);
4095 excess_stat--; 4081 excess_stat--;
4096 } 4082 }
4097 } 4083 }
4098 4084
4099 /* insert the randomitems from the change's treasurelist into 4085 /* insert the randomitems from the change's treasurelist into
4100 * the player ref: player.c 4086 * the player ref: player.c
4101 */ 4087 */
4102 if (change->randomitems != NULL) 4088 if (change->randomitems != NULL)
4103 give_initial_items (pl, change->randomitems); 4089 give_initial_items (pl, change->randomitems);
4104 4090
4105 4091
4106 /* set up the face, for some races. */ 4092 /* set up the face, for some races. */
4107 4093
4108 /* first, look for the force object banning 4094 /* first, look for the force object banning
4109 * changing the face. Certain races never change face with class. 4095 * changing the face. Certain races never change face with class.
4110 */ 4096 */
4111 for (walk = pl->inv; walk != NULL; walk = walk->below) 4097 for (walk = pl->inv; walk != NULL; walk = walk->below)
4112 if (!strcmp (walk->name, "NOCLASSFACECHANGE")) 4098 if (!strcmp (walk->name, "NOCLASSFACECHANGE"))
4113 flag_change_face = 0; 4099 flag_change_face = 0;
4114 4100
4115 if (flag_change_face) 4101 if (flag_change_face)
4116 { 4102 {
4117 pl->animation_id = GET_ANIM_ID (change); 4103 pl->animation_id = GET_ANIM_ID (change);
4118 pl->face = change->face; 4104 pl->face = change->face;
4119 4105
4120 if (QUERY_FLAG (change, FLAG_ANIMATE)) 4106 if (QUERY_FLAG (change, FLAG_ANIMATE))
4121 SET_FLAG (pl, FLAG_ANIMATE); 4107 SET_FLAG (pl, FLAG_ANIMATE);
4122 else 4108 else
4123 CLEAR_FLAG (pl, FLAG_ANIMATE); 4109 CLEAR_FLAG (pl, FLAG_ANIMATE);
4124 } 4110 }
4125 4111
4126 /* check the special case of can't use weapons */ 4112 /* check the special case of can't use weapons */
4127 /*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); */
4128 if (!strcmp (change->name, "monk")) 4114 if (!strcmp (change->name, "monk"))
4129 CLEAR_FLAG (pl, FLAG_USE_WEAPON); 4115 CLEAR_FLAG (pl, FLAG_USE_WEAPON);
4130 4116
4131 break; 4117 break;
4132 } 4118 }
4133 } 4119 }
4134} 4120}
4135 4121
4136/** 4122/**
4137 * This handles items of type 'transformer'. 4123 * This handles items of type 'transformer'.
4211 if (!new_item) 4197 if (!new_item)
4212 { 4198 {
4213 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));
4214 return; 4200 return;
4215 } 4201 }
4202
4216 new_item->nrof = yield; 4203 new_item->nrof = yield;
4217 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));
4218 insert_ob_in_ob (new_item, pl); 4205 insert_ob_in_ob (new_item, pl);
4219 esrv_send_inventory (pl, pl); 4206 esrv_send_inventory (pl, pl);
4220 /* Eat up one item */ 4207 /* Eat up one item */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines