… | |
… | |
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 | |
… | |
… | |
1054 | esrv_del_item (pl->contr, count); |
1057 | esrv_del_item (pl->contr, count); |
1055 | 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 |
1056 | |
1059 | |
1057 | adjust_weight (env, -total_weight ()); |
1060 | adjust_weight (env, -total_weight ()); |
1058 | |
1061 | |
|
|
1062 | // make sure cmov optimisation is applicable |
1059 | *(above ? &above->below : &env->inv) = below; |
1063 | *(above ? &above->below : &env->inv) = below; |
|
|
1064 | *(below ? &below->above : &above ) = above; // &above is just a dummy |
1060 | |
1065 | |
1061 | if (below) |
1066 | above = 0; |
1062 | below->above = above; |
1067 | below = 0; |
|
|
1068 | env = 0; |
1063 | |
1069 | |
1064 | /* we set up values so that it could be inserted into |
1070 | /* we set up values so that it could be inserted into |
1065 | * 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 |
1066 | * to the caller to decide what we want to do. |
1072 | * to the caller to decide what we want to do. |
1067 | */ |
1073 | */ |
1068 | map = env->map; |
1074 | map = env->map; |
1069 | x = env->x; |
1075 | x = env->x; |
1070 | y = env->y; |
1076 | y = env->y; |
1071 | above = 0; |
|
|
1072 | below = 0; |
|
|
1073 | env = 0; |
|
|
1074 | |
1077 | |
1075 | /* 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 |
1076 | * made to players inventory. If set, avoiding the call |
1079 | * made to players inventory. If set, avoiding the call |
1077 | * to save cpu time. |
1080 | * to save cpu time. |
1078 | */ |
1081 | */ |
… | |
… | |
1105 | |
1108 | |
1106 | esrv_del_item (pl->contr, count); |
1109 | esrv_del_item (pl->contr, count); |
1107 | } |
1110 | } |
1108 | |
1111 | |
1109 | /* link the object above us */ |
1112 | /* link the object above us */ |
1110 | if (above) |
1113 | // re-link, make sure compiler can easily use cmove |
1111 | above->below = below; |
1114 | *(above ? &above->below : &ms.top) = below; |
1112 | else |
1115 | *(below ? &below->above : &ms.bot) = above; |
1113 | ms.top = below; /* we were top, set new top */ |
|
|
1114 | |
|
|
1115 | /* Relink the object below us, if there is one */ |
|
|
1116 | if (below) |
|
|
1117 | below->above = above; |
|
|
1118 | else |
|
|
1119 | { |
|
|
1120 | /* Nothing below, which means we need to relink map object for this space |
|
|
1121 | * use translated coordinates in case some oddness with map tiling is |
|
|
1122 | * evident |
|
|
1123 | */ |
|
|
1124 | if (GET_MAP_OB (map, x, y) != this) |
|
|
1125 | 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 ()); |
|
|
1126 | |
|
|
1127 | ms.bot = above; /* goes on above it. */ |
|
|
1128 | } |
|
|
1129 | |
1116 | |
1130 | above = 0; |
1117 | above = 0; |
1131 | below = 0; |
1118 | below = 0; |
1132 | |
1119 | |
1133 | if (map->in_memory == MAP_SAVING) |
1120 | if (map->in_memory == MAP_SAVING) |
… | |
… | |
1290 | * 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 |
1291 | * need extra work |
1278 | * need extra work |
1292 | */ |
1279 | */ |
1293 | if (!xy_normalise (m, op->x, op->y)) |
1280 | if (!xy_normalise (m, op->x, op->y)) |
1294 | { |
1281 | { |
1295 | op->destroy (1); |
1282 | op->head_ ()->destroy (1);// remove head_ once all tail object destroyers found |
1296 | return 0; |
1283 | return 0; |
1297 | } |
1284 | } |
1298 | |
1285 | |
1299 | if (object *more = op->more) |
1286 | if (object *more = op->more) |
1300 | if (!insert_ob_in_map (more, m, originator, flag)) |
1287 | if (!insert_ob_in_map (more, m, originator, flag)) |
… | |
… | |
1818 | LOG (llevError, "Present_arch called outside map.\n"); |
1805 | LOG (llevError, "Present_arch called outside map.\n"); |
1819 | return NULL; |
1806 | return NULL; |
1820 | } |
1807 | } |
1821 | |
1808 | |
1822 | 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) |
1823 | if (tmp->arch == at) |
1810 | if (tmp->arch->archname == at->archname) |
1824 | return tmp; |
1811 | return tmp; |
1825 | |
1812 | |
1826 | return NULL; |
1813 | return NULL; |
1827 | } |
1814 | } |
1828 | |
1815 | |
… | |
… | |
1892 | * The first matching object is returned, or NULL if none. |
1879 | * The first matching object is returned, or NULL if none. |
1893 | */ |
1880 | */ |
1894 | object * |
1881 | object * |
1895 | present_arch_in_ob (const archetype *at, const object *op) |
1882 | present_arch_in_ob (const archetype *at, const object *op) |
1896 | { |
1883 | { |
1897 | for (object *tmp = op->inv; tmp != NULL; tmp = tmp->below) |
1884 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
1898 | if (tmp->arch == at) |
1885 | if (tmp->arch->archname == at->archname) |
1899 | return tmp; |
1886 | return tmp; |
1900 | |
1887 | |
1901 | return NULL; |
1888 | return NULL; |
1902 | } |
1889 | } |
1903 | |
1890 | |