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.51 by root, Fri Dec 22 16:34:00 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>
33#include <skills.h> 27#include <skills.h>
34#include <tod.h> 28#include <tod.h>
35 29
36#ifndef __CEXTRACT__
37# include <sproto.h> 30#include <sproto.h>
38#endif
39 31
40/* Want this regardless of rplay. */ 32/* Want this regardless of rplay. */
41#include <sounds.h> 33#include <sounds.h>
42 34
43/* need math lib for double-precision and pow() in dragon_eat_flesh() */ 35/* need math lib for double-precision and pow() in dragon_eat_flesh() */
201apply_potion (object *op, object *tmp) 193apply_potion (object *op, object *tmp)
202{ 194{
203 int got_one = 0, i; 195 int got_one = 0, i;
204 object *force = 0, *floor = 0; 196 object *force = 0, *floor = 0;
205 197
206 floor = get_map_ob (op->map, op->x, op->y); 198 floor = GET_MAP_OB (op->map, op->x, op->y);
207 199
208 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE) 200 if (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_SAFE)
209 { 201 {
210 if (op->type == PLAYER) 202 if (op->type == PLAYER)
211 new_draw_info (NDI_UNIQUE, 0, op, "Gods prevent you from using this here, it's sacred ground!"); 203 new_draw_info (NDI_UNIQUE, 0, op, "Gods prevent you from using this here, it's sacred ground!");
212 CLEAR_FLAG (tmp, FLAG_APPLIED); 204 CLEAR_FLAG (tmp, FLAG_APPLIED);
213 return 0; 205 return 0;
214 } 206 }
215 207
216 if (op->type == PLAYER) 208 if (op->type == PLAYER)
217 {
218 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 209 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
219 identify (tmp); 210 identify (tmp);
220 }
221 211
222 handle_apply_yield (tmp); 212 handle_apply_yield (tmp);
223 213
224 /* Potion of restoration - only for players */ 214 /* Potion of restoration - only for players */
225 if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE)) 215 if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE))
227 object *depl; 217 object *depl;
228 archetype *at; 218 archetype *at;
229 219
230 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 220 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
231 { 221 {
232 drain_stat (op); 222 op->drain_stat ();
233 fix_player (op); 223 op->update_stats ();
234 decrease_ob (tmp); 224 decrease_ob (tmp);
235 return 1; 225 return 1;
236 } 226 }
227
237 if ((at = find_archetype (ARCH_DEPLETION)) == NULL) 228 if (!(at = archetype::find (ARCH_DEPLETION)))
238 { 229 {
239 LOG (llevError, "Could not find archetype depletion\n"); 230 LOG (llevError, "Could not find archetype depletion\n");
240 return 0; 231 return 0;
241 } 232 }
242 depl = present_arch_in_ob (at, op); 233 depl = present_arch_in_ob (at, op);
234
243 if (depl != NULL) 235 if (depl)
244 { 236 {
245 for (i = 0; i < NUM_STATS; i++) 237 for (i = 0; i < NUM_STATS; i++)
246 if (get_attr_value (&depl->stats, i)) 238 if (get_attr_value (&depl->stats, i))
247 {
248 new_draw_info (NDI_UNIQUE, 0, op, restore_msg[i]); 239 new_draw_info (NDI_UNIQUE, 0, op, restore_msg[i]);
249 } 240
250 remove_ob (depl); 241 depl->destroy ();
251 free_object (depl); 242 op->update_stats ();
252 fix_player (op);
253 } 243 }
254 else 244 else
255 new_draw_info (NDI_UNIQUE, 0, op, "You potion had no effect."); 245 new_draw_info (NDI_UNIQUE, 0, op, "You potion had no effect.");
256 246
257 decrease_ob (tmp); 247 decrease_ob (tmp);
259 } 249 }
260 250
261 /* improvement potion - only for players */ 251 /* improvement potion - only for players */
262 if (op->type == PLAYER && tmp->attacktype & AT_GODPOWER) 252 if (op->type == PLAYER && tmp->attacktype & AT_GODPOWER)
263 { 253 {
264
265 for (i = 1; i < MIN (11, op->level); i++) 254 for (i = 1; i < MIN (11, op->level); i++)
266 { 255 {
267 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 256 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
268 { 257 {
269 if (op->contr->levhp[i] != 1) 258 if (op->contr->levhp[i] != 1)
299 op->contr->levgrace[i] = 3; 288 op->contr->levgrace[i] = 3;
300 break; 289 break;
301 } 290 }
302 } 291 }
303 } 292 }
293
304 /* Just makes checking easier */ 294 /* Just makes checking easier */
305 if (i < MIN (11, op->level)) 295 if (i < MIN (11, op->level))
306 got_one = 1; 296 got_one = 1;
297
307 if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED)) 298 if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED))
308 { 299 {
309 if (got_one) 300 if (got_one)
310 { 301 {
311 fix_player (op); 302 op->update_stats ();
312 new_draw_info (NDI_UNIQUE, 0, op, "The Gods smile upon you and remake you"); 303 new_draw_info (NDI_UNIQUE, 0, op, "The Gods smile upon you and remake you");
313 new_draw_info (NDI_UNIQUE, 0, op, "a little more in their image."); 304 new_draw_info (NDI_UNIQUE, 0, op, "a little more in their image.");
314 new_draw_info (NDI_UNIQUE, 0, op, "You feel a little more perfect."); 305 new_draw_info (NDI_UNIQUE, 0, op, "You feel a little more perfect.");
315 } 306 }
316 else 307 else
318 } 309 }
319 else 310 else
320 { /* cursed potion */ 311 { /* cursed potion */
321 if (got_one) 312 if (got_one)
322 { 313 {
323 fix_player (op); 314 op->update_stats ();
324 new_draw_info (NDI_UNIQUE, 0, op, "The Gods are angry and punish you."); 315 new_draw_info (NDI_UNIQUE, 0, op, "The Gods are angry and punish you.");
325 } 316 }
326 else 317 else
327 new_draw_info (NDI_UNIQUE, 0, op, "You are fortunate that you are so pathetic."); 318 new_draw_info (NDI_UNIQUE, 0, op, "You are fortunate that you are so pathetic.");
328 } 319 }
320
329 decrease_ob (tmp); 321 decrease_ob (tmp);
330 return 1; 322 return 1;
331 } 323 }
332 324
333 325
355 cast_spell (op, tmp, op->facing, tmp->inv, NULL); 347 cast_spell (op, tmp, op->facing, tmp->inv, NULL);
356 348
357 decrease_ob (tmp); 349 decrease_ob (tmp);
358 /* if youre dead, no point in doing this... */ 350 /* if youre dead, no point in doing this... */
359 if (!QUERY_FLAG (op, FLAG_REMOVED)) 351 if (!QUERY_FLAG (op, FLAG_REMOVED))
360 fix_player (op); 352 op->update_stats ();
361 return 1; 353 return 1;
362 } 354 }
363 355
364 /* Deal with protection potions */ 356 /* Deal with protection potions */
365 force = NULL; 357 force = NULL;
409 * that were grouped with the one consumed, his 401 * that were grouped with the one consumed, his
410 * stat will not be raised by them. fix_player just clears 402 * stat will not be raised by them. fix_player just clears
411 * up all the stats. 403 * up all the stats.
412 */ 404 */
413 CLEAR_FLAG (tmp, FLAG_APPLIED); 405 CLEAR_FLAG (tmp, FLAG_APPLIED);
414 fix_player (op); 406 op->update_stats ();
415 decrease_ob (tmp); 407 decrease_ob (tmp);
416 return 1; 408 return 1;
417} 409}
418 410
419/**************************************************************************** 411/****************************************************************************
576 weapon->last_eat++; 568 weapon->last_eat++;
577 new_draw_info_format (NDI_UNIQUE, 0, op, "Weapon's bonus to %s improved by %d", statname, sacrifice_count); 569 new_draw_info_format (NDI_UNIQUE, 0, op, "Weapon's bonus to %s improved by %d", statname, sacrifice_count);
578 decrease_ob (improver); 570 decrease_ob (improver);
579 571
580 /* So it updates the players stats and the window */ 572 /* So it updates the players stats and the window */
581 fix_player (op); 573 op->update_stats ();
582 return 1; 574 return 1;
583} 575}
584 576
585/* Types of improvements, hidden in the sp field. */ 577/* Types of improvements, hidden in the sp field. */
586#define IMPROVE_PREPARE 1 578#define IMPROVE_PREPARE 1
737 eat_item (op, improver->slaying, sacrifice_needed); 729 eat_item (op, improver->slaying, sacrifice_needed);
738 weapon->item_power++; 730 weapon->item_power++;
739 731
740 switch (improver->stats.sp) 732 switch (improver->stats.sp)
741 { 733 {
742 case IMPROVE_STR: 734 case IMPROVE_STR:
743 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Str), 1, "strength"); 735 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Str), 1, "strength");
744 case IMPROVE_DEX: 736 case IMPROVE_DEX:
745 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Dex), 1, "dexterity"); 737 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Dex), 1, "dexterity");
746 case IMPROVE_CON: 738 case IMPROVE_CON:
747 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Con), 1, "constitution"); 739 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Con), 1, "constitution");
748 case IMPROVE_WIS: 740 case IMPROVE_WIS:
749 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Wis), 1, "wisdom"); 741 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Wis), 1, "wisdom");
750 case IMPROVE_CHA: 742 case IMPROVE_CHA:
751 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Cha), 1, "charisma"); 743 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Cha), 1, "charisma");
752 case IMPROVE_INT: 744 case IMPROVE_INT:
753 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Int), 1, "intelligence"); 745 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Int), 1, "intelligence");
754 case IMPROVE_POW: 746 case IMPROVE_POW:
755 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Pow), 1, "power"); 747 return improve_weapon_stat (op, improver, weapon, (signed char *) &(weapon->stats.Pow), 1, "power");
756 default: 748 default:
757 new_draw_info (NDI_UNIQUE, 0, op, "Unknown improvement type."); 749 new_draw_info (NDI_UNIQUE, 0, op, "Unknown improvement type.");
758 } 750 }
759 LOG (llevError, "improve_weapon: Got to end of function\n"); 751 LOG (llevError, "improve_weapon: Got to end of function\n");
760 return 0; 752 return 0;
761} 753}
762 754
889 881
890 if (op->type == PLAYER) 882 if (op->type == PLAYER)
891 { 883 {
892 esrv_send_item (op, armour); 884 esrv_send_item (op, armour);
893 if (QUERY_FLAG (armour, FLAG_APPLIED)) 885 if (QUERY_FLAG (armour, FLAG_APPLIED))
894 fix_player (op); 886 op->update_stats ();
895 } 887 }
896 decrease_ob (improver); 888 decrease_ob (improver);
897 if (tmp) 889 if (tmp)
898 { 890 {
899 insert_ob_in_ob (tmp, op); 891 insert_ob_in_ob (tmp, op);
958 price_in = nr * CONV_NEED (converter) * item->value; 950 price_in = nr * CONV_NEED (converter) * item->value;
959 } 951 }
960 else 952 else
961 { 953 {
962 price_in = item->value; 954 price_in = item->value;
963 remove_ob (item); 955 item->destroy ();
964 free_object (item);
965 } 956 }
966 } 957 }
967 958
968 if (converter->inv != NULL) 959 if (converter->inv != NULL)
969 { 960 {
1033 if (op->type != PLAYER) 1024 if (op->type != PLAYER)
1034 return 0; /* This might change */ 1025 return 0; /* This might change */
1035 1026
1036 if (sack == NULL || sack->type != CONTAINER) 1027 if (sack == NULL || sack->type != CONTAINER)
1037 { 1028 {
1038 LOG (llevError, "apply_container: %s is not container!\n", &sack->name); 1029 LOG (llevError, "apply_container: %s is not container!\n", sack ? &sack->name : "[nullobject]");
1039 return 0; 1030 return 0;
1040 } 1031 }
1041 op->contr->last_used = NULL; 1032
1042 op->contr->last_used_id = 0; 1033 op->contr->last_used = 0;
1043 1034
1044 if (sack->env != op) 1035 if (sack->env != op)
1045 { 1036 {
1046 if (sack->other_arch == NULL || sack->env != NULL) 1037 if (sack->other_arch == NULL || sack->env != NULL)
1047 { 1038 {
1048 new_draw_info (NDI_UNIQUE, 0, op, "You must get it first."); 1039 new_draw_info (NDI_UNIQUE, 0, op, "You must get it first.");
1049 return 1; 1040 return 1;
1050 } 1041 }
1042
1051 /* It's on the ground, the problems begin */ 1043 /* It's on the ground, the problems begin */
1052 if (op->container != sack) 1044 if (op->container != sack)
1053 { 1045 {
1054 /* it's closed OR some player has opened it */ 1046 /* it's closed OR some player has opened it */
1055 if (QUERY_FLAG (sack, FLAG_APPLIED)) 1047 if (QUERY_FLAG (sack, FLAG_APPLIED))
1056 { 1048 {
1057 for (tmp = get_map_ob (sack->map, sack->x, sack->y); tmp && tmp->container != sack; tmp = tmp->above); 1049 for (tmp = GET_MAP_OB (sack->map, sack->x, sack->y); tmp && tmp->container != sack; tmp = tmp->above);
1058 if (tmp) 1050 if (tmp)
1059 { 1051 {
1060 /* some other player have opened it */ 1052 /* some other player have opened it */
1061 new_draw_info_format (NDI_UNIQUE, 0, op, "%s is already occupied.", query_name (sack)); 1053 new_draw_info_format (NDI_UNIQUE, 0, op, "%s is already occupied.", query_name (sack));
1062 return 1; 1054 return 1;
1082 } 1074 }
1083 else 1075 else
1084 { 1076 {
1085 sack->move_off = 0; 1077 sack->move_off = 0;
1086 tmp = sack->inv; 1078 tmp = sack->inv;
1079
1087 if (tmp && tmp->type == CLOSE_CON) 1080 if (tmp && tmp->type == CLOSE_CON)
1088 { 1081 tmp->destroy ();
1089 remove_ob (tmp);
1090 free_object (tmp);
1091 }
1092 } 1082 }
1093 } 1083 }
1094 } 1084 }
1095 1085
1096 if (QUERY_FLAG (sack, FLAG_APPLIED)) 1086 if (QUERY_FLAG (sack, FLAG_APPLIED))
1128 tmp = find_key (op, op, sack); 1118 tmp = find_key (op, op, sack);
1129 if (tmp) 1119 if (tmp)
1130 { 1120 {
1131 sprintf (buf, "You unlock %s with %s.", query_name (sack), query_name (tmp)); 1121 sprintf (buf, "You unlock %s with %s.", query_name (sack), query_name (tmp));
1132 SET_FLAG (sack, FLAG_APPLIED); 1122 SET_FLAG (sack, FLAG_APPLIED);
1123
1133 if (sack->env == NULL) 1124 if (sack->env == NULL)
1134 { /* if it's on ground,open it also */ 1125 { /* if it's on ground,open it also */
1135 new_draw_info (NDI_UNIQUE, 0, op, buf); 1126 new_draw_info (NDI_UNIQUE, 0, op, buf);
1136 apply_container (op, sack); 1127 apply_container (op, sack);
1137 return 1; 1128 return 1;
1138 } 1129 }
1139 } 1130 }
1140 else 1131 else
1141 {
1142 sprintf (buf, "You don't have the key to unlock %s.", query_name (sack)); 1132 sprintf (buf, "You don't have the key to unlock %s.", query_name (sack));
1143 }
1144 } 1133 }
1145 else 1134 else
1146 { 1135 {
1147 sprintf (buf, "You readied %s.", query_name (sack)); 1136 sprintf (buf, "You readied %s.", query_name (sack));
1148 SET_FLAG (sack, FLAG_APPLIED); 1137 SET_FLAG (sack, FLAG_APPLIED);
1138
1149 if (sack->env == NULL) 1139 if (sack->env == NULL)
1150 { /* if it's on ground,open it also */ 1140 { /* if it's on ground,open it also */
1151 new_draw_info (NDI_UNIQUE, 0, op, buf); 1141 new_draw_info (NDI_UNIQUE, 0, op, buf);
1152 apply_container (op, sack); 1142 apply_container (op, sack);
1153 return 1; 1143 return 1;
1154 } 1144 }
1155 } 1145 }
1156 } 1146 }
1147
1157 new_draw_info (NDI_UNIQUE, 0, op, buf); 1148 new_draw_info (NDI_UNIQUE, 0, op, buf);
1149
1158 if (op->contr) 1150 if (op->contr)
1159 op->contr->socket.update_look = 1; 1151 op->contr->ns->floorbox_update ();
1152
1160 return 1; 1153 return 1;
1161} 1154}
1162 1155
1163/** 1156/**
1164 * Eneq(@csd.uu.se): Handle apply on containers. This is for containers 1157 * Eneq(@csd.uu.se): Handle apply on containers. This is for containers
1182 if (op->type != PLAYER) 1175 if (op->type != PLAYER)
1183 return 0; /* This might change */ 1176 return 0; /* This might change */
1184 1177
1185 if (sack == NULL || sack->type != CONTAINER) 1178 if (sack == NULL || sack->type != CONTAINER)
1186 { 1179 {
1187 LOG (llevError, "esrv_apply_container: %s is not container!\n", &sack->name); 1180 LOG (llevError, "esrv_apply_container: %s is not container!\n", sack ? &sack->name : "[nullobject]");
1188 return 0; 1181 return 0;
1189 } 1182 }
1190 1183
1191 /* If we have a currently open container, then it needs to be closed in all cases 1184 /* 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 1185 * if we are opening this one up. We then fall through if appropriate for
1315 else 1308 else
1316 { 1309 {
1317 altar->value = 1; /* works only once */ 1310 altar->value = 1; /* works only once */
1318 push_button (altar); 1311 push_button (altar);
1319 } 1312 }
1313
1320 return sacrifice == NULL; 1314 return !sacrifice;
1321 } 1315 }
1322 else 1316 else
1323 {
1324 return 0; 1317 return 0;
1325 }
1326} 1318}
1327
1328 1319
1329/** 1320/**
1330 * Handles 'movement' of shop mats. 1321 * Handles 'movement' of shop mats.
1331 * Returns 1 if 'op' was destroyed, 0 if not. 1322 * Returns 1 if 'op' was destroyed, 0 if not.
1332 * Largely re-written to not use nearly as many gotos, plus 1323 * Largely re-written to not use nearly as many gotos, plus
1349 * the shop. 1340 * the shop.
1350 */ 1341 */
1351 for (tmp = op->inv; tmp; tmp = next) 1342 for (tmp = op->inv; tmp; tmp = next)
1352 { 1343 {
1353 next = tmp->below; 1344 next = tmp->below;
1345
1354 if (QUERY_FLAG (tmp, FLAG_UNPAID)) 1346 if (QUERY_FLAG (tmp, FLAG_UNPAID))
1355 { 1347 {
1356 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); 1348 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9);
1357 1349
1358 remove_ob (tmp); 1350 tmp->remove ();
1351
1359 if (i == -1) 1352 if (i == -1)
1360 i = 0; 1353 i = 0;
1354
1361 tmp->map = op->map; 1355 tmp->map = op->map;
1362 tmp->x = op->x + freearr_x[i]; 1356 tmp->x = op->x + freearr_x[i];
1363 tmp->y = op->y + freearr_y[i]; 1357 tmp->y = op->y + freearr_y[i];
1364 insert_ob_in_map (tmp, op->map, op, 0); 1358 insert_ob_in_map (tmp, op->map, op, 0);
1365 } 1359 }
1377 1371
1378 /* Somebody dropped an unpaid item, just move to an adjacent place. */ 1372 /* 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); 1373 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
1380 1374
1381 if (i != -1) 1375 if (i != -1)
1382 {
1383 rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat); 1376 rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat);
1384 } 1377
1385 return 0; 1378 return 0;
1386 } 1379 }
1387 /* Removed code that checked for multipart objects - it appears that 1380 /* Removed code that checked for multipart objects - it appears that
1388 * the teleport function should be able to handle this just fine. 1381 * the teleport function should be able to handle this just fine.
1389 */ 1382 */
1390 rv = teleport (shop_mat, SHOP_MAT, op); 1383 rv = teleport (shop_mat, SHOP_MAT, op);
1391 } 1384 }
1392 /* immediate block below is only used for players */ 1385 else if (can_pay (op) && get_payment (op))
1393 else if (can_pay (op))
1394 { 1386 {
1395 get_payment (op, op->inv); 1387 /* this is only used for players */
1396 rv = teleport (shop_mat, SHOP_MAT, op); 1388 rv = teleport (shop_mat, SHOP_MAT, op);
1397 1389
1398 if (shop_mat->msg) 1390 if (shop_mat->msg)
1399 {
1400 new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg); 1391 new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg);
1401 }
1402 /* This check below is a bit simplistic - generally it should be correct, 1392 /* 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 1393 * but there is never a guarantee that the bottom space on the map is
1404 * actually the shop floor. 1394 * actually the shop floor.
1405 */ 1395 */
1406 else if (!rv && !is_in_shop (op)) 1396 else if (!rv && !is_in_shop (op))
1407 { 1397 {
1408 opinion = shopkeeper_approval (op->map, op); 1398 opinion = shopkeeper_approval (op->map, op);
1399
1409 if (opinion > 0.9) 1400 if (opinion > 0.9)
1410 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper gives you a friendly wave."); 1401 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper gives you a friendly wave.");
1411 else if (opinion > 0.75) 1402 else if (opinion > 0.75)
1412 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper waves to you."); 1403 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper waves to you.");
1413 else if (opinion > 0.5) 1404 else if (opinion > 0.5)
1420 { 1411 {
1421 /* if we get here, a player tried to leave a shop but was not able 1412 /* 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 1413 * to afford the items he has. We try to move the player so that
1423 * they are not on the mat anymore 1414 * they are not on the mat anymore
1424 */ 1415 */
1425
1426 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); 1416 int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
1427 1417
1428 if (i == -1) 1418 if (i == -1)
1429 { 1419 {
1430 LOG (llevError, "Internal shop-mat problem.\n"); 1420 LOG (llevError, "Internal shop-mat problem.\n");
1431 } 1421 }
1432 else 1422 else
1433 { 1423 {
1434 remove_ob (op); 1424 op->remove ();
1435 op->x += freearr_x[i]; 1425 op->x += freearr_x[i];
1436 op->y += freearr_y[i]; 1426 op->y += freearr_y[i];
1437 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL; 1427 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL;
1438 } 1428 }
1439 } 1429 }
1430
1440 CLEAR_FLAG (op, FLAG_NO_APPLY); 1431 CLEAR_FLAG (op, FLAG_NO_APPLY);
1441 return rv; 1432 return rv;
1442} 1433}
1443 1434
1444/** 1435/**
1707 apply_id_altar (victim, trap, originator); 1698 apply_id_altar (victim, trap, originator);
1708 goto leave; 1699 goto leave;
1709 1700
1710 case SIGN: 1701 case SIGN:
1711 if (victim->type != PLAYER && trap->stats.food > 0) 1702 if (victim->type != PLAYER && trap->stats.food > 0)
1712 goto leave; /* monsters musn't apply magic_mouths with counters */ 1703 goto leave; /* monsters musn't apply magic_mouths with counters */
1713 1704
1714 apply_sign (victim, trap, 1); 1705 apply_sign (victim, trap, 1);
1715 goto leave; 1706 goto leave;
1716 1707
1717 case CONTAINER: 1708 case CONTAINER:
1797 1788
1798 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1789 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1799 { 1790 {
1800 /*exp_gain *= 2; because they just identified it too */ 1791 /*exp_gain *= 2; because they just identified it too */
1801 SET_FLAG (tmp, FLAG_IDENTIFIED); 1792 SET_FLAG (tmp, FLAG_IDENTIFIED);
1793
1802 /* If in a container, update how it looks */ 1794 /* If in a container, update how it looks */
1803 if (tmp->env) 1795 if (tmp->env)
1804 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1796 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1805 else 1797 else
1806 op->contr->socket.update_look = 1; 1798 op->contr->ns->floorbox_update ();
1807 } 1799 }
1800
1808 change_exp (op, exp_gain, skill_ob->skill, 0); 1801 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 */ 1802 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT); /* so no more xp gained from this book */
1810 } 1803 }
1811} 1804}
1812 1805
1817static void 1810static void
1818apply_skillscroll (object *op, object *tmp) 1811apply_skillscroll (object *op, object *tmp)
1819{ 1812{
1820 switch ((int) learn_skill (op, tmp)) 1813 switch ((int) learn_skill (op, tmp))
1821 { 1814 {
1822 case 0: 1815 case 0:
1823 new_draw_info (NDI_UNIQUE, 0, op, "You already possess the knowledge "); 1816 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)); 1817 new_draw_info_format (NDI_UNIQUE, 0, op, "held within the %s.\n", query_name (tmp));
1825 return; 1818 return;
1826 1819
1827 case 1: 1820 case 1:
1828 new_draw_info_format (NDI_UNIQUE, 0, op, "You succeed in learning %s", &tmp->skill); 1821 new_draw_info_format (NDI_UNIQUE, 0, op, "You succeed in learning %s", &tmp->skill);
1829 decrease_ob (tmp); 1822 decrease_ob (tmp);
1830 return; 1823 return;
1831 1824
1832 default: 1825 default:
1833 new_draw_info_format (NDI_UNIQUE, 0, op, "You fail to learn the knowledge of the %s.\n", query_name (tmp)); 1826 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); 1827 decrease_ob (tmp);
1835 return; 1828 return;
1836 } 1829 }
1837} 1830}
1838 1831
1839/** 1832/**
1840 * Actually makes op learn spell. 1833 * Actually makes op learn spell.
1861 } 1854 }
1862 return; 1855 return;
1863 } 1856 }
1864 1857
1865 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0); 1858 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0);
1866 tmp = get_object (); 1859 tmp = spell->clone ();
1867 copy_object (spell, tmp);
1868 insert_ob_in_ob (tmp, op); 1860 insert_ob_in_ob (tmp, op);
1869 1861
1870 if (special_prayer) 1862 if (special_prayer)
1871 {
1872 SET_FLAG (tmp, FLAG_STARTEQUIP); 1863 SET_FLAG (tmp, FLAG_STARTEQUIP);
1873 }
1874 1864
1875 esrv_add_spells (op->contr, tmp); 1865 esrv_add_spells (op->contr, tmp);
1876} 1866}
1877 1867
1878/** 1868/**
1895 } 1885 }
1896 1886
1897 new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You lose knowledge of %s.", spell); 1887 new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You lose knowledge of %s.", spell);
1898 player_unready_range_ob (op->contr, spob); 1888 player_unready_range_ob (op->contr, spob);
1899 esrv_remove_spell (op->contr, spob); 1889 esrv_remove_spell (op->contr, spob);
1900 remove_ob (spob); 1890 spob->destroy ();
1901 free_object (spob);
1902} 1891}
1903 1892
1904/** 1893/**
1905 * Handles player applying a spellbook. 1894 * Handles player applying a spellbook.
1906 * Checks whether player has knowledge of required skill, doesn't already know the spell, 1895 * 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."); 1933 new_draw_info (NDI_UNIQUE, 0, op, "You can't read! Your attempt fails.");
1945 return; 1934 return;
1946 } 1935 }
1947 1936
1948 spell = tmp->inv; 1937 spell = tmp->inv;
1938
1949 if (!spell) 1939 if (!spell)
1950 { 1940 {
1951 LOG (llevError, "apply_spellbook: Book %s has no spell in it!\n", &tmp->name); 1941 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."); 1942 new_draw_info (NDI_UNIQUE, 0, op, "The spellbook symbols make no sense.");
1953 return; 1943 return;
1954 } 1944 }
1955 if (spell->level > (skop->level + 10)) 1945
1946 if (skop->level < int (sqrtf (spell->level) * 1.5f))
1956 { 1947 {
1957 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to decipher the strange symbols."); 1948 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; 1949 return;
1959 } 1950 }
1960 1951
1961 new_draw_info_format (NDI_UNIQUE, 0, op, "The spellbook contains the %s level spell %s.", get_levelnumber (spell->level), &spell->name); 1952 new_draw_info_format (NDI_UNIQUE, 0, op, "The spellbook contains the %s level spell %s.", get_levelnumber (spell->level), &spell->name);
1962 1953
1963 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1954 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1964 { 1955 {
1965 identify (tmp); 1956 identify (tmp);
1957
1966 if (tmp->env) 1958 if (tmp->env)
1967 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1959 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1968 else 1960 else
1969 op->contr->socket.update_look = 1; 1961 op->contr->ns->floorbox_update ();
1970 } 1962 }
1971 1963
1972 /* I removed the check for special_prayer_mark here - it didn't make 1964 /* 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 1965 * 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 1966 * if the player doesn't know the spell, doesn't make a lot of sense that
1981 } 1973 }
1982 1974
1983 if (spell->skill) 1975 if (spell->skill)
1984 { 1976 {
1985 spell_skill = find_skill_by_name (op, spell->skill); 1977 spell_skill = find_skill_by_name (op, spell->skill);
1978
1986 if (!spell_skill) 1979 if (!spell_skill)
1987 { 1980 {
1988 new_draw_info_format (NDI_UNIQUE, 0, op, "You lack the skill %s to use this spell", &spell->skill); 1981 new_draw_info_format (NDI_UNIQUE, 0, op, "You lack the skill %s to use this spell", &spell->skill);
1989 return; 1982 return;
1990 } 1983 }
1984
1991 if (spell_skill->level < spell->level) 1985 if (spell_skill->level < spell->level)
1992 { 1986 {
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); 1987 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; 1988 return;
1995 } 1989 }
2088 */ 2082 */
2089static void 2083static void
2090apply_treasure (object *op, object *tmp) 2084apply_treasure (object *op, object *tmp)
2091{ 2085{
2092 object *treas; 2086 object *treas;
2093 tag_t tmp_tag = tmp->count, op_tag = op->count;
2094 2087
2095 2088
2096 /* Nice side effect of new treasure creation method is that the treasure 2089 /* 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 2090 * 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 2091 * inventory. So that when the chest burns up, the items still exist. Also
2109 } 2102 }
2110 while (tmp->inv) 2103 while (tmp->inv)
2111 { 2104 {
2112 treas = tmp->inv; 2105 treas = tmp->inv;
2113 2106
2114 remove_ob (treas); 2107 treas->remove ();
2115 new_draw_info_format (NDI_UNIQUE, 0, op, "You find %s in the chest.", query_name (treas)); 2108 new_draw_info_format (NDI_UNIQUE, 0, op, "You find %s in the chest.", query_name (treas));
2116 2109
2117 treas->x = op->x; 2110 treas->x = op->x;
2118 treas->y = op->y; 2111 treas->y = op->y;
2119 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR); 2112 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR);
2120 2113
2121 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && QUERY_FLAG (op, FLAG_ALIVE)) 2114 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && QUERY_FLAG (op, FLAG_ALIVE))
2122 spring_trap (treas, op); 2115 spring_trap (treas, op);
2116
2123 /* If either player or container was destroyed, no need to do 2117 /* If either player or container was destroyed, no need to do
2124 * further processing. I think this should be enclused with 2118 * further processing. I think this should be enclused with
2125 * spring trap above, as I don't think there is otherwise 2119 * spring trap above, as I don't think there is otherwise
2126 * any way for the treasure chest or player to get killed 2120 * any way for the treasure chest or player to get killed
2127 */ 2121 */
2128 if (was_destroyed (op, op_tag) || was_destroyed (tmp, tmp_tag)) 2122 if (op->destroyed () || tmp->destroyed ())
2129 break; 2123 break;
2130 } 2124 }
2131 2125
2132 if (!was_destroyed (tmp, tmp_tag) && tmp->inv == NULL) 2126 if (!tmp->destroyed () && tmp->inv == NULL)
2133 decrease_ob (tmp); 2127 decrease_ob (tmp);
2134 2128
2135} 2129}
2136 2130
2137/** 2131/**
2332 2326
2333 if (i >= 0 && i < NROFATTACKS && skin->resist[i] < 95) 2327 if (i >= 0 && i < NROFATTACKS && skin->resist[i] < 95)
2334 { 2328 {
2335 /* resistance increased! */ 2329 /* resistance increased! */
2336 skin->resist[i]++; 2330 skin->resist[i]++;
2337 fix_player (op); 2331 op->update_stats ();
2338 2332
2339 sprintf (buf, "Your skin is now more resistant to %s!", change_resist_msg[i]); 2333 sprintf (buf, "Your skin is now more resistant to %s!", change_resist_msg[i]);
2340 new_draw_info (NDI_UNIQUE | NDI_RED, 0, op, buf); 2334 new_draw_info (NDI_UNIQUE | NDI_RED, 0, op, buf);
2341 } 2335 }
2342 2336
2361 } 2355 }
2362 } 2356 }
2363 return 1; 2357 return 1;
2364} 2358}
2365 2359
2366static void
2367apply_savebed (object *pl)
2368{
2369#ifndef COZY_SERVER
2370 if (!pl->contr->name_changed || !pl->stats.exp)
2371 {
2372 new_draw_info (NDI_UNIQUE, 0, pl, "You don't deserve to save your character yet.");
2373 return;
2374 }
2375#endif
2376 INVOKE_PLAYER (LOGOUT, pl->contr);
2377 /* Need to call terminate_all_pets() before we remove the player ob */
2378 terminate_all_pets (pl);
2379 remove_ob (pl);
2380 pl->direction = 0;
2381 new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, pl, "%s leaves the game.", &pl->name);
2382
2383 /* update respawn position */
2384 strcpy (pl->contr->savebed_map, pl->map->path);
2385 pl->contr->bed_x = pl->x;
2386 pl->contr->bed_y = pl->y;
2387
2388 strcpy (pl->contr->killer, "left");
2389 check_score (pl); /* Always check score */
2390 (void) save_player (pl, 0);
2391 pl->map->players--;
2392#if MAP_MAXTIMEOUT
2393 MAP_SWAP_TIME (pl->map) = MAP_TIMEOUT (pl->map);
2394#endif
2395 play_again (pl);
2396 pl->speed = 0;
2397 update_ob_speed (pl);
2398}
2399
2400/** 2360/**
2401 * Handles applying an improve armor scroll. 2361 * Handles applying an improve armor scroll.
2402 * Does some sanity checks, then calls improve_armour. 2362 * Does some sanity checks, then calls improve_armour.
2403 */ 2363 */
2404static void 2364static void
2409 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC)) 2369 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC))
2410 { 2370 {
2411 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the scroll."); 2371 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the scroll.");
2412 return; 2372 return;
2413 } 2373 }
2374
2414 armor = find_marked_object (op); 2375 armor = find_marked_object (op);
2376
2415 if (!armor) 2377 if (!armor)
2416 { 2378 {
2417 new_draw_info (NDI_UNIQUE, 0, op, "You need to mark an armor object."); 2379 new_draw_info (NDI_UNIQUE, 0, op, "You need to mark an armor object.");
2418 return; 2380 return;
2419 } 2381 }
2382
2420 if (armor->type != ARMOUR 2383 if (armor->type != ARMOUR
2421 && armor->type != CLOAK 2384 && armor->type != CLOAK
2422 && armor->type != BOOTS && armor->type != GLOVES && armor->type != BRACERS && armor->type != SHIELD && armor->type != HELMET) 2385 && armor->type != BOOTS && armor->type != GLOVES && armor->type != BRACERS && armor->type != SHIELD && armor->type != HELMET)
2423 { 2386 {
2424 new_draw_info (NDI_UNIQUE, 0, op, "Your marked item is not armour!\n"); 2387 new_draw_info (NDI_UNIQUE, 0, op, "Your marked item is not armour!\n");
2426 } 2389 }
2427 2390
2428 new_draw_info (NDI_UNIQUE, 0, op, "Applying armour enchantment."); 2391 new_draw_info (NDI_UNIQUE, 0, op, "Applying armour enchantment.");
2429 improve_armour (op, tmp, armor); 2392 improve_armour (op, tmp, armor);
2430} 2393}
2431
2432 2394
2433extern void 2395extern void
2434apply_poison (object *op, object *tmp) 2396apply_poison (object *op, object *tmp)
2435{ 2397{
2436 if (op->type == PLAYER) 2398 if (op->type == PLAYER)
2452/** 2414/**
2453 * This fonction return true if the exit is not a 2 ways one or it is 2 ways, valid exit. 2415 * This fonction return true if the exit is not a 2 ways one or it is 2 ways, valid exit.
2454 * A valid 2 way exit means: 2416 * A valid 2 way exit means:
2455 * -You can come back (there is another exit at the other side) 2417 * -You can come back (there is another exit at the other side)
2456 * -You are 2418 * -You are
2457 * ° the owner of the exit 2419 * ° the owner of the exit
2458 * ° or in the same party as the owner 2420 * ° or in the same party as the owner
2459 * 2421 *
2460 * Note: a owner in a 2 way exit is saved as the owner's name 2422 * Note: a owner in a 2 way exit is saved as the owner's name
2461 * in the field exit->name cause the field exit->owner doesn't 2423 * in the field exit->name cause the field exit->owner doesn't
2462 * survive in the swapping (in fact the whole exit doesn't survive). 2424 * survive in the swapping (in fact the whole exit doesn't survive).
2463 */ 2425 */
2465is_legal_2ways_exit (object *op, object *exit) 2427is_legal_2ways_exit (object *op, object *exit)
2466{ 2428{
2467 object *tmp; 2429 object *tmp;
2468 object *exit_owner; 2430 object *exit_owner;
2469 player *pp; 2431 player *pp;
2470 mapstruct *exitmap; 2432 maptile *exitmap;
2471 2433
2472 if (exit->stats.exp != 1) 2434 if (exit->stats.exp != 1)
2473 return 1; /*This is not a 2 way, so it is legal */ 2435 return 1; /*This is not a 2 way, so it is legal */
2474 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race) 2436 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race)
2475 return 0; /* This is a reset town portal */ 2437 return 0; /* This is a reset town portal */
2480 exitmap = ready_map_name (EXIT_PATH (exit), MAP_PLAYER_UNIQUE); 2442 exitmap = ready_map_name (EXIT_PATH (exit), MAP_PLAYER_UNIQUE);
2481 else 2443 else
2482 exitmap = ready_map_name (EXIT_PATH (exit), 0); 2444 exitmap = ready_map_name (EXIT_PATH (exit), 0);
2483 if (exitmap) 2445 if (exitmap)
2484 { 2446 {
2485 tmp = get_map_ob (exitmap, EXIT_X (exit), EXIT_Y (exit)); 2447 tmp = GET_MAP_OB (exitmap, EXIT_X (exit), EXIT_Y (exit));
2486 if (!tmp) 2448 if (!tmp)
2487 return 0; 2449 return 0;
2488 for ((tmp = get_map_ob (exitmap, EXIT_X (exit), EXIT_Y (exit))); tmp; tmp = tmp->above) 2450 for ((tmp = GET_MAP_OB (exitmap, EXIT_X (exit), EXIT_Y (exit))); tmp; tmp = tmp->above)
2489 { 2451 {
2490 if (tmp->type != EXIT) 2452 if (tmp->type != EXIT)
2491 continue; /*Not an exit */ 2453 continue; /*Not an exit */
2492 if (!EXIT_PATH (tmp)) 2454 if (!EXIT_PATH (tmp))
2493 continue; /*Not a valid exit */ 2455 continue; /*Not a valid exit */
2557 { 2519 {
2558 new_draw_info (NDI_UNIQUE, 0, op, "You should pay for it first."); 2520 new_draw_info (NDI_UNIQUE, 0, op, "You should pay for it first.");
2559 return 1; 2521 return 1;
2560 } 2522 }
2561 else 2523 else
2562 {
2563 return 0; /* monsters just skip unpaid items */ 2524 return 0; /* monsters just skip unpaid items */
2564 }
2565 } 2525 }
2566 2526
2567 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op))) 2527 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op)))
2568 return RESULT_INT (0); 2528 return RESULT_INT (0);
2569 2529
2570 switch (tmp->type) 2530 switch (tmp->type)
2571 { 2531 {
2572
2573 case CF_HANDLE: 2532 case CF_HANDLE:
2574 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2533 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2575 play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE); 2534 play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE);
2576 tmp->value = tmp->value ? 0 : 1; 2535 tmp->value = tmp->value ? 0 : 1;
2577 SET_ANIMATION (tmp, tmp->value); 2536 SET_ANIMATION (tmp, tmp->value);
2578 update_object (tmp, UP_OBJ_FACE); 2537 update_object (tmp, UP_OBJ_FACE);
2579 push_button (tmp); 2538 push_button (tmp);
2580 return 1; 2539 return 1;
2581 2540
2582 case TRIGGER: 2541 case TRIGGER:
2583 if (check_trigger (tmp, op)) 2542 if (check_trigger (tmp, op))
2584 { 2543 {
2585 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2544 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2586 play_sound_map (tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE); 2545 play_sound_map (tmp->map, tmp->x, tmp->y, SOUND_TURN_HANDLE);
2587 } 2546 }
2588 else 2547 else
2589 { 2548 {
2590 new_draw_info (NDI_UNIQUE, 0, op, "The handle doesn't move."); 2549 new_draw_info (NDI_UNIQUE, 0, op, "The handle doesn't move.");
2591 } 2550 }
2592 return 1; 2551 return 1;
2593 2552
2594 case EXIT: 2553 case EXIT:
2595 if (op->type != PLAYER) 2554 if (op->type != PLAYER)
2555 return 0;
2556 if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp))
2557 {
2558 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s is closed.", query_name (tmp));
2559 }
2560 else
2561 {
2562 /* Don't display messages for random maps. */
2563 if (tmp->msg && strncmp (EXIT_PATH (tmp), "/!", 2) && strncmp (EXIT_PATH (tmp), "/random/", 8))
2564 new_draw_info (NDI_NAVY, 0, op, tmp->msg);
2565 enter_exit (op, tmp);
2566 }
2567 return 1;
2568
2569 case SIGN:
2570 apply_sign (op, tmp, 0);
2571 return 1;
2572
2573 case BOOK:
2574 if (op->type == PLAYER)
2575 {
2576 apply_book (op, tmp);
2577 return 1;
2578 }
2579 else
2580 {
2596 return 0; 2581 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 } 2582 }
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 2583
2610 case SIGN: 2584 case SKILLSCROLL:
2611 apply_sign (op, tmp, 0);
2612 return 1;
2613
2614 case BOOK:
2615 if (op->type == PLAYER) 2585 if (op->type == PLAYER)
2616 { 2586 {
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); 2587 apply_skillscroll (op, tmp);
2629 return 1; 2588 return 1;
2630 } 2589 }
2590 return 0;
2591
2592 case SPELLBOOK:
2593 if (op->type == PLAYER)
2594 {
2595 apply_spellbook (op, tmp);
2596 return 1;
2597 }
2598 return 0;
2599
2600 case SCROLL:
2601 apply_scroll (op, tmp, 0);
2602 return 1;
2603
2604 case POTION:
2605 (void) apply_potion (op, tmp);
2606 return 1;
2607
2608 /* Eneq(@csd.uu.se): Handle apply on containers. */
2609 case CLOSE_CON:
2610 if (op->type == PLAYER)
2611 (void) esrv_apply_container (op, tmp->env);
2612 else
2613 (void) apply_container (op, tmp->env);
2614 return 1;
2615
2616 case CONTAINER:
2617 if (op->type == PLAYER)
2618 (void) esrv_apply_container (op, tmp);
2619 else
2620 (void) apply_container (op, tmp);
2621 return 1;
2622
2623 case TREASURE:
2624 if (op->type == PLAYER)
2625 {
2626 apply_treasure (op, tmp);
2627 return 1;
2628 }
2629 else
2630 {
2631 return 0;
2632 }
2633
2634 case WEAPON:
2635 case ARMOUR:
2636 case BOOTS:
2637 case GLOVES:
2638 case AMULET:
2639 case GIRDLE:
2640 case BRACERS:
2641 case SHIELD:
2642 case HELMET:
2643 case RING:
2644 case CLOAK:
2645 case WAND:
2646 case ROD:
2647 case HORN:
2648 case SKILL:
2649 case BOW:
2650 case LAMP:
2651 case BUILDER:
2652 case SKILL_TOOL:
2653 if (tmp->env != op)
2654 return 2; /* not in inventory */
2655 (void) apply_special (op, tmp, aflag);
2656 return 1;
2657
2658 case DRINK:
2659 case FOOD:
2660 case FLESH:
2661 apply_food (op, tmp);
2662 return 1;
2663
2664 case POISON:
2665 apply_poison (op, tmp);
2666 return 1;
2667
2668 case SAVEBED:
2669 return 1;
2670
2671 case ARMOUR_IMPROVER:
2672 if (op->type == PLAYER)
2673 {
2674 apply_armour_improver (op, tmp);
2675 return 1;
2676 }
2677 else
2631 return 0; 2678 return 0;
2632 2679
2633 case SPELLBOOK:
2634 if (op->type == PLAYER)
2635 {
2636 apply_spellbook (op, tmp);
2637 return 1;
2638 }
2639 return 0;
2640
2641 case SCROLL:
2642 apply_scroll (op, tmp, 0);
2643 return 1;
2644
2645 case POTION:
2646 (void) apply_potion (op, tmp);
2647 return 1;
2648
2649 /* Eneq(@csd.uu.se): Handle apply on containers. */
2650 case CLOSE_CON:
2651 if (op->type == PLAYER)
2652 (void) esrv_apply_container (op, tmp->env);
2653 else
2654 (void) apply_container (op, tmp->env);
2655 return 1;
2656
2657 case CONTAINER:
2658 if (op->type == PLAYER)
2659 (void) esrv_apply_container (op, tmp);
2660 else
2661 (void) apply_container (op, tmp);
2662 return 1;
2663
2664 case TREASURE:
2665 if (op->type == PLAYER)
2666 {
2667 apply_treasure (op, tmp);
2668 return 1;
2669 }
2670 else
2671 {
2672 return 0;
2673 }
2674
2675 case WEAPON:
2676 case ARMOUR:
2677 case BOOTS:
2678 case GLOVES:
2679 case AMULET:
2680 case GIRDLE:
2681 case BRACERS:
2682 case SHIELD:
2683 case HELMET:
2684 case RING:
2685 case CLOAK:
2686 case WAND:
2687 case ROD:
2688 case HORN:
2689 case SKILL:
2690 case BOW:
2691 case LAMP:
2692 case BUILDER:
2693 case SKILL_TOOL:
2694 if (tmp->env != op)
2695 return 2; /* not in inventory */
2696 (void) apply_special (op, tmp, aflag);
2697 return 1;
2698
2699 case DRINK:
2700 case FOOD:
2701 case FLESH:
2702 apply_food (op, tmp);
2703 return 1;
2704
2705 case POISON:
2706 apply_poison (op, tmp);
2707 return 1;
2708
2709 case SAVEBED:
2710 if (op->type == PLAYER)
2711 {
2712 apply_savebed (op);
2713 return 1;
2714 }
2715 else
2716 {
2717 return 0;
2718 }
2719
2720 case ARMOUR_IMPROVER:
2721 if (op->type == PLAYER)
2722 {
2723 apply_armour_improver (op, tmp);
2724 return 1;
2725 }
2726 else
2727 {
2728 return 0;
2729 }
2730
2731 case WEAPON_IMPROVER: 2680 case WEAPON_IMPROVER:
2732 (void) check_improve_weapon (op, tmp); 2681 (void) check_improve_weapon (op, tmp);
2733 return 1; 2682 return 1;
2734 2683
2735 case CLOCK: 2684 case CLOCK:
2736 if (op->type == PLAYER) 2685 if (op->type == PLAYER)
2737 { 2686 {
2738 char buf[MAX_BUF]; 2687 char buf[MAX_BUF];
2739 timeofday_t tod; 2688 timeofday_t tod;
2740 2689
2741 get_tod (&tod); 2690 get_tod (&tod);
2742 sprintf (buf, "It is %d minute%s past %d o'clock %s", 2691 sprintf (buf, "It is %d minute%s past %d o'clock %s",
2743 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"), 2692 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"),
2744 ((tod.hour % 14 == 0) ? 14 : ((tod.hour) % 14)), ((tod.hour >= 14) ? "pm" : "am")); 2693 ((tod.hour % 14 == 0) ? 14 : ((tod.hour) % 14)), ((tod.hour >= 14) ? "pm" : "am"));
2745 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0); 2694 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0);
2746 new_draw_info (NDI_UNIQUE, 0, op, buf); 2695 new_draw_info (NDI_UNIQUE, 0, op, buf);
2747 return 1; 2696 return 1;
2748 } 2697 }
2749 else 2698 else
2750 { 2699 {
2751 return 0; 2700 return 0;
2752 } 2701 }
2753 2702
2754 case MENU: 2703 case MENU:
2755 if (op->type == PLAYER) 2704 if (op->type == PLAYER)
2756 { 2705 {
2757 shop_listing (op); 2706 shop_listing (op);
2758 return 1; 2707 return 1;
2759 } 2708 }
2760 else 2709 else
2761 { 2710 {
2762 return 0; 2711 return 0;
2763 } 2712 }
2764 2713
2765 case POWER_CRYSTAL: 2714 case POWER_CRYSTAL:
2766 apply_power_crystal (op, tmp); /* see egoitem.c */ 2715 apply_power_crystal (op, tmp); /* see egoitem.c */
2767 return 1; 2716 return 1;
2768 2717
2769 case LIGHTER: /* for lighting torches/lanterns/etc */ 2718 case LIGHTER: /* for lighting torches/lanterns/etc */
2770 if (op->type == PLAYER) 2719 if (op->type == PLAYER)
2771 { 2720 {
2772 apply_lighter (op, tmp); 2721 apply_lighter (op, tmp);
2773 return 1; 2722 return 1;
2774 } 2723 }
2775 else 2724 else
2776 { 2725 {
2777 return 0; 2726 return 0;
2778 } 2727 }
2779 2728
2780 case ITEM_TRANSFORMER: 2729 case ITEM_TRANSFORMER:
2781 apply_item_transformer (op, tmp); 2730 apply_item_transformer (op, tmp);
2782 return 1; 2731 return 1;
2783 2732
2784 default: 2733 default:
2785 return 0; 2734 return 0;
2786 } 2735 }
2787} 2736}
2788 2737
2789 2738
2790/* quiet suppresses the "don't know how to apply" and "you must get it first" 2739/* 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)) 2763 if (op->type != PLAYER && QUERY_FLAG (op, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ))
2815 { 2764 {
2816 play_sound_map (pl->map, pl->x, pl->y, SOUND_OB_EVAPORATE); 2765 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!"); 2766 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."); 2767 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion.");
2819 remove_ob (op); 2768 op->destroy ();
2820 free_object (op);
2821 return 1; 2769 return 1;
2822 } 2770 }
2823 2771
2824 pl->contr->last_used = op; 2772 pl->contr->last_used = op;
2825 pl->contr->last_used_id = op->count;
2826 2773
2827 tmp = manual_apply (pl, op, aflag); 2774 tmp = manual_apply (pl, op, aflag);
2828 if (!quiet) 2775 if (!quiet)
2829 { 2776 {
2830 if (tmp == 0) 2777 if (tmp == 0)
2896 object *tmp2; 2843 object *tmp2;
2897 2844
2898 CLEAR_FLAG (op, FLAG_APPLIED); 2845 CLEAR_FLAG (op, FLAG_APPLIED);
2899 switch (op->type) 2846 switch (op->type)
2900 { 2847 {
2901 case WEAPON: 2848 case WEAPON:
2902 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwield %s.", query_name (op)); 2849 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwield %s.", query_name (op));
2903 2850
2904 (void) change_abil (who, op); 2851 (void) change_abil (who, op);
2905 if (QUERY_FLAG (who, FLAG_READY_WEAPON)) 2852 if (QUERY_FLAG (who, FLAG_READY_WEAPON))
2906 CLEAR_FLAG (who, FLAG_READY_WEAPON); 2853 CLEAR_FLAG (who, FLAG_READY_WEAPON);
2907 clear_skill (who); 2854 clear_skill (who);
2908 break; 2855 break;
2909 2856
2910 case SKILL: /* allows objects to impart skills */ 2857 case SKILL: /* allows objects to impart skills */
2911 case SKILL_TOOL: 2858 case SKILL_TOOL:
2912 if (op != who->chosen_skill) 2859 if (op != who->chosen_skill)
2913 { 2860 {
2914 LOG (llevError, "BUG: apply_special(): applied skill is not a chosen skill\n"); 2861 LOG (llevError, "BUG: apply_special(): applied skill is not a chosen skill\n");
2915 } 2862 }
2916 if (who->type == PLAYER) 2863 if (who->type == PLAYER)
2917 { 2864 {
2918 if (who->contr->shoottype == range_skill) 2865 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; 2866 who->contr->shoottype = range_none;
2986 } 2867 if (!op->invisible)
2987 else
2988 { 2868 {
2989 if (op->type == BOW) 2869 new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op));
2990 CLEAR_FLAG (who, FLAG_READY_BOW); 2870 }
2991 else 2871 else
2992 CLEAR_FLAG (who, FLAG_READY_RANGE); 2872 {
2873 new_draw_info_format (NDI_UNIQUE, 0, who, "You can no longer use the skill: %s.", &op->skill);
2993 } 2874 }
2875 }
2876 (void) change_abil (who, op);
2877 who->chosen_skill = NULL;
2878 CLEAR_FLAG (who, FLAG_READY_SKILL);
2994 break; 2879 break;
2995 2880
2881 case ARMOUR:
2882 case HELMET:
2996 case BUILDER: 2883 case SHIELD:
2884 case RING:
2885 case BOOTS:
2886 case GLOVES:
2887 case AMULET:
2888 case GIRDLE:
2889 case BRACERS:
2890 case CLOAK:
2891 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwear %s.", query_name (op));
2892 (void) change_abil (who, op);
2893 break;
2894 case LAMP:
2895 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn off your %s.", &op->name);
2896 tmp2 = arch_to_object (op->other_arch);
2897 tmp2->x = op->x;
2898 tmp2->y = op->y;
2899 tmp2->map = op->map;
2900 tmp2->below = op->below;
2901 tmp2->above = op->above;
2902 tmp2->stats.food = op->stats.food;
2903 CLEAR_FLAG (tmp2, FLAG_APPLIED);
2904
2905 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
2906 SET_FLAG (tmp2, FLAG_INV_LOCKED);
2907
2908 if (who->type == PLAYER)
2909 esrv_del_item (who->contr, op->count);
2910
2911 op->destroy ();
2912 insert_ob_in_ob (tmp2, who);
2913 who->update_stats ();
2914 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2915 {
2916 if (who->type == PLAYER)
2917 {
2918 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
2919 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
2920 }
2921 }
2922 if (who->type == PLAYER)
2923 esrv_send_item (who, tmp2);
2924 return 1; /* otherwise, an attempt to drop causes problems */
2925 break;
2926 case BOW:
2927 case WAND:
2928 case ROD:
2929 case HORN:
2930 clear_skill (who);
2997 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op)); 2931 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2932 if (who->type == PLAYER)
2933 {
2998 who->contr->shoottype = range_none; 2934 who->contr->shoottype = range_none;
2935 }
2936 else
2937 {
2938 if (op->type == BOW)
2939 CLEAR_FLAG (who, FLAG_READY_BOW);
2940 else
2941 CLEAR_FLAG (who, FLAG_READY_RANGE);
2942 }
2943 break;
2944
2945 case BUILDER:
2946 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2947 who->contr->shoottype = range_none;
2999 who->contr->ranges[range_builder] = NULL; 2948 who->contr->ranges[range_builder] = NULL;
3000 break; 2949 break;
3001 2950
3002 default: 2951 default:
3003 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op)); 2952 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op));
3004 break; 2953 break;
3005 } 2954 }
3006 2955
3007 fix_player (who); 2956 who->update_stats ();
3008 2957
3009 if (!(aflags & AP_NO_MERGE)) 2958 if (!(aflags & AP_NO_MERGE))
3010 { 2959 {
3011 object *tmp; 2960 object *tmp;
3012
3013 tag_t del_tag = op->count;
3014 2961
3015 tmp = merge_ob (op, NULL); 2962 tmp = merge_ob (op, NULL);
3016 if (who->type == PLAYER) 2963 if (who->type == PLAYER)
3017 { 2964 {
3018 if (tmp) 2965 if (tmp)
3019 { /* it was merged */ 2966 { /* it was merged */
3020 esrv_del_item (who->contr, del_tag); 2967 esrv_del_item (who->contr, op->count);
3021 op = tmp; 2968 op = tmp;
3022 } 2969 }
2970
3023 esrv_send_item (who, op); 2971 esrv_send_item (who, op);
3024 } 2972 }
3025 } 2973 }
3026 return 0; 2974 return 0;
3027} 2975}
3431 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op))) 3379 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who)) || INVOKE_OBJECT (READY, who, ARG_OBJECT (op)))
3432 return RESULT_INT (0); 3380 return RESULT_INT (0);
3433 3381
3434 switch (op->type) 3382 switch (op->type)
3435 { 3383 {
3436 case WEAPON: 3384 case WEAPON:
3437 if (!check_weapon_power (who, op->last_eat)) 3385 if (!check_weapon_power (who, op->last_eat))
3438 { 3386 {
3439 new_draw_info (NDI_UNIQUE, 0, who, "That weapon is too powerful for you to use."); 3387 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!."); 3388 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!.");
3441 if (tmp != NULL) 3389 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); 3390 (void) insert_ob_in_ob (tmp, who);
3391 return 1;
3392 }
3393 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3394 {
3395 /* if the weapon does not have the name as the character, can't use it. */
3396 /* (Ragnarok's sword attempted to be used by Foo: won't work) */
3397 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3398 if (tmp != NULL)
3399 (void) insert_ob_in_ob (tmp, who);
3400 return 1;
3401 }
3402 SET_FLAG (op, FLAG_APPLIED);
3403
3404 if (skop)
3405 change_skill (who, skop, 1);
3406 if (!QUERY_FLAG (who, FLAG_READY_WEAPON))
3407 SET_FLAG (who, FLAG_READY_WEAPON);
3408
3409 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op));
3410
3411 (void) change_abil (who, op);
3412 break;
3413
3414 case ARMOUR:
3415 case HELMET:
3416 case SHIELD:
3417 case BOOTS:
3418 case GLOVES:
3419 case GIRDLE:
3420 case BRACERS:
3421 case CLOAK:
3422 case RING:
3423 case AMULET:
3424 SET_FLAG (op, FLAG_APPLIED);
3425 new_draw_info_format (NDI_UNIQUE, 0, who, "You wear %s.", query_name (op));
3426 (void) change_abil (who, op);
3427 break;
3428 case LAMP:
3429 if (op->stats.food < 1)
3430 {
3431 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name);
3432 return 1;
3433 }
3434 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name);
3435 tmp2 = arch_to_object (op->other_arch);
3436 tmp2->stats.food = op->stats.food;
3437 SET_FLAG (tmp2, FLAG_APPLIED);
3438 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
3439 SET_FLAG (tmp2, FLAG_INV_LOCKED);
3440 insert_ob_in_ob (tmp2, who);
3441
3442 /* Remove the old lantern */
3443 if (who->type == PLAYER)
3444 esrv_del_item (who->contr, op->count);
3445
3446 op->destroy ();
3447
3448 /* insert the portion that was split off */
3449 if (tmp != NULL)
3450 {
3451 (void) insert_ob_in_ob (tmp, who);
3504 if (who->type == PLAYER) 3452 if (who->type == PLAYER)
3505 esrv_send_item (who, tmp); 3453 esrv_send_item (who, tmp);
3506 } 3454 }
3507 fix_player (who); 3455 who->update_stats ();
3508 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 3456 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
3509 { 3457 {
3510 if (who->type == PLAYER) 3458 if (who->type == PLAYER)
3511 { 3459 {
3512 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); 3460 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
3513 SET_FLAG (tmp2, FLAG_KNOWN_CURSED); 3461 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
3514 } 3462 }
3515 } 3463 }
3516 if (who->type == PLAYER) 3464 if (who->type == PLAYER)
3517 esrv_send_item (who, tmp2); 3465 esrv_send_item (who, tmp2);
3518 return 0; 3466 return 0;
3519 break; 3467 break;
3520 3468
3521 /* this part is needed for skill-tools */ 3469 /* this part is needed for skill-tools */
3522 case SKILL: 3470 case SKILL:
3523 case SKILL_TOOL: 3471 case SKILL_TOOL:
3524 if (who->chosen_skill) 3472 if (who->chosen_skill)
3525 { 3473 {
3526 LOG (llevError, "BUG: apply_special(): can't apply two skills\n"); 3474 LOG (llevError, "BUG: apply_special(): can't apply two skills\n");
3527 return 1; 3475 return 1;
3528 } 3476 }
3529 if (who->type == PLAYER) 3477 if (who->type == PLAYER)
3530 { 3478 {
3531 who->contr->shoottype = range_skill; 3479 who->contr->shoottype = range_skill;
3532 who->contr->ranges[range_skill] = op; 3480 who->contr->ranges[range_skill] = op;
3533 if (!op->invisible) 3481 if (!op->invisible)
3534 { 3482 {
3535 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); 3483 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); 3484 new_draw_info_format (NDI_UNIQUE, 0, who, "You can now use the skill: %s.", &op->skill);
3537 } 3485 }
3538 else 3486 else
3539 { 3487 {
3540 new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name); 3488 new_draw_info_format (NDI_UNIQUE, 0, who, "Readied skill: %s.", op->skill ? &op->skill : &op->name);
3541 } 3489 }
3542 } 3490 }
3543 SET_FLAG (op, FLAG_APPLIED); 3491 SET_FLAG (op, FLAG_APPLIED);
3544 (void) change_abil (who, op); 3492 (void) change_abil (who, op);
3545 who->chosen_skill = op; 3493 who->chosen_skill = op;
3546 SET_FLAG (who, FLAG_READY_SKILL); 3494 SET_FLAG (who, FLAG_READY_SKILL);
3547 break; 3495 break;
3548 3496
3549 case BOW: 3497 case BOW:
3550 if (!check_weapon_power (who, op->last_eat)) 3498 if (!check_weapon_power (who, op->last_eat))
3551 { 3499 {
3552 new_draw_info (NDI_UNIQUE, 0, who, "That item is too powerful for you to use."); 3500 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!."); 3501 new_draw_info (NDI_UNIQUE, 0, who, "It would consume your soul!.");
3554 if (tmp != NULL) 3502 if (tmp != NULL)
3555 (void) insert_ob_in_ob (tmp, who); 3503 (void) insert_ob_in_ob (tmp, who);
3556 return 1; 3504 return 1;
3557 } 3505 }
3558 if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) 3506 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3559 { 3507 {
3560 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner."); 3508 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3561 if (tmp != NULL) 3509 if (tmp != NULL)
3562 (void) insert_ob_in_ob (tmp, who); 3510 (void) insert_ob_in_ob (tmp, who);
3563 return 1; 3511 return 1;
3564 } 3512 }
3565 /*FALLTHROUGH*/ case WAND: 3513 /*FALLTHROUGH*/ case WAND:
3566 case ROD: 3514 case ROD:
3567 case HORN: 3515 case HORN:
3568 /* check for skill, alter player status */ 3516 /* check for skill, alter player status */
3569 SET_FLAG (op, FLAG_APPLIED); 3517 SET_FLAG (op, FLAG_APPLIED);
3570 if (skop) 3518 if (skop)
3571 change_skill (who, skop, 0); 3519 change_skill (who, skop, 0);
3572 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op)); 3520 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready %s.", query_name (op));
3573 3521
3574 if (who->type == PLAYER) 3522 if (who->type == PLAYER)
3575 { 3523 {
3576 if (op->type == BOW) 3524 if (op->type == BOW)
3577 { 3525 {
3578 (void) change_abil (who, op); 3526 (void) change_abil (who, op);
3579 new_draw_info_format (NDI_UNIQUE, 0, who, 3527 new_draw_info_format (NDI_UNIQUE, 0, who,
3580 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op)); 3528 "You will now fire %s with %s.", op->race ? &op->race : "nothing", query_name (op));
3581 who->contr->shoottype = range_bow; 3529 who->contr->shoottype = range_bow;
3582 } 3530 }
3583 else 3531 else
3584 { 3532 {
3585 who->contr->shoottype = range_misc; 3533 who->contr->shoottype = range_misc;
3586 } 3534 }
3587 } 3535 }
3588 else 3536 else
3589 { 3537 {
3590 if (op->type == BOW) 3538 if (op->type == BOW)
3591 SET_FLAG (who, FLAG_READY_BOW); 3539 SET_FLAG (who, FLAG_READY_BOW);
3592 else 3540 else
3593 SET_FLAG (who, FLAG_READY_RANGE); 3541 SET_FLAG (who, FLAG_READY_RANGE);
3594 } 3542 }
3595 break; 3543 break;
3596 3544
3597 case BUILDER: 3545 case BUILDER:
3598 if (who->contr->ranges[range_builder]) 3546 if (who->contr->ranges[range_builder])
3599 unapply_special (who, who->contr->ranges[range_builder], 0); 3547 unapply_special (who, who->contr->ranges[range_builder], 0);
3600 who->contr->shoottype = range_builder; 3548 who->contr->shoottype = range_builder;
3601 who->contr->ranges[range_builder] = op; 3549 who->contr->ranges[range_builder] = op;
3602 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op)); 3550 new_draw_info_format (NDI_UNIQUE, 0, who, "You ready your %s.", query_name (op));
3603 break; 3551 break;
3604 3552
3605 default: 3553 default:
3606 new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op)); 3554 new_draw_info_format (NDI_UNIQUE, 0, who, "You apply %s.", query_name (op));
3607 } /* end of switch op->type */ 3555 } /* end of switch op->type */
3608 3556
3609 SET_FLAG (op, FLAG_APPLIED); 3557 SET_FLAG (op, FLAG_APPLIED);
3610 3558
3611 if (tmp != NULL) 3559 if (tmp != NULL)
3612 tmp = insert_ob_in_ob (tmp, who); 3560 tmp = insert_ob_in_ob (tmp, who);
3613 3561
3614 fix_player (who); 3562 who->update_stats ();
3615 3563
3616 /* We exclude spell casting objects. The fire code will set the 3564 /* We exclude spell casting objects. The fire code will set the
3617 * been applied flag when they are used - until that point, 3565 * been applied flag when they are used - until that point,
3618 * you don't know anything about them. 3566 * you don't know anything about them.
3619 */ 3567 */
3658 object *tmp = NULL, *tmp2; 3606 object *tmp = NULL, *tmp2;
3659 int i; 3607 int i;
3660 3608
3661 switch (op->type) 3609 switch (op->type)
3662 { 3610 {
3663 case SHOP_FLOOR: 3611 case SHOP_FLOOR:
3664 if (!HAS_RANDOM_ITEMS (op)) 3612 if (!op->has_random_items ())
3665 return 0; 3613 return 0;
3614
3666 do 3615 do
3667 { 3616 {
3668 i = 10; /* let's give it 10 tries */ 3617 i = 10; /* let's give it 10 tries */
3669 while ((tmp = generate_treasure (op->randomitems, 3618 while ((tmp = generate_treasure (op->randomitems,
3670 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i); 3619 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i);
3671 if (tmp == NULL) 3620 if (tmp == NULL)
3672 return 0; 3621 return 0;
3673 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 3622 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
3674 { 3623 {
3675 free_object (tmp); 3624 tmp->destroy ();
3676 tmp = NULL; 3625 tmp = NULL;
3677 } 3626 }
3678 } 3627 }
3679 while (!tmp); 3628 while (!tmp);
3629
3680 tmp->x = op->x; 3630 tmp->x = op->x;
3681 tmp->y = op->y; 3631 tmp->y = op->y;
3682 SET_FLAG (tmp, FLAG_UNPAID); 3632 SET_FLAG (tmp, FLAG_UNPAID);
3683 insert_ob_in_map (tmp, op->map, NULL, 0); 3633 insert_ob_in_map (tmp, op->map, NULL, 0);
3684 CLEAR_FLAG (op, FLAG_AUTO_APPLY); 3634 CLEAR_FLAG (op, FLAG_AUTO_APPLY);
3685 identify (tmp); 3635 identify (tmp);
3686 break; 3636 break;
3687 3637
3688 case TREASURE: 3638 case TREASURE:
3689 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 3639 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
3690 return 0; 3640 return 0;
3641
3691 while ((op->stats.hp--) > 0) 3642 while ((op->stats.hp--) > 0)
3692 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0, 3643 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); 3644 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3694 3645
3695 /* If we generated an object and put it in this object inventory, 3646 /* 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 3647 * move it to the parent object as the current object is about
3697 * to disappear. An example of this item is the random_* stuff 3648 * to disappear. An example of this item is the random_* stuff
3698 * that is put inside other objects. 3649 * that is put inside other objects.
3699 */ 3650 */
3700 for (tmp = op->inv; tmp; tmp = tmp2) 3651 for (tmp = op->inv; tmp; tmp = tmp2)
3701 { 3652 {
3702 tmp2 = tmp->below; 3653 tmp2 = tmp->below;
3703 remove_ob (tmp); 3654 tmp->remove ();
3655
3704 if (op->env) 3656 if (op->env)
3705 insert_ob_in_ob (tmp, op->env); 3657 insert_ob_in_ob (tmp, op->env);
3706 else 3658 else
3707 free_object (tmp); 3659 tmp->destroy ();
3708 } 3660 }
3709 remove_ob (op); 3661
3710 free_object (op); 3662 op->destroy ();
3711 break; 3663 break;
3712 } 3664 }
3713 return tmp ? 1 : 0; 3665 return tmp ? 1 : 0;
3714} 3666}
3715 3667
3716/** 3668/**
3718 * when an original map is loaded) and performs special actions for 3670 * when an original map is loaded) and performs special actions for
3719 * certain objects (most initialization of chests and creation of 3671 * certain objects (most initialization of chests and creation of
3720 * treasures and stuff). Calls auto_apply if appropriate. 3672 * treasures and stuff). Calls auto_apply if appropriate.
3721 */ 3673 */
3722void 3674void
3723fix_auto_apply (mapstruct *m) 3675fix_auto_apply (maptile *m)
3724{ 3676{
3725 object *tmp, *above = NULL; 3677 object *tmp, *above = NULL;
3726 int x, y; 3678 int x, y;
3727 3679
3728 if (m == NULL) 3680 if (m == NULL)
3729 return; 3681 return;
3730 3682
3731 for (x = 0; x < MAP_WIDTH (m); x++) 3683 for (x = 0; x < MAP_WIDTH (m); x++)
3732 for (y = 0; y < MAP_HEIGHT (m); y++) 3684 for (y = 0; y < MAP_HEIGHT (m); y++)
3733 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = above) 3685 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = above)
3734 { 3686 {
3735 above = tmp->above; 3687 above = tmp->above;
3736 3688
3737 if (tmp->inv) 3689 if (tmp->inv)
3738 { 3690 {
3742 { 3694 {
3743 invnext = invtmp->below; 3695 invnext = invtmp->below;
3744 3696
3745 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY)) 3697 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY))
3746 auto_apply (invtmp); 3698 auto_apply (invtmp);
3747 else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS (invtmp)) 3699 else if (invtmp->type == TREASURE && invtmp->has_random_items ())
3748 { 3700 {
3749 while ((invtmp->stats.hp--) > 0) 3701 while ((invtmp->stats.hp--) > 0)
3750 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3702 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3751 3703
3752 invtmp->randomitems = NULL; 3704 invtmp->randomitems = NULL;
3753 } 3705 }
3754 else if (invtmp && invtmp->arch 3706 else if (invtmp && invtmp->arch
3755 && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS && HAS_RANDOM_ITEMS (invtmp)) 3707 && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS && invtmp->has_random_items ())
3756 { 3708 {
3757 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3709 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3758 /* Need to clear this so that we never try to create 3710 /* Need to clear this so that we never try to create
3759 * treasure again for this object 3711 * treasure again for this object
3760 */ 3712 */
3777 3729
3778 } 3730 }
3779 3731
3780 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY)) 3732 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY))
3781 auto_apply (tmp); 3733 auto_apply (tmp);
3782 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && HAS_RANDOM_ITEMS (tmp)) 3734 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && tmp->has_random_items ())
3783 { 3735 {
3784 while ((tmp->stats.hp--) > 0) 3736 while ((tmp->stats.hp--) > 0)
3785 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0); 3737 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0);
3786 tmp->randomitems = NULL; 3738 tmp->randomitems = NULL;
3787 } 3739 }
3802 * This is a problem for the above objects, because they have counters 3754 * This is a problem for the above objects, because they have counters
3803 * which say how many times to make the treasure. 3755 * which say how many times to make the treasure.
3804 */ 3756 */
3805 else if (tmp && tmp->arch && tmp->type != PLAYER 3757 else if (tmp && tmp->arch && tmp->type != PLAYER
3806 && tmp->type != TREASURE && tmp->type != SPELL 3758 && tmp->type != TREASURE && tmp->type != SPELL
3807 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && HAS_RANDOM_ITEMS (tmp)) 3759 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && tmp->has_random_items ())
3808 { 3760 {
3809 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0); 3761 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0);
3810 tmp->randomitems = NULL; 3762 tmp->randomitems = NULL;
3811 } 3763 }
3812 } 3764 }
3813 3765
3814 for (x = 0; x < MAP_WIDTH (m); x++) 3766 for (x = 0; x < MAP_WIDTH (m); x++)
3815 for (y = 0; y < MAP_HEIGHT (m); y++) 3767 for (y = 0; y < MAP_HEIGHT (m); y++)
3816 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above) 3768 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above)
3817 if (tmp->above && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL)) 3769 if (tmp->above && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
3818 check_trigger (tmp, tmp->above); 3770 check_trigger (tmp, tmp->above);
3819} 3771}
3820 3772
3821/** 3773/**
3851 { 3803 {
3852 force->resist[i] = food->resist[i] / 2; 3804 force->resist[i] = food->resist[i] / 2;
3853 did_one = 1; 3805 did_one = 1;
3854 } 3806 }
3855 } 3807 }
3808
3856 if (did_one) 3809 if (did_one)
3857 { 3810 {
3858 force->speed = 0.1; 3811 force->speed = 0.1;
3859 update_ob_speed (force); 3812 update_ob_speed (force);
3860 /* bigger morsel of food = longer effect time */ 3813 /* bigger morsel of food = longer effect time */
3861 force->stats.food = food->stats.food / 5; 3814 force->duration = food->stats.food / 5;
3862 SET_FLAG (force, FLAG_IS_USED_UP);
3863 SET_FLAG (force, FLAG_APPLIED); 3815 SET_FLAG (force, FLAG_APPLIED);
3864 change_abil (who, force); 3816 change_abil (who, force);
3865 insert_ob_in_ob (force, who); 3817 insert_ob_in_ob (force, who);
3866 } 3818 }
3867 else 3819 else
3868 { 3820 force->destroy ();
3869 free_object (force);
3870 }
3871 3821
3872 /* check for hp, sp change */ 3822 /* check for hp, sp change */
3873 if (food->stats.hp != 0) 3823 if (food->stats.hp != 0)
3874 { 3824 {
3875 if (QUERY_FLAG (food, FLAG_CURSED)) 3825 if (QUERY_FLAG (food, FLAG_CURSED))
3901 new_draw_info (NDI_UNIQUE, 0, who, "You feel a rush of magical energy!"); 3851 new_draw_info (NDI_UNIQUE, 0, who, "You feel a rush of magical energy!");
3902 who->stats.sp += food->stats.sp; 3852 who->stats.sp += food->stats.sp;
3903 /* place limit on max sp from food? */ 3853 /* place limit on max sp from food? */
3904 } 3854 }
3905 } 3855 }
3906 fix_player (who); 3856 who->update_stats ();
3907} 3857}
3908
3909 3858
3910/** 3859/**
3911 * Designed primarily to light torches/lanterns/etc. 3860 * Designed primarily to light torches/lanterns/etc.
3912 * Also burns up burnable material too. First object in the inventory is 3861 * Also burns up burnable material too. First object in the inventory is
3913 * the selected object to "burn". -b.t. 3862 * the selected object to "burn". -b.t.
3914 */ 3863 */
3915
3916void 3864void
3917apply_lighter (object *who, object *lighter) 3865apply_lighter (object *who, object *lighter)
3918{ 3866{
3919 object *item; 3867 object *item;
3920 int is_player_env = 0; 3868 int is_player_env = 0;
3921 uint32 nrof;
3922 tag_t count;
3923 char item_name[MAX_BUF];
3924 3869
3925 item = find_marked_object (who); 3870 item = find_marked_object (who);
3926 if (item) 3871 if (item)
3927 { 3872 {
3928 if (lighter->last_eat && lighter->stats.food) 3873 if (lighter->last_eat && lighter->stats.food)
3929 { /* lighter gets used up */ 3874 { /* lighter gets used up */
3930 /* Split multiple lighters if they're being used up. Otherwise * 3875 /* Split multiple lighters if they're being used up. Otherwise *
3931 * one charge from each would be used up. --DAMN */ 3876 * one charge from each would be used up. --DAMN */
3932 if (lighter->nrof > 1) 3877 if (lighter->nrof > 1)
3933 { 3878 {
3934 object *oneLighter = get_object (); 3879 object *oneLighter = lighter->clone ();
3935 3880
3936 copy_object (lighter, oneLighter);
3937 lighter->nrof -= 1; 3881 lighter->nrof -= 1;
3938 oneLighter->nrof = 1; 3882 oneLighter->nrof = 1;
3939 oneLighter->stats.food--; 3883 oneLighter->stats.food--;
3940 esrv_send_item (who, lighter); 3884 esrv_send_item (who, lighter);
3941 oneLighter = insert_ob_in_ob (oneLighter, who); 3885 oneLighter = insert_ob_in_ob (oneLighter, who);
3942 esrv_send_item (who, oneLighter); 3886 esrv_send_item (who, oneLighter);
3943 } 3887 }
3944 else 3888 else
3945 {
3946 lighter->stats.food--; 3889 lighter->stats.food--;
3947 }
3948
3949 } 3890 }
3950 else if (lighter->last_eat) 3891 else if (lighter->last_eat)
3951 { /* no charges left in lighter */ 3892 { /* 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); 3893 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; 3894 return;
3954 } 3895 }
3896
3955 /* Perhaps we should split what we are trying to light on fire? 3897 /* 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 3898 * I can't see many times when you would want to light multiple
3957 * objects at once. 3899 * objects at once.
3958 */ 3900 */
3959 nrof = item->nrof; 3901
3960 count = item->count;
3961 /* 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
3963 * some sense.
3964 */
3965 strcpy (item_name, item->name);
3966 if (who == is_player_inv (item)) 3902 if (who == item->in_player ())
3967 is_player_env = 1; 3903 is_player_env = 1;
3968 3904
3969 save_throw_object (item, AT_FIRE, who); 3905 save_throw_object (item, AT_FIRE, who);
3970 /* Change to check count and not freed, since the object pointer 3906
3971 * may have gotten recycled 3907 if (item->destroyed ())
3972 */ 3908 {
3973 if ((nrof != item->nrof) || (count != item->count))
3974 {
3975 new_draw_info_format (NDI_UNIQUE, 0, who, "You light the %s with the %s.", &item_name, &lighter->name); 3909 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 3910 /* Need to update the player so that the players glow radius
3977 * gets changed. 3911 * gets changed.
3978 */ 3912 */
3979 if (is_player_env) 3913 if (is_player_env)
3980 fix_player (who); 3914 who->update_stats ();
3981 } 3915 }
3982 else 3916 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); 3917 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 } 3918 }
3988 else /* nothing to light */ 3919 else /* nothing to light */
3989 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object."); 3920 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object.");
3990 3921
3991} 3922}
4005 object *tmp; 3936 object *tmp;
4006 3937
4007 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!."); 3938 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!.");
4008 tmp = get_archetype (SPELL_WONDER); 3939 tmp = get_archetype (SPELL_WONDER);
4009 cast_wonder (op, op, 0, tmp); 3940 cast_wonder (op, op, 0, tmp);
4010 free_object (tmp); 3941 tmp->destroy ();
4011 } 3942 }
4012 else if (failure <= -15 && failure > -35) 3943 else if (failure <= -15 && failure > -35)
4013 { /* drain mana */ 3944 { /* drain mana */
4014 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!."); 3945 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!.");
4015 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW); 3946 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW);
4038 object *tmp; 3969 object *tmp;
4039 3970
4040 tmp = get_archetype (LOOSE_MANA); 3971 tmp = get_archetype (LOOSE_MANA);
4041 cast_magic_storm (op, tmp, power); 3972 cast_magic_storm (op, tmp, power);
4042 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!"); 3973 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!");
4043 free_object (tmp); 3974 tmp->destroy ();
4044 } 3975 }
4045 } 3976 }
4046} 3977}
4047 3978
4048void 3979void
4052 for the race, put the excess stat some 3983 for the race, put the excess stat some
4053 where else. */ 3984 where else. */
4054 3985
4055 switch (change->type) 3986 switch (change->type)
4056 { 3987 {
4057 case CLASS: 3988 case CLASS:
4058 { 3989 {
4059 living *stats = &(pl->contr->orig_stats); 3990 living *stats = &(pl->contr->orig_stats);
4060 living *ns = &(change->stats); 3991 living *ns = &(change->stats);
4061 object *walk; 3992 object *walk;
4062 int flag_change_face = 1; 3993 int flag_change_face = 1;
4063 3994
4064 /* the following code assigns stats up to the stat max 3995 /* the following code assigns stats up to the stat max
4065 * for the race, and if the stat max is exceeded, 3996 * for the race, and if the stat max is exceeded,
4066 * tries to randomly reassign the excess stat 3997 * tries to randomly reassign the excess stat
4067 */ 3998 */
4068 int i, j; 3999 int i, j;
4069 4000
4070 for (i = 0; i < NUM_STATS; i++) 4001 for (i = 0; i < NUM_STATS; i++)
4071 { 4002 {
4072 sint8 stat = get_attr_value (stats, i); 4003 sint8 stat = get_attr_value (stats, i);
4073 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); 4004 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4074 4005
4075 stat += get_attr_value (ns, i); 4006 stat += get_attr_value (ns, i);
4076 if (stat > 20 + race_bonus) 4007 if (stat > 20 + race_bonus)
4077 { 4008 {
4078 excess_stat++; 4009 excess_stat++;
4079 stat = 20 + race_bonus; 4010 stat = 20 + race_bonus;
4080 } 4011 }
4081 set_attr_value (stats, i, stat); 4012 set_attr_value (stats, i, stat);
4082 } 4013 }
4083 4014
4084 for (j = 0; excess_stat > 0 && j < 100; j++) 4015 for (j = 0; excess_stat > 0 && j < 100; j++)
4085 { /* try 100 times to assign excess stats */ 4016 { /* try 100 times to assign excess stats */
4086 int i = rndm (0, 6); 4017 int i = rndm (0, 6);
4087 int stat = get_attr_value (stats, i); 4018 int stat = get_attr_value (stats, i);
4088 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); 4019 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4089 4020
4090 if (i == CHA) 4021 if (i == CHA)
4091 continue; /* exclude cha from this */ 4022 continue; /* exclude cha from this */
4092 if (stat < 20 + race_bonus) 4023 if (stat < 20 + race_bonus)
4093 { 4024 {
4094 change_attr_value (stats, i, 1); 4025 change_attr_value (stats, i, 1);
4095 excess_stat--; 4026 excess_stat--;
4096 } 4027 }
4097 } 4028 }
4098 4029
4099 /* insert the randomitems from the change's treasurelist into 4030 /* insert the randomitems from the change's treasurelist into
4100 * the player ref: player.c 4031 * the player ref: player.c
4101 */ 4032 */
4102 if (change->randomitems != NULL) 4033 if (change->randomitems != NULL)
4103 give_initial_items (pl, change->randomitems); 4034 give_initial_items (pl, change->randomitems);
4104 4035
4105 4036
4106 /* set up the face, for some races. */ 4037 /* set up the face, for some races. */
4107 4038
4108 /* first, look for the force object banning 4039 /* first, look for the force object banning
4109 * changing the face. Certain races never change face with class. 4040 * changing the face. Certain races never change face with class.
4110 */ 4041 */
4111 for (walk = pl->inv; walk != NULL; walk = walk->below) 4042 for (walk = pl->inv; walk != NULL; walk = walk->below)
4112 if (!strcmp (walk->name, "NOCLASSFACECHANGE")) 4043 if (!strcmp (walk->name, "NOCLASSFACECHANGE"))
4113 flag_change_face = 0; 4044 flag_change_face = 0;
4114 4045
4115 if (flag_change_face) 4046 if (flag_change_face)
4116 { 4047 {
4117 pl->animation_id = GET_ANIM_ID (change); 4048 pl->animation_id = GET_ANIM_ID (change);
4118 pl->face = change->face; 4049 pl->face = change->face;
4119 4050
4120 if (QUERY_FLAG (change, FLAG_ANIMATE)) 4051 if (QUERY_FLAG (change, FLAG_ANIMATE))
4121 SET_FLAG (pl, FLAG_ANIMATE); 4052 SET_FLAG (pl, FLAG_ANIMATE);
4122 else 4053 else
4123 CLEAR_FLAG (pl, FLAG_ANIMATE); 4054 CLEAR_FLAG (pl, FLAG_ANIMATE);
4124 } 4055 }
4125 4056
4126 /* check the special case of can't use weapons */ 4057 /* check the special case of can't use weapons */
4127 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */ 4058 /*if(QUERY_FLAG(change,FLAG_USE_WEAPON)) CLEAR_FLAG(pl,FLAG_USE_WEAPON); */
4128 if (!strcmp (change->name, "monk")) 4059 if (!strcmp (change->name, "monk"))
4129 CLEAR_FLAG (pl, FLAG_USE_WEAPON); 4060 CLEAR_FLAG (pl, FLAG_USE_WEAPON);
4130 4061
4131 break; 4062 break;
4132 } 4063 }
4133 } 4064 }
4134} 4065}
4135 4066
4136/** 4067/**
4137 * This handles items of type 'transformer'. 4068 * This handles items of type 'transformer'.
4211 if (!new_item) 4142 if (!new_item)
4212 { 4143 {
4213 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0)); 4144 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0));
4214 return; 4145 return;
4215 } 4146 }
4147
4216 new_item->nrof = yield; 4148 new_item->nrof = yield;
4217 new_draw_info_format (NDI_UNIQUE, 0, pl, "You %s the %s.", &transformer->slaying, query_base_name (marked, 0)); 4149 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); 4150 insert_ob_in_ob (new_item, pl);
4219 esrv_send_inventory (pl, pl); 4151 esrv_send_inventory (pl, pl);
4220 /* Eat up one item */ 4152 /* Eat up one item */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines