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

Comparing deliantra/server/common/object.C (file contents):
Revision 1.358 by root, Sun Nov 25 15:50:20 2012 UTC vs.
Revision 1.364 by root, Sat Sep 16 22:17:42 2017 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 9 * the terms of the Affero GNU General Public License as published by the
72 25, 26, 27, 30, 31, 32, 33, 36, 37, 39, 39, 42, 43, 44, 45, 48, 72 25, 26, 27, 30, 31, 32, 33, 36, 37, 39, 39, 42, 43, 44, 45, 48,
73 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49 73 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49
74}; 74};
75 75
76const char *wall_suffix[16] = { 76const char *wall_suffix[16] = {
77 "0", 77 "0",
78 "1_3", 78 "1_3",
79 "1_4", 79 "1_4",
80 "2_1_2", 80 "2_1_2",
81 "1_2", 81 "1_2",
82 "2_2_4", 82 "2_2_4",
83 "2_2_1", 83 "2_2_1",
84 "3_1", 84 "3_1",
85 "1_1", 85 "1_1",
86 "2_2_3", 86 "2_2_3",
87 "2_2_2", 87 "2_2_2",
88 "3_3", 88 "3_3",
89 "2_1_1", 89 "2_1_1",
90 "3_4", 90 "3_4",
91 "3_2", 91 "3_2",
92 "4" 92 "4"
93}; 93};
94 94
95static void 95static void
96write_uuid (uval64 skip, bool sync) 96write_uuid (uval64 skip, bool sync)
97{ 97{
235static bool 235static bool
236compare_ob_value_lists_one (const object *wants, const object *has) 236compare_ob_value_lists_one (const object *wants, const object *has)
237{ 237{
238 /* n-squared behaviour (see kv.get), but I'm hoping both 238 /* n-squared behaviour (see kv.get), but I'm hoping both
239 * objects with lists are rare, and lists stay short. If not, use a 239 * objects with lists are rare, and lists stay short. If not, use a
240 * different structure or at least keep the lists sorted... 240 * different structure or at least keep the lists sorted...
241 */ 241 */
242 242
243 /* For each field in wants, */ 243 /* For each field in wants, */
244 for (key_value *kv = wants->kv.first; kv; kv = kv->next) 244 for (key_value *kv = wants->kv.first; kv; kv = kv->next)
245 if (has->kv.get (kv->key) != kv->value) 245 if (has->kv.get (kv->key) != kv->value)
351 /* inventory ok - still need to check rest of this object to see 351 /* inventory ok - still need to check rest of this object to see
352 * if it is valid. 352 * if it is valid.
353 */ 353 */
354 } 354 }
355 355
356 /* Don't merge objects that are applied. With the new 'body' code, 356 /* Don't merge objects that are applied. With the new 'body' code,
357 * it is possible for most any character to have more than one of 357 * it is possible for most any character to have more than one of
358 * some items equipped, and we don't want those to merge. 358 * some items equipped, and we don't want those to merge.
359 */ 359 */
360 if (ob1->flag [FLAG_APPLIED] || ob2->flag [FLAG_APPLIED]) 360 if (ob1->flag [FLAG_APPLIED] || ob2->flag [FLAG_APPLIED])
361 return 0; 361 return 0;
362 362
363 /* Note sure why the following is the case - either the object has to 363 /* Not sure why the following is the case - either the object has to
364 * be animated or have a very low speed. Is this an attempted monster 364 * be animated or have a very low speed. Is this an attempted monster
365 * check? 365 * check?
366 */ 366 */
367 if (!ob1->flag [FLAG_ANIMATE] && ob1->has_active_speed ()) 367 if (!ob1->flag [FLAG_ANIMATE] && ob1->has_active_speed ())
368 return 0; 368 return 0;
369 369
753 || (op->flag [FLAG_DAMNED] && !(m.flags_ & P_NO_CLERIC)) 753 || (op->flag [FLAG_DAMNED] && !(m.flags_ & P_NO_CLERIC))
754 || (m.move_on | op->move_on ) != m.move_on 754 || (m.move_on | op->move_on ) != m.move_on
755 || (m.move_off | op->move_off ) != m.move_off 755 || (m.move_off | op->move_off ) != m.move_off
756 || (m.move_slow | op->move_slow) != m.move_slow 756 || (m.move_slow | op->move_slow) != m.move_slow
757 /* This isn't perfect, but I don't expect a lot of objects to 757 /* This isn't perfect, but I don't expect a lot of objects to
758 * have move_allow right now. 758 * have move_allow right now.
759 */ 759 */
760 || ((m.move_block | op->move_block) & ~op->move_allow) != m.move_block 760 || ((m.move_block | op->move_block) & ~op->move_allow) != m.move_block
761 m.invalidate (); 761 m.invalidate ();
762#else 762#else
763 // the above is not strong enough a test to skip updating. los maybe? TODO (schmorp) 763 // the above is not strong enough a test to skip updating. los maybe? TODO (schmorp)
843 op->activate_recursive (); 843 op->activate_recursive ();
844} 844}
845 845
846/* This function removes object 'op' from the list of active 846/* This function removes object 'op' from the list of active
847 * objects. 847 * objects.
848 * This should only be used for style maps or other such 848 * This should only be used for style maps or other such
849 * reference maps where you don't want an object that isn't 849 * reference maps where you don't want an object that isn't
850 * in play chewing up cpu time getting processed. 850 * in play chewing up cpu time getting processed.
851 * The reverse of this is to call update_ob_speed, which 851 * The reverse of this is to call update_ob_speed, which
852 * will do the right thing based on the speed of the object. 852 * will do the right thing based on the speed of the object.
853 */ 853 */
1088 flag [FLAG_REMOVED] = true; 1088 flag [FLAG_REMOVED] = true;
1089 1089
1090 if (more) 1090 if (more)
1091 more->remove (); 1091 more->remove ();
1092 1092
1093 /* 1093 /*
1094 * In this case, the object to be removed is in someones 1094 * In this case, the object to be removed is in someones
1095 * inventory. 1095 * inventory.
1096 */ 1096 */
1097 if (env) 1097 if (env)
1098 { 1098 {
1403 * We've already dealt with merging if appropriate. 1403 * We've already dealt with merging if appropriate.
1404 * Generally, we want to put the new object on top. But if 1404 * Generally, we want to put the new object on top. But if
1405 * flag contains INS_ABOVE_FLOOR_ONLY, once we find the last 1405 * flag contains INS_ABOVE_FLOOR_ONLY, once we find the last
1406 * floor, we want to insert above that and no further. 1406 * floor, we want to insert above that and no further.
1407 * Also, if there are spell objects on this space, we stop processing 1407 * Also, if there are spell objects on this space, we stop processing
1408 * once we get to them. This reduces the need to traverse over all of 1408 * once we get to them. This reduces the need to traverse over all of
1409 * them when adding another one - this saves quite a bit of cpu time 1409 * them when adding another one - this saves quite a bit of cpu time
1410 * when lots of spells are cast in one area. Currently, it is presumed 1410 * when lots of spells are cast in one area. Currently, it is presumed
1411 * that flying non pickable objects are spell objects. 1411 * that flying non pickable objects are spell objects.
1412 */ 1412 */
1413 for (object *tmp = ms.bot; tmp; tmp = tmp->above) 1413 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
1539 1539
1540 return op; 1540 return op;
1541} 1541}
1542 1542
1543/* this function inserts an object in the map, but if it 1543/* this function inserts an object in the map, but if it
1544 * finds an object of its own type, it'll remove that one first. 1544 * finds an object of its own type, it'll remove that one first.
1545 * op is the object to insert it under: supplies x and the map. 1545 * op is the object to insert it under: supplies x and the map.
1546 */ 1546 */
1547void 1547void
1548replace_insert_ob_in_map (shstr_tmp archname, object *op) 1548replace_insert_ob_in_map (shstr_tmp archname, object *op)
1549{ 1549{
1678/* 1678/*
1679 * env->insert (op) 1679 * env->insert (op)
1680 * This function inserts the object op in the linked list 1680 * This function inserts the object op in the linked list
1681 * inside the object environment. 1681 * inside the object environment.
1682 * 1682 *
1683 * The function returns now pointer to inserted item, and return value can 1683 * The function returns now pointer to inserted item, and return value can
1684 * be != op, if items are merged. -Tero 1684 * be != op, if items are merged. -Tero
1685 */ 1685 */
1686object * 1686object *
1687object::insert (object *op) 1687object::insert (object *op)
1688{ 1688{
1808 */ 1808 */
1809 if ((op->move_type & ~move_on & ~move_block) != 0 && (op->move_type & ~move_slow & ~move_block) != 0) 1809 if ((op->move_type & ~move_on & ~move_block) != 0 && (op->move_type & ~move_slow & ~move_block) != 0)
1810 return 0; 1810 return 0;
1811 1811
1812 /* The objects have to be checked from top to bottom. 1812 /* The objects have to be checked from top to bottom.
1813 * Hence, we first go to the top: 1813 * Hence, we first go to the top:
1814 */ 1814 */
1815 for (object *next, *tmp = ms.top; tmp; tmp = next) 1815 for (object *next, *tmp = ms.top; tmp; tmp = next)
1816 { 1816 {
1817 next = tmp->below; 1817 next = tmp->below;
1818 1818
2002 * inform the caller. However, insert_ob_in_map will update as 2002 * inform the caller. However, insert_ob_in_map will update as
2003 * necessary, so the caller shouldn't need to do any special work. 2003 * necessary, so the caller shouldn't need to do any special work.
2004 * Note - updated to take an object instead of archetype - this is necessary 2004 * Note - updated to take an object instead of archetype - this is necessary
2005 * because arch_blocked (now ob_blocked) needs to know the movement type 2005 * because arch_blocked (now ob_blocked) needs to know the movement type
2006 * to know if the space in question will block the object. We can't use 2006 * to know if the space in question will block the object. We can't use
2007 * the archetype because that isn't correct if the monster has been 2007 * the archetype because that isn't correct if the monster has been
2008 * customized, changed states, etc. 2008 * customized, changed states, etc.
2009 */ 2009 */
2010int 2010int
2011find_free_spot (const object *ob, maptile *m, int x, int y, int start, int stop) 2011find_free_spot (const object *ob, maptile *m, int x, int y, int start, int stop)
2012{ 2012{
2035 continue; 2035 continue;
2036 } 2036 }
2037 2037
2038 /* Basically, if we find a wall on a space, we cut down the search size. 2038 /* Basically, if we find a wall on a space, we cut down the search size.
2039 * In this way, we won't return spaces that are on another side of a wall. 2039 * In this way, we won't return spaces that are on another side of a wall.
2040 * This mostly work, but it cuts down the search size in all directions - 2040 * This mostly work, but it cuts down the search size in all directions -
2041 * if the space being examined only has a wall to the north and empty 2041 * if the space being examined only has a wall to the north and empty
2042 * spaces in all the other directions, this will reduce the search space 2042 * spaces in all the other directions, this will reduce the search space
2043 * to only the spaces immediately surrounding the target area, and 2043 * to only the spaces immediately surrounding the target area, and
2044 * won't look 2 spaces south of the target space. 2044 * won't look 2 spaces south of the target space.
2045 */ 2045 */
2075 */ 2075 */
2076int 2076int
2077find_first_free_spot (const object *ob, maptile *m, int x, int y) 2077find_first_free_spot (const object *ob, maptile *m, int x, int y)
2078{ 2078{
2079 for (int i = 0; i < SIZEOFFREE; i++) 2079 for (int i = 0; i < SIZEOFFREE; i++)
2080 if (!ob->blocked (m, x + freearr_x[i], y + freearr_y[i])) 2080 if (!ob->blocked (m, x + DIRX (i), y + DIRY (i)))
2081 return i; 2081 return i;
2082 2082
2083 return -1; 2083 return -1;
2084} 2084}
2085 2085
2096 2096
2097 while (--end) 2097 while (--end)
2098 swap (arr [end], arr [rndm (end + 1)]); 2098 swap (arr [end], arr [rndm (end + 1)]);
2099} 2099}
2100 2100
2101/* new function to make monster searching more efficient, and effective! 2101/* new function to make monster searching more efficient, and effective!
2102 * This basically returns a randomized array (in the passed pointer) of 2102 * This basically returns a randomized array (in the passed pointer) of
2103 * the spaces to find monsters. In this way, it won't always look for 2103 * the spaces to find monsters. In this way, it won't always look for
2104 * monsters to the north first. However, the size of the array passed 2104 * monsters to the north first. However, the size of the array passed
2105 * covers all the spaces, so within that size, all the spaces within 2105 * covers all the spaces, so within that size, all the spaces within
2106 * the 3x3 area will be searched, just not in a predictable order. 2106 * the 3x3 area will be searched, just not in a predictable order.
2350 int mflags; 2350 int mflags;
2351 2351
2352 if (dir < 0) 2352 if (dir < 0)
2353 return 0; /* exit condition: invalid direction */ 2353 return 0; /* exit condition: invalid direction */
2354 2354
2355 dx = x + freearr_x[dir]; 2355 dx = x + DIRX (dir);
2356 dy = y + freearr_y[dir]; 2356 dy = y + DIRY (dir);
2357 2357
2358 mflags = get_map_flags (m, &m, dx, dy, &dx, &dy); 2358 mflags = get_map_flags (m, &m, dx, dy, &dx, &dy);
2359 2359
2360 /* This functional arguably was incorrect before - it was 2360 /* This functional arguably was incorrect before - it was
2361 * checking for P_WALL - that was basically seeing if 2361 * checking for P_WALL - that was basically seeing if
2434 2434
2435 return 0; 2435 return 0;
2436} 2436}
2437 2437
2438/* Zero the key_values on op, decrementing the shared-string 2438/* Zero the key_values on op, decrementing the shared-string
2439 * refcounts and freeing the links. 2439 * refcounts and freeing the links.
2440 */ 2440 */
2441void 2441void
2442key_values::clear () 2442key_values::clear ()
2443{ 2443{
2444 for (key_value *kvp = first; kvp; ) 2444 for (key_value *kvp = first; kvp; )
2719//+GPL 2719//+GPL
2720 2720
2721object * 2721object *
2722object::force_find (shstr_tmp name) 2722object::force_find (shstr_tmp name)
2723{ 2723{
2724 /* cycle through his inventory to look for the MARK we want to 2724 /* cycle through his inventory to look for the MARK we want to
2725 * place 2725 * place
2726 */ 2726 */
2727 for (object *tmp = inv; tmp; tmp = tmp->below) 2727 for (object *tmp = inv; tmp; tmp = tmp->below)
2728 if (tmp->type == FORCE && tmp->slaying == name) 2728 if (tmp->type == FORCE && tmp->slaying == name)
2729 return splay (tmp); 2729 return splay (tmp);
2730 2730

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines