summaryrefslogtreecommitdiff
path: root/src/common/db.h
diff options
context:
space:
mode:
authorMichieru <Michieru@users.noreply.github.com>2014-10-04 10:46:42 +0200
committerMichieru <Michieru@users.noreply.github.com>2014-10-04 10:46:42 +0200
commitfc011576a21251bd1e78c5f5e1104673f8712020 (patch)
tree59fd741aa6078d032328df84cbc66d1c4d7307eb /src/common/db.h
parentc813ffe0ba08d3330397da4116b25bfe374a6116 (diff)
downloadhercules-fc011576a21251bd1e78c5f5e1104673f8712020.tar.gz
hercules-fc011576a21251bd1e78c5f5e1104673f8712020.tar.bz2
hercules-fc011576a21251bd1e78c5f5e1104673f8712020.tar.xz
hercules-fc011576a21251bd1e78c5f5e1104673f8712020.zip
Pathfinding now works exactly as on the client
- This should solve most of the position lag problems, especially ones that caused monsters to suddenly appear next to you (happened especially often when using icewall) - Added a new heap implementation to db.h (POP2, PUSH2, SIFTUP, SIFTDOWN, UPDATE) that simulates the heap that the client uses, there was no other way to reproduce 100% exact behavior - I recommend using the old heap implementation for everything else - Updated path.c to use the new heap macros and also fixed the order in which the different possible directions are pushed into heap - Special thanks to rversteegen for helping me with various tests and the heap implementation - Special thanks to ultramage for providing info that helped us narrowing down the possible variables Mega thanks to Playtester (rathena:c009b3f4a)
Diffstat (limited to 'src/common/db.h')
-rw-r--r--src/common/db.h99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/common/db.h b/src/common/db.h
index bf59e37d6..f807188eb 100644
--- a/src/common/db.h
+++ b/src/common/db.h
@@ -1347,6 +1347,7 @@ void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...);
/////////////////////////////////////////////////////////////////////
// Binary heap library based on defines. (uses the vector defines above)
// uses aMalloc, aRealloc, aFree
+// WARNING: BHEAP implementation details affect behaviour of A* pathfinding
@@ -1459,6 +1460,21 @@ void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...);
+/// See BHEAP_PUSH. Version used by A* implementation, matching client bheap.
+///
+/// @param __heap Binary heap
+/// @param __val Value
+/// @param __topcmp Comparator
+/// @param __swp Swapper
+#define BHEAP_PUSH2(__heap,__val,__topcmp,__swp) \
+ do{ \
+ size_t _i_ = VECTOR_LENGTH(__heap); \
+ VECTOR_PUSH(__heap,__val); /* insert at end */ \
+ BHEAP_SIFTDOWN(__heap,0,_i_,__topcmp,__swp); \
+ }while(0)
+
+
+
/// Removes the top value of the heap. (using the '=' operator)
/// Assumes the heap is not empty.
///
@@ -1474,6 +1490,21 @@ void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...);
+/// See BHEAP_POP. Version used by A* implementation, matching client bheap.
+///
+/// @param __heap Binary heap
+/// @param __topcmp Comparator
+/// @param __swp Swapper
+#define BHEAP_POP2(__heap,__topcmp,__swp) \
+ do{ \
+ VECTOR_INDEX(__heap,0) = VECTOR_POP(__heap); /* put last at index */ \
+ if( !VECTOR_LENGTH(__heap) ) /* removed last, nothing to do */ \
+ break; \
+ BHEAP_SIFTUP(__heap,0,__topcmp,__swp); \
+ }while(0)
+
+
+
/// Removes the target value of the heap. (using the '=' operator)
/// Assumes the index exists.
///
@@ -1522,6 +1553,74 @@ void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...);
+/// Follow path up towards (but not all the way to) the root, swapping nodes until finding
+/// a place where the new item that was placed at __idx fits.
+/// Only goes as high as __startidx (usually 0).
+///
+/// @param __heap Binary heap
+/// @param __startidx Index of an ancestor of __idx
+/// @param __idx Index of an inserted element
+/// @param __topcmp Comparator
+/// @param __swp Swapper
+#define BHEAP_SIFTDOWN(__heap,__startidx,__idx,__topcmp,__swp) \
+ do{ \
+ size_t _i2_ = __idx; \
+ while( _i2_ > __startidx ) \
+ { /* restore heap property in parents */ \
+ size_t _parent_ = (_i2_-1)/2; \
+ if( __topcmp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i2_)) <= 0 ) \
+ break; /* done */ \
+ __swp(VECTOR_INDEX(__heap,_parent_),VECTOR_INDEX(__heap,_i2_)); \
+ _i2_ = _parent_; \
+ } \
+ }while(0)
+
+
+
+/// Repeatedly swap the smaller child with parent, after placing a new item at __idx.
+///
+/// @param __heap Binary heap
+/// @param __idx Index of an inserted element
+/// @param __topcmp Comparator
+/// @param __swp Swapper
+#define BHEAP_SIFTUP(__heap,__idx,__topcmp,__swp) \
+ do{ \
+ size_t _i_ = __idx; \
+ size_t _lchild_ = _i_*2 + 1; \
+ while( _lchild_ < VECTOR_LENGTH(__heap) ) \
+ { /* restore heap property in childs */ \
+ size_t _rchild_ = _i_*2 + 2; \
+ if( _rchild_ >= VECTOR_LENGTH(__heap) || __topcmp(VECTOR_INDEX(__heap,_lchild_),VECTOR_INDEX(__heap,_rchild_)) < 0 ) \
+ { /* left child */ \
+ __swp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_lchild_)); \
+ _i_ = _lchild_; \
+ } \
+ else \
+ { /* right child */ \
+ __swp(VECTOR_INDEX(__heap,_i_),VECTOR_INDEX(__heap,_rchild_)); \
+ _i_ = _rchild_; \
+ } \
+ _lchild_ = _i_*2 + 1; \
+ } \
+ BHEAP_SIFTDOWN(__heap,__idx,_i_,__topcmp,__swp); \
+ }while(0)
+
+
+
+/// Call this after modifying the item at __idx__ to restore the heap
+///
+/// @param __heap Binary heap
+/// @param __idx Index
+/// @param __topcmp Comparator
+/// @param __swp Swapper
+#define BHEAP_UPDATE(__heap,__idx,__topcmp,__swp) \
+ do{ \
+ BHEAP_SIFTDOWN(__heap,0,__idx,__topcmp,__swp); \
+ BHEAP_SIFTUP(__heap,__idx,__topcmp,__swp); \
+ }while(0)
+
+
+
/// Clears the binary heap, freeing allocated data.
///
/// @param __heap Binary heap