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

Comparing deliantra/server/server/apply.C (file contents):
Revision 1.22 by root, Sun Sep 10 15:59:57 2006 UTC vs.
Revision 1.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.22 2006/09/10 15:59:57 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The authors can be reached via e-mail to crossfire-devel@real-time.com 21 The authors can be reached via e-mail to <crossfire@schmorp.de>
28*/ 22*/
29 23
30#include <global.h> 24#include <global.h>
31#include <living.h> 25#include <living.h>
32#include <spells.h> 26#include <spells.h>
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/**
1524 if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator))) 1515 if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator)))
1525 goto leave; 1516 goto leave;
1526 1517
1527 switch (trap->type) 1518 switch (trap->type)
1528 { 1519 {
1529 case PLAYERMOVER: 1520 case PLAYERMOVER:
1530 if (trap->attacktype && (trap->level || victim->type != PLAYER) && !should_director_abort (trap, victim)) 1521 if (trap->attacktype && (trap->level || victim->type != PLAYER) && !should_director_abort (trap, victim))
1522 {
1523 if (!trap->stats.maxsp)
1524 trap->stats.maxsp = 2;
1525
1526 /* Is this correct? From the docs, it doesn't look like it
1527 * should be divided by trap->speed
1528 */
1529 victim->speed_left = -FABS (trap->stats.maxsp * victim->speed / trap->speed);
1530
1531 /* Just put in some sanity check. I think there is a bug in the
1532 * above with some objects have zero speed, and thus the player
1533 * getting permanently paralyzed.
1534 */
1535 if (victim->speed_left < -50.0)
1536 victim->speed_left = -50.0;
1537 /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left); */
1538 }
1539 goto leave;
1540
1541 case SPINNER:
1542 if (victim->direction)
1543 {
1544 victim->direction = absdir (victim->direction - trap->stats.sp);
1545 update_turn_face (victim);
1546 }
1547 goto leave;
1548
1549 case DIRECTOR:
1550 if (victim->direction && !should_director_abort (trap, victim))
1551 {
1552 victim->direction = trap->stats.sp;
1553 update_turn_face (victim);
1554 }
1555 goto leave;
1556
1557 case BUTTON:
1558 case PEDESTAL:
1559 update_button (trap);
1560 goto leave;
1561
1562 case ALTAR:
1563 /* sacrifice victim on trap */
1564 apply_altar (trap, victim, originator);
1565 goto leave;
1566
1567 case THROWN_OBJ:
1568 if (trap->inv == NULL)
1569 goto leave;
1570 /* fallthrough */
1571
1572 case ARROW:
1573 /* bad bug: monster throw a object, make a step forwards, step on object ,
1574 * trigger this here and get hit by own missile - and will be own enemy.
1575 * Victim then is his own enemy and will start to kill herself (this is
1576 * removed) but we have not synced victim and his missile. To avoid senseless
1577 * action, we avoid hits here
1578 */
1579 if ((QUERY_FLAG (victim, FLAG_ALIVE) && trap->speed) && trap->owner != victim)
1580 hit_with_arrow (trap, victim);
1581 goto leave;
1582
1583 case SPELL_EFFECT:
1584 apply_spell_effect (trap, victim);
1585 goto leave;
1586
1587 case TRAPDOOR:
1588 {
1589 int max, sound_was_played;
1590 object *ab, *ab_next;
1591
1592 if (!trap->value)
1531 { 1593 {
1532 if (!trap->stats.maxsp) 1594 int tot;
1533 trap->stats.maxsp = 2;
1534 1595
1535 /* Is this correct? From the docs, it doesn't look like it 1596 for (ab = trap->above, tot = 0; ab != NULL; ab = ab->above)
1536 * should be divided by trap->speed 1597 if ((ab->move_type && trap->move_on) || ab->move_type == 0)
1598 tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying;
1599
1600 if (!(trap->value = (tot > trap->weight) ? 1 : 0))
1601 goto leave;
1602
1603 SET_ANIMATION (trap, trap->value);
1604 update_object (trap, UP_OBJ_FACE);
1605 }
1606
1607 for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab; ab = ab_next)
1608 {
1609 /* need to set this up, since if we do transfer the object,
1610 * ab->above would be bogus
1537 */ 1611 */
1538 victim->speed_left = -FABS (trap->stats.maxsp * victim->speed / trap->speed);
1539
1540 /* Just put in some sanity check. I think there is a bug in the
1541 * above with some objects have zero speed, and thus the player
1542 * getting permanently paralyzed.
1543 */
1544 if (victim->speed_left < -50.0)
1545 victim->speed_left = -50.0;
1546 /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left); */
1547 }
1548 goto leave;
1549
1550 case SPINNER:
1551 if (victim->direction)
1552 {
1553 victim->direction = absdir (victim->direction - trap->stats.sp);
1554 update_turn_face (victim);
1555 }
1556 goto leave;
1557
1558 case DIRECTOR:
1559 if (victim->direction && !should_director_abort (trap, victim))
1560 {
1561 victim->direction = trap->stats.sp;
1562 update_turn_face (victim);
1563 }
1564 goto leave;
1565
1566 case BUTTON:
1567 case PEDESTAL:
1568 update_button (trap);
1569 goto leave;
1570
1571 case ALTAR:
1572 /* sacrifice victim on trap */
1573 apply_altar (trap, victim, originator);
1574 goto leave;
1575
1576 case THROWN_OBJ:
1577 if (trap->inv == NULL)
1578 goto leave;
1579 /* fallthrough */
1580
1581 case ARROW:
1582
1583 /* bad bug: monster throw a object, make a step forwards, step on object ,
1584 * trigger this here and get hit by own missile - and will be own enemy.
1585 * Victim then is his own enemy and will start to kill herself (this is
1586 * removed) but we have not synced victim and his missile. To avoid senseless
1587 * action, we avoid hits here
1588 */
1589 if ((QUERY_FLAG (victim, FLAG_ALIVE) && trap->speed) && trap->owner != victim)
1590 hit_with_arrow (trap, victim);
1591 goto leave;
1592
1593 case SPELL_EFFECT:
1594 apply_spell_effect (trap, victim);
1595 goto leave;
1596
1597 case TRAPDOOR:
1598 {
1599 int max, sound_was_played;
1600 object *ab, *ab_next;
1601
1602 if (!trap->value)
1603 {
1604 int tot;
1605
1606 for (ab = trap->above, tot = 0; ab != NULL; ab = ab->above)
1607 if ((ab->move_type && trap->move_on) || ab->move_type == 0)
1608 tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying;
1609
1610 if (!(trap->value = (tot > trap->weight) ? 1 : 0))
1611 goto leave;
1612
1613 SET_ANIMATION (trap, trap->value);
1614 update_object (trap, UP_OBJ_FACE);
1615 }
1616
1617 for (ab = trap->above, max = 100, sound_was_played = 0; --max && ab; ab = ab_next)
1618 {
1619 /* need to set this up, since if we do transfer the object,
1620 * ab->above would be bogus
1621 */
1622 ab_next = ab->above; 1612 ab_next = ab->above;
1623 1613
1624 if ((ab->move_type && trap->move_on) || ab->move_type == 0) 1614 if ((ab->move_type && trap->move_on) || ab->move_type == 0)
1625 {
1626 if (!sound_was_played)
1627 {
1628 play_sound_map (trap->map, trap->x, trap->y, SOUND_FALL_HOLE);
1629 sound_was_played = 1;
1630 }
1631 new_draw_info (NDI_UNIQUE, 0, ab, "You fall into a trapdoor!");
1632 transfer_ob (ab, (int) EXIT_X (trap), (int) EXIT_Y (trap), 0, ab);
1633 }
1634 }
1635 goto leave;
1636 }
1637
1638
1639 case CONVERTER:
1640 if (convert_item (victim, trap) < 0)
1641 {
1642 object *op;
1643
1644 new_draw_info_format (NDI_UNIQUE, 0, originator, "The %s seems to be broken!", query_name (trap));
1645
1646 op = get_archetype ("burnout");
1647 if (op != NULL)
1648 { 1615 {
1649 op->x = trap->x; 1616 if (!sound_was_played)
1650 op->y = trap->y; 1617 {
1651 insert_ob_in_map (op, trap->map, trap, 0); 1618 play_sound_map (trap->map, trap->x, trap->y, SOUND_FALL_HOLE);
1619 sound_was_played = 1;
1620 }
1621 new_draw_info (NDI_UNIQUE, 0, ab, "You fall into a trapdoor!");
1622 transfer_ob (ab, (int) EXIT_X (trap), (int) EXIT_Y (trap), 0, ab);
1652 } 1623 }
1653 } 1624 }
1654 goto leave; 1625 goto leave;
1626 }
1655 1627
1628
1629 case CONVERTER:
1630 if (convert_item (victim, trap) < 0)
1631 {
1632 object *op;
1633
1634 new_draw_info_format (NDI_UNIQUE, 0, originator, "The %s seems to be broken!", query_name (trap));
1635
1636 op = get_archetype ("burnout");
1637 if (op != NULL)
1638 {
1639 op->x = trap->x;
1640 op->y = trap->y;
1641 insert_ob_in_map (op, trap->map, trap, 0);
1642 }
1643 }
1644 goto leave;
1645
1656 case TRIGGER_BUTTON: 1646 case TRIGGER_BUTTON:
1657 case TRIGGER_PEDESTAL: 1647 case TRIGGER_PEDESTAL:
1658 case TRIGGER_ALTAR: 1648 case TRIGGER_ALTAR:
1659 check_trigger (trap, victim); 1649 check_trigger (trap, victim);
1650 goto leave;
1651
1652 case DEEP_SWAMP:
1653 walk_on_deep_swamp (trap, victim);
1654 goto leave;
1655
1656 case CHECK_INV:
1657 check_inv (victim, trap);
1658 goto leave;
1659
1660 case HOLE:
1661 /* Hole not open? */
1662 if (trap->stats.wc > 0)
1660 goto leave; 1663 goto leave;
1661 1664
1662 case DEEP_SWAMP: 1665 /* Is this a multipart monster and not the head? If so, return.
1663 walk_on_deep_swamp (trap, victim); 1666 * Processing will happen if the head runs into the pit
1667 */
1668 if (victim->head)
1664 goto leave; 1669 goto leave;
1665 1670
1666 case CHECK_INV:
1667 check_inv (victim, trap);
1668 goto leave;
1669
1670 case HOLE:
1671 /* Hole not open? */
1672 if (trap->stats.wc > 0)
1673 goto leave;
1674
1675 /* Is this a multipart monster and not the head? If so, return.
1676 * Processing will happen if the head runs into the pit
1677 */
1678 if (victim->head)
1679 goto leave;
1680
1681 play_sound_map (victim->map, victim->x, victim->y, SOUND_FALL_HOLE); 1671 play_sound_map (victim->map, victim->x, victim->y, SOUND_FALL_HOLE);
1682 new_draw_info (NDI_UNIQUE, 0, victim, "You fall through the hole!\n"); 1672 new_draw_info (NDI_UNIQUE, 0, victim, "You fall through the hole!\n");
1683 transfer_ob (victim, EXIT_X (trap), EXIT_Y (trap), 1, victim); 1673 transfer_ob (victim, EXIT_X (trap), EXIT_Y (trap), 1, victim);
1684 goto leave; 1674 goto leave;
1685 1675
1686 case EXIT: 1676 case EXIT:
1687 if (victim->type == PLAYER && EXIT_PATH (trap)) 1677 if (victim->type == PLAYER && EXIT_PATH (trap))
1688 { 1678 {
1689 /* Basically, don't show exits leading to random maps the 1679 /* Basically, don't show exits leading to random maps the
1690 * players output. 1680 * players output.
1691 */ 1681 */
1692 if (trap->msg && strncmp (EXIT_PATH (trap), "/!", 2) && strncmp (EXIT_PATH (trap), "/random/", 8)) 1682 if (trap->msg && strncmp (EXIT_PATH (trap), "/!", 2) && strncmp (EXIT_PATH (trap), "/random/", 8))
1693 new_draw_info (NDI_NAVY, 0, victim, trap->msg); 1683 new_draw_info (NDI_NAVY, 0, victim, trap->msg);
1694 enter_exit (victim, trap); 1684 enter_exit (victim, trap);
1695 } 1685 }
1696 goto leave; 1686 goto leave;
1697 1687
1698 case ENCOUNTER: 1688 case ENCOUNTER:
1699 /* may be some leftovers on this */ 1689 /* may be some leftovers on this */
1700 goto leave; 1690 goto leave;
1701 1691
1702 case SHOP_MAT: 1692 case SHOP_MAT:
1703 apply_shop_mat (trap, victim); 1693 apply_shop_mat (trap, victim);
1704 goto leave; 1694 goto leave;
1705 1695
1706 /* Drop a certain amount of gold, and have one item identified */ 1696 /* Drop a certain amount of gold, and have one item identified */
1707 case IDENTIFY_ALTAR: 1697 case IDENTIFY_ALTAR:
1708 apply_id_altar (victim, trap, originator); 1698 apply_id_altar (victim, trap, originator);
1709 goto leave; 1699 goto leave;
1710 1700
1711 case SIGN: 1701 case SIGN:
1712 if (victim->type != PLAYER && trap->stats.food > 0) 1702 if (victim->type != PLAYER && trap->stats.food > 0)
1713 goto leave; /* monsters musn't apply magic_mouths with counters */ 1703 goto leave; /* monsters musn't apply magic_mouths with counters */
1714 1704
1715 apply_sign (victim, trap, 1); 1705 apply_sign (victim, trap, 1);
1716 goto leave; 1706 goto leave;
1717 1707
1718 case CONTAINER: 1708 case CONTAINER:
1719 if (victim->type == PLAYER) 1709 if (victim->type == PLAYER)
1720 (void) esrv_apply_container (victim, trap); 1710 (void) esrv_apply_container (victim, trap);
1721 else 1711 else
1722 (void) apply_container (victim, trap); 1712 (void) apply_container (victim, trap);
1723 goto leave; 1713 goto leave;
1724 1714
1725 case RUNE: 1715 case RUNE:
1726 case TRAP: 1716 case TRAP:
1727 if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE)) 1717 if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE))
1728 { 1718 {
1729 spring_trap (trap, victim); 1719 spring_trap (trap, victim);
1730 } 1720 }
1731 goto leave; 1721 goto leave;
1732 1722
1733 default: 1723 default:
1734 LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not " 1724 LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not "
1735 "handled in move_apply()\n", &trap->name, &trap->arch->name, trap->type); 1725 "handled in move_apply()\n", &trap->name, &trap->arch->name, trap->type);
1736 goto leave; 1726 goto leave;
1737 } 1727 }
1738 1728
1739leave: 1729leave:
1740 recursion_depth--; 1730 recursion_depth--;
1741} 1731}
1798 1788
1799 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1789 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1800 { 1790 {
1801 /*exp_gain *= 2; because they just identified it too */ 1791 /*exp_gain *= 2; because they just identified it too */
1802 SET_FLAG (tmp, FLAG_IDENTIFIED); 1792 SET_FLAG (tmp, FLAG_IDENTIFIED);
1793
1803 /* If in a container, update how it looks */ 1794 /* If in a container, update how it looks */
1804 if (tmp->env) 1795 if (tmp->env)
1805 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1796 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1806 else 1797 else
1807 op->contr->socket.update_look = 1; 1798 op->contr->ns->floorbox_update ();
1808 } 1799 }
1800
1809 change_exp (op, exp_gain, skill_ob->skill, 0); 1801 change_exp (op, exp_gain, skill_ob->skill, 0);
1810 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT); /* so no more xp gained from this book */ 1802 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT); /* so no more xp gained from this book */
1811 } 1803 }
1812} 1804}
1813 1805
1818static void 1810static void
1819apply_skillscroll (object *op, object *tmp) 1811apply_skillscroll (object *op, object *tmp)
1820{ 1812{
1821 switch ((int) learn_skill (op, tmp)) 1813 switch ((int) learn_skill (op, tmp))
1822 { 1814 {
1823 case 0: 1815 case 0:
1824 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 ");
1825 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));
1826 return; 1818 return;
1827 1819
1828 case 1: 1820 case 1:
1829 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);
1830 decrease_ob (tmp); 1822 decrease_ob (tmp);
1831 return; 1823 return;
1832 1824
1833 default: 1825 default:
1834 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));
1835 decrease_ob (tmp); 1827 decrease_ob (tmp);
1836 return; 1828 return;
1837 } 1829 }
1838} 1830}
1839 1831
1840/** 1832/**
1841 * Actually makes op learn spell. 1833 * Actually makes op learn spell.
1862 } 1854 }
1863 return; 1855 return;
1864 } 1856 }
1865 1857
1866 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0); 1858 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0);
1867 tmp = get_object (); 1859 tmp = spell->clone ();
1868 copy_object (spell, tmp);
1869 insert_ob_in_ob (tmp, op); 1860 insert_ob_in_ob (tmp, op);
1870 1861
1871 if (special_prayer) 1862 if (special_prayer)
1872 {
1873 SET_FLAG (tmp, FLAG_STARTEQUIP); 1863 SET_FLAG (tmp, FLAG_STARTEQUIP);
1874 }
1875 1864
1876 esrv_add_spells (op->contr, tmp); 1865 esrv_add_spells (op->contr, tmp);
1877} 1866}
1878 1867
1879/** 1868/**
1896 } 1885 }
1897 1886
1898 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);
1899 player_unready_range_ob (op->contr, spob); 1888 player_unready_range_ob (op->contr, spob);
1900 esrv_remove_spell (op->contr, spob); 1889 esrv_remove_spell (op->contr, spob);
1901 remove_ob (spob); 1890 spob->destroy ();
1902 free_object (spob);
1903} 1891}
1904 1892
1905/** 1893/**
1906 * Handles player applying a spellbook. 1894 * Handles player applying a spellbook.
1907 * 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,
1945 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.");
1946 return; 1934 return;
1947 } 1935 }
1948 1936
1949 spell = tmp->inv; 1937 spell = tmp->inv;
1938
1950 if (!spell) 1939 if (!spell)
1951 { 1940 {
1952 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);
1953 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.");
1954 return; 1943 return;
1955 } 1944 }
1956 if (spell->level > (skop->level + 10)) 1945
1946 if (skop->level < int (sqrtf (spell->level) * 1.5f))
1957 { 1947 {
1958 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.");
1959 return; 1949 return;
1960 } 1950 }
1961 1951
1962 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);
1963 1953
1964 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1954 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1965 { 1955 {
1966 identify (tmp); 1956 identify (tmp);
1957
1967 if (tmp->env) 1958 if (tmp->env)
1968 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1959 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1969 else 1960 else
1970 op->contr->socket.update_look = 1; 1961 op->contr->ns->floorbox_update ();
1971 } 1962 }
1972 1963
1973 /* 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
1974 * 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
1975 * 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
1982 } 1973 }
1983 1974
1984 if (spell->skill) 1975 if (spell->skill)
1985 { 1976 {
1986 spell_skill = find_skill_by_name (op, spell->skill); 1977 spell_skill = find_skill_by_name (op, spell->skill);
1978
1987 if (!spell_skill) 1979 if (!spell_skill)
1988 { 1980 {
1989 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);
1990 return; 1982 return;
1991 } 1983 }
1984
1992 if (spell_skill->level < spell->level) 1985 if (spell_skill->level < spell->level)
1993 { 1986 {
1994 new_draw_info_format (NDI_UNIQUE, 0, op, "You need to be level %d in %s to learn this spell.", spell->level, &spell->skill); 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);
1995 return; 1988 return;
1996 } 1989 }
2089 */ 2082 */
2090static void 2083static void
2091apply_treasure (object *op, object *tmp) 2084apply_treasure (object *op, object *tmp)
2092{ 2085{
2093 object *treas; 2086 object *treas;
2094 tag_t tmp_tag = tmp->count, op_tag = op->count;
2095 2087
2096 2088
2097 /* 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
2098 * 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
2099 * 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
2110 } 2102 }
2111 while (tmp->inv) 2103 while (tmp->inv)
2112 { 2104 {
2113 treas = tmp->inv; 2105 treas = tmp->inv;
2114 2106
2115 remove_ob (treas); 2107 treas->remove ();
2116 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));
2117 2109
2118 treas->x = op->x; 2110 treas->x = op->x;
2119 treas->y = op->y; 2111 treas->y = op->y;
2120 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);
2121 2113
2122 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))
2123 spring_trap (treas, op); 2115 spring_trap (treas, op);
2116
2124 /* If either player or container was destroyed, no need to do 2117 /* If either player or container was destroyed, no need to do
2125 * further processing. I think this should be enclused with 2118 * further processing. I think this should be enclused with
2126 * spring trap above, as I don't think there is otherwise 2119 * spring trap above, as I don't think there is otherwise
2127 * any way for the treasure chest or player to get killed 2120 * any way for the treasure chest or player to get killed
2128 */ 2121 */
2129 if (was_destroyed (op, op_tag) || was_destroyed (tmp, tmp_tag)) 2122 if (op->destroyed () || tmp->destroyed ())
2130 break; 2123 break;
2131 } 2124 }
2132 2125
2133 if (!was_destroyed (tmp, tmp_tag) && tmp->inv == NULL) 2126 if (!tmp->destroyed () && tmp->inv == NULL)
2134 decrease_ob (tmp); 2127 decrease_ob (tmp);
2135 2128
2136} 2129}
2137 2130
2138/** 2131/**
2333 2326
2334 if (i >= 0 && i < NROFATTACKS && skin->resist[i] < 95) 2327 if (i >= 0 && i < NROFATTACKS && skin->resist[i] < 95)
2335 { 2328 {
2336 /* resistance increased! */ 2329 /* resistance increased! */
2337 skin->resist[i]++; 2330 skin->resist[i]++;
2338 fix_player (op); 2331 op->update_stats ();
2339 2332
2340 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]);
2341 new_draw_info (NDI_UNIQUE | NDI_RED, 0, op, buf); 2334 new_draw_info (NDI_UNIQUE | NDI_RED, 0, op, buf);
2342 } 2335 }
2343 2336
2362 } 2355 }
2363 } 2356 }
2364 return 1; 2357 return 1;
2365} 2358}
2366 2359
2367static void
2368apply_savebed (object *pl)
2369{
2370#ifndef COZY_SERVER
2371 if (!pl->contr->name_changed || !pl->stats.exp)
2372 {
2373 new_draw_info (NDI_UNIQUE, 0, pl, "You don't deserve to save your character yet.");
2374 return;
2375 }
2376#endif
2377 INVOKE_PLAYER (LOGOUT, pl->contr);
2378 /* Need to call terminate_all_pets() before we remove the player ob */
2379 terminate_all_pets (pl);
2380 remove_ob (pl);
2381 pl->direction = 0;
2382 new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, pl, "%s leaves the game.", &pl->name);
2383
2384 /* update respawn position */
2385 strcpy (pl->contr->savebed_map, pl->map->path);
2386 pl->contr->bed_x = pl->x;
2387 pl->contr->bed_y = pl->y;
2388
2389 strcpy (pl->contr->killer, "left");
2390 check_score (pl); /* Always check score */
2391 (void) save_player (pl, 0);
2392 pl->map->players--;
2393#if MAP_MAXTIMEOUT
2394 MAP_SWAP_TIME (pl->map) = MAP_TIMEOUT (pl->map);
2395#endif
2396 play_again (pl);
2397 pl->speed = 0;
2398 update_ob_speed (pl);
2399}
2400
2401/** 2360/**
2402 * Handles applying an improve armor scroll. 2361 * Handles applying an improve armor scroll.
2403 * Does some sanity checks, then calls improve_armour. 2362 * Does some sanity checks, then calls improve_armour.
2404 */ 2363 */
2405static void 2364static void
2410 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))
2411 { 2370 {
2412 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.");
2413 return; 2372 return;
2414 } 2373 }
2374
2415 armor = find_marked_object (op); 2375 armor = find_marked_object (op);
2376
2416 if (!armor) 2377 if (!armor)
2417 { 2378 {
2418 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.");
2419 return; 2380 return;
2420 } 2381 }
2382
2421 if (armor->type != ARMOUR 2383 if (armor->type != ARMOUR
2422 && armor->type != CLOAK 2384 && armor->type != CLOAK
2423 && 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)
2424 { 2386 {
2425 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");
2427 } 2389 }
2428 2390
2429 new_draw_info (NDI_UNIQUE, 0, op, "Applying armour enchantment."); 2391 new_draw_info (NDI_UNIQUE, 0, op, "Applying armour enchantment.");
2430 improve_armour (op, tmp, armor); 2392 improve_armour (op, tmp, armor);
2431} 2393}
2432
2433 2394
2434extern void 2395extern void
2435apply_poison (object *op, object *tmp) 2396apply_poison (object *op, object *tmp)
2436{ 2397{
2437 if (op->type == PLAYER) 2398 if (op->type == PLAYER)
2453/** 2414/**
2454 * 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.
2455 * A valid 2 way exit means: 2416 * A valid 2 way exit means:
2456 * -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)
2457 * -You are 2418 * -You are
2458 * ° the owner of the exit 2419 * ° the owner of the exit
2459 * ° or in the same party as the owner 2420 * ° or in the same party as the owner
2460 * 2421 *
2461 * 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
2462 * 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
2463 * 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).
2464 */ 2425 */
2466is_legal_2ways_exit (object *op, object *exit) 2427is_legal_2ways_exit (object *op, object *exit)
2467{ 2428{
2468 object *tmp; 2429 object *tmp;
2469 object *exit_owner; 2430 object *exit_owner;
2470 player *pp; 2431 player *pp;
2471 mapstruct *exitmap; 2432 maptile *exitmap;
2472 2433
2473 if (exit->stats.exp != 1) 2434 if (exit->stats.exp != 1)
2474 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 */
2475 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race) 2436 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race)
2476 return 0; /* This is a reset town portal */ 2437 return 0; /* This is a reset town portal */
2481 exitmap = ready_map_name (EXIT_PATH (exit), MAP_PLAYER_UNIQUE); 2442 exitmap = ready_map_name (EXIT_PATH (exit), MAP_PLAYER_UNIQUE);
2482 else 2443 else
2483 exitmap = ready_map_name (EXIT_PATH (exit), 0); 2444 exitmap = ready_map_name (EXIT_PATH (exit), 0);
2484 if (exitmap) 2445 if (exitmap)
2485 { 2446 {
2486 tmp = get_map_ob (exitmap, EXIT_X (exit), EXIT_Y (exit)); 2447 tmp = GET_MAP_OB (exitmap, EXIT_X (exit), EXIT_Y (exit));
2487 if (!tmp) 2448 if (!tmp)
2488 return 0; 2449 return 0;
2489 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)
2490 { 2451 {
2491 if (tmp->type != EXIT) 2452 if (tmp->type != EXIT)
2492 continue; /*Not an exit */ 2453 continue; /*Not an exit */
2493 if (!EXIT_PATH (tmp)) 2454 if (!EXIT_PATH (tmp))
2494 continue; /*Not a valid exit */ 2455 continue; /*Not a valid exit */
2558 { 2519 {
2559 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.");
2560 return 1; 2521 return 1;
2561 } 2522 }
2562 else 2523 else
2563 {
2564 return 0; /* monsters just skip unpaid items */ 2524 return 0; /* monsters just skip unpaid items */
2565 }
2566 } 2525 }
2567 2526
2568 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op))) 2527 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op)))
2569 return RESULT_INT (0); 2528 return RESULT_INT (0);
2570 2529
2571 switch (tmp->type) 2530 switch (tmp->type)
2572 { 2531 {
2573
2574 case CF_HANDLE: 2532 case CF_HANDLE:
2575 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2533 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2576 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);
2577 tmp->value = tmp->value ? 0 : 1; 2535 tmp->value = tmp->value ? 0 : 1;
2578 SET_ANIMATION (tmp, tmp->value); 2536 SET_ANIMATION (tmp, tmp->value);
2579 update_object (tmp, UP_OBJ_FACE); 2537 update_object (tmp, UP_OBJ_FACE);
2580 push_button (tmp); 2538 push_button (tmp);
2581 return 1; 2539 return 1;
2582 2540
2583 case TRIGGER: 2541 case TRIGGER:
2584 if (check_trigger (tmp, op)) 2542 if (check_trigger (tmp, op))
2585 { 2543 {
2586 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2544 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2587 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);
2588 } 2546 }
2589 else 2547 else
2590 { 2548 {
2591 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.");
2592 } 2550 }
2593 return 1; 2551 return 1;
2594 2552
2595 case EXIT: 2553 case EXIT:
2596 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 {
2597 return 0; 2581 return 0;
2598 if (!EXIT_PATH (tmp) || !is_legal_2ways_exit (op, tmp))
2599 {
2600 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s is closed.", query_name (tmp));
2601 } 2582 }
2602 else
2603 {
2604 /* Don't display messages for random maps. */
2605 if (tmp->msg && strncmp (EXIT_PATH (tmp), "/!", 2) && strncmp (EXIT_PATH (tmp), "/random/", 8))
2606 new_draw_info (NDI_NAVY, 0, op, tmp->msg);
2607 enter_exit (op, tmp);
2608 }
2609 return 1;
2610 2583
2611 case SIGN: 2584 case SKILLSCROLL:
2612 apply_sign (op, tmp, 0);
2613 return 1;
2614
2615 case BOOK:
2616 if (op->type == PLAYER) 2585 if (op->type == PLAYER)
2617 { 2586 {
2618 apply_book (op, tmp);
2619 return 1;
2620 }
2621 else
2622 {
2623 return 0;
2624 }
2625
2626 case SKILLSCROLL:
2627 if (op->type == PLAYER)
2628 {
2629 apply_skillscroll (op, tmp); 2587 apply_skillscroll (op, tmp);
2630 return 1; 2588 return 1;
2631 } 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
2632 return 0; 2678 return 0;
2633 2679
2634 case SPELLBOOK:
2635 if (op->type == PLAYER)
2636 {
2637 apply_spellbook (op, tmp);
2638 return 1;
2639 }
2640 return 0;
2641
2642 case SCROLL:
2643 apply_scroll (op, tmp, 0);
2644 return 1;
2645
2646 case POTION:
2647 (void) apply_potion (op, tmp);
2648 return 1;
2649
2650 /* Eneq(@csd.uu.se): Handle apply on containers. */
2651 case CLOSE_CON:
2652 if (op->type == PLAYER)
2653 (void) esrv_apply_container (op, tmp->env);
2654 else
2655 (void) apply_container (op, tmp->env);
2656 return 1;
2657
2658 case CONTAINER:
2659 if (op->type == PLAYER)
2660 (void) esrv_apply_container (op, tmp);
2661 else
2662 (void) apply_container (op, tmp);
2663 return 1;
2664
2665 case TREASURE:
2666 if (op->type == PLAYER)
2667 {
2668 apply_treasure (op, tmp);
2669 return 1;
2670 }
2671 else
2672 {
2673 return 0;
2674 }
2675
2676 case WEAPON:
2677 case ARMOUR:
2678 case BOOTS:
2679 case GLOVES:
2680 case AMULET:
2681 case GIRDLE:
2682 case BRACERS:
2683 case SHIELD:
2684 case HELMET:
2685 case RING:
2686 case CLOAK:
2687 case WAND:
2688 case ROD:
2689 case HORN:
2690 case SKILL:
2691 case BOW:
2692 case LAMP:
2693 case BUILDER:
2694 case SKILL_TOOL:
2695 if (tmp->env != op)
2696 return 2; /* not in inventory */
2697 (void) apply_special (op, tmp, aflag);
2698 return 1;
2699
2700 case DRINK:
2701 case FOOD:
2702 case FLESH:
2703 apply_food (op, tmp);
2704 return 1;
2705
2706 case POISON:
2707 apply_poison (op, tmp);
2708 return 1;
2709
2710 case SAVEBED:
2711 if (op->type == PLAYER)
2712 {
2713 apply_savebed (op);
2714 return 1;
2715 }
2716 else
2717 {
2718 return 0;
2719 }
2720
2721 case ARMOUR_IMPROVER:
2722 if (op->type == PLAYER)
2723 {
2724 apply_armour_improver (op, tmp);
2725 return 1;
2726 }
2727 else
2728 {
2729 return 0;
2730 }
2731
2732 case WEAPON_IMPROVER: 2680 case WEAPON_IMPROVER:
2733 (void) check_improve_weapon (op, tmp); 2681 (void) check_improve_weapon (op, tmp);
2734 return 1; 2682 return 1;
2735 2683
2736 case CLOCK: 2684 case CLOCK:
2737 if (op->type == PLAYER) 2685 if (op->type == PLAYER)
2738 { 2686 {
2739 char buf[MAX_BUF]; 2687 char buf[MAX_BUF];
2740 timeofday_t tod; 2688 timeofday_t tod;
2741 2689
2742 get_tod (&tod); 2690 get_tod (&tod);
2743 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",
2744 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"), 2692 tod.minute + 1, ((tod.minute + 1 < 2) ? "" : "s"),
2745 ((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"));
2746 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0); 2694 play_sound_player_only (op->contr, SOUND_CLOCK, 0, 0);
2747 new_draw_info (NDI_UNIQUE, 0, op, buf); 2695 new_draw_info (NDI_UNIQUE, 0, op, buf);
2748 return 1; 2696 return 1;
2749 } 2697 }
2750 else 2698 else
2751 { 2699 {
2752 return 0; 2700 return 0;
2753 } 2701 }
2754 2702
2755 case MENU: 2703 case MENU:
2756 if (op->type == PLAYER) 2704 if (op->type == PLAYER)
2757 { 2705 {
2758 shop_listing (op); 2706 shop_listing (op);
2759 return 1; 2707 return 1;
2760 } 2708 }
2761 else 2709 else
2762 { 2710 {
2763 return 0; 2711 return 0;
2764 } 2712 }
2765 2713
2766 case POWER_CRYSTAL: 2714 case POWER_CRYSTAL:
2767 apply_power_crystal (op, tmp); /* see egoitem.c */ 2715 apply_power_crystal (op, tmp); /* see egoitem.c */
2768 return 1; 2716 return 1;
2769 2717
2770 case LIGHTER: /* for lighting torches/lanterns/etc */ 2718 case LIGHTER: /* for lighting torches/lanterns/etc */
2771 if (op->type == PLAYER) 2719 if (op->type == PLAYER)
2772 { 2720 {
2773 apply_lighter (op, tmp); 2721 apply_lighter (op, tmp);
2774 return 1; 2722 return 1;
2775 } 2723 }
2776 else 2724 else
2777 { 2725 {
2778 return 0; 2726 return 0;
2779 } 2727 }
2780 2728
2781 case ITEM_TRANSFORMER: 2729 case ITEM_TRANSFORMER:
2782 apply_item_transformer (op, tmp); 2730 apply_item_transformer (op, tmp);
2783 return 1; 2731 return 1;
2784 2732
2785 default: 2733 default:
2786 return 0; 2734 return 0;
2787 } 2735 }
2788} 2736}
2789 2737
2790 2738
2791/* 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"
2815 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))
2816 { 2764 {
2817 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);
2818 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!");
2819 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.");
2820 remove_ob (op); 2768 op->destroy ();
2821 free_object (op);
2822 return 1; 2769 return 1;
2823 } 2770 }
2824 2771
2825 pl->contr->last_used = op; 2772 pl->contr->last_used = op;
2826 pl->contr->last_used_id = op->count;
2827 2773
2828 tmp = manual_apply (pl, op, aflag); 2774 tmp = manual_apply (pl, op, aflag);
2829 if (!quiet) 2775 if (!quiet)
2830 { 2776 {
2831 if (tmp == 0) 2777 if (tmp == 0)
2897 object *tmp2; 2843 object *tmp2;
2898 2844
2899 CLEAR_FLAG (op, FLAG_APPLIED); 2845 CLEAR_FLAG (op, FLAG_APPLIED);
2900 switch (op->type) 2846 switch (op->type)
2901 { 2847 {
2902 case WEAPON: 2848 case WEAPON:
2903 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));
2904 2850
2905 (void) change_abil (who, op); 2851 (void) change_abil (who, op);
2906 if (QUERY_FLAG (who, FLAG_READY_WEAPON)) 2852 if (QUERY_FLAG (who, FLAG_READY_WEAPON))
2907 CLEAR_FLAG (who, FLAG_READY_WEAPON); 2853 CLEAR_FLAG (who, FLAG_READY_WEAPON);
2908 clear_skill (who); 2854 clear_skill (who);
2909 break; 2855 break;
2910 2856
2911 case SKILL: /* allows objects to impart skills */ 2857 case SKILL: /* allows objects to impart skills */
2912 case SKILL_TOOL: 2858 case SKILL_TOOL:
2913 if (op != who->chosen_skill) 2859 if (op != who->chosen_skill)
2914 { 2860 {
2915 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");
2916 } 2862 }
2917 if (who->type == PLAYER) 2863 if (who->type == PLAYER)
2918 { 2864 {
2919 if (who->contr->shoottype == range_skill) 2865 if (who->contr->shoottype == range_skill)
2920 who->contr->shoottype = range_none;
2921 if (!op->invisible)
2922 {
2923 new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op));
2924 }
2925 else
2926 {
2927 new_draw_info_format (NDI_UNIQUE, 0, who, "You can no longer use the skill: %s.", &op->skill);
2928 }
2929 }
2930 (void) change_abil (who, op);
2931 who->chosen_skill = NULL;
2932 CLEAR_FLAG (who, FLAG_READY_SKILL);
2933 break;
2934
2935 case ARMOUR:
2936 case HELMET:
2937 case SHIELD:
2938 case RING:
2939 case BOOTS:
2940 case GLOVES:
2941 case AMULET:
2942 case GIRDLE:
2943 case BRACERS:
2944 case CLOAK:
2945 new_draw_info_format (NDI_UNIQUE, 0, who, "You unwear %s.", query_name (op));
2946 (void) change_abil (who, op);
2947 break;
2948 case LAMP:
2949 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn off your %s.", &op->name);
2950 tmp2 = arch_to_object (op->other_arch);
2951 tmp2->x = op->x;
2952 tmp2->y = op->y;
2953 tmp2->map = op->map;
2954 tmp2->below = op->below;
2955 tmp2->above = op->above;
2956 tmp2->stats.food = op->stats.food;
2957 CLEAR_FLAG (tmp2, FLAG_APPLIED);
2958 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
2959 SET_FLAG (tmp2, FLAG_INV_LOCKED);
2960 if (who->type == PLAYER)
2961 esrv_del_item (who->contr, (tag_t) op->count);
2962 remove_ob (op);
2963 free_object (op);
2964 insert_ob_in_ob (tmp2, who);
2965 fix_player (who);
2966 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2967 {
2968 if (who->type == PLAYER)
2969 {
2970 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
2971 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
2972 }
2973 }
2974 if (who->type == PLAYER)
2975 esrv_send_item (who, tmp2);
2976 return 1; /* otherwise, an attempt to drop causes problems */
2977 break;
2978 case BOW:
2979 case WAND:
2980 case ROD:
2981 case HORN:
2982 clear_skill (who);
2983 new_draw_info_format (NDI_UNIQUE, 0, who, "You unready %s.", query_name (op));
2984 if (who->type == PLAYER)
2985 {
2986 who->contr->shoottype = range_none; 2866 who->contr->shoottype = range_none;
2987 } 2867 if (!op->invisible)
2988 else
2989 { 2868 {
2990 if (op->type == BOW) 2869 new_draw_info_format (NDI_UNIQUE, 0, who, "You stop using the %s.", query_name (op));
2991 CLEAR_FLAG (who, FLAG_READY_BOW); 2870 }
2992 else 2871 else
2993 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);
2994 } 2874 }
2875 }
2876 (void) change_abil (who, op);
2877 who->chosen_skill = NULL;
2878 CLEAR_FLAG (who, FLAG_READY_SKILL);
2995 break; 2879 break;
2996 2880
2881 case ARMOUR:
2882 case HELMET:
2997 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);
2998 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 {
2999 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;
3000 who->contr->ranges[range_builder] = NULL; 2948 who->contr->ranges[range_builder] = NULL;
3001 break; 2949 break;
3002 2950
3003 default: 2951 default:
3004 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));
3005 break; 2953 break;
3006 } 2954 }
3007 2955
3008 fix_player (who); 2956 who->update_stats ();
3009 2957
3010 if (!(aflags & AP_NO_MERGE)) 2958 if (!(aflags & AP_NO_MERGE))
3011 { 2959 {
3012 object *tmp; 2960 object *tmp;
3013
3014 tag_t del_tag = op->count;
3015 2961
3016 tmp = merge_ob (op, NULL); 2962 tmp = merge_ob (op, NULL);
3017 if (who->type == PLAYER) 2963 if (who->type == PLAYER)
3018 { 2964 {
3019 if (tmp) 2965 if (tmp)
3020 { /* it was merged */ 2966 { /* it was merged */
3021 esrv_del_item (who->contr, del_tag); 2967 esrv_del_item (who->contr, op->count);
3022 op = tmp; 2968 op = tmp;
3023 } 2969 }
2970
3024 esrv_send_item (who, op); 2971 esrv_send_item (who, op);
3025 } 2972 }
3026 } 2973 }
3027 return 0; 2974 return 0;
3028} 2975}
3432 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)))
3433 return RESULT_INT (0); 3380 return RESULT_INT (0);
3434 3381
3435 switch (op->type) 3382 switch (op->type)
3436 { 3383 {
3437 case WEAPON: 3384 case WEAPON:
3438 if (!check_weapon_power (who, op->last_eat)) 3385 if (!check_weapon_power (who, op->last_eat))
3439 { 3386 {
3440 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.");
3441 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!.");
3442 if (tmp != NULL) 3389 if (tmp != NULL)
3443 (void) insert_ob_in_ob (tmp, who);
3444 return 1;
3445 }
3446 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3447 {
3448 /* if the weapon does not have the name as the character, can't use it. */
3449 /* (Ragnarok's sword attempted to be used by Foo: won't work) */
3450 new_draw_info (NDI_UNIQUE, 0, who, "The weapon does not recognize you as its owner.");
3451 if (tmp != NULL)
3452 (void) insert_ob_in_ob (tmp, who);
3453 return 1;
3454 }
3455 SET_FLAG (op, FLAG_APPLIED);
3456
3457 if (skop)
3458 change_skill (who, skop, 1);
3459 if (!QUERY_FLAG (who, FLAG_READY_WEAPON))
3460 SET_FLAG (who, FLAG_READY_WEAPON);
3461
3462 new_draw_info_format (NDI_UNIQUE, 0, who, "You wield %s.", query_name (op));
3463
3464 (void) change_abil (who, op);
3465 break;
3466
3467 case ARMOUR:
3468 case HELMET:
3469 case SHIELD:
3470 case BOOTS:
3471 case GLOVES:
3472 case GIRDLE:
3473 case BRACERS:
3474 case CLOAK:
3475 case RING:
3476 case AMULET:
3477 SET_FLAG (op, FLAG_APPLIED);
3478 new_draw_info_format (NDI_UNIQUE, 0, who, "You wear %s.", query_name (op));
3479 (void) change_abil (who, op);
3480 break;
3481 case LAMP:
3482 if (op->stats.food < 1)
3483 {
3484 new_draw_info_format (NDI_UNIQUE, 0, who, "Your %s is out of" " fuel!", &op->name);
3485 return 1;
3486 }
3487 new_draw_info_format (NDI_UNIQUE, 0, who, "You turn on your %s.", &op->name);
3488 tmp2 = arch_to_object (op->other_arch);
3489 tmp2->stats.food = op->stats.food;
3490 SET_FLAG (tmp2, FLAG_APPLIED);
3491 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
3492 SET_FLAG (tmp2, FLAG_INV_LOCKED);
3493 insert_ob_in_ob (tmp2, who);
3494
3495 /* Remove the old lantern */
3496 if (who->type == PLAYER)
3497 esrv_del_item (who->contr, (tag_t) op->count);
3498 remove_ob (op);
3499 free_object (op);
3500
3501 /* insert the portion that was split off */
3502 if (tmp != NULL)
3503 {
3504 (void) insert_ob_in_ob (tmp, who); 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);
3505 if (who->type == PLAYER) 3452 if (who->type == PLAYER)
3506 esrv_send_item (who, tmp); 3453 esrv_send_item (who, tmp);
3507 } 3454 }
3508 fix_player (who); 3455 who->update_stats ();
3509 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 3456 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
3510 { 3457 {
3511 if (who->type == PLAYER) 3458 if (who->type == PLAYER)
3512 { 3459 {
3513 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!");
3514 SET_FLAG (tmp2, FLAG_KNOWN_CURSED); 3461 SET_FLAG (tmp2, FLAG_KNOWN_CURSED);
3515 } 3462 }
3516 } 3463 }
3517 if (who->type == PLAYER) 3464 if (who->type == PLAYER)
3518 esrv_send_item (who, tmp2); 3465 esrv_send_item (who, tmp2);
3519 return 0; 3466 return 0;
3520 break; 3467 break;
3521 3468
3522 /* this part is needed for skill-tools */ 3469 /* this part is needed for skill-tools */
3523 case SKILL: 3470 case SKILL:
3524 case SKILL_TOOL: 3471 case SKILL_TOOL:
3525 if (who->chosen_skill) 3472 if (who->chosen_skill)
3526 { 3473 {
3527 LOG (llevError, "BUG: apply_special(): can't apply two skills\n"); 3474 LOG (llevError, "BUG: apply_special(): can't apply two skills\n");
3528 return 1; 3475 return 1;
3529 } 3476 }
3530 if (who->type == PLAYER) 3477 if (who->type == PLAYER)
3531 { 3478 {
3532 who->contr->shoottype = range_skill; 3479 who->contr->shoottype = range_skill;
3533 who->contr->ranges[range_skill] = op; 3480 who->contr->ranges[range_skill] = op;
3534 if (!op->invisible) 3481 if (!op->invisible)
3535 { 3482 {
3536 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));
3537 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);
3538 } 3485 }
3539 else 3486 else
3540 { 3487 {
3541 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);
3542 } 3489 }
3543 } 3490 }
3544 SET_FLAG (op, FLAG_APPLIED); 3491 SET_FLAG (op, FLAG_APPLIED);
3545 (void) change_abil (who, op); 3492 (void) change_abil (who, op);
3546 who->chosen_skill = op; 3493 who->chosen_skill = op;
3547 SET_FLAG (who, FLAG_READY_SKILL); 3494 SET_FLAG (who, FLAG_READY_SKILL);
3548 break; 3495 break;
3549 3496
3550 case BOW: 3497 case BOW:
3551 if (!check_weapon_power (who, op->last_eat)) 3498 if (!check_weapon_power (who, op->last_eat))
3552 { 3499 {
3553 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.");
3554 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!.");
3555 if (tmp != NULL) 3502 if (tmp != NULL)
3556 (void) insert_ob_in_ob (tmp, who); 3503 (void) insert_ob_in_ob (tmp, who);
3557 return 1; 3504 return 1;
3558 } 3505 }
3559 if (op->level && (strncmp (op->name, who->name, strlen (who->name)))) 3506 if (op->level && (strncmp (op->name, who->name, strlen (who->name))))
3560 { 3507 {
3561 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.");
3562 if (tmp != NULL) 3509 if (tmp != NULL)
3563 (void) insert_ob_in_ob (tmp, who); 3510 (void) insert_ob_in_ob (tmp, who);
3564 return 1; 3511 return 1;
3565 } 3512 }
3566 /*FALLTHROUGH*/ case WAND: 3513 /*FALLTHROUGH*/ case WAND:
3567 case ROD: 3514 case ROD:
3568 case HORN: 3515 case HORN:
3569 /* check for skill, alter player status */ 3516 /* check for skill, alter player status */
3570 SET_FLAG (op, FLAG_APPLIED); 3517 SET_FLAG (op, FLAG_APPLIED);
3571 if (skop) 3518 if (skop)
3572 change_skill (who, skop, 0); 3519 change_skill (who, skop, 0);
3573 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));
3574 3521
3575 if (who->type == PLAYER) 3522 if (who->type == PLAYER)
3576 { 3523 {
3577 if (op->type == BOW) 3524 if (op->type == BOW)
3578 { 3525 {
3579 (void) change_abil (who, op); 3526 (void) change_abil (who, op);
3580 new_draw_info_format (NDI_UNIQUE, 0, who, 3527 new_draw_info_format (NDI_UNIQUE, 0, who,
3581 "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));
3582 who->contr->shoottype = range_bow; 3529 who->contr->shoottype = range_bow;
3583 } 3530 }
3584 else 3531 else
3585 { 3532 {
3586 who->contr->shoottype = range_misc; 3533 who->contr->shoottype = range_misc;
3587 } 3534 }
3588 } 3535 }
3589 else 3536 else
3590 { 3537 {
3591 if (op->type == BOW) 3538 if (op->type == BOW)
3592 SET_FLAG (who, FLAG_READY_BOW); 3539 SET_FLAG (who, FLAG_READY_BOW);
3593 else 3540 else
3594 SET_FLAG (who, FLAG_READY_RANGE); 3541 SET_FLAG (who, FLAG_READY_RANGE);
3595 } 3542 }
3596 break; 3543 break;
3597 3544
3598 case BUILDER: 3545 case BUILDER:
3599 if (who->contr->ranges[range_builder]) 3546 if (who->contr->ranges[range_builder])
3600 unapply_special (who, who->contr->ranges[range_builder], 0); 3547 unapply_special (who, who->contr->ranges[range_builder], 0);
3601 who->contr->shoottype = range_builder; 3548 who->contr->shoottype = range_builder;
3602 who->contr->ranges[range_builder] = op; 3549 who->contr->ranges[range_builder] = op;
3603 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));
3604 break; 3551 break;
3605 3552
3606 default: 3553 default:
3607 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));
3608 } /* end of switch op->type */ 3555 } /* end of switch op->type */
3609 3556
3610 SET_FLAG (op, FLAG_APPLIED); 3557 SET_FLAG (op, FLAG_APPLIED);
3611 3558
3612 if (tmp != NULL) 3559 if (tmp != NULL)
3613 tmp = insert_ob_in_ob (tmp, who); 3560 tmp = insert_ob_in_ob (tmp, who);
3614 3561
3615 fix_player (who); 3562 who->update_stats ();
3616 3563
3617 /* We exclude spell casting objects. The fire code will set the 3564 /* We exclude spell casting objects. The fire code will set the
3618 * been applied flag when they are used - until that point, 3565 * been applied flag when they are used - until that point,
3619 * you don't know anything about them. 3566 * you don't know anything about them.
3620 */ 3567 */
3659 object *tmp = NULL, *tmp2; 3606 object *tmp = NULL, *tmp2;
3660 int i; 3607 int i;
3661 3608
3662 switch (op->type) 3609 switch (op->type)
3663 { 3610 {
3664 case SHOP_FLOOR: 3611 case SHOP_FLOOR:
3665 if (!HAS_RANDOM_ITEMS (op)) 3612 if (!op->has_random_items ())
3666 return 0; 3613 return 0;
3614
3667 do 3615 do
3668 { 3616 {
3669 i = 10; /* let's give it 10 tries */ 3617 i = 10; /* let's give it 10 tries */
3670 while ((tmp = generate_treasure (op->randomitems, 3618 while ((tmp = generate_treasure (op->randomitems,
3671 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);
3672 if (tmp == NULL) 3620 if (tmp == NULL)
3673 return 0; 3621 return 0;
3674 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 3622 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
3675 { 3623 {
3676 free_object (tmp); 3624 tmp->destroy ();
3677 tmp = NULL; 3625 tmp = NULL;
3678 } 3626 }
3679 } 3627 }
3680 while (!tmp); 3628 while (!tmp);
3629
3681 tmp->x = op->x; 3630 tmp->x = op->x;
3682 tmp->y = op->y; 3631 tmp->y = op->y;
3683 SET_FLAG (tmp, FLAG_UNPAID); 3632 SET_FLAG (tmp, FLAG_UNPAID);
3684 insert_ob_in_map (tmp, op->map, NULL, 0); 3633 insert_ob_in_map (tmp, op->map, NULL, 0);
3685 CLEAR_FLAG (op, FLAG_AUTO_APPLY); 3634 CLEAR_FLAG (op, FLAG_AUTO_APPLY);
3686 identify (tmp); 3635 identify (tmp);
3687 break; 3636 break;
3688 3637
3689 case TREASURE: 3638 case TREASURE:
3690 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 3639 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
3691 return 0; 3640 return 0;
3641
3692 while ((op->stats.hp--) > 0) 3642 while ((op->stats.hp--) > 0)
3693 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0, 3643 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0,
3694 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0); 3644 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3695 3645
3696 /* 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,
3697 * 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
3698 * to disappear. An example of this item is the random_* stuff 3648 * to disappear. An example of this item is the random_* stuff
3699 * that is put inside other objects. 3649 * that is put inside other objects.
3700 */ 3650 */
3701 for (tmp = op->inv; tmp; tmp = tmp2) 3651 for (tmp = op->inv; tmp; tmp = tmp2)
3702 { 3652 {
3703 tmp2 = tmp->below; 3653 tmp2 = tmp->below;
3704 remove_ob (tmp); 3654 tmp->remove ();
3655
3705 if (op->env) 3656 if (op->env)
3706 insert_ob_in_ob (tmp, op->env); 3657 insert_ob_in_ob (tmp, op->env);
3707 else 3658 else
3708 free_object (tmp); 3659 tmp->destroy ();
3709 } 3660 }
3710 remove_ob (op); 3661
3711 free_object (op); 3662 op->destroy ();
3712 break; 3663 break;
3713 } 3664 }
3714 return tmp ? 1 : 0; 3665 return tmp ? 1 : 0;
3715} 3666}
3716 3667
3717/** 3668/**
3719 * when an original map is loaded) and performs special actions for 3670 * when an original map is loaded) and performs special actions for
3720 * certain objects (most initialization of chests and creation of 3671 * certain objects (most initialization of chests and creation of
3721 * treasures and stuff). Calls auto_apply if appropriate. 3672 * treasures and stuff). Calls auto_apply if appropriate.
3722 */ 3673 */
3723void 3674void
3724fix_auto_apply (mapstruct *m) 3675fix_auto_apply (maptile *m)
3725{ 3676{
3726 object *tmp, *above = NULL; 3677 object *tmp, *above = NULL;
3727 int x, y; 3678 int x, y;
3728 3679
3729 if (m == NULL) 3680 if (m == NULL)
3730 return; 3681 return;
3731 3682
3732 for (x = 0; x < MAP_WIDTH (m); x++) 3683 for (x = 0; x < MAP_WIDTH (m); x++)
3733 for (y = 0; y < MAP_HEIGHT (m); y++) 3684 for (y = 0; y < MAP_HEIGHT (m); y++)
3734 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)
3735 { 3686 {
3736 above = tmp->above; 3687 above = tmp->above;
3737 3688
3738 if (tmp->inv) 3689 if (tmp->inv)
3739 { 3690 {
3743 { 3694 {
3744 invnext = invtmp->below; 3695 invnext = invtmp->below;
3745 3696
3746 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY)) 3697 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY))
3747 auto_apply (invtmp); 3698 auto_apply (invtmp);
3748 else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS (invtmp)) 3699 else if (invtmp->type == TREASURE && invtmp->has_random_items ())
3749 { 3700 {
3750 while ((invtmp->stats.hp--) > 0) 3701 while ((invtmp->stats.hp--) > 0)
3751 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3702 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3752 3703
3753 invtmp->randomitems = NULL; 3704 invtmp->randomitems = NULL;
3754 } 3705 }
3755 else if (invtmp && invtmp->arch 3706 else if (invtmp && invtmp->arch
3756 && 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 ())
3757 { 3708 {
3758 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3709 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3759 /* Need to clear this so that we never try to create 3710 /* Need to clear this so that we never try to create
3760 * treasure again for this object 3711 * treasure again for this object
3761 */ 3712 */
3778 3729
3779 } 3730 }
3780 3731
3781 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY)) 3732 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY))
3782 auto_apply (tmp); 3733 auto_apply (tmp);
3783 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 ())
3784 { 3735 {
3785 while ((tmp->stats.hp--) > 0) 3736 while ((tmp->stats.hp--) > 0)
3786 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0); 3737 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0);
3787 tmp->randomitems = NULL; 3738 tmp->randomitems = NULL;
3788 } 3739 }
3803 * 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
3804 * which say how many times to make the treasure. 3755 * which say how many times to make the treasure.
3805 */ 3756 */
3806 else if (tmp && tmp->arch && tmp->type != PLAYER 3757 else if (tmp && tmp->arch && tmp->type != PLAYER
3807 && tmp->type != TREASURE && tmp->type != SPELL 3758 && tmp->type != TREASURE && tmp->type != SPELL
3808 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && HAS_RANDOM_ITEMS (tmp)) 3759 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && tmp->has_random_items ())
3809 { 3760 {
3810 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0); 3761 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0);
3811 tmp->randomitems = NULL; 3762 tmp->randomitems = NULL;
3812 } 3763 }
3813 } 3764 }
3814 3765
3815 for (x = 0; x < MAP_WIDTH (m); x++) 3766 for (x = 0; x < MAP_WIDTH (m); x++)
3816 for (y = 0; y < MAP_HEIGHT (m); y++) 3767 for (y = 0; y < MAP_HEIGHT (m); y++)
3817 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)
3818 if (tmp->above && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL)) 3769 if (tmp->above && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
3819 check_trigger (tmp, tmp->above); 3770 check_trigger (tmp, tmp->above);
3820} 3771}
3821 3772
3822/** 3773/**
3852 { 3803 {
3853 force->resist[i] = food->resist[i] / 2; 3804 force->resist[i] = food->resist[i] / 2;
3854 did_one = 1; 3805 did_one = 1;
3855 } 3806 }
3856 } 3807 }
3808
3857 if (did_one) 3809 if (did_one)
3858 { 3810 {
3859 force->speed = 0.1; 3811 force->speed = 0.1;
3860 update_ob_speed (force); 3812 update_ob_speed (force);
3861 /* bigger morsel of food = longer effect time */ 3813 /* bigger morsel of food = longer effect time */
3862 force->stats.food = food->stats.food / 5; 3814 force->duration = food->stats.food / 5;
3863 SET_FLAG (force, FLAG_IS_USED_UP);
3864 SET_FLAG (force, FLAG_APPLIED); 3815 SET_FLAG (force, FLAG_APPLIED);
3865 change_abil (who, force); 3816 change_abil (who, force);
3866 insert_ob_in_ob (force, who); 3817 insert_ob_in_ob (force, who);
3867 } 3818 }
3868 else 3819 else
3869 { 3820 force->destroy ();
3870 free_object (force);
3871 }
3872 3821
3873 /* check for hp, sp change */ 3822 /* check for hp, sp change */
3874 if (food->stats.hp != 0) 3823 if (food->stats.hp != 0)
3875 { 3824 {
3876 if (QUERY_FLAG (food, FLAG_CURSED)) 3825 if (QUERY_FLAG (food, FLAG_CURSED))
3902 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!");
3903 who->stats.sp += food->stats.sp; 3852 who->stats.sp += food->stats.sp;
3904 /* place limit on max sp from food? */ 3853 /* place limit on max sp from food? */
3905 } 3854 }
3906 } 3855 }
3907 fix_player (who); 3856 who->update_stats ();
3908} 3857}
3909
3910 3858
3911/** 3859/**
3912 * Designed primarily to light torches/lanterns/etc. 3860 * Designed primarily to light torches/lanterns/etc.
3913 * 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
3914 * the selected object to "burn". -b.t. 3862 * the selected object to "burn". -b.t.
3915 */ 3863 */
3916
3917void 3864void
3918apply_lighter (object *who, object *lighter) 3865apply_lighter (object *who, object *lighter)
3919{ 3866{
3920 object *item; 3867 object *item;
3921 int is_player_env = 0; 3868 int is_player_env = 0;
3922 uint32 nrof;
3923 tag_t count;
3924 char item_name[MAX_BUF];
3925 3869
3926 item = find_marked_object (who); 3870 item = find_marked_object (who);
3927 if (item) 3871 if (item)
3928 { 3872 {
3929 if (lighter->last_eat && lighter->stats.food) 3873 if (lighter->last_eat && lighter->stats.food)
3930 { /* lighter gets used up */ 3874 { /* lighter gets used up */
3931 /* Split multiple lighters if they're being used up. Otherwise * 3875 /* Split multiple lighters if they're being used up. Otherwise *
3932 * one charge from each would be used up. --DAMN */ 3876 * one charge from each would be used up. --DAMN */
3933 if (lighter->nrof > 1) 3877 if (lighter->nrof > 1)
3934 { 3878 {
3935 object *oneLighter = get_object (); 3879 object *oneLighter = lighter->clone ();
3936 3880
3937 copy_object (lighter, oneLighter);
3938 lighter->nrof -= 1; 3881 lighter->nrof -= 1;
3939 oneLighter->nrof = 1; 3882 oneLighter->nrof = 1;
3940 oneLighter->stats.food--; 3883 oneLighter->stats.food--;
3941 esrv_send_item (who, lighter); 3884 esrv_send_item (who, lighter);
3942 oneLighter = insert_ob_in_ob (oneLighter, who); 3885 oneLighter = insert_ob_in_ob (oneLighter, who);
3943 esrv_send_item (who, oneLighter); 3886 esrv_send_item (who, oneLighter);
3944 } 3887 }
3945 else 3888 else
3946 {
3947 lighter->stats.food--; 3889 lighter->stats.food--;
3948 }
3949
3950 } 3890 }
3951 else if (lighter->last_eat) 3891 else if (lighter->last_eat)
3952 { /* no charges left in lighter */ 3892 { /* no charges left in lighter */
3953 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with a used up %s.", &item->name, &lighter->name); 3893 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with a used up %s.", &item->name, &lighter->name);
3954 return; 3894 return;
3955 } 3895 }
3896
3956 /* 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?
3957 * 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
3958 * objects at once. 3899 * objects at once.
3959 */ 3900 */
3960 nrof = item->nrof; 3901
3961 count = item->count;
3962 /* If the item is destroyed, we don't have a valid pointer to the
3963 * name object, so make a copy so the message we print out makes
3964 * some sense.
3965 */
3966 strcpy (item_name, item->name);
3967 if (who == is_player_inv (item)) 3902 if (who == item->in_player ())
3968 is_player_env = 1; 3903 is_player_env = 1;
3969 3904
3970 save_throw_object (item, AT_FIRE, who); 3905 save_throw_object (item, AT_FIRE, who);
3971 /* Change to check count and not freed, since the object pointer 3906
3972 * may have gotten recycled 3907 if (item->destroyed ())
3973 */ 3908 {
3974 if ((nrof != item->nrof) || (count != item->count))
3975 {
3976 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);
3977 /* Need to update the player so that the players glow radius 3910 /* Need to update the player so that the players glow radius
3978 * gets changed. 3911 * gets changed.
3979 */ 3912 */
3980 if (is_player_env) 3913 if (is_player_env)
3981 fix_player (who); 3914 who->update_stats ();
3982 } 3915 }
3983 else 3916 else
3984 {
3985 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with the %s and fail.", &item->name, &lighter->name); 3917 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with the %s and fail.", &item->name, &lighter->name);
3986 }
3987
3988 } 3918 }
3989 else /* nothing to light */ 3919 else /* nothing to light */
3990 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.");
3991 3921
3992} 3922}
4006 object *tmp; 3936 object *tmp;
4007 3937
4008 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!."); 3938 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!.");
4009 tmp = get_archetype (SPELL_WONDER); 3939 tmp = get_archetype (SPELL_WONDER);
4010 cast_wonder (op, op, 0, tmp); 3940 cast_wonder (op, op, 0, tmp);
4011 free_object (tmp); 3941 tmp->destroy ();
4012 } 3942 }
4013 else if (failure <= -15 && failure > -35) 3943 else if (failure <= -15 && failure > -35)
4014 { /* drain mana */ 3944 { /* drain mana */
4015 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!."); 3945 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!.");
4016 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW); 3946 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW);
4039 object *tmp; 3969 object *tmp;
4040 3970
4041 tmp = get_archetype (LOOSE_MANA); 3971 tmp = get_archetype (LOOSE_MANA);
4042 cast_magic_storm (op, tmp, power); 3972 cast_magic_storm (op, tmp, power);
4043 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!"); 3973 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!");
4044 free_object (tmp); 3974 tmp->destroy ();
4045 } 3975 }
4046 } 3976 }
4047} 3977}
4048 3978
4049void 3979void
4053 for the race, put the excess stat some 3983 for the race, put the excess stat some
4054 where else. */ 3984 where else. */
4055 3985
4056 switch (change->type) 3986 switch (change->type)
4057 { 3987 {
4058 case CLASS: 3988 case CLASS:
4059 { 3989 {
4060 living *stats = &(pl->contr->orig_stats); 3990 living *stats = &(pl->contr->orig_stats);
4061 living *ns = &(change->stats); 3991 living *ns = &(change->stats);
4062 object *walk; 3992 object *walk;
4063 int flag_change_face = 1; 3993 int flag_change_face = 1;
4064 3994
4065 /* the following code assigns stats up to the stat max 3995 /* the following code assigns stats up to the stat max
4066 * for the race, and if the stat max is exceeded, 3996 * for the race, and if the stat max is exceeded,
4067 * tries to randomly reassign the excess stat 3997 * tries to randomly reassign the excess stat
4068 */ 3998 */
4069 int i, j; 3999 int i, j;
4070 4000
4071 for (i = 0; i < NUM_STATS; i++) 4001 for (i = 0; i < NUM_STATS; i++)
4072 { 4002 {
4073 sint8 stat = get_attr_value (stats, i); 4003 sint8 stat = get_attr_value (stats, i);
4074 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); 4004 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4075 4005
4076 stat += get_attr_value (ns, i); 4006 stat += get_attr_value (ns, i);
4077 if (stat > 20 + race_bonus) 4007 if (stat > 20 + race_bonus)
4078 { 4008 {
4079 excess_stat++; 4009 excess_stat++;
4080 stat = 20 + race_bonus; 4010 stat = 20 + race_bonus;
4081 } 4011 }
4082 set_attr_value (stats, i, stat); 4012 set_attr_value (stats, i, stat);
4083 } 4013 }
4084 4014
4085 for (j = 0; excess_stat > 0 && j < 100; j++) 4015 for (j = 0; excess_stat > 0 && j < 100; j++)
4086 { /* try 100 times to assign excess stats */ 4016 { /* try 100 times to assign excess stats */
4087 int i = rndm (0, 6); 4017 int i = rndm (0, 6);
4088 int stat = get_attr_value (stats, i); 4018 int stat = get_attr_value (stats, i);
4089 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i); 4019 int race_bonus = get_attr_value (&(pl->arch->clone.stats), i);
4090 4020
4091 if (i == CHA) 4021 if (i == CHA)
4092 continue; /* exclude cha from this */ 4022 continue; /* exclude cha from this */
4093 if (stat < 20 + race_bonus) 4023 if (stat < 20 + race_bonus)
4094 { 4024 {
4095 change_attr_value (stats, i, 1); 4025 change_attr_value (stats, i, 1);
4096 excess_stat--; 4026 excess_stat--;
4097 } 4027 }
4098 } 4028 }
4099 4029
4100 /* insert the randomitems from the change's treasurelist into 4030 /* insert the randomitems from the change's treasurelist into
4101 * the player ref: player.c 4031 * the player ref: player.c
4102 */ 4032 */
4103 if (change->randomitems != NULL) 4033 if (change->randomitems != NULL)
4104 give_initial_items (pl, change->randomitems); 4034 give_initial_items (pl, change->randomitems);
4105 4035
4106 4036
4107 /* set up the face, for some races. */ 4037 /* set up the face, for some races. */
4108 4038
4109 /* first, look for the force object banning 4039 /* first, look for the force object banning
4110 * changing the face. Certain races never change face with class. 4040 * changing the face. Certain races never change face with class.
4111 */ 4041 */
4112 for (walk = pl->inv; walk != NULL; walk = walk->below) 4042 for (walk = pl->inv; walk != NULL; walk = walk->below)
4113 if (!strcmp (walk->name, "NOCLASSFACECHANGE")) 4043 if (!strcmp (walk->name, "NOCLASSFACECHANGE"))
4114 flag_change_face = 0; 4044 flag_change_face = 0;
4115 4045
4116 if (flag_change_face) 4046 if (flag_change_face)
4117 { 4047 {
4118 pl->animation_id = GET_ANIM_ID (change); 4048 pl->animation_id = GET_ANIM_ID (change);
4119 pl->face = change->face; 4049 pl->face = change->face;
4120 4050
4121 if (QUERY_FLAG (change, FLAG_ANIMATE)) 4051 if (QUERY_FLAG (change, FLAG_ANIMATE))
4122 SET_FLAG (pl, FLAG_ANIMATE); 4052 SET_FLAG (pl, FLAG_ANIMATE);
4123 else 4053 else
4124 CLEAR_FLAG (pl, FLAG_ANIMATE); 4054 CLEAR_FLAG (pl, FLAG_ANIMATE);
4125 } 4055 }
4126 4056
4127 /* check the special case of can't use weapons */ 4057 /* check the special case of can't use weapons */
4128 /*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); */
4129 if (!strcmp (change->name, "monk")) 4059 if (!strcmp (change->name, "monk"))
4130 CLEAR_FLAG (pl, FLAG_USE_WEAPON); 4060 CLEAR_FLAG (pl, FLAG_USE_WEAPON);
4131 4061
4132 break; 4062 break;
4133 } 4063 }
4134 } 4064 }
4135} 4065}
4136 4066
4137/** 4067/**
4138 * This handles items of type 'transformer'. 4068 * This handles items of type 'transformer'.
4212 if (!new_item) 4142 if (!new_item)
4213 { 4143 {
4214 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));
4215 return; 4145 return;
4216 } 4146 }
4147
4217 new_item->nrof = yield; 4148 new_item->nrof = yield;
4218 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));
4219 insert_ob_in_ob (new_item, pl); 4150 insert_ob_in_ob (new_item, pl);
4220 esrv_send_inventory (pl, pl); 4151 esrv_send_inventory (pl, pl);
4221 /* Eat up one item */ 4152 /* Eat up one item */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines