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.36 by root, Tue Sep 12 19:20:06 2006 UTC vs.
Revision 1.51 by root, Sun Sep 17 16:21:53 2006 UTC

1
2/* 1/*
3 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
4 3
5 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
6 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
17 16
18 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
19 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 20
22 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
23*/ 22*/
24 23
25/* Eneq(@csd.uu.se): Added weight-modifiers in environment of objects. 24/* Eneq(@csd.uu.se): Added weight-modifiers in environment of objects.
26 sub/add_weight will transcend the environment updating the carrying 25 sub/add_weight will transcend the environment updating the carrying
27 variable. */ 26 variable. */
32#include <object.h> 31#include <object.h>
33#include <funcpoint.h> 32#include <funcpoint.h>
34#include <loader.h> 33#include <loader.h>
35 34
36int nrofallocobjects = 0; 35int nrofallocobjects = 0;
36static UUID uuid;
37const uint64 UUID_SKIP = 1<<19;
37 38
38object *objects; /* Pointer to the list of used objects */
39object *active_objects; /* List of active objects that need to be processed */ 39object *active_objects; /* List of active objects that need to be processed */
40 40
41short freearr_x[SIZEOFFREE] = { 0, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1, 41short freearr_x[SIZEOFFREE] = { 0, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1,
42 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3, -3, -3, -3, -3, -2, -1 42 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3, -3, -3, -3, -3, -2, -1
43}; 43};
49}; 49};
50int freedir[SIZEOFFREE] = { 50int freedir[SIZEOFFREE] = {
51 0, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 8, 8, 8, 51 0, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 8, 8, 8,
52 1, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 7, 8, 8, 8, 8, 8 52 1, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 7, 8, 8, 8, 8, 8
53}; 53};
54
55static void
56write_uuid (void)
57{
58 char filename1[MAX_BUF], filename2[MAX_BUF];
59
60 sprintf (filename1, "%s/uuid", settings.localdir);
61 sprintf (filename2, "%s/uuid~", settings.localdir);
62
63 FILE *fp;
64
65 if (!(fp = fopen (filename2, "w")))
66 {
67 LOG (llevError, "ERROR: cannot open %s for writing, unable to write UUID!\n", filename2);
68 return;
69 }
70
71 fprintf (fp, "<1,%llx>\n", (unsigned long long)uuid.seq + UUID_SKIP * 2);
72 fclose (fp);
73 rename (filename2, filename1);
74}
75
76static void
77read_uuid (void)
78{
79 char filename[MAX_BUF];
80
81 sprintf (filename, "%s/uuid", settings.localdir);
82
83 FILE *fp;
84
85 if (!(fp = fopen (filename, "r")))
86 {
87 if (errno == ENOENT)
88 {
89 LOG (llevInfo, "RESET uid to 1\n");
90 uuid.seq = 0;
91 write_uuid ();
92 return;
93 }
94
95 LOG (llevError, "FATAL: cannot open %s for reading!\n", filename);
96 _exit (1);
97 }
98
99 int version;
100 unsigned long long uid;
101 if (2 != fscanf (fp, "<%d,%llx>\n", &version, &uid) || version != 1)
102 {
103 LOG (llevError, "FATAL: error reading uid from %s!\n", filename);
104 _exit (1);
105 }
106
107 uuid.seq = uid;
108 write_uuid ();
109 LOG (llevDebug, "read UID: %lld\n", uid);
110 fclose (fp);
111}
112
113UUID
114gen_uuid ()
115{
116 UUID uid;
117
118 uid.seq = ++uuid.seq;
119
120 if (!(uuid.seq & (UUID_SKIP - 1)))
121 write_uuid ();
122
123 return uid;
124}
125
126void
127init_uuid ()
128{
129 read_uuid ();
130}
54 131
55/* Returns TRUE if every key_values in wants has a partner with the same value in has. */ 132/* Returns TRUE if every key_values in wants has a partner with the same value in has. */
56static int 133static int
57compare_ob_value_lists_one (const object *wants, const object *has) 134compare_ob_value_lists_one (const object *wants, const object *has)
58{ 135{
254 { 331 {
255 if (inv->inv) 332 if (inv->inv)
256 sum_weight (inv); 333 sum_weight (inv);
257 sum += inv->carrying + inv->weight * (inv->nrof ? inv->nrof : 1); 334 sum += inv->carrying + inv->weight * (inv->nrof ? inv->nrof : 1);
258 } 335 }
336
259 if (op->type == CONTAINER && op->stats.Str) 337 if (op->type == CONTAINER && op->stats.Str)
260 sum = (sum * (100 - op->stats.Str)) / 100; 338 sum = (sum * (100 - op->stats.Str)) / 100;
339
261 if (op->carrying != sum) 340 if (op->carrying != sum)
262 op->carrying = sum; 341 op->carrying = sum;
342
263 return sum; 343 return sum;
264} 344}
265 345
266/** 346/**
267 * Return the outermost environment object for a given object. 347 * Return the outermost environment object for a given object.
365void 445void
366dump_all_objects (void) 446dump_all_objects (void)
367{ 447{
368 object *op; 448 object *op;
369 449
370 for (op = objects; op != NULL; op = op->next) 450 for (op = object::first; op != NULL; op = op->next)
371 { 451 {
372 dump_object (op); 452 dump_object (op);
373 fprintf (logfile, "Object %d\n:%s\n", op->count, errmsg); 453 fprintf (logfile, "Object %s\n", errmsg);
374 } 454 }
375} 455}
376 456
377/* 457/*
378 * get_nearest_part(multi-object, object 2) returns the part of the 458 * get_nearest_part(multi-object, object 2) returns the part of the
401object * 481object *
402find_object (tag_t i) 482find_object (tag_t i)
403{ 483{
404 object *op; 484 object *op;
405 485
406 for (op = objects; op != NULL; op = op->next) 486 for (op = object::first; op != NULL; op = op->next)
407 if (op->count == i) 487 if (op->count == i)
408 break; 488 break;
489
409 return op; 490 return op;
410} 491}
411 492
412/* 493/*
413 * Returns the first object which has a name equal to the argument. 494 * Returns the first object which has a name equal to the argument.
419find_object_name (const char *str) 500find_object_name (const char *str)
420{ 501{
421 shstr_cmp str_ (str); 502 shstr_cmp str_ (str);
422 object *op; 503 object *op;
423 504
424 for (op = objects; op != NULL; op = op->next) 505 for (op = object::first; op != NULL; op = op->next)
425 if (op->name == str_) 506 if (op->name == str_)
426 break; 507 break;
427 508
428 return op; 509 return op;
429} 510}
430 511
431void 512void
432free_all_object_data () 513free_all_object_data ()
433{ 514{
434 LOG (llevDebug, "%d allocated objects\n", nrofallocobjects); 515 LOG (llevDebug, "%d allocated objects\n", nrofallocobjects);
435}
436
437/*
438 * Returns the object which this object marks as being the owner.
439 * A id-scheme is used to avoid pointing to objects which have been
440 * freed and are now reused. If this is detected, the owner is
441 * set to NULL, and NULL is returned.
442 * Changed 2004-02-12 - if the player is setting at the play again
443 * prompt, he is removed, and we don't want to treat him as an owner of
444 * anything, so check removed flag. I don't expect that this should break
445 * anything - once an object is removed, it is basically dead anyways.
446 */
447object *
448object::get_owner ()
449{
450 if (!owner
451 || QUERY_FLAG (owner, FLAG_FREED)
452 || QUERY_FLAG (owner, FLAG_REMOVED))
453 owner = 0;
454
455 return owner;
456} 516}
457 517
458/* 518/*
459 * Sets the owner and sets the skill and exp pointers to owner's current 519 * Sets the owner and sets the skill and exp pointers to owner's current
460 * skill and experience objects. 520 * skill and experience objects.
530 590
531 /* What is not cleared is next, prev, and count */ 591 /* What is not cleared is next, prev, and count */
532 592
533 expmul = 1.0; 593 expmul = 1.0;
534 face = blank_face; 594 face = blank_face;
535 attacked_by_count = -1;
536 595
537 if (settings.casting_time) 596 if (settings.casting_time)
538 casting_time = -1; 597 casting_time = -1;
539} 598}
540 599
835 894
836 if (op->more != NULL) 895 if (op->more != NULL)
837 update_object (op->more, action); 896 update_object (op->more, action);
838} 897}
839 898
840static unordered_vector<object *> mortals; 899object::vector object::mortals;
841static std::vector<object *> freed; 900object::vector object::objects; // not yet used
901object *object::first;
842 902
843void object::free_mortals () 903void object::free_mortals ()
844{ 904{
845 for (unordered_vector<object *>::iterator i = mortals.begin (); i != mortals.end ();) 905 for (AUTODECL (i, mortals.begin ()); i != mortals.end ();)
846 if ((*i)->refcnt) 906 if ((*i)->refcnt)
847 ++i; // further delay freeing 907 ++i; // further delay freeing
848 else 908 else
849 { 909 {
850 freed.push_back (*i);//D
851 //delete *i; 910 delete *i;
852 mortals.erase (i); 911 mortals.erase (i);
853 } 912 }
854 913
855 if (mortals.size() && 0)//D 914 static int lastmortals = 0;//D
915
916 if (mortals.size() != lastmortals && lastmortals > 100)//D
917 {
918 lastmortals = mortals.size ();//D
856 LOG (llevDebug, "%d objects in mortal queue\n", mortals.size());//D 919 LOG (llevDebug, "%d objects in mortal queue\n", lastmortals);//D
920 }
857} 921}
858 922
859object::object () 923object::object ()
860{ 924{
861 SET_FLAG (this, FLAG_REMOVED); 925 SET_FLAG (this, FLAG_REMOVED);
862 926
863 expmul = 1.0; 927 expmul = 1.0;
864 face = blank_face; 928 face = blank_face;
865 attacked_by_count = -1;
866} 929}
867 930
868object::~object () 931object::~object ()
869{ 932{
870 free_key_values (this); 933 free_key_values (this);
871} 934}
872 935
873void object::link () 936void object::link ()
874{ 937{
875 count = ++ob_count; 938 count = ++ob_count;
939 uuid = gen_uuid ();
876 940
877 prev = 0; 941 prev = 0;
878 next = objects; 942 next = object::first;
879 943
880 if (objects) 944 if (object::first)
881 objects->prev = this; 945 object::first->prev = this;
882 946
883 objects = this; 947 object::first = this;
884} 948}
885 949
886void object::unlink () 950void object::unlink ()
887{ 951{
888 count = 0; 952 if (this == object::first)
953 object::first = next;
889 954
890 /* Remove this object from the list of used objects */ 955 /* Remove this object from the list of used objects */
891 if (prev)
892 {
893 prev->next = next; 956 if (prev) prev->next = next;
957 if (next) next->prev = prev;
958
894 prev = 0; 959 prev = 0;
895 }
896
897 if (next)
898 {
899 next->prev = prev;
900 next = 0; 960 next = 0;
901 }
902
903 if (this == objects)
904 objects = next;
905} 961}
906 962
907object *object::create () 963object *object::create ()
908{ 964{
909 object *op;
910
911 if (freed.empty ())
912 op = new object; 965 object *op = new object;
913 else
914 {
915 // highly annoying, but the only way to get it stable right now
916 op = freed.back ();
917 freed.pop_back ();
918 op->~object ();
919 new ((void *) op) object;
920 }
921
922 op->link (); 966 op->link ();
923 return op; 967 return op;
924} 968}
925 969
926/* 970/*
992 op = tmp; 1036 op = tmp;
993 } 1037 }
994 } 1038 }
995 } 1039 }
996 1040
1041 // clear those pointers that likely might have circular references to us
997 owner = 0; 1042 owner = 0;
1043 enemy = 0;
1044 attacked_by = 0;
998 1045
999 /* Remove object from the active list */ 1046 /* Remove object from the active list */
1000 speed = 0; 1047 speed = 0;
1001 update_ob_speed (this); 1048 update_ob_speed (this);
1002 1049
1014sub_weight (object *op, signed long weight) 1061sub_weight (object *op, signed long weight)
1015{ 1062{
1016 while (op != NULL) 1063 while (op != NULL)
1017 { 1064 {
1018 if (op->type == CONTAINER) 1065 if (op->type == CONTAINER)
1019 {
1020 weight = (signed long) (weight * (100 - op->stats.Str) / 100); 1066 weight = (signed long) (weight * (100 - op->stats.Str) / 100);
1021 } 1067
1022 op->carrying -= weight; 1068 op->carrying -= weight;
1023 op = op->env; 1069 op = op->env;
1024 } 1070 }
1025} 1071}
1026 1072
1034 */ 1080 */
1035 1081
1036void 1082void
1037remove_ob (object *op) 1083remove_ob (object *op)
1038{ 1084{
1085 object *tmp, *last = 0;
1039 object * 1086 object *otmp;
1040 tmp, *
1041 last = NULL;
1042 object *
1043 otmp;
1044 1087
1045 tag_t
1046 tag;
1047 int
1048 check_walk_off; 1088 int check_walk_off;
1049 mapstruct * 1089 maptile *m;
1050 m;
1051 1090
1052 sint16 1091 sint16 x, y;
1053 x,
1054 y;
1055 1092
1056 if (QUERY_FLAG (op, FLAG_REMOVED)) 1093 if (QUERY_FLAG (op, FLAG_REMOVED))
1057 return; 1094 return;
1058 1095
1059 SET_FLAG (op, FLAG_REMOVED); 1096 SET_FLAG (op, FLAG_REMOVED);
1152 op->below = 0; 1189 op->below = 0;
1153 1190
1154 if (op->map->in_memory == MAP_SAVING) 1191 if (op->map->in_memory == MAP_SAVING)
1155 return; 1192 return;
1156 1193
1157 tag = op->count;
1158 check_walk_off = !QUERY_FLAG (op, FLAG_NO_APPLY); 1194 check_walk_off = !QUERY_FLAG (op, FLAG_NO_APPLY);
1159 1195
1160 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above) 1196 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above)
1161 { 1197 {
1162 /* No point updating the players look faces if he is the object 1198 /* No point updating the players look faces if he is the object
1177 1213
1178 tmp->contr->socket.update_look = 1; 1214 tmp->contr->socket.update_look = 1;
1179 } 1215 }
1180 1216
1181 /* See if player moving off should effect something */ 1217 /* See if player moving off should effect something */
1182 if (check_walk_off && ((op->move_type & tmp->move_off) && (op->move_type & ~tmp->move_off & ~tmp->move_block) == 0)) 1218 if (check_walk_off
1219 && ((op->move_type & tmp->move_off)
1220 && (op->move_type & ~tmp->move_off & ~tmp->move_block) == 0))
1183 { 1221 {
1184 move_apply (tmp, op, NULL); 1222 move_apply (tmp, op, NULL);
1185 1223
1186 if (was_destroyed (op, tag)) 1224 if (op->destroyed ())
1187 {
1188 LOG (llevError, "BUG: remove_ob(): name %s, archname %s destroyed " "leaving object\n", &tmp->name, &tmp->arch->name); 1225 LOG (llevError, "BUG: remove_ob(): name %s, destroyed leaving object\n", tmp->debug_desc ());
1189 }
1190 } 1226 }
1191 1227
1192 /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */ 1228 /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */
1193 1229
1194 if (tmp->above == tmp) 1230 if (tmp->above == tmp)
1222 * This function goes through all objects below and including top, and 1258 * This function goes through all objects below and including top, and
1223 * merges op to the first matching object. 1259 * merges op to the first matching object.
1224 * If top is NULL, it is calculated. 1260 * If top is NULL, it is calculated.
1225 * Returns pointer to object if it succeded in the merge, otherwise NULL 1261 * Returns pointer to object if it succeded in the merge, otherwise NULL
1226 */ 1262 */
1227
1228object * 1263object *
1229merge_ob (object *op, object *top) 1264merge_ob (object *op, object *top)
1230{ 1265{
1231 if (!op->nrof) 1266 if (!op->nrof)
1232 return 0; 1267 return 0;
1248 free_object (op); 1283 free_object (op);
1249 return top; 1284 return top;
1250 } 1285 }
1251 } 1286 }
1252 1287
1253 return NULL; 1288 return 0;
1254} 1289}
1255 1290
1256/* 1291/*
1257 * same as insert_ob_in_map except it handle separate coordinates and do a clean 1292 * same as insert_ob_in_map except it handle separate coordinates and do a clean
1258 * job preparing multi-part monsters 1293 * job preparing multi-part monsters
1259 */ 1294 */
1260object * 1295object *
1261insert_ob_in_map_at (object *op, mapstruct *m, object *originator, int flag, int x, int y) 1296insert_ob_in_map_at (object *op, maptile *m, object *originator, int flag, int x, int y)
1262{ 1297{
1263 object *tmp; 1298 object *tmp;
1264 1299
1265 if (op->head) 1300 if (op->head)
1266 op = op->head; 1301 op = op->head;
1294 * NULL if 'op' was destroyed 1329 * NULL if 'op' was destroyed
1295 * just 'op' otherwise 1330 * just 'op' otherwise
1296 */ 1331 */
1297 1332
1298object * 1333object *
1299insert_ob_in_map (object *op, mapstruct *m, object *originator, int flag) 1334insert_ob_in_map (object *op, maptile *m, object *originator, int flag)
1300{ 1335{
1301 object *tmp, *top, *floor = NULL; 1336 object *tmp, *top, *floor = NULL;
1302 sint16 x, y; 1337 sint16 x, y;
1303 1338
1304 if (QUERY_FLAG (op, FLAG_FREED)) 1339 if (QUERY_FLAG (op, FLAG_FREED))
1585 remove_ob (tmp); 1620 remove_ob (tmp);
1586 free_object (tmp); 1621 free_object (tmp);
1587 } 1622 }
1588 } 1623 }
1589 1624
1590 tmp1 = arch_to_object (find_archetype (arch_string)); 1625 tmp1 = arch_to_object (archetype::find (arch_string));
1591 1626
1592 tmp1->x = op->x; 1627 tmp1->x = op->x;
1593 tmp1->y = op->y; 1628 tmp1->y = op->y;
1594 insert_ob_in_map (tmp1, op->map, op, 0); 1629 insert_ob_in_map (tmp1, op->map, op, 0);
1595} 1630}
1894 */ 1929 */
1895 1930
1896int 1931int
1897check_move_on (object *op, object *originator) 1932check_move_on (object *op, object *originator)
1898{ 1933{
1899 object * 1934 object *tmp;
1900 tmp; 1935 maptile *m = op->map;
1901 tag_t
1902 tag;
1903 mapstruct *
1904 m = op->map;
1905 int
1906 x = op->x, y = op->y; 1936 int x = op->x, y = op->y;
1907 1937
1908 MoveType 1938 MoveType move_on, move_slow, move_block;
1909 move_on,
1910 move_slow,
1911 move_block;
1912 1939
1913 if (QUERY_FLAG (op, FLAG_NO_APPLY)) 1940 if (QUERY_FLAG (op, FLAG_NO_APPLY))
1914 return 0; 1941 return 0;
1915
1916 tag = op->count;
1917 1942
1918 move_on = GET_MAP_MOVE_ON (op->map, op->x, op->y); 1943 move_on = GET_MAP_MOVE_ON (op->map, op->x, op->y);
1919 move_slow = GET_MAP_MOVE_SLOW (op->map, op->x, op->y); 1944 move_slow = GET_MAP_MOVE_SLOW (op->map, op->x, op->y);
1920 move_block = GET_MAP_MOVE_BLOCK (op->map, op->x, op->y); 1945 move_block = GET_MAP_MOVE_BLOCK (op->map, op->x, op->y);
1921 1946
1982 if ((!op->move_type && tmp->move_on & MOVE_WALK) || 2007 if ((!op->move_type && tmp->move_on & MOVE_WALK) ||
1983 ((op->move_type & tmp->move_on) && (op->move_type & ~tmp->move_on & ~tmp->move_block) == 0)) 2008 ((op->move_type & tmp->move_on) && (op->move_type & ~tmp->move_on & ~tmp->move_block) == 0))
1984 { 2009 {
1985 move_apply (tmp, op, originator); 2010 move_apply (tmp, op, originator);
1986 2011
1987 if (was_destroyed (op, tag)) 2012 if (op->destroyed ())
1988 return 1; 2013 return 1;
1989 2014
1990 /* what the person/creature stepped onto has moved the object 2015 /* what the person/creature stepped onto has moved the object
1991 * someplace new. Don't process any further - if we did, 2016 * someplace new. Don't process any further - if we did,
1992 * have a feeling strange problems would result. 2017 * have a feeling strange problems would result.
2004 * a matching archetype at the given map and coordinates. 2029 * a matching archetype at the given map and coordinates.
2005 * The first matching object is returned, or NULL if none. 2030 * The first matching object is returned, or NULL if none.
2006 */ 2031 */
2007 2032
2008object * 2033object *
2009present_arch (const archetype *at, mapstruct *m, int x, int y) 2034present_arch (const archetype *at, maptile *m, int x, int y)
2010{ 2035{
2011 object * 2036 object *
2012 tmp; 2037 tmp;
2013 2038
2014 if (m == NULL || out_of_map (m, x, y)) 2039 if (m == NULL || out_of_map (m, x, y))
2027 * a matching type variable at the given map and coordinates. 2052 * a matching type variable at the given map and coordinates.
2028 * The first matching object is returned, or NULL if none. 2053 * The first matching object is returned, or NULL if none.
2029 */ 2054 */
2030 2055
2031object * 2056object *
2032present (unsigned char type, mapstruct *m, int x, int y) 2057present (unsigned char type, maptile *m, int x, int y)
2033{ 2058{
2034 object * 2059 object *
2035 tmp; 2060 tmp;
2036 2061
2037 if (out_of_map (m, x, y)) 2062 if (out_of_map (m, x, y))
2177 * the archetype because that isn't correct if the monster has been 2202 * the archetype because that isn't correct if the monster has been
2178 * customized, changed states, etc. 2203 * customized, changed states, etc.
2179 */ 2204 */
2180 2205
2181int 2206int
2182find_free_spot (const object *ob, mapstruct *m, int x, int y, int start, int stop) 2207find_free_spot (const object *ob, maptile *m, int x, int y, int start, int stop)
2183{ 2208{
2184 int 2209 int
2185 i, 2210 i,
2186 index = 0, flag; 2211 index = 0, flag;
2187 static int 2212 static int
2208 return -1; 2233 return -1;
2209 return altern[RANDOM () % index]; 2234 return altern[RANDOM () % index];
2210} 2235}
2211 2236
2212/* 2237/*
2213 * find_first_free_spot(archetype, mapstruct, x, y) works like 2238 * find_first_free_spot(archetype, maptile, x, y) works like
2214 * find_free_spot(), but it will search max number of squares. 2239 * find_free_spot(), but it will search max number of squares.
2215 * But it will return the first available spot, not a random choice. 2240 * But it will return the first available spot, not a random choice.
2216 * Changed 0.93.2: Have it return -1 if there is no free spot available. 2241 * Changed 0.93.2: Have it return -1 if there is no free spot available.
2217 */ 2242 */
2218 2243
2219int 2244int
2220find_first_free_spot (const object *ob, mapstruct *m, int x, int y) 2245find_first_free_spot (const object *ob, maptile *m, int x, int y)
2221{ 2246{
2222 int 2247 int
2223 i; 2248 i;
2224 2249
2225 for (i = 0; i < SIZEOFFREE; i++) 2250 for (i = 0; i < SIZEOFFREE; i++)
2289 * because we have to know what movement the thing looking to move 2314 * because we have to know what movement the thing looking to move
2290 * there is capable of. 2315 * there is capable of.
2291 */ 2316 */
2292 2317
2293int 2318int
2294find_dir (mapstruct *m, int x, int y, object *exclude) 2319find_dir (maptile *m, int x, int y, object *exclude)
2295{ 2320{
2296 int 2321 int
2297 i, 2322 i,
2298 max = SIZEOFFREE, mflags; 2323 max = SIZEOFFREE, mflags;
2299 2324
2300 sint16 nx, ny; 2325 sint16 nx, ny;
2301 object * 2326 object *
2302 tmp; 2327 tmp;
2303 mapstruct * 2328 maptile *
2304 mp; 2329 mp;
2305 2330
2306 MoveType blocked, move_type; 2331 MoveType blocked, move_type;
2307 2332
2308 if (exclude && exclude->head) 2333 if (exclude && exclude->head)
2516 * Modified to be map tile aware -.MSW 2541 * Modified to be map tile aware -.MSW
2517 */ 2542 */
2518 2543
2519 2544
2520int 2545int
2521can_see_monsterP (mapstruct *m, int x, int y, int dir) 2546can_see_monsterP (maptile *m, int x, int y, int dir)
2522{ 2547{
2523 sint16 dx, dy; 2548 sint16 dx, dy;
2524 int 2549 int
2525 mflags; 2550 mflags;
2526 2551
2606 if (prev) 2631 if (prev)
2607 prev->more = tmp; 2632 prev->more = tmp;
2608 prev = tmp; 2633 prev = tmp;
2609 } 2634 }
2610 2635
2611 /*** copy inventory ***/
2612 for (item = src->inv; item; item = item->below) 2636 for (item = src->inv; item; item = item->below)
2613 {
2614 (void) insert_ob_in_ob (object_create_clone (item), dst); 2637 insert_ob_in_ob (object_create_clone (item), dst);
2615 }
2616 2638
2617 return dst; 2639 return dst;
2618} 2640}
2619 2641
2620/* return true if the object was destroyed, 0 otherwise */
2621int
2622was_destroyed (const object *op, tag_t old_tag)
2623{
2624 /* checking for FLAG_FREED isn't necessary, but makes this function more
2625 * robust */
2626 return op->count != old_tag || QUERY_FLAG (op, FLAG_FREED);
2627}
2628
2629/* GROS - Creates an object using a string representing its content. */ 2642/* GROS - Creates an object using a string representing its content. */
2630
2631/* Basically, we save the content of the string to a temp file, then call */ 2643/* Basically, we save the content of the string to a temp file, then call */
2632
2633/* load_object on it. I admit it is a highly inefficient way to make things, */ 2644/* load_object on it. I admit it is a highly inefficient way to make things, */
2634
2635/* but it was simple to make and allows reusing the load_object function. */ 2645/* but it was simple to make and allows reusing the load_object function. */
2636
2637/* Remember not to use load_object_str in a time-critical situation. */ 2646/* Remember not to use load_object_str in a time-critical situation. */
2638
2639/* Also remember that multiparts objects are not supported for now. */ 2647/* Also remember that multiparts objects are not supported for now. */
2640 2648
2641object * 2649object *
2642load_object_str (const char *obstr) 2650load_object_str (const char *obstr)
2643{ 2651{
2644 object * 2652 object *op;
2645 op;
2646 char
2647 filename[MAX_BUF]; 2653 char filename[MAX_BUF];
2648 2654
2649 sprintf (filename, "%s/cfloadobstr2044", settings.tmpdir); 2655 sprintf (filename, "%s/cfloadobstr2044", settings.tmpdir);
2650 2656
2651 FILE *
2652 tempfile = fopen (filename, "w"); 2657 FILE *tempfile = fopen (filename, "w");
2653 2658
2654 if (tempfile == NULL) 2659 if (tempfile == NULL)
2655 { 2660 {
2656 LOG (llevError, "Error - Unable to access load object temp file\n"); 2661 LOG (llevError, "Error - Unable to access load object temp file\n");
2657 return NULL; 2662 return NULL;
2658 }; 2663 }
2664
2659 fprintf (tempfile, obstr); 2665 fprintf (tempfile, obstr);
2660 fclose (tempfile); 2666 fclose (tempfile);
2661 2667
2662 op = get_object (); 2668 op = get_object ();
2663 2669
2677 * returns NULL if no match. 2683 * returns NULL if no match.
2678 */ 2684 */
2679object * 2685object *
2680find_obj_by_type_subtype (const object *who, int type, int subtype) 2686find_obj_by_type_subtype (const object *who, int type, int subtype)
2681{ 2687{
2682 object * 2688 object *tmp;
2683 tmp;
2684 2689
2685 for (tmp = who->inv; tmp; tmp = tmp->below) 2690 for (tmp = who->inv; tmp; tmp = tmp->below)
2686 if (tmp->type == type && tmp->subtype == subtype) 2691 if (tmp->type == type && tmp->subtype == subtype)
2687 return tmp; 2692 return tmp;
2688 2693
2696 * do the desired thing. 2701 * do the desired thing.
2697 */ 2702 */
2698key_value * 2703key_value *
2699get_ob_key_link (const object *ob, const char *key) 2704get_ob_key_link (const object *ob, const char *key)
2700{ 2705{
2701 key_value * 2706 key_value *link;
2702 link;
2703 2707
2704 for (link = ob->key_values; link != NULL; link = link->next) 2708 for (link = ob->key_values; link != NULL; link = link->next)
2705 {
2706 if (link->key == key) 2709 if (link->key == key)
2707 {
2708 return link; 2710 return link;
2709 }
2710 }
2711 2711
2712 return NULL; 2712 return NULL;
2713} 2713}
2714 2714
2715/* 2715/*

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines