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.27 by root, Thu Sep 14 21:16:12 2006 UTC vs.
Revision 1.43 by root, Tue Dec 19 05:12:52 2006 UTC

1
2/*
3 * static char *rcsid_apply_c =
4 * "$Id: apply.C,v 1.27 2006/09/14 21:16:12 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The authors can be reached via e-mail to crossfire-devel@real-time.com 21 The authors can be reached via e-mail to <crossfire@schmorp.de>
28*/ 22*/
29 23
30#include <global.h> 24#include <global.h>
31#include <living.h> 25#include <living.h>
32#include <spells.h> 26#include <spells.h>
212 CLEAR_FLAG (tmp, FLAG_APPLIED); 206 CLEAR_FLAG (tmp, FLAG_APPLIED);
213 return 0; 207 return 0;
214 } 208 }
215 209
216 if (op->type == PLAYER) 210 if (op->type == PLAYER)
217 {
218 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 211 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
219 identify (tmp); 212 identify (tmp);
220 }
221 213
222 handle_apply_yield (tmp); 214 handle_apply_yield (tmp);
223 215
224 /* Potion of restoration - only for players */ 216 /* Potion of restoration - only for players */
225 if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE)) 217 if (op->type == PLAYER && (tmp->attacktype & AT_DEPLETE))
232 drain_stat (op); 224 drain_stat (op);
233 fix_player (op); 225 fix_player (op);
234 decrease_ob (tmp); 226 decrease_ob (tmp);
235 return 1; 227 return 1;
236 } 228 }
229
237 if ((at = archetype::find (ARCH_DEPLETION)) == NULL) 230 if ((at = archetype::find (ARCH_DEPLETION)) == NULL)
238 { 231 {
239 LOG (llevError, "Could not find archetype depletion\n"); 232 LOG (llevError, "Could not find archetype depletion\n");
240 return 0; 233 return 0;
241 } 234 }
242 depl = present_arch_in_ob (at, op); 235 depl = present_arch_in_ob (at, op);
236
243 if (depl != NULL) 237 if (depl != NULL)
244 { 238 {
245 for (i = 0; i < NUM_STATS; i++) 239 for (i = 0; i < NUM_STATS; i++)
246 if (get_attr_value (&depl->stats, i)) 240 if (get_attr_value (&depl->stats, i))
247 {
248 new_draw_info (NDI_UNIQUE, 0, op, restore_msg[i]); 241 new_draw_info (NDI_UNIQUE, 0, op, restore_msg[i]);
249 } 242
250 remove_ob (depl); 243 depl->destroy ();
251 free_object (depl);
252 fix_player (op); 244 fix_player (op);
253 } 245 }
254 else 246 else
255 new_draw_info (NDI_UNIQUE, 0, op, "You potion had no effect."); 247 new_draw_info (NDI_UNIQUE, 0, op, "You potion had no effect.");
256 248
259 } 251 }
260 252
261 /* improvement potion - only for players */ 253 /* improvement potion - only for players */
262 if (op->type == PLAYER && tmp->attacktype & AT_GODPOWER) 254 if (op->type == PLAYER && tmp->attacktype & AT_GODPOWER)
263 { 255 {
264
265 for (i = 1; i < MIN (11, op->level); i++) 256 for (i = 1; i < MIN (11, op->level); i++)
266 { 257 {
267 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 258 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
268 { 259 {
269 if (op->contr->levhp[i] != 1) 260 if (op->contr->levhp[i] != 1)
299 op->contr->levgrace[i] = 3; 290 op->contr->levgrace[i] = 3;
300 break; 291 break;
301 } 292 }
302 } 293 }
303 } 294 }
295
304 /* Just makes checking easier */ 296 /* Just makes checking easier */
305 if (i < MIN (11, op->level)) 297 if (i < MIN (11, op->level))
306 got_one = 1; 298 got_one = 1;
299
307 if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED)) 300 if (!QUERY_FLAG (tmp, FLAG_CURSED) && !QUERY_FLAG (tmp, FLAG_DAMNED))
308 { 301 {
309 if (got_one) 302 if (got_one)
310 { 303 {
311 fix_player (op); 304 fix_player (op);
324 new_draw_info (NDI_UNIQUE, 0, op, "The Gods are angry and punish you."); 317 new_draw_info (NDI_UNIQUE, 0, op, "The Gods are angry and punish you.");
325 } 318 }
326 else 319 else
327 new_draw_info (NDI_UNIQUE, 0, op, "You are fortunate that you are so pathetic."); 320 new_draw_info (NDI_UNIQUE, 0, op, "You are fortunate that you are so pathetic.");
328 } 321 }
322
329 decrease_ob (tmp); 323 decrease_ob (tmp);
330 return 1; 324 return 1;
331 } 325 }
332 326
333 327
958 price_in = nr * CONV_NEED (converter) * item->value; 952 price_in = nr * CONV_NEED (converter) * item->value;
959 } 953 }
960 else 954 else
961 { 955 {
962 price_in = item->value; 956 price_in = item->value;
963 remove_ob (item); 957 item->destroy ();
964 free_object (item);
965 } 958 }
966 } 959 }
967 960
968 if (converter->inv != NULL) 961 if (converter->inv != NULL)
969 { 962 {
1033 if (op->type != PLAYER) 1026 if (op->type != PLAYER)
1034 return 0; /* This might change */ 1027 return 0; /* This might change */
1035 1028
1036 if (sack == NULL || sack->type != CONTAINER) 1029 if (sack == NULL || sack->type != CONTAINER)
1037 { 1030 {
1038 LOG (llevError, "apply_container: %s is not container!\n", &sack->name); 1031 LOG (llevError, "apply_container: %s is not container!\n", sack ? &sack->name : "[nullobject]");
1039 return 0; 1032 return 0;
1040 } 1033 }
1041 op->contr->last_used = NULL; 1034
1042 op->contr->last_used_id = 0; 1035 op->contr->last_used = 0;
1043 1036
1044 if (sack->env != op) 1037 if (sack->env != op)
1045 { 1038 {
1046 if (sack->other_arch == NULL || sack->env != NULL) 1039 if (sack->other_arch == NULL || sack->env != NULL)
1047 { 1040 {
1048 new_draw_info (NDI_UNIQUE, 0, op, "You must get it first."); 1041 new_draw_info (NDI_UNIQUE, 0, op, "You must get it first.");
1049 return 1; 1042 return 1;
1050 } 1043 }
1044
1051 /* It's on the ground, the problems begin */ 1045 /* It's on the ground, the problems begin */
1052 if (op->container != sack) 1046 if (op->container != sack)
1053 { 1047 {
1054 /* it's closed OR some player has opened it */ 1048 /* it's closed OR some player has opened it */
1055 if (QUERY_FLAG (sack, FLAG_APPLIED)) 1049 if (QUERY_FLAG (sack, FLAG_APPLIED))
1082 } 1076 }
1083 else 1077 else
1084 { 1078 {
1085 sack->move_off = 0; 1079 sack->move_off = 0;
1086 tmp = sack->inv; 1080 tmp = sack->inv;
1081
1087 if (tmp && tmp->type == CLOSE_CON) 1082 if (tmp && tmp->type == CLOSE_CON)
1088 { 1083 tmp->destroy ();
1089 remove_ob (tmp);
1090 free_object (tmp);
1091 }
1092 } 1084 }
1093 } 1085 }
1094 } 1086 }
1095 1087
1096 if (QUERY_FLAG (sack, FLAG_APPLIED)) 1088 if (QUERY_FLAG (sack, FLAG_APPLIED))
1152 apply_container (op, sack); 1144 apply_container (op, sack);
1153 return 1; 1145 return 1;
1154 } 1146 }
1155 } 1147 }
1156 } 1148 }
1149
1157 new_draw_info (NDI_UNIQUE, 0, op, buf); 1150 new_draw_info (NDI_UNIQUE, 0, op, buf);
1151
1158 if (op->contr) 1152 if (op->contr)
1159 op->contr->socket.update_look = 1; 1153 op->contr->socket->floorbox_update ();
1154
1160 return 1; 1155 return 1;
1161} 1156}
1162 1157
1163/** 1158/**
1164 * Eneq(@csd.uu.se): Handle apply on containers. This is for containers 1159 * Eneq(@csd.uu.se): Handle apply on containers. This is for containers
1182 if (op->type != PLAYER) 1177 if (op->type != PLAYER)
1183 return 0; /* This might change */ 1178 return 0; /* This might change */
1184 1179
1185 if (sack == NULL || sack->type != CONTAINER) 1180 if (sack == NULL || sack->type != CONTAINER)
1186 { 1181 {
1187 LOG (llevError, "esrv_apply_container: %s is not container!\n", &sack->name); 1182 LOG (llevError, "esrv_apply_container: %s is not container!\n", sack ? &sack->name : "[nullobject]");
1188 return 0; 1183 return 0;
1189 } 1184 }
1190 1185
1191 /* If we have a currently open container, then it needs to be closed in all cases 1186 /* If we have a currently open container, then it needs to be closed in all cases
1192 * if we are opening this one up. We then fall through if appropriate for 1187 * if we are opening this one up. We then fall through if appropriate for
1352 1347
1353 if (QUERY_FLAG (tmp, FLAG_UNPAID)) 1348 if (QUERY_FLAG (tmp, FLAG_UNPAID))
1354 { 1349 {
1355 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9); 1350 int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9);
1356 1351
1357 remove_ob (tmp); 1352 tmp->remove ();
1358 1353
1359 if (i == -1) 1354 if (i == -1)
1360 i = 0; 1355 i = 0;
1361 1356
1362 tmp->map = op->map; 1357 tmp->map = op->map;
1426 { 1421 {
1427 LOG (llevError, "Internal shop-mat problem.\n"); 1422 LOG (llevError, "Internal shop-mat problem.\n");
1428 } 1423 }
1429 else 1424 else
1430 { 1425 {
1431 remove_ob (op); 1426 op->remove ();
1432 op->x += freearr_x[i]; 1427 op->x += freearr_x[i];
1433 op->y += freearr_y[i]; 1428 op->y += freearr_y[i];
1434 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL; 1429 rv = insert_ob_in_map (op, op->map, shop_mat, 0) == NULL;
1435 } 1430 }
1436 } 1431 }
1795 1790
1796 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1791 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1797 { 1792 {
1798 /*exp_gain *= 2; because they just identified it too */ 1793 /*exp_gain *= 2; because they just identified it too */
1799 SET_FLAG (tmp, FLAG_IDENTIFIED); 1794 SET_FLAG (tmp, FLAG_IDENTIFIED);
1795
1800 /* If in a container, update how it looks */ 1796 /* If in a container, update how it looks */
1801 if (tmp->env) 1797 if (tmp->env)
1802 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1798 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1803 else 1799 else
1804 op->contr->socket.update_look = 1; 1800 op->contr->socket->floorbox_update ();
1805 } 1801 }
1802
1806 change_exp (op, exp_gain, skill_ob->skill, 0); 1803 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 */ 1804 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT); /* so no more xp gained from this book */
1808 } 1805 }
1809} 1806}
1810 1807
1859 } 1856 }
1860 return; 1857 return;
1861 } 1858 }
1862 1859
1863 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0); 1860 play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0);
1864 tmp = get_object (); 1861 tmp = spell->clone ();
1865 copy_object (spell, tmp);
1866 insert_ob_in_ob (tmp, op); 1862 insert_ob_in_ob (tmp, op);
1867 1863
1868 if (special_prayer) 1864 if (special_prayer)
1869 {
1870 SET_FLAG (tmp, FLAG_STARTEQUIP); 1865 SET_FLAG (tmp, FLAG_STARTEQUIP);
1871 }
1872 1866
1873 esrv_add_spells (op->contr, tmp); 1867 esrv_add_spells (op->contr, tmp);
1874} 1868}
1875 1869
1876/** 1870/**
1893 } 1887 }
1894 1888
1895 new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You lose knowledge of %s.", spell); 1889 new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You lose knowledge of %s.", spell);
1896 player_unready_range_ob (op->contr, spob); 1890 player_unready_range_ob (op->contr, spob);
1897 esrv_remove_spell (op->contr, spob); 1891 esrv_remove_spell (op->contr, spob);
1898 remove_ob (spob); 1892 spob->destroy ();
1899 free_object (spob);
1900} 1893}
1901 1894
1902/** 1895/**
1903 * Handles player applying a spellbook. 1896 * Handles player applying a spellbook.
1904 * Checks whether player has knowledge of required skill, doesn't already know the spell, 1897 * Checks whether player has knowledge of required skill, doesn't already know the spell,
1942 new_draw_info (NDI_UNIQUE, 0, op, "You can't read! Your attempt fails."); 1935 new_draw_info (NDI_UNIQUE, 0, op, "You can't read! Your attempt fails.");
1943 return; 1936 return;
1944 } 1937 }
1945 1938
1946 spell = tmp->inv; 1939 spell = tmp->inv;
1940
1947 if (!spell) 1941 if (!spell)
1948 { 1942 {
1949 LOG (llevError, "apply_spellbook: Book %s has no spell in it!\n", &tmp->name); 1943 LOG (llevError, "apply_spellbook: Book %s has no spell in it!\n", &tmp->name);
1950 new_draw_info (NDI_UNIQUE, 0, op, "The spellbook symbols make no sense."); 1944 new_draw_info (NDI_UNIQUE, 0, op, "The spellbook symbols make no sense.");
1951 return; 1945 return;
1952 } 1946 }
1953 if (spell->level > (skop->level + 10)) 1947
1948 if (skop->level < int (sqrtf (spell->level) * 1.5f))
1954 { 1949 {
1955 new_draw_info (NDI_UNIQUE, 0, op, "You are unable to decipher the strange symbols."); 1950 new_draw_info (NDI_UNIQUE, 0, op, "It is too hard to read at your level: You are unable to decipher the strange symbols.");
1956 return; 1951 return;
1957 } 1952 }
1958 1953
1959 new_draw_info_format (NDI_UNIQUE, 0, op, "The spellbook contains the %s level spell %s.", get_levelnumber (spell->level), &spell->name); 1954 new_draw_info_format (NDI_UNIQUE, 0, op, "The spellbook contains the %s level spell %s.", get_levelnumber (spell->level), &spell->name);
1960 1955
1961 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1956 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1962 { 1957 {
1963 identify (tmp); 1958 identify (tmp);
1959
1964 if (tmp->env) 1960 if (tmp->env)
1965 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp); 1961 esrv_update_item (UPD_FLAGS | UPD_NAME, op, tmp);
1966 else 1962 else
1967 op->contr->socket.update_look = 1; 1963 op->contr->socket->floorbox_update ();
1968 } 1964 }
1969 1965
1970 /* I removed the check for special_prayer_mark here - it didn't make 1966 /* I removed the check for special_prayer_mark here - it didn't make
1971 * a lot of sense - special prayers are not found in spellbooks, and 1967 * a lot of sense - special prayers are not found in spellbooks, and
1972 * if the player doesn't know the spell, doesn't make a lot of sense that 1968 * if the player doesn't know the spell, doesn't make a lot of sense that
2088 */ 2084 */
2089static void 2085static void
2090apply_treasure (object *op, object *tmp) 2086apply_treasure (object *op, object *tmp)
2091{ 2087{
2092 object *treas; 2088 object *treas;
2093 tag_t tmp_tag = tmp->count, op_tag = op->count;
2094 2089
2095 2090
2096 /* Nice side effect of new treasure creation method is that the treasure 2091 /* Nice side effect of new treasure creation method is that the treasure
2097 * for the chest is done when the chest is created, and put into the chest 2092 * for the chest is done when the chest is created, and put into the chest
2098 * inventory. So that when the chest burns up, the items still exist. Also 2093 * inventory. So that when the chest burns up, the items still exist. Also
2109 } 2104 }
2110 while (tmp->inv) 2105 while (tmp->inv)
2111 { 2106 {
2112 treas = tmp->inv; 2107 treas = tmp->inv;
2113 2108
2114 remove_ob (treas); 2109 treas->remove ();
2115 new_draw_info_format (NDI_UNIQUE, 0, op, "You find %s in the chest.", query_name (treas)); 2110 new_draw_info_format (NDI_UNIQUE, 0, op, "You find %s in the chest.", query_name (treas));
2116 2111
2117 treas->x = op->x; 2112 treas->x = op->x;
2118 treas->y = op->y; 2113 treas->y = op->y;
2119 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR); 2114 treas = insert_ob_in_map (treas, op->map, op, INS_BELOW_ORIGINATOR);
2120 2115
2121 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && QUERY_FLAG (op, FLAG_ALIVE)) 2116 if (treas && (treas->type == RUNE || treas->type == TRAP) && treas->level && QUERY_FLAG (op, FLAG_ALIVE))
2122 spring_trap (treas, op); 2117 spring_trap (treas, op);
2118
2123 /* If either player or container was destroyed, no need to do 2119 /* If either player or container was destroyed, no need to do
2124 * further processing. I think this should be enclused with 2120 * further processing. I think this should be enclused with
2125 * spring trap above, as I don't think there is otherwise 2121 * spring trap above, as I don't think there is otherwise
2126 * any way for the treasure chest or player to get killed 2122 * any way for the treasure chest or player to get killed
2127 */ 2123 */
2128 if (was_destroyed (op, op_tag) || was_destroyed (tmp, tmp_tag)) 2124 if (op->destroyed () || tmp->destroyed ())
2129 break; 2125 break;
2130 } 2126 }
2131 2127
2132 if (!was_destroyed (tmp, tmp_tag) && tmp->inv == NULL) 2128 if (!tmp->destroyed () && tmp->inv == NULL)
2133 decrease_ob (tmp); 2129 decrease_ob (tmp);
2134 2130
2135} 2131}
2136 2132
2137/** 2133/**
2374 } 2370 }
2375#endif 2371#endif
2376 INVOKE_PLAYER (LOGOUT, pl->contr); 2372 INVOKE_PLAYER (LOGOUT, pl->contr);
2377 /* Need to call terminate_all_pets() before we remove the player ob */ 2373 /* Need to call terminate_all_pets() before we remove the player ob */
2378 terminate_all_pets (pl); 2374 terminate_all_pets (pl);
2379 remove_ob (pl); 2375 pl->remove ();
2380 pl->direction = 0; 2376 pl->direction = 0;
2381 new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, pl, "%s leaves the game.", &pl->name); 2377 new_draw_info_format (NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, pl, "%s leaves the game.", &pl->name);
2382 2378
2383 /* update respawn position */ 2379 /* update respawn position */
2384 strcpy (pl->contr->savebed_map, pl->map->path); 2380 strcpy (pl->contr->savebed_map, pl->map->path);
2465is_legal_2ways_exit (object *op, object *exit) 2461is_legal_2ways_exit (object *op, object *exit)
2466{ 2462{
2467 object *tmp; 2463 object *tmp;
2468 object *exit_owner; 2464 object *exit_owner;
2469 player *pp; 2465 player *pp;
2470 mapstruct *exitmap; 2466 maptile *exitmap;
2471 2467
2472 if (exit->stats.exp != 1) 2468 if (exit->stats.exp != 1)
2473 return 1; /*This is not a 2 way, so it is legal */ 2469 return 1; /*This is not a 2 way, so it is legal */
2474 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race) 2470 if (!has_been_loaded (EXIT_PATH (exit)) && exit->race)
2475 return 0; /* This is a reset town portal */ 2471 return 0; /* This is a reset town portal */
2814 if (op->type != PLAYER && QUERY_FLAG (op, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ)) 2810 if (op->type != PLAYER && QUERY_FLAG (op, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ))
2815 { 2811 {
2816 play_sound_map (pl->map, pl->x, pl->y, SOUND_OB_EVAPORATE); 2812 play_sound_map (pl->map, pl->x, pl->y, SOUND_OB_EVAPORATE);
2817 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff " "of smoke!"); 2813 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff " "of smoke!");
2818 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion."); 2814 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion.");
2819 remove_ob (op); 2815 op->destroy ();
2820 free_object (op);
2821 return 1; 2816 return 1;
2822 } 2817 }
2823 2818
2824 pl->contr->last_used = op; 2819 pl->contr->last_used = op;
2825 pl->contr->last_used_id = op->count;
2826 2820
2827 tmp = manual_apply (pl, op, aflag); 2821 tmp = manual_apply (pl, op, aflag);
2828 if (!quiet) 2822 if (!quiet)
2829 { 2823 {
2830 if (tmp == 0) 2824 if (tmp == 0)
2952 tmp2->map = op->map; 2946 tmp2->map = op->map;
2953 tmp2->below = op->below; 2947 tmp2->below = op->below;
2954 tmp2->above = op->above; 2948 tmp2->above = op->above;
2955 tmp2->stats.food = op->stats.food; 2949 tmp2->stats.food = op->stats.food;
2956 CLEAR_FLAG (tmp2, FLAG_APPLIED); 2950 CLEAR_FLAG (tmp2, FLAG_APPLIED);
2951
2957 if (QUERY_FLAG (op, FLAG_INV_LOCKED)) 2952 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
2958 SET_FLAG (tmp2, FLAG_INV_LOCKED); 2953 SET_FLAG (tmp2, FLAG_INV_LOCKED);
2954
2959 if (who->type == PLAYER) 2955 if (who->type == PLAYER)
2960 esrv_del_item (who->contr, (tag_t) op->count); 2956 esrv_del_item (who->contr, op->count);
2961 remove_ob (op); 2957
2962 free_object (op); 2958 op->destroy ();
2963 insert_ob_in_ob (tmp2, who); 2959 insert_ob_in_ob (tmp2, who);
2964 fix_player (who); 2960 fix_player (who);
2965 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED)) 2961 if (QUERY_FLAG (op, FLAG_CURSED) || QUERY_FLAG (op, FLAG_DAMNED))
2966 { 2962 {
2967 if (who->type == PLAYER) 2963 if (who->type == PLAYER)
3008 3004
3009 if (!(aflags & AP_NO_MERGE)) 3005 if (!(aflags & AP_NO_MERGE))
3010 { 3006 {
3011 object *tmp; 3007 object *tmp;
3012 3008
3013 tag_t del_tag = op->count;
3014
3015 tmp = merge_ob (op, NULL); 3009 tmp = merge_ob (op, NULL);
3016 if (who->type == PLAYER) 3010 if (who->type == PLAYER)
3017 { 3011 {
3018 if (tmp) 3012 if (tmp)
3019 { /* it was merged */ 3013 { /* it was merged */
3020 esrv_del_item (who->contr, del_tag); 3014 esrv_del_item (who->contr, op->count);
3021 op = tmp; 3015 op = tmp;
3022 } 3016 }
3017
3023 esrv_send_item (who, op); 3018 esrv_send_item (who, op);
3024 } 3019 }
3025 } 3020 }
3026 return 0; 3021 return 0;
3027} 3022}
3491 SET_FLAG (tmp2, FLAG_INV_LOCKED); 3486 SET_FLAG (tmp2, FLAG_INV_LOCKED);
3492 insert_ob_in_ob (tmp2, who); 3487 insert_ob_in_ob (tmp2, who);
3493 3488
3494 /* Remove the old lantern */ 3489 /* Remove the old lantern */
3495 if (who->type == PLAYER) 3490 if (who->type == PLAYER)
3496 esrv_del_item (who->contr, (tag_t) op->count); 3491 esrv_del_item (who->contr, op->count);
3497 remove_ob (op); 3492
3498 free_object (op); 3493 op->destroy ();
3499 3494
3500 /* insert the portion that was split off */ 3495 /* insert the portion that was split off */
3501 if (tmp != NULL) 3496 if (tmp != NULL)
3502 { 3497 {
3503 (void) insert_ob_in_ob (tmp, who); 3498 (void) insert_ob_in_ob (tmp, who);
3659 int i; 3654 int i;
3660 3655
3661 switch (op->type) 3656 switch (op->type)
3662 { 3657 {
3663 case SHOP_FLOOR: 3658 case SHOP_FLOOR:
3664 if (!HAS_RANDOM_ITEMS (op)) 3659 if (!op->has_random_items ())
3665 return 0; 3660 return 0;
3661
3666 do 3662 do
3667 { 3663 {
3668 i = 10; /* let's give it 10 tries */ 3664 i = 10; /* let's give it 10 tries */
3669 while ((tmp = generate_treasure (op->randomitems, 3665 while ((tmp = generate_treasure (op->randomitems,
3670 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i); 3666 op->stats.exp ? (int) op->stats.exp : MAX (op->map->difficulty, 5))) == NULL && --i);
3671 if (tmp == NULL) 3667 if (tmp == NULL)
3672 return 0; 3668 return 0;
3673 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) 3669 if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
3674 { 3670 {
3675 free_object (tmp); 3671 tmp->destroy ();
3676 tmp = NULL; 3672 tmp = NULL;
3677 } 3673 }
3678 } 3674 }
3679 while (!tmp); 3675 while (!tmp);
3676
3680 tmp->x = op->x; 3677 tmp->x = op->x;
3681 tmp->y = op->y; 3678 tmp->y = op->y;
3682 SET_FLAG (tmp, FLAG_UNPAID); 3679 SET_FLAG (tmp, FLAG_UNPAID);
3683 insert_ob_in_map (tmp, op->map, NULL, 0); 3680 insert_ob_in_map (tmp, op->map, NULL, 0);
3684 CLEAR_FLAG (op, FLAG_AUTO_APPLY); 3681 CLEAR_FLAG (op, FLAG_AUTO_APPLY);
3686 break; 3683 break;
3687 3684
3688 case TREASURE: 3685 case TREASURE:
3689 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 3686 if (QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
3690 return 0; 3687 return 0;
3688
3691 while ((op->stats.hp--) > 0) 3689 while ((op->stats.hp--) > 0)
3692 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0, 3690 create_treasure (op->randomitems, op, op->map ? GT_ENVIRONMENT : 0,
3693 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0); 3691 op->stats.exp ? (int) op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3694 3692
3695 /* If we generated an object and put it in this object inventory, 3693 /* If we generated an object and put it in this object inventory,
3698 * that is put inside other objects. 3696 * that is put inside other objects.
3699 */ 3697 */
3700 for (tmp = op->inv; tmp; tmp = tmp2) 3698 for (tmp = op->inv; tmp; tmp = tmp2)
3701 { 3699 {
3702 tmp2 = tmp->below; 3700 tmp2 = tmp->below;
3703 remove_ob (tmp); 3701 tmp->remove ();
3702
3704 if (op->env) 3703 if (op->env)
3705 insert_ob_in_ob (tmp, op->env); 3704 insert_ob_in_ob (tmp, op->env);
3706 else 3705 else
3707 free_object (tmp); 3706 tmp->destroy ();
3708 } 3707 }
3709 remove_ob (op); 3708
3710 free_object (op); 3709 op->destroy ();
3711 break; 3710 break;
3712 } 3711 }
3713 return tmp ? 1 : 0; 3712 return tmp ? 1 : 0;
3714} 3713}
3715 3714
3718 * when an original map is loaded) and performs special actions for 3717 * when an original map is loaded) and performs special actions for
3719 * certain objects (most initialization of chests and creation of 3718 * certain objects (most initialization of chests and creation of
3720 * treasures and stuff). Calls auto_apply if appropriate. 3719 * treasures and stuff). Calls auto_apply if appropriate.
3721 */ 3720 */
3722void 3721void
3723fix_auto_apply (mapstruct *m) 3722fix_auto_apply (maptile *m)
3724{ 3723{
3725 object *tmp, *above = NULL; 3724 object *tmp, *above = NULL;
3726 int x, y; 3725 int x, y;
3727 3726
3728 if (m == NULL) 3727 if (m == NULL)
3742 { 3741 {
3743 invnext = invtmp->below; 3742 invnext = invtmp->below;
3744 3743
3745 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY)) 3744 if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY))
3746 auto_apply (invtmp); 3745 auto_apply (invtmp);
3747 else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS (invtmp)) 3746 else if (invtmp->type == TREASURE && invtmp->has_random_items ())
3748 { 3747 {
3749 while ((invtmp->stats.hp--) > 0) 3748 while ((invtmp->stats.hp--) > 0)
3750 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3749 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3751 3750
3752 invtmp->randomitems = NULL; 3751 invtmp->randomitems = NULL;
3753 } 3752 }
3754 else if (invtmp && invtmp->arch 3753 else if (invtmp && invtmp->arch
3755 && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS && HAS_RANDOM_ITEMS (invtmp)) 3754 && invtmp->type != TREASURE && invtmp->type != SPELL && invtmp->type != CLASS && invtmp->has_random_items ())
3756 { 3755 {
3757 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); 3756 create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3758 /* Need to clear this so that we never try to create 3757 /* Need to clear this so that we never try to create
3759 * treasure again for this object 3758 * treasure again for this object
3760 */ 3759 */
3777 3776
3778 } 3777 }
3779 3778
3780 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY)) 3779 if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY))
3781 auto_apply (tmp); 3780 auto_apply (tmp);
3782 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && HAS_RANDOM_ITEMS (tmp)) 3781 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && tmp->has_random_items ())
3783 { 3782 {
3784 while ((tmp->stats.hp--) > 0) 3783 while ((tmp->stats.hp--) > 0)
3785 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0); 3784 create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0);
3786 tmp->randomitems = NULL; 3785 tmp->randomitems = NULL;
3787 } 3786 }
3802 * This is a problem for the above objects, because they have counters 3801 * This is a problem for the above objects, because they have counters
3803 * which say how many times to make the treasure. 3802 * which say how many times to make the treasure.
3804 */ 3803 */
3805 else if (tmp && tmp->arch && tmp->type != PLAYER 3804 else if (tmp && tmp->arch && tmp->type != PLAYER
3806 && tmp->type != TREASURE && tmp->type != SPELL 3805 && tmp->type != TREASURE && tmp->type != SPELL
3807 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && HAS_RANDOM_ITEMS (tmp)) 3806 && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && tmp->has_random_items ())
3808 { 3807 {
3809 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0); 3808 create_treasure (tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0);
3810 tmp->randomitems = NULL; 3809 tmp->randomitems = NULL;
3811 } 3810 }
3812 } 3811 }
3863 SET_FLAG (force, FLAG_APPLIED); 3862 SET_FLAG (force, FLAG_APPLIED);
3864 change_abil (who, force); 3863 change_abil (who, force);
3865 insert_ob_in_ob (force, who); 3864 insert_ob_in_ob (force, who);
3866 } 3865 }
3867 else 3866 else
3868 { 3867 force->destroy ();
3869 free_object (force);
3870 }
3871 3868
3872 /* check for hp, sp change */ 3869 /* check for hp, sp change */
3873 if (food->stats.hp != 0) 3870 if (food->stats.hp != 0)
3874 { 3871 {
3875 if (QUERY_FLAG (food, FLAG_CURSED)) 3872 if (QUERY_FLAG (food, FLAG_CURSED))
3916void 3913void
3917apply_lighter (object *who, object *lighter) 3914apply_lighter (object *who, object *lighter)
3918{ 3915{
3919 object *item; 3916 object *item;
3920 int is_player_env = 0; 3917 int is_player_env = 0;
3921 uint32 nrof;
3922 tag_t count;
3923 char item_name[MAX_BUF]; 3918 char item_name[MAX_BUF];
3924 3919
3925 item = find_marked_object (who); 3920 item = find_marked_object (who);
3926 if (item) 3921 if (item)
3927 { 3922 {
3929 { /* lighter gets used up */ 3924 { /* lighter gets used up */
3930 /* Split multiple lighters if they're being used up. Otherwise * 3925 /* Split multiple lighters if they're being used up. Otherwise *
3931 * one charge from each would be used up. --DAMN */ 3926 * one charge from each would be used up. --DAMN */
3932 if (lighter->nrof > 1) 3927 if (lighter->nrof > 1)
3933 { 3928 {
3934 object *oneLighter = get_object (); 3929 object *oneLighter = lighter->clone ();
3935 3930
3936 copy_object (lighter, oneLighter);
3937 lighter->nrof -= 1; 3931 lighter->nrof -= 1;
3938 oneLighter->nrof = 1; 3932 oneLighter->nrof = 1;
3939 oneLighter->stats.food--; 3933 oneLighter->stats.food--;
3940 esrv_send_item (who, lighter); 3934 esrv_send_item (who, lighter);
3941 oneLighter = insert_ob_in_ob (oneLighter, who); 3935 oneLighter = insert_ob_in_ob (oneLighter, who);
3942 esrv_send_item (who, oneLighter); 3936 esrv_send_item (who, oneLighter);
3943 } 3937 }
3944 else 3938 else
3945 {
3946 lighter->stats.food--; 3939 lighter->stats.food--;
3947 }
3948
3949 } 3940 }
3950 else if (lighter->last_eat) 3941 else if (lighter->last_eat)
3951 { /* no charges left in lighter */ 3942 { /* no charges left in lighter */
3952 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with a used up %s.", &item->name, &lighter->name); 3943 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with a used up %s.", &item->name, &lighter->name);
3953 return; 3944 return;
3954 } 3945 }
3955 /* Perhaps we should split what we are trying to light on fire? 3946 /* Perhaps we should split what we are trying to light on fire?
3956 * I can't see many times when you would want to light multiple 3947 * I can't see many times when you would want to light multiple
3957 * objects at once. 3948 * objects at once.
3958 */ 3949 */
3959 nrof = item->nrof;
3960 count = item->count;
3961 /* If the item is destroyed, we don't have a valid pointer to the 3950 /* If the item is destroyed, we don't have a valid pointer to the
3962 * name object, so make a copy so the message we print out makes 3951 * name object, so make a copy so the message we print out makes
3963 * some sense. 3952 * some sense.
3964 */ 3953 */
3965 strcpy (item_name, item->name); 3954 strcpy (item_name, item->name);
3968 3957
3969 save_throw_object (item, AT_FIRE, who); 3958 save_throw_object (item, AT_FIRE, who);
3970 /* Change to check count and not freed, since the object pointer 3959 /* Change to check count and not freed, since the object pointer
3971 * may have gotten recycled 3960 * may have gotten recycled
3972 */ 3961 */
3973 if ((nrof != item->nrof) || (count != item->count)) 3962 if (item->destroyed ())
3974 { 3963 {
3975 new_draw_info_format (NDI_UNIQUE, 0, who, "You light the %s with the %s.", &item_name, &lighter->name); 3964 new_draw_info_format (NDI_UNIQUE, 0, who, "You light the %s with the %s.", &item_name, &lighter->name);
3976 /* Need to update the player so that the players glow radius 3965 /* Need to update the player so that the players glow radius
3977 * gets changed. 3966 * gets changed.
3978 */ 3967 */
3979 if (is_player_env) 3968 if (is_player_env)
3980 fix_player (who); 3969 fix_player (who);
3981 } 3970 }
3982 else 3971 else
3983 {
3984 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with the %s and fail.", &item->name, &lighter->name); 3972 new_draw_info_format (NDI_UNIQUE, 0, who, "You attempt to light the %s with the %s and fail.", &item->name, &lighter->name);
3985 }
3986
3987 } 3973 }
3988 else /* nothing to light */ 3974 else /* nothing to light */
3989 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object."); 3975 new_draw_info (NDI_UNIQUE, 0, who, "You need to mark a lightable object.");
3990 3976
3991} 3977}
4005 object *tmp; 3991 object *tmp;
4006 3992
4007 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!."); 3993 new_draw_info (NDI_UNIQUE, 0, op, "Your spell warps!.");
4008 tmp = get_archetype (SPELL_WONDER); 3994 tmp = get_archetype (SPELL_WONDER);
4009 cast_wonder (op, op, 0, tmp); 3995 cast_wonder (op, op, 0, tmp);
4010 free_object (tmp); 3996 tmp->destroy ();
4011 } 3997 }
4012 else if (failure <= -15 && failure > -35) 3998 else if (failure <= -15 && failure > -35)
4013 { /* drain mana */ 3999 { /* drain mana */
4014 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!."); 4000 new_draw_info (NDI_UNIQUE, 0, op, "Your mana is drained!.");
4015 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW); 4001 op->stats.sp -= random_roll (0, power - 1, op, PREFER_LOW);
4038 object *tmp; 4024 object *tmp;
4039 4025
4040 tmp = get_archetype (LOOSE_MANA); 4026 tmp = get_archetype (LOOSE_MANA);
4041 cast_magic_storm (op, tmp, power); 4027 cast_magic_storm (op, tmp, power);
4042 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!"); 4028 new_draw_info (NDI_UNIQUE, 0, op, "You unlease uncontrolled mana!");
4043 free_object (tmp); 4029 tmp->destroy ();
4044 } 4030 }
4045 } 4031 }
4046} 4032}
4047 4033
4048void 4034void
4211 if (!new_item) 4197 if (!new_item)
4212 { 4198 {
4213 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0)); 4199 new_draw_info_format (NDI_UNIQUE, 0, pl, "This %s is strange, better to not use it.", query_base_name (marked, 0));
4214 return; 4200 return;
4215 } 4201 }
4202
4216 new_item->nrof = yield; 4203 new_item->nrof = yield;
4217 new_draw_info_format (NDI_UNIQUE, 0, pl, "You %s the %s.", &transformer->slaying, query_base_name (marked, 0)); 4204 new_draw_info_format (NDI_UNIQUE, 0, pl, "You %s the %s.", &transformer->slaying, query_base_name (marked, 0));
4218 insert_ob_in_ob (new_item, pl); 4205 insert_ob_in_ob (new_item, pl);
4219 esrv_send_inventory (pl, pl); 4206 esrv_send_inventory (pl, pl);
4220 /* Eat up one item */ 4207 /* Eat up one item */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines