--- deliantra/server/common/object.C 2010/04/23 09:22:46 1.334 +++ deliantra/server/common/object.C 2010/07/02 17:39:23 1.339 @@ -73,6 +73,25 @@ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49 }; +const char *wall_suffix[16] = { + "0", + "1_3", + "1_4", + "2_1_2", + "1_2", + "2_2_4", + "2_2_1", + "3_1", + "1_1", + "2_2_3", + "2_2_2", + "3_3", + "2_1_1", + "3_4", + "3_2", + "4" +}; + static void write_uuid (uval64 skip, bool sync) { @@ -428,37 +447,35 @@ } // adjust weight per container type ("of holding") -static sint32 -weight_adjust_for (object *op, sint32 weight) +static uint32 +weight_adjust_for (object *op, uint32 weight) { return op->type == CONTAINER - ? lerp (weight, 0, 100, 0, 100 - op->stats.Str) + ? weight - weight * op->stats.Str / 100 : weight; } /* - * adjust_weight(object, weight) adds the specified weight to an object, + * subtracts, then adds, the specified weight to an object, * and also updates how much the environment(s) is/are carrying. */ static void -adjust_weight (object *op, sint32 weight) +adjust_weight (object *op, sint32 sub, sint32 add) { while (op) { - // adjust by actual difference to account for rounding errors - // i.e. (w2 - w1) / f != w2 / f - w1 / f and the latter is correct - weight = weight_adjust_for (op, op->carrying + weight) - - weight_adjust_for (op, op->carrying); + sint32 ocarrying = op->carrying; - if (!weight) - return; - - op->carrying += weight; + op->carrying -= weight_adjust_for (op, sub); + op->carrying += weight_adjust_for (op, add); if (object *pl = op->visible_to ()) if (pl != op) // player is handled lazily esrv_update_item (UPD_WEIGHT, pl, op); + sub = ocarrying; + add = op->carrying; + op = op->env; } } @@ -475,17 +492,14 @@ for (object *op = inv; op; op = op->below) { - if (op->inv) - op->update_weight (); + op->update_weight (); - sum += op->total_weight (); + sum += weight_adjust_for (this, op->total_weight ()); } - sum = weight_adjust_for (this, sum); - if (sum != carrying) { - if (carrying != sum)//D + if (carrying != sum && carrying)//D LOG (llevDebug, "updating carrying got %ld, expected %ld (%s)\n", (long long)sum, (long long)carrying, debug_desc ()); @@ -1146,7 +1160,7 @@ esrv_del_item (pl->contr, count); flag [FLAG_REMOVED] = true; // hack around the issue of visible_to checking flag_removed - adjust_weight (env, -total_weight ()); + adjust_weight (env, total_weight (), 0); object *pl = in_player (); @@ -1170,14 +1184,14 @@ { if (expect_false (pl->contr->combat_ob == this)) { - pl->apply (pl->contr->combat_ob, AP_UNAPPLY); + pl->apply (pl->contr->combat_ob, AP_UNAPPLY | AP_IGNORE_CURSE); pl->contr->combat_ob = 0; if (pl->contr->ranged_ob) pl->apply (pl->contr->ranged_ob); } if (expect_false (pl->contr->ranged_ob == this)) { - pl->apply (pl->contr->ranged_ob, AP_UNAPPLY); + pl->apply (pl->contr->ranged_ob, AP_UNAPPLY | AP_IGNORE_CURSE); pl->contr->ranged_ob = 0; if (pl->contr->combat_ob) pl->apply (pl->contr->combat_ob); } @@ -1657,12 +1671,15 @@ if (nrof > nr) { + sint64 oweight = total_weight (); + nrof -= nr; - adjust_weight (env, -weight * max (1, nr)); // carrying == 0 if (object *pl = visible_to ()) esrv_update_item (UPD_NROF, pl, this); + adjust_weight (env, oweight, total_weight ()); + return true; } else @@ -1746,13 +1763,17 @@ if (object::can_merge (tmp, op)) { /* return the original object and remove inserted object - (client needs the original object) */ + (client prefers the original object) */ + + // carring must be 0 for mergable objects + sint64 oweight = tmp->weight * tmp->nrof; + tmp->nrof += op->nrof; if (object *pl = tmp->visible_to ()) esrv_update_item (UPD_NROF, pl, tmp); - adjust_weight (this, op->total_weight ()); + adjust_weight (this, oweight, tmp->weight * tmp->nrof); op->destroy (); op = tmp; @@ -1778,7 +1799,7 @@ if (object *pl = op->visible_to ()) esrv_send_item (pl, op); - adjust_weight (this, op->total_weight ()); + adjust_weight (this, 0, op->total_weight ()); inserted: /* reset the light list and los of the players on the map */ @@ -1886,7 +1907,9 @@ if ((!op->move_type && tmp->move_on & MOVE_WALK) || ((op->move_type & tmp->move_on) && (op->move_type & ~tmp->move_on & ~tmp->move_block) == 0)) { - if (tmp->type == EXIT && (flags & INS_NO_AUTO_EXIT)) //TODO: temporary, fix exits instead + if ((flags & INS_NO_AUTO_EXIT) + && (tmp->type == EXIT || tmp->type == TELEPORTER + || tmp->type == HOLE || tmp->type == TRAPDOOR)) //TODO: temporary, fix exits instead continue; move_apply (tmp, op, originator);