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.228 by root, Sat May 3 11:14:50 2008 UTC vs.
Revision 1.236 by root, Tue May 6 20:08:37 2008 UTC

354 return 0; 354 return 0;
355} 355}
356 356
357// adjust weight per container type ("of holding") 357// adjust weight per container type ("of holding")
358static sint32 358static sint32
359weight_adjust (object *op, sint32 weight) 359weight_adjust_for (object *op, sint32 weight)
360{ 360{
361 return op->type == CONTAINER 361 return op->type == CONTAINER
362 ? lerp (weight, 0, 100, 0, 100 - op->stats.Str) 362 ? lerp (weight, 0, 100, 0, 100 - op->stats.Str)
363 : weight; 363 : weight;
364} 364}
370static void 370static void
371adjust_weight (object *op, sint32 weight) 371adjust_weight (object *op, sint32 weight)
372{ 372{
373 while (op) 373 while (op)
374 { 374 {
375 // adjust by actual difference to account for rounding errors
376 // i.e. (w2 - w1) / f != w2 / f - w1 / f and the latter is correct
375 weight = weight_adjust (op, weight); 377 weight = weight_adjust_for (op, op->carrying)
378 - weight_adjust_for (op, op->carrying - weight);
376 379
377 if (!weight) 380 if (!weight)
378 return; 381 return;
379 382
380 op->carrying += weight; 383 op->carrying += weight;
403 op->update_weight (); 406 op->update_weight ();
404 407
405 sum += op->total_weight (); 408 sum += op->total_weight ();
406 } 409 }
407 410
408 sum = weight_adjust (this, sum); 411 sum = weight_adjust_for (this, sum);
409 412
410 if (sum != carrying) 413 if (sum != carrying)
411 { 414 {
412 carrying = sum; 415 carrying = sum;
413 416
949 nodrop = 1; 952 nodrop = 1;
950 953
951 alloc (); 954 alloc ();
952 in_memory = MAP_ACTIVE; 955 in_memory = MAP_ACTIVE;
953 } 956 }
957
958 ~freed_map ()
959 {
960 destroy ();
961 }
954} freed_map; // freed objects are moved here to avoid crashes 962} freed_map; // freed objects are moved here to avoid crashes
955 963
956void 964void
957object::do_destroy () 965object::do_destroy ()
958{ 966{
1049 esrv_del_item (pl->contr, count); 1057 esrv_del_item (pl->contr, count);
1050 flag [FLAG_REMOVED] = true; // hack around the issue of visible_to checking flag_removed 1058 flag [FLAG_REMOVED] = true; // hack around the issue of visible_to checking flag_removed
1051 1059
1052 adjust_weight (env, -total_weight ()); 1060 adjust_weight (env, -total_weight ());
1053 1061
1062 // make sure cmov optimisation is applicable
1054 *(above ? &above->below : &env->inv) = below; 1063 *(above ? &above->below : &env->inv) = below;
1064 *(below ? &below->above : &above ) = above; // &above is just a dummy
1055 1065
1056 if (below) 1066 above = 0;
1057 below->above = above; 1067 below = 0;
1068 env = 0;
1058 1069
1059 /* we set up values so that it could be inserted into 1070 /* we set up values so that it could be inserted into
1060 * the map, but we don't actually do that - it is up 1071 * the map, but we don't actually do that - it is up
1061 * to the caller to decide what we want to do. 1072 * to the caller to decide what we want to do.
1062 */ 1073 */
1063 map = env->map; 1074 map = env->map;
1064 x = env->x; 1075 x = env->x;
1065 y = env->y; 1076 y = env->y;
1066 above = 0;
1067 below = 0;
1068 env = 0;
1069 1077
1070 /* NO_FIX_PLAYER is set when a great many changes are being 1078 /* NO_FIX_PLAYER is set when a great many changes are being
1071 * made to players inventory. If set, avoiding the call 1079 * made to players inventory. If set, avoiding the call
1072 * to save cpu time. 1080 * to save cpu time.
1073 */ 1081 */
1100 1108
1101 esrv_del_item (pl->contr, count); 1109 esrv_del_item (pl->contr, count);
1102 } 1110 }
1103 1111
1104 /* link the object above us */ 1112 /* link the object above us */
1105 if (above) 1113 // re-link, make sure compiler can easily use cmove
1106 above->below = below; 1114 *(above ? &above->below : &ms.top) = below;
1107 else 1115 *(below ? &below->above : &ms.bot) = above;
1108 ms.top = below; /* we were top, set new top */
1109
1110 /* Relink the object below us, if there is one */
1111 if (below)
1112 below->above = above;
1113 else
1114 {
1115 /* Nothing below, which means we need to relink map object for this space
1116 * use translated coordinates in case some oddness with map tiling is
1117 * evident
1118 */
1119 if (GET_MAP_OB (map, x, y) != this)
1120 LOG (llevError, "remove_ob: GET_MAP_OB does not return object to be removed even though it appears to be on the bottom? %s\n", debug_desc ());
1121
1122 ms.bot = above; /* goes on above it. */
1123 }
1124 1116
1125 above = 0; 1117 above = 0;
1126 below = 0; 1118 below = 0;
1127 1119
1128 if (map->in_memory == MAP_SAVING) 1120 if (map->in_memory == MAP_SAVING)
1285 * of areas of callers (eg, anything that uses find_free_spot would now 1277 * of areas of callers (eg, anything that uses find_free_spot would now
1286 * need extra work 1278 * need extra work
1287 */ 1279 */
1288 if (!xy_normalise (m, op->x, op->y)) 1280 if (!xy_normalise (m, op->x, op->y))
1289 { 1281 {
1290 op->destroy (1); 1282 op->head_ ()->destroy (1);// remove head_ once all tail object destroyers found
1291 return 0; 1283 return 0;
1292 } 1284 }
1293 1285
1294 if (object *more = op->more) 1286 if (object *more = op->more)
1295 if (!insert_ob_in_map (more, m, originator, flag)) 1287 if (!insert_ob_in_map (more, m, originator, flag))
1582 } 1574 }
1583 else 1575 else
1584 { 1576 {
1585 decrease (nr); 1577 decrease (nr);
1586 1578
1587 object *op = object_create_clone (this); 1579 object *op = deep_clone ();
1588 op->nrof = nr; 1580 op->nrof = nr;
1589 return op; 1581 return op;
1590 } 1582 }
1591} 1583}
1592 1584
1813 LOG (llevError, "Present_arch called outside map.\n"); 1805 LOG (llevError, "Present_arch called outside map.\n");
1814 return NULL; 1806 return NULL;
1815 } 1807 }
1816 1808
1817 for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above) 1809 for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above)
1818 if (tmp->arch == at) 1810 if (tmp->arch->archname == at->archname)
1819 return tmp; 1811 return tmp;
1820 1812
1821 return NULL; 1813 return NULL;
1822} 1814}
1823 1815
1887 * The first matching object is returned, or NULL if none. 1879 * The first matching object is returned, or NULL if none.
1888 */ 1880 */
1889object * 1881object *
1890present_arch_in_ob (const archetype *at, const object *op) 1882present_arch_in_ob (const archetype *at, const object *op)
1891{ 1883{
1892 for (object *tmp = op->inv; tmp != NULL; tmp = tmp->below) 1884 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1893 if (tmp->arch == at) 1885 if (tmp->arch->archname == at->archname)
1894 return tmp; 1886 return tmp;
1895 1887
1896 return NULL; 1888 return NULL;
1897} 1889}
1898 1890
2307 2299
2308/* 2300/*
2309 * create clone from object to another 2301 * create clone from object to another
2310 */ 2302 */
2311object * 2303object *
2312object_create_clone (object *asrc) 2304object::deep_clone ()
2313{ 2305{
2306 assert (("deep_clone called on non-head object", is_head ()));
2307
2314 object *dst = 0; 2308 object *dst = clone ();
2315 2309
2316 if (!asrc)
2317 return 0;
2318
2319 object *src = asrc->head_ ();
2320
2321 object *prev = 0; 2310 object *prev = dst;
2322 for (object *part = src; part; part = part->more) 2311 for (object *part = this->more; part; part = part->more)
2323 { 2312 {
2324 object *tmp = part->clone (); 2313 object *tmp = part->clone ();
2325
2326 tmp->x -= src->x;
2327 tmp->y -= src->y;
2328
2329 if (!part->head)
2330 {
2331 dst = tmp;
2332 tmp->head = 0;
2333 }
2334 else
2335 tmp->head = dst; 2314 tmp->head = dst;
2336
2337 tmp->more = 0;
2338
2339 if (prev)
2340 prev->more = tmp; 2315 prev->more = tmp;
2341
2342 prev = tmp; 2316 prev = tmp;
2343 } 2317 }
2344 2318
2345 for (object *item = src->inv; item; item = item->below) 2319 for (object *item = inv; item; item = item->below)
2346 insert_ob_in_ob (object_create_clone (item), dst); 2320 insert_ob_in_ob (item->deep_clone (), dst);
2347 2321
2348 return dst; 2322 return dst;
2349} 2323}
2350 2324
2351/* This returns the first object in who's inventory that 2325/* This returns the first object in who's inventory that

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines