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.26 by root, Wed Sep 13 23:41:47 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.26 2006/09/13 23:41:47 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
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
1352 1345
1353 if (QUERY_FLAG (tmp, FLAG_UNPAID)) 1346 if (QUERY_FLAG (tmp, FLAG_UNPAID))
1354 { 1347 {
1355 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);
1356 1349
1357 remove_ob (tmp); 1350 tmp->remove ();
1358 1351
1359 if (i == -1) 1352 if (i == -1)
1360 i = 0; 1353 i = 0;
1361 1354
1362 tmp->map = op->map; 1355 tmp->map = op->map;
1426 { 1419 {
1427 LOG (llevError, "Internal shop-mat problem.\n"); 1420 LOG (llevError, "Internal shop-mat problem.\n");
1428 } 1421 }
1429 else 1422 else
1430 { 1423 {
1431 remove_ob (op); 1424 op->remove ();
1432 op->x += freearr_x[i]; 1425 op->x += freearr_x[i];
1433 op->y += freearr_y[i]; 1426 op->y += freearr_y[i];
1434 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;
1435 } 1428 }
1436 } 1429 }
1795 1788
1796 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1789 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1797 { 1790 {
1798 /*exp_gain *= 2; because they just identified it too */ 1791 /*exp_gain *= 2; because they just identified it too */
1799 SET_FLAG (tmp, FLAG_IDENTIFIED); 1792 SET_FLAG (tmp, FLAG_IDENTIFIED);
1793
1800 /* If in a container, update how it looks */ 1794 /* If in a container, update how it looks */
1801 if (tmp->env) 1795 if (tmp->env)
1802 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1796 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1803 else 1797 else
1804 op->contr->socket.update_look = 1; 1798 op->contr->ns->floorbox_update ();
1805 } 1799 }
1800
1806 change_exp (op, exp_gain, skill_ob->skill, 0); 1801 change_exp (op, exp_gain, skill_ob->skill, 0);
1807 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 */
1808 } 1803 }
1809} 1804}
1810 1805
1859 } 1854 }
1860 return; 1855 return;
1861 } 1856 }
1862 1857
1863 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0); 1858 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0);
1864 tmp = get_object (); 1859 tmp = spell->clone ();
1865 copy_object (spell, tmp);
1866 insert_ob_in_ob (tmp, op); 1860 insert_ob_in_ob (tmp, op);
1867 1861
1868 if (special_prayer) 1862 if (special_prayer)
1869 {
1870 SET_FLAG (tmp, FLAG_STARTEQUIP); 1863 SET_FLAG (tmp, FLAG_STARTEQUIP);
1871 }
1872 1864
1873 esrv_add_spells (op->contr, tmp); 1865 esrv_add_spells (op->contr, tmp);
1874} 1866}
1875 1867
1876/** 1868/**
1893 } 1885 }
1894 1886
1895 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);
1896 player_unready_range_ob (op->contr, spob); 1888 player_unready_range_ob (op->contr, spob);
1897 esrv_remove_spell (op->contr, spob); 1889 esrv_remove_spell (op->contr, spob);
1898 remove_ob (spob); 1890 spob->destroy ();
1899 free_object (spob);
1900} 1891}
1901 1892
1902/** 1893/**
1903 * Handles player applying a spellbook. 1894 * Handles player applying a spellbook.
1904 * 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,
1942 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.");
1943 return; 1934 return;
1944 } 1935 }
1945 1936
1946 spell = tmp->inv; 1937 spell = tmp->inv;
1938
1947 if (!spell) 1939 if (!spell)
1948 { 1940 {
1949 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);
1950 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.");
1951 return; 1943 return;
1952 } 1944 }
1953 if (spell->level > (skop->level + 10)) 1945
1946 if (skop->level < int (sqrtf (spell->level) * 1.5f))
1954 { 1947 {
1955 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.");
1956 return; 1949 return;
1957 } 1950 }
1958 1951
1959 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);
1960 1953
1961 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1954 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1962 { 1955 {
1963 identify (tmp); 1956 identify (tmp);
1957
1964 if (tmp->env) 1958 if (tmp->env)
1965 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1959 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1966 else 1960 else
1967 op->contr->socket.update_look = 1; 1961 op->contr->ns->floorbox_update ();
1968 } 1962 }
1969 1963
1970 /* 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
1971 * 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
1972 * 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
2088 */ 2082 */
2089static void 2083static void
2090apply_treasure (object *op, object *tmp) 2084apply_treasure (object *op, object *tmp)
2091{ 2085{
2092 object *treas; 2086 object *treas;
2093 tag_t tmp_tag = tmp->count, op_tag = op->count;
2094 2087
2095 2088
2096 /* Nice side effect of new treasure creation method is that the treasure 2089 /* Nice side effect of new treasure creation method is that the treasure
2097 * for the chest is done when the chest is created, and put into the chest 2090 * for the chest is done when the chest is created, and put into the chest
2098 * inventory. So that when the chest burns up, the items still exist. Also 2091 * inventory. So that when the chest burns up, the items still exist. Also
2109 } 2102 }
2110 while (tmp->inv) 2103 while (tmp->inv)
2111 { 2104 {
2112 treas = tmp->inv; 2105 treas = tmp->inv;
2113 2106
2114 remove_ob (treas); 2107 treas->remove ();
2115 new_draw_info_format (NDI_UNIQUE, 0, op, "You find %s in the chest.", query_name (treas)); 2108 new_draw_info_format (NDI_UNIQUE, 0, op, "You find %s in the chest.", query_name (treas));
2116 2109
2117 treas->x = op->x; 2110 treas->x = op->x;
2118 treas->y = op->y; 2111 treas->y = op->y;
2119 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR); 2112 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR);
2120 2113
2121 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && QUERY_FLAG (op, FLAG_ALIVE)) 2114 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && QUERY_FLAG (op, FLAG_ALIVE))
2122 spring_trap (treas, op); 2115 spring_trap (treas, op);
2116
2123 /* If either player or container was destroyed, no need to do 2117 /* If either player or container was destroyed, no need to do
2124 * further processing. I think this should be enclused with 2118 * further processing. I think this should be enclused with
2125 * spring trap above, as I don't think there is otherwise 2119 * spring trap above, as I don't think there is otherwise
2126 * any way for the treasure chest or player to get killed 2120 * any way for the treasure chest or player to get killed
2127 */ 2121 */
2128 if (was_destroyed (op, op_tag) || was_destroyed (tmp, tmp_tag)) 2122 if (op->destroyed () || tmp->destroyed ())
2129 break; 2123 break;
2130 } 2124 }
2131 2125
2132 if (!was_destroyed (tmp, tmp_tag) && tmp->inv == NULL) 2126 if (!tmp->destroyed () && tmp->inv == NULL)
2133 decrease_ob (tmp); 2127 decrease_ob (tmp);
2134 2128
2135} 2129}
2136 2130
2137/** 2131/**
2332 2326
2333 if (i >= 0 && i < NROFATTACKS && skin->resist[i] < 95) 2327 if (i >= 0 && i < NROFATTACKS && skin->resist[i] < 95)
2334 { 2328 {
2335 /* resistance increased! */ 2329 /* resistance increased! */
2336 skin->resist[i]++; 2330 skin->resist[i]++;
2337 fix_player (op); 2331 op->update_stats ();
2338 2332
2339 sprintf (buf, "Your skin is now more resistant to %s!", change_resist_msg[i]); 2333 sprintf (buf, "Your skin is now more resistant to %s!", change_resist_msg[i]);
2340 new_draw_info (NDI_UNIQUE | NDI_RED, 0, op, buf); 2334 new_draw_info (NDI_UNIQUE | NDI_RED, 0, op, buf);
2341 } 2335 }
2342 2336
2361 } 2355 }
2362 } 2356 }
2363 return 1; 2357 return 1;
2364} 2358}
2365 2359
2366static void
2367apply_savebed (object *pl)
2368{
2369#ifndef COZY_SERVER
2370 if (!pl->contr->name_changed || !pl->stats.exp)
2371 {
2372 new_draw_info (NDI_UNIQUE, 0, pl, "You don't deserve to save your character yet.");
2373 return;
2374 }
2375#endif
2376 INVOKE_PLAYER (LOGOUT, pl->contr);
2377 /* Need to call terminate_all_pets() before we remove the player ob */
2378 terminate_all_pets (pl);
2379 remove_ob (pl);
2380 pl->direction = 0;
2381 new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, pl, "%s leaves the game.", &pl->name);
2382
2383 /* update respawn position */
2384 strcpy (pl->contr->savebed_map, pl->map->path);
2385 pl->contr->bed_x = pl->x;
2386 pl->contr->bed_y = pl->y;
2387
2388 strcpy (pl->contr->killer, "left");
2389 check_score (pl); /* Always check score */
2390 (void) save_player (pl, 0);
2391 pl->map->players--;
2392#if MAP_MAXTIMEOUT
2393 MAP_SWAP_TIME (pl->map) = MAP_TIMEOUT (pl->map);
2394#endif
2395 play_again (pl);
2396 pl->speed = 0;
2397 update_ob_speed (pl);
2398}
2399
2400/** 2360/**
2401 * Handles applying an improve armor scroll. 2361 * Handles applying an improve armor scroll.
2402 * Does some sanity checks, then calls improve_armour. 2362 * Does some sanity checks, then calls improve_armour.
2403 */ 2363 */
2404static void 2364static void
2409 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC)) 2369 if (!QUERY_FLAG (op, FLAG_WIZCAST) && (get_map_flags (op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_MAGIC))
2410 { 2370 {
2411 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the scroll."); 2371 new_draw_info (NDI_UNIQUE, 0, op, "Something blocks the magic of the scroll.");
2412 return; 2372 return;
2413 } 2373 }
2374
2414 armor = find_marked_object (op); 2375 armor = find_marked_object (op);
2376
2415 if (!armor) 2377 if (!armor)
2416 { 2378 {
2417 new_draw_info (NDI_UNIQUE, 0, op, "You need to mark an armor object."); 2379 new_draw_info (NDI_UNIQUE, 0, op, "You need to mark an armor object.");
2418 return; 2380 return;
2419 } 2381 }
2382
2420 if (armor->type != ARMOUR 2383 if (armor->type != ARMOUR
2421 && armor->type != CLOAK 2384 && armor->type != CLOAK
2422 && armor->type != BOOTS && armor->type != GLOVES && armor->type != BRACERS && armor->type != SHIELD && armor->type != HELMET) 2385 && armor->type != BOOTS && armor->type != GLOVES && armor->type != BRACERS && armor->type != SHIELD && armor->type != HELMET)
2423 { 2386 {
2424 new_draw_info (NDI_UNIQUE, 0, op, "Your marked item is not armour!\n"); 2387 new_draw_info (NDI_UNIQUE, 0, op, "Your marked item is not armour!\n");
2426 } 2389 }
2427 2390
2428 new_draw_info (NDI_UNIQUE, 0, op, "Applying armour enchantment."); 2391 new_draw_info (NDI_UNIQUE, 0, op, "Applying armour enchantment.");
2429 improve_armour (op, tmp, armor); 2392 improve_armour (op, tmp, armor);
2430} 2393}
2431
2432 2394
2433extern void 2395extern void
2434apply_poison (object *op, object *tmp) 2396apply_poison (object *op, object *tmp)
2435{ 2397{
2436 if (op->type == PLAYER) 2398 if (op->type == PLAYER)
2452/** 2414/**
2453 * This fonction return true if the exit is not a 2 ways one or it is 2 ways, valid exit. 2415 * This fonction return true if the exit is not a 2 ways one or it is 2 ways, valid exit.
2454 * A valid 2 way exit means: 2416 * A valid 2 way exit means:
2455 * -You can come back (there is another exit at the other side) 2417 * -You can come back (there is another exit at the other side)
2456 * -You are 2418 * -You are
2457 * ° the owner of the exit 2419 * ° the owner of the exit
2458 * ° or in the same party as the owner 2420 * ° or in the same party as the owner
2459 * 2421 *
2460 * Note: a owner in a 2 way exit is saved as the owner's name 2422 * Note: a owner in a 2 way exit is saved as the owner's name
2461 * in the field exit->name cause the field exit->owner doesn't 2423 * in the field exit->name cause the field exit->owner doesn't
2462 * survive in the swapping (in fact the whole exit doesn't survive). 2424 * survive in the swapping (in fact the whole exit doesn't survive).
2463 */ 2425 */
2465is_legal_2ways_exit (object *op, object *exit) 2427is_legal_2ways_exit (object *op, object *exit)
2466{ 2428{
2467 object *tmp; 2429 object *tmp;
2468 object *exit_owner; 2430 object *exit_owner;
2469 player *pp; 2431 player *pp;
2470 mapstruct *exitmap; 2432 maptile *exitmap;
2471 2433
2472 if (exit->stats.exp != 1) 2434 if (exit->stats.exp != 1)
2473 return 1; /*This is not a 2 way, so it is legal */ 2435 return 1; /*This is not a 2 way, so it is legal */
2474 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race) 2436 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race)
2475 return 0; /* This is a reset town portal */ 2437 return 0; /* This is a reset town portal */
2480 exitmap = ready_map_name (EXIT_PATH (exit), MAP_PLAYER_UNIQUE); 2442 exitmap = ready_map_name (EXIT_PATH (exit), MAP_PLAYER_UNIQUE);
2481 else 2443 else
2482 exitmap = ready_map_name (EXIT_PATH (exit), 0); 2444 exitmap = ready_map_name (EXIT_PATH (exit), 0);
2483 if (exitmap) 2445 if (exitmap)
2484 { 2446 {
2485 tmp = get_map_ob (exitmap, EXIT_X (exit), EXIT_Y (exit)); 2447 tmp = GET_MAP_OB (exitmap, EXIT_X (exit), EXIT_Y (exit));
2486 if (!tmp) 2448 if (!tmp)
2487 return 0; 2449 return 0;
2488 for ((tmp = get_map_ob (exitmap, EXIT_X (exit), EXIT_Y (exit))); tmp; tmp = tmp->above) 2450 for ((tmp = GET_MAP_OB (exitmap, EXIT_X (exit), EXIT_Y (exit))); tmp; tmp = tmp->above)
2489 { 2451 {
2490 if (tmp->type != EXIT) 2452 if (tmp->type != EXIT)
2491 continue; /*Not an exit */ 2453 continue; /*Not an exit */
2492 if (!EXIT_PATH (tmp)) 2454 if (!EXIT_PATH (tmp))
2493 continue; /*Not a valid exit */ 2455 continue; /*Not a valid exit */
2557 { 2519 {
2558 new_draw_info (NDI_UNIQUE, 0, op, "You should pay for it first."); 2520 new_draw_info (NDI_UNIQUE, 0, op, "You should pay for it first.");
2559 return 1; 2521 return 1;
2560 } 2522 }
2561 else 2523 else
2562 {
2563 return 0; /* monsters just skip unpaid items */ 2524 return 0; /* monsters just skip unpaid items */
2564 }
2565 } 2525 }
2566 2526
2567 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op))) 2527 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op)))
2568 return RESULT_INT (0); 2528 return RESULT_INT (0);
2569 2529
2570 switch (tmp->type) 2530 switch (tmp->type)
2571 { 2531 {
2572
2573 case CF_HANDLE: 2532 case CF_HANDLE:
2574 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle."); 2533 new_draw_info (NDI_UNIQUE, 0, op, "You turn the handle.");
2575 play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE); 2534 play_sound_map (op->map, op->x, op->y, SOUND_TURN_HANDLE);
2576 tmp->value = tmp->value ? 0 : 1; 2535 tmp->value = tmp->value ? 0 : 1;
2577 SET_ANIMATION (tmp, tmp->value); 2536 SET_ANIMATION (tmp, tmp->value);
2705 case POISON: 2664 case POISON:
2706 apply_poison (op, tmp); 2665 apply_poison (op, tmp);
2707 return 1; 2666 return 1;
2708 2667
2709 case SAVEBED: 2668 case SAVEBED:
2710 if (op->type == PLAYER)
2711 {
2712 apply_savebed (op);
2713 return 1; 2669 return 1;
2714 }
2715 else
2716 {
2717 return 0;
2718 }
2719 2670
2720 case ARMOUR_IMPROVER: 2671 case ARMOUR_IMPROVER:
2721 if (op->type == PLAYER) 2672 if (op->type == PLAYER)
2722 { 2673 {
2723 apply_armour_improver (op, tmp); 2674 apply_armour_improver (op, tmp);
2724 return 1; 2675 return 1;
2725 } 2676 }
2726 else 2677 else
2727 {
2728 return 0; 2678 return 0;
2729 }
2730 2679
2731 case WEAPON_IMPROVER: 2680 case WEAPON_IMPROVER:
2732 (void) check_improve_weapon (op, tmp); 2681 (void) check_improve_weapon (op, tmp);
2733 return 1; 2682 return 1;
2734 2683
2814 if (op->type != PLAYER && QUERY_FLAG (op, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ)) 2763 if (op->type != PLAYER && QUERY_FLAG (op, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ))
2815 { 2764 {
2816 play_sound_map (pl->map, pl->x, pl->y, SOUND_OB_EVAPORATE); 2765 play_sound_map (pl->map, pl->x, pl->y, SOUND_OB_EVAPORATE);
2817 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff " "of smoke!"); 2766 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff " "of smoke!");
2818 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion."); 2767 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion.");
2819 remove_ob (op); 2768 op->destroy ();
2820 free_object (op);
2821 return 1; 2769 return 1;
2822 } 2770 }
2823 2771
2824 pl->contr->last_used = op; 2772 pl->contr->last_used = op;
2825 pl->contr->last_used_id = op->count;
2826 2773
2827 tmp = manual_apply (pl, op, aflag); 2774 tmp = manual_apply (pl, op, aflag);
2828 if (!quiet) 2775 if (!quiet)
2829 { 2776 {
2830 if (tmp == 0) 2777 if (tmp == 0)
2952 tmp2->map = op->map; 2899 tmp2->map = op->map;
2953 tmp2->below = op->below; 2900 tmp2->below = op->below;
2954 tmp2->above = op->above; 2901 tmp2->above = op->above;
2955 tmp2->stats.food = op->stats.food; 2902 tmp2->stats.food = op->stats.food;
2956 CLEAR_FLAG (tmp2, FLAG_APPLIED); 2903 CLEAR_FLAG (tmp2, FLAG_APPLIED);
2904
2957 if (QUERY_FLAG (op, FLAG_INV_LOCKED)) 2905 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
2958 SET_FLAG (tmp2, FLAG_INV_LOCKED); 2906 SET_FLAG (tmp2, FLAG_INV_LOCKED);
2907
2959 if (who->type == PLAYER) 2908 if (who->type == PLAYER)
2960 esrv_del_item (who->contr, (tag_t) op->count); 2909 esrv_del_item (who->contr, op->count);
2961 remove_ob (op); 2910
2962 free_object (op); 2911 op->destroy ();
2963 insert_ob_in_ob (tmp2, who); 2912 insert_ob_in_ob (tmp2, who);
2964 fix_player (who); 2913 who->update_stats ();
2965 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 2914 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2966 { 2915 {
2967 if (who->type == PLAYER) 2916 if (who->type == PLAYER)
2968 { 2917 {
2969 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); 2918 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
3002 default: 2951 default:
3003 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op)); 2952 new_draw_info_format (NDI_UNIQUE, 0, who, "You unapply %s.", query_name (op));
3004 break; 2953 break;
3005 } 2954 }
3006 2955
3007 fix_player (who); 2956 who->update_stats ();
3008 2957
3009 if (!(aflags & AP_NO_MERGE)) 2958 if (!(aflags & AP_NO_MERGE))
3010 { 2959 {
3011 object *tmp; 2960 object *tmp;
3012
3013 tag_t del_tag = op->count;
3014 2961
3015 tmp = merge_ob (op, NULL); 2962 tmp = merge_ob (op, NULL);
3016 if (who->type == PLAYER) 2963 if (who->type == PLAYER)
3017 { 2964 {
3018 if (tmp) 2965 if (tmp)
3019 { /* it was merged */ 2966 { /* it was merged */
3020 esrv_del_item (who->contr, del_tag); 2967 esrv_del_item (who->contr, op->count);
3021 op = tmp; 2968 op = tmp;
3022 } 2969 }
2970
3023 esrv_send_item (who, op); 2971 esrv_send_item (who, op);
3024 } 2972 }
3025 } 2973 }
3026 return 0; 2974 return 0;
3027} 2975}
3491 SET_FLAG (tmp2, FLAG_INV_LOCKED); 3439 SET_FLAG (tmp2, FLAG_INV_LOCKED);
3492 insert_ob_in_ob (tmp2, who); 3440 insert_ob_in_ob (tmp2, who);
3493 3441
3494 /* Remove the old lantern */ 3442 /* Remove the old lantern */
3495 if (who->type == PLAYER) 3443 if (who->type == PLAYER)
3496 esrv_del_item (who->contr, (tag_t) op->count); 3444 esrv_del_item (who->contr, op->count);
3497 remove_ob (op); 3445
3498 free_object (op); 3446 op->destroy ();
3499 3447
3500 /* insert the portion that was split off */ 3448 /* insert the portion that was split off */
3501 if (tmp != NULL) 3449 if (tmp != NULL)
3502 { 3450 {
3503 (void) insert_ob_in_ob (tmp, who); 3451 (void) insert_ob_in_ob (tmp, who);
3504 if (who->type == PLAYER) 3452 if (who->type == PLAYER)
3505 esrv_send_item (who, tmp); 3453 esrv_send_item (who, tmp);
3506 } 3454 }
3507 fix_player (who); 3455 who->update_stats ();
3508 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 3456 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
3509 { 3457 {
3510 if (who->type == PLAYER) 3458 if (who->type == PLAYER)
3511 { 3459 {
3512 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!"); 3460 new_draw_info (NDI_UNIQUE, 0, who, "Oops, it feels deadly cold!");
3609 SET_FLAG (op, FLAG_APPLIED); 3557 SET_FLAG (op, FLAG_APPLIED);
3610 3558
3611 if (tmp != NULL) 3559 if (tmp != NULL)
3612 tmp = insert_ob_in_ob (tmp, who); 3560 tmp = insert_ob_in_ob (tmp, who);
3613 3561
3614 fix_player (who); 3562 who->update_stats ();
3615 3563
3616 /* We exclude spell casting objects. The fire code will set the 3564 /* We exclude spell casting objects. The fire code will set the
3617 * been applied flag when they are used - until that point, 3565 * been applied flag when they are used - until that point,
3618 * you don't know anything about them. 3566 * you don't know anything about them.
3619 */ 3567 */
3659 int i; 3607 int i;
3660 3608
3661 switch (op->type) 3609 switch (op->type)
3662 { 3610 {
3663 case SHOP_FLOOR: 3611 case SHOP_FLOOR:
3664 if (!HAS_RANDOM_ITEMS (op)) 3612 if (!op->has_random_items ())
3665 return 0; 3613 return 0;
3614
3666 do 3615 do
3667 { 3616 {
3668 i = 10; /* let's give it 10 tries */ 3617 i = 10; /* let's give it 10 tries */
3669 while ((tmp = generate_treasure (op->randomitems, 3618 while ((tmp = generate_treasure (op->randomitems,
3670 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i); 3619 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i);
3671 if (tmp == NULL) 3620 if (tmp == NULL)
3672 return 0; 3621 return 0;
3673 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 3622 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
3674 { 3623 {
3675 free_object (tmp); 3624 tmp->destroy ();
3676 tmp = NULL; 3625 tmp = NULL;
3677 } 3626 }
3678 } 3627 }
3679 while (!tmp); 3628 while (!tmp);
3629
3680 tmp->x = op->x; 3630 tmp->x = op->x;
3681 tmp->y = op->y; 3631 tmp->y = op->y;
3682 SET_FLAG (tmp, FLAG_UNPAID); 3632 SET_FLAG (tmp, FLAG_UNPAID);
3683 insert_ob_in_map (tmp, op->map, NULL, 0); 3633 insert_ob_in_map (tmp, op->map, NULL, 0);
3684 CLEAR_FLAG (op, FLAG_AUTO_APPLY); 3634 CLEAR_FLAG (op, FLAG_AUTO_APPLY);
3686 break; 3636 break;
3687 3637
3688 case TREASURE: 3638 case TREASURE:
3689 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 3639 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
3690 return 0; 3640 return 0;
3641
3691 while ((op->stats.hp--) > 0) 3642 while ((op->stats.hp--) > 0)
3692 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0, 3643 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0,
3693 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0); 3644 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3694 3645
3695 /* If we generated an object and put it in this object inventory, 3646 /* If we generated an object and put it in this object inventory,
3698 * that is put inside other objects. 3649 * that is put inside other objects.
3699 */ 3650 */
3700 for (tmp = op->inv; tmp; tmp = tmp2) 3651 for (tmp = op->inv; tmp; tmp = tmp2)
3701 { 3652 {
3702 tmp2 = tmp->below; 3653 tmp2 = tmp->below;
3703 remove_ob (tmp); 3654 tmp->remove ();
3655
3704 if (op->env) 3656 if (op->env)
3705 insert_ob_in_ob (tmp, op->env); 3657 insert_ob_in_ob (tmp, op->env);
3706 else 3658 else
3707 free_object (tmp); 3659 tmp->destroy ();
3708 } 3660 }
3709 remove_ob (op); 3661
3710 free_object (op); 3662 op->destroy ();
3711 break; 3663 break;
3712 } 3664 }
3713 return tmp ? 1 : 0; 3665 return tmp ? 1 : 0;
3714} 3666}
3715 3667
3718 * when an original map is loaded) and performs special actions for 3670 * when an original map is loaded) and performs special actions for
3719 * certain objects (most initialization of chests and creation of 3671 * certain objects (most initialization of chests and creation of
3720 * treasures and stuff). Calls auto_apply if appropriate. 3672 * treasures and stuff). Calls auto_apply if appropriate.
3721 */ 3673 */
3722void 3674void
3723fix_auto_apply (mapstruct *m) 3675fix_auto_apply (maptile *m)
3724{ 3676{
3725 object *tmp, *above = NULL; 3677 object *tmp, *above = NULL;
3726 int x, y; 3678 int x, y;
3727 3679
3728 if (m == NULL) 3680 if (m == NULL)
3729 return; 3681 return;
3730 3682
3731 for (x = 0; x < MAP_WIDTH (m); x++) 3683 for (x = 0; x < MAP_WIDTH (m); x++)
3732 for (y = 0; y < MAP_HEIGHT (m); y++) 3684 for (y = 0; y < MAP_HEIGHT (m); y++)
3733 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = above) 3685 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = above)
3734 { 3686 {
3735 above = tmp->above; 3687 above = tmp->above;
3736 3688
3737 if (tmp->inv) 3689 if (tmp->inv)
3738 { 3690 {
3742 { 3694 {
3743 invnext = invtmp->below; 3695 invnext = invtmp->below;
3744 3696
3745 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY)) 3697 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY))
3746 auto_apply (invtmp); 3698 auto_apply (invtmp);
3747 else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS (invtmp)) 3699 else if (invtmp->type == TREASURE && invtmp->has_random_items ())
3748 { 3700 {
3749 while ((invtmp->stats.hp--) > 0) 3701 while ((invtmp->stats.hp--) > 0)
3750 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3702 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3751 3703
3752 invtmp->randomitems = NULL; 3704 invtmp->randomitems = NULL;
3753 } 3705 }
3754 else if (invtmp && invtmp->arch 3706 else if (invtmp && invtmp->arch
3755 && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS && HAS_RANDOM_ITEMS (invtmp)) 3707 && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS && invtmp->has_random_items ())
3756 { 3708 {
3757 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3709 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3758 /* Need to clear this so that we never try to create 3710 /* Need to clear this so that we never try to create
3759 * treasure again for this object 3711 * treasure again for this object
3760 */ 3712 */
3777 3729
3778 } 3730 }
3779 3731
3780 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY)) 3732 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY))
3781 auto_apply (tmp); 3733 auto_apply (tmp);
3782 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && HAS_RANDOM_ITEMS (tmp)) 3734 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && tmp->has_random_items ())
3783 { 3735 {
3784 while ((tmp->stats.hp--) > 0) 3736 while ((tmp->stats.hp--) > 0)
3785 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0); 3737 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0);
3786 tmp->randomitems = NULL; 3738 tmp->randomitems = NULL;
3787 } 3739 }
3802 * This is a problem for the above objects, because they have counters 3754 * This is a problem for the above objects, because they have counters
3803 * which say how many times to make the treasure. 3755 * which say how many times to make the treasure.
3804 */ 3756 */
3805 else if (tmp && tmp->arch && tmp->type != PLAYER 3757 else if (tmp && tmp->arch && tmp->type != PLAYER
3806 && tmp->type != TREASURE && tmp->type != SPELL 3758 && tmp->type != TREASURE && tmp->type != SPELL
3807 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && HAS_RANDOM_ITEMS (tmp)) 3759 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && tmp->has_random_items ())
3808 { 3760 {
3809 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0); 3761 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0);
3810 tmp->randomitems = NULL; 3762 tmp->randomitems = NULL;
3811 } 3763 }
3812 } 3764 }
3813 3765
3814 for (x = 0; x < MAP_WIDTH (m); x++) 3766 for (x = 0; x < MAP_WIDTH (m); x++)
3815 for (y = 0; y < MAP_HEIGHT (m); y++) 3767 for (y = 0; y < MAP_HEIGHT (m); y++)
3816 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above) 3768 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above)
3817 if (tmp->above && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL)) 3769 if (tmp->above && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
3818 check_trigger (tmp, tmp->above); 3770 check_trigger (tmp, tmp->above);
3819} 3771}
3820 3772
3821/** 3773/**
3851 { 3803 {
3852 force->resist[i] = food->resist[i] / 2; 3804 force->resist[i] = food->resist[i] / 2;
3853 did_one = 1; 3805 did_one = 1;
3854 } 3806 }
3855 } 3807 }
3808
3856 if (did_one) 3809 if (did_one)
3857 { 3810 {
3858 force->speed = 0.1; 3811 force->speed = 0.1;
3859 update_ob_speed (force); 3812 update_ob_speed (force);
3860 /* bigger morsel of food = longer effect time */ 3813 /* bigger morsel of food = longer effect time */
3861 force->stats.food = food->stats.food / 5; 3814 force->duration = food->stats.food / 5;
3862 SET_FLAG (force, FLAG_IS_USED_UP);
3863 SET_FLAG (force, FLAG_APPLIED); 3815 SET_FLAG (force, FLAG_APPLIED);
3864 change_abil (who, force); 3816 change_abil (who, force);
3865 insert_ob_in_ob (force, who); 3817 insert_ob_in_ob (force, who);
3866 } 3818 }
3867 else 3819 else
3868 { 3820 force->destroy ();
3869 free_object (force);
3870 }
3871 3821
3872 /* check for hp, sp change */ 3822 /* check for hp, sp change */
3873 if (food->stats.hp != 0) 3823 if (food->stats.hp != 0)
3874 { 3824 {
3875 if (QUERY_FLAG (food, FLAG_CURSED)) 3825 if (QUERY_FLAG (food, FLAG_CURSED))
3901 new_draw_info (NDI_UNIQUE, 0, who, "You feel a rush of magical energy!"); 3851 new_draw_info (NDI_UNIQUE, 0, who, "You feel a rush of magical energy!");
3902 who->stats.sp += food->stats.sp; 3852 who->stats.sp += food->stats.sp;
3903 /* place limit on max sp from food? */ 3853 /* place limit on max sp from food? */
3904 } 3854 }
3905 } 3855 }
3906 fix_player (who); 3856 who->update_stats ();
3907} 3857}
3908
3909 3858
3910/** 3859/**
3911 * Designed primarily to light torches/lanterns/etc. 3860 * Designed primarily to light torches/lanterns/etc.
3912 * Also burns up burnable material too. First object in the inventory is 3861 * Also burns up burnable material too. First object in the inventory is
3913 * the selected object to "burn". -b.t. 3862 * the selected object to "burn". -b.t.
3914 */ 3863 */
3915
3916void 3864void
3917apply_lighter (object *who, object *lighter) 3865apply_lighter (object *who, object *lighter)
3918{ 3866{
3919 object *item; 3867 object *item;
3920 int is_player_env = 0; 3868 int is_player_env = 0;
3921 uint32 nrof;
3922 tag_t count;
3923 char item_name[MAX_BUF];
3924 3869
3925 item = find_marked_object (who); 3870 item = find_marked_object (who);
3926 if (item) 3871 if (item)
3927 { 3872 {
3928 if (lighter->last_eat && lighter->stats.food) 3873 if (lighter->last_eat && lighter->stats.food)
3929 { /* lighter gets used up */ 3874 { /* lighter gets used up */
3930 /* Split multiple lighters if they're being used up. Otherwise * 3875 /* Split multiple lighters if they're being used up. Otherwise *
3931 * one charge from each would be used up. --DAMN */ 3876 * one charge from each would be used up. --DAMN */
3932 if (lighter->nrof > 1) 3877 if (lighter->nrof > 1)
3933 { 3878 {
3934 object *oneLighter = get_object (); 3879 object *oneLighter = lighter->clone ();
3935 3880
3936 copy_object (lighter, oneLighter);
3937 lighter->nrof -= 1; 3881 lighter->nrof -= 1;
3938 oneLighter->nrof = 1; 3882 oneLighter->nrof = 1;
3939 oneLighter->stats.food--; 3883 oneLighter->stats.food--;
3940 esrv_send_item (who, lighter); 3884 esrv_send_item (who, lighter);
3941 oneLighter = insert_ob_in_ob (oneLighter, who); 3885 oneLighter = insert_ob_in_ob (oneLighter, who);
3942 esrv_send_item (who, oneLighter); 3886 esrv_send_item (who, oneLighter);
3943 } 3887 }
3944 else 3888 else
3945 {
3946 lighter->stats.food--; 3889 lighter->stats.food--;
3947 }
3948
3949 } 3890 }
3950 else if (lighter->last_eat) 3891 else if (lighter->last_eat)
3951 { /* no charges left in lighter */ 3892 { /* no charges left in lighter */
3952 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with a used up %s.", &item->name, &lighter->name); 3893 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with a used up %s.", &item->name, &lighter->name);
3953 return; 3894 return;
3954 } 3895 }
3896
3955 /* Perhaps we should split what we are trying to light on fire? 3897 /* Perhaps we should split what we are trying to light on fire?
3956 * I can't see many times when you would want to light multiple 3898 * I can't see many times when you would want to light multiple
3957 * objects at once. 3899 * objects at once.
3958 */ 3900 */
3959 nrof = item->nrof; 3901
3960 count = item->count;
3961 /* If the item is destroyed, we don't have a valid pointer to the
3962 * name object, so make a copy so the message we print out makes
3963 * some sense.
3964 */
3965 strcpy (item_name, item->name);
3966 if (who == is_player_inv (item)) 3902 if (who == item->in_player ())
3967 is_player_env = 1; 3903 is_player_env = 1;
3968 3904
3969 save_throw_object (item, AT_FIRE, who); 3905 save_throw_object (item, AT_FIRE, who);
3970 /* Change to check count and not freed, since the object pointer 3906
3971 * may have gotten recycled 3907 if (item->destroyed ())
3972 */ 3908 {
3973 if ((nrof != item->nrof) || (count != item->count))
3974 {
3975 new_draw_info_format (NDI_UNIQUE, 0, who, "You light the %s with the %s.", &item_name, &lighter->name); 3909 new_draw_info_format (NDI_UNIQUE, 0, who, "You light the %s with the %s.", &item->name, &lighter->name);
3976 /* Need to update the player so that the players glow radius 3910 /* Need to update the player so that the players glow radius
3977 * gets changed. 3911 * gets changed.
3978 */ 3912 */
3979 if (is_player_env) 3913 if (is_player_env)
3980 fix_player (who); 3914 who->update_stats ();
3981 } 3915 }
3982 else 3916 else
3983 {
3984 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with the %s and fail.", &item->name, &lighter->name); 3917 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with the %s and fail.", &item->name, &lighter->name);
3985 }
3986
3987 } 3918 }
3988 else /* nothing to light */ 3919 else /* nothing to light */
3989 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object."); 3920 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object.");
3990 3921
3991} 3922}
4005 object *tmp; 3936 object *tmp;
4006 3937
4007 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!."); 3938 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!.");
4008 tmp = get_archetype (SPELL_WONDER); 3939 tmp = get_archetype (SPELL_WONDER);
4009 cast_wonder (op, op, 0, tmp); 3940 cast_wonder (op, op, 0, tmp);
4010 free_object (tmp); 3941 tmp->destroy ();
4011 } 3942 }
4012 else if (failure <= -15 && failure > -35) 3943 else if (failure <= -15 && failure > -35)
4013 { /* drain mana */ 3944 { /* drain mana */
4014 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!."); 3945 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!.");
4015 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW); 3946 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW);
4038 object *tmp; 3969 object *tmp;
4039 3970
4040 tmp = get_archetype (LOOSE_MANA); 3971 tmp = get_archetype (LOOSE_MANA);
4041 cast_magic_storm (op, tmp, power); 3972 cast_magic_storm (op, tmp, power);
4042 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!"); 3973 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!");
4043 free_object (tmp); 3974 tmp->destroy ();
4044 } 3975 }
4045 } 3976 }
4046} 3977}
4047 3978
4048void 3979void
4211 if (!new_item) 4142 if (!new_item)
4212 { 4143 {
4213 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0)); 4144 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0));
4214 return; 4145 return;
4215 } 4146 }
4147
4216 new_item->nrof = yield; 4148 new_item->nrof = yield;
4217 new_draw_info_format (NDI_UNIQUE, 0, pl, "You %s the %s.", &transformer->slaying, query_base_name (marked, 0)); 4149 new_draw_info_format (NDI_UNIQUE, 0, pl, "You %s the %s.", &transformer->slaying, query_base_name (marked, 0));
4218 insert_ob_in_ob (new_item, pl); 4150 insert_ob_in_ob (new_item, pl);
4219 esrv_send_inventory (pl, pl); 4151 esrv_send_inventory (pl, pl);
4220 /* Eat up one item */ 4152 /* Eat up one item */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines