… | |
… | |
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") |
358 | static sint32 |
358 | static sint32 |
359 | weight_adjust (object *op, sint32 weight) |
359 | weight_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 | } |
… | |
… | |
370 | static void |
370 | static void |
371 | adjust_weight (object *op, sint32 weight) |
371 | adjust_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 | |
956 | void |
964 | void |
957 | object::do_destroy () |
965 | object::do_destroy () |
958 | { |
966 | { |
… | |
… | |
1109 | |
1117 | |
1110 | /* Relink the object below us, if there is one */ |
1118 | /* Relink the object below us, if there is one */ |
1111 | if (below) |
1119 | if (below) |
1112 | below->above = above; |
1120 | below->above = above; |
1113 | else |
1121 | else |
1114 | { |
1122 | ms.bot = above; |
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 | |
1123 | |
1125 | above = 0; |
1124 | above = 0; |
1126 | below = 0; |
1125 | below = 0; |
1127 | |
1126 | |
1128 | if (map->in_memory == MAP_SAVING) |
1127 | if (map->in_memory == MAP_SAVING) |
… | |
… | |
1285 | * of areas of callers (eg, anything that uses find_free_spot would now |
1284 | * of areas of callers (eg, anything that uses find_free_spot would now |
1286 | * need extra work |
1285 | * need extra work |
1287 | */ |
1286 | */ |
1288 | if (!xy_normalise (m, op->x, op->y)) |
1287 | if (!xy_normalise (m, op->x, op->y)) |
1289 | { |
1288 | { |
1290 | op->destroy (1); |
1289 | op->head_ ()->destroy (1);// remove head_ once all tail object destroyers found |
1291 | return 0; |
1290 | return 0; |
1292 | } |
1291 | } |
1293 | |
1292 | |
1294 | if (object *more = op->more) |
1293 | if (object *more = op->more) |
1295 | if (!insert_ob_in_map (more, m, originator, flag)) |
1294 | if (!insert_ob_in_map (more, m, originator, flag)) |
… | |
… | |
1582 | } |
1581 | } |
1583 | else |
1582 | else |
1584 | { |
1583 | { |
1585 | decrease (nr); |
1584 | decrease (nr); |
1586 | |
1585 | |
1587 | object *op = object_create_clone (this); |
1586 | object *op = deep_clone (); |
1588 | op->nrof = nr; |
1587 | op->nrof = nr; |
1589 | return op; |
1588 | return op; |
1590 | } |
1589 | } |
1591 | } |
1590 | } |
1592 | |
1591 | |
… | |
… | |
1813 | LOG (llevError, "Present_arch called outside map.\n"); |
1812 | LOG (llevError, "Present_arch called outside map.\n"); |
1814 | return NULL; |
1813 | return NULL; |
1815 | } |
1814 | } |
1816 | |
1815 | |
1817 | for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above) |
1816 | for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above) |
1818 | if (tmp->arch == at) |
1817 | if (tmp->arch->archname == at->archname) |
1819 | return tmp; |
1818 | return tmp; |
1820 | |
1819 | |
1821 | return NULL; |
1820 | return NULL; |
1822 | } |
1821 | } |
1823 | |
1822 | |
… | |
… | |
1887 | * The first matching object is returned, or NULL if none. |
1886 | * The first matching object is returned, or NULL if none. |
1888 | */ |
1887 | */ |
1889 | object * |
1888 | object * |
1890 | present_arch_in_ob (const archetype *at, const object *op) |
1889 | present_arch_in_ob (const archetype *at, const object *op) |
1891 | { |
1890 | { |
1892 | for (object *tmp = op->inv; tmp != NULL; tmp = tmp->below) |
1891 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
1893 | if (tmp->arch == at) |
1892 | if (tmp->arch->archname == at->archname) |
1894 | return tmp; |
1893 | return tmp; |
1895 | |
1894 | |
1896 | return NULL; |
1895 | return NULL; |
1897 | } |
1896 | } |
1898 | |
1897 | |
… | |
… | |
2307 | |
2306 | |
2308 | /* |
2307 | /* |
2309 | * create clone from object to another |
2308 | * create clone from object to another |
2310 | */ |
2309 | */ |
2311 | object * |
2310 | object * |
2312 | object_create_clone (object *asrc) |
2311 | object::deep_clone () |
2313 | { |
2312 | { |
|
|
2313 | assert (("deep_clone called on non-head object", is_head ())); |
|
|
2314 | |
2314 | object *dst = 0; |
2315 | object *dst = clone (); |
2315 | |
2316 | |
2316 | if (!asrc) |
|
|
2317 | return 0; |
|
|
2318 | |
|
|
2319 | object *src = asrc->head_ (); |
|
|
2320 | |
|
|
2321 | object *prev = 0; |
2317 | object *prev = dst; |
2322 | for (object *part = src; part; part = part->more) |
2318 | for (object *part = this->more; part; part = part->more) |
2323 | { |
2319 | { |
2324 | object *tmp = part->clone (); |
2320 | 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; |
2321 | tmp->head = dst; |
2336 | |
|
|
2337 | tmp->more = 0; |
|
|
2338 | |
|
|
2339 | if (prev) |
|
|
2340 | prev->more = tmp; |
2322 | prev->more = tmp; |
2341 | |
|
|
2342 | prev = tmp; |
2323 | prev = tmp; |
2343 | } |
2324 | } |
2344 | |
2325 | |
2345 | for (object *item = src->inv; item; item = item->below) |
2326 | for (object *item = inv; item; item = item->below) |
2346 | insert_ob_in_ob (object_create_clone (item), dst); |
2327 | insert_ob_in_ob (item->deep_clone (), dst); |
2347 | |
2328 | |
2348 | return dst; |
2329 | return dst; |
2349 | } |
2330 | } |
2350 | |
2331 | |
2351 | /* This returns the first object in who's inventory that |
2332 | /* This returns the first object in who's inventory that |