--- deliantra/server/common/object.C 2010/04/18 06:55:34 1.328 +++ deliantra/server/common/object.C 2010/04/23 09:22:46 1.334 @@ -447,8 +447,8 @@ { // 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_adjust_for (op, op->carrying - weight); + weight = weight_adjust_for (op, op->carrying + weight) + - weight_adjust_for (op, op->carrying); if (!weight) return; @@ -486,7 +486,7 @@ if (sum != carrying) { if (carrying != sum)//D - LOG (llevDebug, "updating weight got %ld, expected %ld (%s)\n", + LOG (llevDebug, "updating carrying got %ld, expected %ld (%s)\n", (long long)sum, (long long)carrying, debug_desc ()); carrying = sum; @@ -1574,14 +1574,14 @@ /* if this is not the head or flag has been passed, don't check walk on status */ if (!(flag & INS_NO_WALK_ON) && op->is_head ()) { - if (check_move_on (op, originator)) + if (check_move_on (op, originator, flag)) return 0; - /* If we are a multi part object, lets work our way through the check + /* If we are a multi part object, let's work our way through the check * walk on's. */ for (object *tmp = op->more; tmp; tmp = tmp->more) - if (check_move_on (tmp, originator)) + if (check_move_on (tmp, originator, flag)) return 0; } @@ -1817,7 +1817,7 @@ * on top. */ int -check_move_on (object *op, object *originator) +check_move_on (object *op, object *originator, int flags) { if (op->flag [FLAG_NO_APPLY]) return 0; @@ -1886,6 +1886,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 + continue; + move_apply (tmp, op, originator); if (op->destroyed ()) @@ -2220,33 +2223,67 @@ } /* - * find_dir_2(delta-x,delta-y) will return a direction in which - * an object which has subtracted the x and y coordinates of another - * object, needs to travel toward it. + * find_dir_2(delta-x,delta-y) will return a direction value + * for running into direct [dx, dy]. + * (the opposite of crossfire's find_dir_2!) */ int find_dir_2 (int x, int y) { +#if 1 // new algorithm + // this works by putting x, y into 16 sectors, which + // are not equal sized, but are a better approximation + // then the old algorithm, and then using a mapping + // table to map it into a direction value. + // basically, it maps these comparisons to each bit + // bit #3: x < 0 + // bit #2: y < 0 + // bit #1: x > y + // bit #0: x > 2y + + static const uint8 dir[16] = { + 4, 5, 4, 3, + 2, 1, 2, 3, + 6, 5, 6, 7, + 8, 1, 8, 7, + }; + int sector = 0; + + // this is a bit ugly, but more likely to result in branchless code + sector |= x < 0 ? 8 : 0; + x = x < 0 ? -x : x; // abs + + sector |= y < 0 ? 4 : 0; + y = y < 0 ? -y : y; // abs + + if (x > y) + { + sector |= 2; + + if (x > y * 2) + sector |= 1; + } + else + { + if (y > x * 2) + sector |= 1; + else if (!y) + return 0; // x == 0 here + } + + return dir [sector]; +#else // old algorithm int q; if (y) q = 128 * x / y; else if (x) - q = 512 * x; // to make it > 309 + q = -512 * x; // to make it > 309 else return 0; if (y > 0) { - if (q < -309) return 3; - if (q < -52) return 2; - if (q < 52) return 1; - if (q < 309) return 8; - - return 7; - } - else - { if (q < -309) return 7; if (q < -52) return 6; if (q < 52) return 5; @@ -2254,6 +2291,16 @@ return 3; } + else + { + if (q < -309) return 3; + if (q < -52) return 2; + if (q < 52) return 1; + if (q < 309) return 8; + + return 7; + } +#endif } /*