summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map/battle.c6
-rw-r--r--src/map/map.c8
-rw-r--r--src/map/mob.c2
-rw-r--r--src/map/path.c16
-rw-r--r--src/map/path.h43
-rw-r--r--src/map/skill.c24
-rw-r--r--src/map/unit.c20
7 files changed, 68 insertions, 51 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index bc963a7f4..c0c4618fb 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -6091,7 +6091,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
}
/*==========================================
* Check if can attack from this range
- * Basic check then calling path_search for obstacle etc..
+ * Basic check then calling path->search for obstacle etc..
*------------------------------------------*/
bool battle_check_range(struct block_list *src, struct block_list *bl, int range)
{
@@ -6105,7 +6105,7 @@ bool battle_check_range(struct block_list *src, struct block_list *bl, int range
#ifndef CIRCULAR_AREA
if( src->type == BL_PC ) { // Range for players' attacks and skills should always have a circular check. [Angezerus]
int dx = src->x - bl->x, dy = src->y - bl->y;
- if( !check_distance(dx, dy, range) )
+ if( !path->check_distance(dx, dy, range) )
return false;
} else
#endif
@@ -6118,7 +6118,7 @@ bool battle_check_range(struct block_list *src, struct block_list *bl, int range
if( d > AREA_SIZE )
return false; // Avoid targetting objects beyond your range of sight.
- return path_search_long(NULL,src->m,src->x,src->y,bl->x,bl->y,CELL_CHKWALL);
+ return path->search_long(NULL,src->m,src->x,src->y,bl->x,bl->y,CELL_CHKWALL);
}
static const struct _battle_data {
diff --git a/src/map/map.c b/src/map/map.c
index d84a451ec..e4d3e4869 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -810,7 +810,7 @@ static int bl_vgetall_inshootrange(struct block_list *bl, va_list args)
if (!check_distance_bl(center, bl, range))
return 0;
#endif
- if (!path_search_long(NULL, center->m, center->x, center->y, bl->x, bl->y, CELL_CHKWALL))
+ if (!path->search_long(NULL, center->m, center->x, center->y, bl->x, bl->y, CELL_CHKWALL))
return 0;
return 1;
}
@@ -1039,7 +1039,7 @@ static int bl_vgetall_inpath(struct block_list *bl, va_list args)
if ( k < 0 || k > len_limit ) //Since more skills use this, check for ending point as well.
return 0;
- if ( k > magnitude2 && !path_search_long(NULL, m, x0, y0, xi, yi, CELL_CHKWALL) )
+ if ( k > magnitude2 && !path->search_long(NULL, m, x0, y0, xi, yi, CELL_CHKWALL) )
return 0; //Targets beyond the initial ending point need the wall check.
//All these shifts are to increase the precision of the intersection point and distance considering how it's
@@ -2296,7 +2296,7 @@ int map_random_dir(struct block_list *bl, int16 *x, int16 *y)
segment = (short)sqrt((float)(dist2 - segment*segment)); //The complement of the previously picked segment
yi = bl->y + segment*diry[j];
} while (
- (iMap->getcell(bl->m,xi,yi,CELL_CHKNOPASS) || !path_search(NULL,bl->m,bl->x,bl->y,xi,yi,1,CELL_CHKNOREACH))
+ (iMap->getcell(bl->m,xi,yi,CELL_CHKNOPASS) || !path->search(NULL,bl->m,bl->x,bl->y,xi,yi,1,CELL_CHKNOREACH))
&& (++i)<100 );
if (i < 100) {
@@ -5173,6 +5173,7 @@ void map_hp_symbols(void) {
HPM->share(npc,"npc");
HPM->share(mapreg,"mapreg");
HPM->share(pet,"pet");
+ HPM->share(path,"path");
/* partial */
HPM->share(mapit,"mapit");
@@ -5222,6 +5223,7 @@ void map_load_defaults(void) {
unit_defaults();
mapreg_defaults();
pet_defaults();
+ path_defaults();
}
int do_init(int argc, char *argv[])
{
diff --git a/src/map/mob.c b/src/map/mob.c
index 94d5b3527..701a89b6c 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -1081,7 +1081,7 @@ int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
) { //Pick closest target?
if( map[bl->m].icewall_num &&
- !path_search_long(NULL,bl->m,md->bl.x,md->bl.y,bl->x,bl->y,CELL_CHKICEWALL) ) {
+ !path->search_long(NULL,bl->m,md->bl.x,md->bl.y,bl->x,bl->y,CELL_CHKICEWALL) ) {
if( !check_distance_bl(&md->bl, bl, status_get_range(&md->bl) ) )
return 0;
diff --git a/src/map/path.c b/src/map/path.c
index 32a4189bb..2de3eab00 100644
--- a/src/map/path.c
+++ b/src/map/path.c
@@ -1,5 +1,6 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Portions Copyright (c) Athena Dev Teams
#include "../common/cbasetypes.h"
#include "../common/db.h"
@@ -23,6 +24,8 @@
#define DIR_SOUTH 4
#define DIR_EAST 8
+struct path_interface path_s;
+
/// @name Structures and defines for A* pathfinding
/// @{
@@ -458,3 +461,12 @@ unsigned int distance(int dx, int dy)
return (dx<dy?dy:dx);
#endif
}
+void path_defaults(void) {
+ path = &path_s;
+
+ path->blownpos = path_blownpos;
+ path->search_long = path_search_long;
+ path->search = path_search;
+ path->check_distance = check_distance;
+ path->distance = distance;
+}
diff --git a/src/map/path.h b/src/map/path.h
index 5bc551dc9..e872c8877 100644
--- a/src/map/path.h
+++ b/src/map/path.h
@@ -1,5 +1,6 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Portions Copyright (c) Athena Dev Teams
#ifndef _PATH_H_
#define _PATH_H_
@@ -22,25 +23,27 @@ struct shootpath_data {
int y[MAX_WALKPATH];
};
-// calculates destination cell for knockback
-int path_blownpos(int16 m,int16 x0,int16 y0,int16 dx,int16 dy,int count);
-
-// tries to find a walkable path
-bool path_search(struct walkpath_data *wpd,int16 m,int16 x0,int16 y0,int16 x1,int16 y1,int flag,cell_chk cell);
-
-// tries to find a shootable path
-bool path_search_long(struct shootpath_data *spd,int16 m,int16 x0,int16 y0,int16 x1,int16 y1,cell_chk cell);
-
+#define check_distance_bl(bl1, bl2, distance) path->check_distance((bl1)->x - (bl2)->x, (bl1)->y - (bl2)->y, distance)
+#define check_distance_blxy(bl, x1, y1, distance) path->check_distance((bl)->x-(x1), (bl)->y-(y1), distance)
+#define check_distance_xy(x0, y0, x1, y1, distance) path->check_distance((x0)-(x1), (y0)-(y1), distance)
+
+#define distance_bl(bl1, bl2) path->distance((bl1)->x - (bl2)->x, (bl1)->y - (bl2)->y)
+#define distance_blxy(bl, x1, y1) path->distance((bl)->x-(x1), (bl)->y-(y1))
+#define distance_xy(x0, y0, x1, y1) path->distance((x0)-(x1), (y0)-(y1))
+
+struct path_interface {
+ // calculates destination cell for knockback
+ int (*blownpos) (int16 m, int16 x0, int16 y0, int16 dx, int16 dy, int count);
+ // tries to find a walkable path
+ bool (*search) (struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int flag, cell_chk cell);
+ // tries to find a shootable path
+ bool (*search_long) (struct shootpath_data *spd, int16 m, int16 x0, int16 y0, int16 x1, int16 y1, cell_chk cell);
+ int (*check_distance) (int dx, int dy, int distance);
+ unsigned int (*distance) (int dx, int dy);
+};
-// distance related functions
-int check_distance(int dx, int dy, int distance);
-#define check_distance_bl(bl1, bl2, distance) check_distance((bl1)->x - (bl2)->x, (bl1)->y - (bl2)->y, distance)
-#define check_distance_blxy(bl, x1, y1, distance) check_distance((bl)->x-(x1), (bl)->y-(y1), distance)
-#define check_distance_xy(x0, y0, x1, y1, distance) check_distance((x0)-(x1), (y0)-(y1), distance)
+struct path_interface *path;
-unsigned int distance(int dx, int dy);
-#define distance_bl(bl1, bl2) distance((bl1)->x - (bl2)->x, (bl1)->y - (bl2)->y)
-#define distance_blxy(bl, x1, y1) distance((bl)->x-(x1), (bl)->y-(y1))
-#define distance_xy(x0, y0, x1, y1) distance((x0)-(x1), (y0)-(y1))
+void path_defaults(void);
#endif /* _PATH_H_ */
diff --git a/src/map/skill.c b/src/map/skill.c
index cb8708d52..ecd672319 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -3266,12 +3266,12 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
case WZ_METEOR:
if( skl->type >= 0 ) {
int x = skl->type>>16, y = skl->type&0xFFFF;
- if( path_search_long(NULL, src->m, src->x, src->y, x, y, CELL_CHKWALL) )
+ if( path->search_long(NULL, src->m, src->x, src->y, x, y, CELL_CHKWALL) )
skill->unitsetting(src,skl->skill_id,skl->skill_lv,x,y,skl->flag);
- if( path_search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
+ if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
clif->skill_poseffect(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,tick);
}
- else if( path_search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
+ else if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
skill->unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,skl->flag);
break;
case GN_CRAZYWEED_ATK: {
@@ -3574,7 +3574,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case KN_CHARGEATK: {
- bool path = path_search_long(NULL, src->m, src->x, src->y, bl->x, bl->y,CELL_CHKWALL);
+ bool path_exists = path->search_long(NULL, src->m, src->x, src->y, bl->x, bl->y,CELL_CHKWALL);
unsigned int dist = distance_bl(src, bl);
uint8 dir = iMap->calc_dir(bl, src->x, src->y);
@@ -3583,7 +3583,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
clif->slide(src, bl->x, bl->y);
// cause damage and knockback if the path to target was a straight one
- if( path ) {
+ if( path_exists ) {
skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, dist);
skill->blown(src, bl, dist, dir, 0);
//HACK: since knockback officially defaults to the left, the client also turns to the left... therefore,
@@ -4257,7 +4257,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case WL_FROSTMISTY:
// Doesn't deal damage through non-shootable walls.
- if( path_search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKWALL) )
+ if( path->search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKWALL) )
skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag|SD_ANIMATION);
break;
case WL_HELLINFERNO:
@@ -4279,7 +4279,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
}
case RA_WUGBITE:
- if( path_search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKNOREACH) ) {
+ if( path->search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKNOREACH) ) {
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
}else if( sd && skill_id == RA_WUGBITE ) // Only RA_WUGBITE has the skill fail message.
clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
@@ -4681,7 +4681,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
}
if( ud->skill_id == RA_WUGSTRIKE ){
- if( !path_search(NULL,src->m,src->x,src->y,target->x,target->y,1,CELL_CHKNOREACH))
+ if( !path->search(NULL,src->m,src->x,src->y,target->x,target->y,1,CELL_CHKNOREACH))
break;
}
@@ -4769,7 +4769,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
skill->consume_requirement(sd,ud->skill_id,ud->skill_lv,1);
}
#ifdef OFFICIAL_WALKPATH
- if( !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL) )
+ if( !path->search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL) )
break;
#endif
if( (src->type == BL_MER || src->type == BL_HOM) && !skill->check_condition_mercenary(src, ud->skill_id, ud->skill_lv, 1) )
@@ -9941,7 +9941,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
tmpx = x - area + rnd()%(area * 2 + 1);
tmpy = y - area + rnd()%(area * 2 + 1);
- if( i == 0 && path_search_long(NULL, src->m, src->x, src->y, tmpx, tmpy, CELL_CHKWALL) )
+ if( i == 0 && path->search_long(NULL, src->m, src->x, src->y, tmpx, tmpy, CELL_CHKWALL) )
clif->skill_poseffect(src,skill_id,skill_lv,tmpx,tmpy,tick);
if( i > 0 )
@@ -10486,7 +10486,7 @@ int skill_icewall_block(struct block_list *bl,va_list ap) {
if( !md->target_id || ( target = iMap->id2bl(md->target_id) ) == NULL )
return 0;
- if( path_search_long(NULL,bl->m,bl->x,bl->y,target->x,target->y,CELL_CHKICEWALL) )
+ if( path->search_long(NULL,bl->m,bl->x,bl->y,target->x,target->y,CELL_CHKICEWALL) )
return 0;
if( !check_distance_bl(bl, target, status_get_range(bl) ) ) {
@@ -10894,7 +10894,7 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
if( !group->state.song_dance && !iMap->getcell(src->m,ux,uy,CELL_CHKREACH) )
continue; // don't place skill units on walls (except for songs/dances/encores)
- if( battle_config.skill_wall_check && skill->get_unit_flag(skill_id)&UF_PATHCHECK && !path_search_long(NULL,src->m,ux,uy,x,y,CELL_CHKWALL) )
+ if( battle_config.skill_wall_check && skill->get_unit_flag(skill_id)&UF_PATHCHECK && !path->search_long(NULL,src->m,ux,uy,x,y,CELL_CHKWALL) )
continue; // no path between cell and center of casting.
switch( skill_id ) {
diff --git a/src/map/unit.c b/src/map/unit.c
index d8efcefef..ee9920e4b 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -95,7 +95,7 @@ int unit_walktoxy_sub(struct block_list *bl)
ud = unit->bl2ud(bl);
if(ud == NULL) return 0;
- if( !path_search(&wpd,bl->m,bl->x,bl->y,ud->to_x,ud->to_y,ud->state.walk_easy,CELL_CHKNOPASS) )
+ if( !path->search(&wpd,bl->m,bl->x,bl->y,ud->to_x,ud->to_y,ud->state.walk_easy,CELL_CHKNOPASS) )
return 0;
memcpy(&ud->walkpath,&wpd,sizeof(wpd));
@@ -349,11 +349,11 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag)
if( ud == NULL) return 0;
- if (!path_search(&wpd, bl->m, bl->x, bl->y, x, y, flag&1, CELL_CHKNOPASS)) // Count walk path cells
+ if (!path->search(&wpd, bl->m, bl->x, bl->y, x, y, flag&1, CELL_CHKNOPASS)) // Count walk path cells
return 0;
#ifdef OFFICIAL_WALKPATH
- if( !path_search_long(NULL, bl->m, bl->x, bl->y, x, y, CELL_CHKNOPASS) // Check if there is an obstacle between
+ if( !path->search_long(NULL, bl->m, bl->x, bl->y, x, y, CELL_CHKNOPASS) // Check if there is an obstacle between
&& (wpd.path_len > (battle_config.max_walk_path/17)*14) // Official number of walkable cells is 14 if and only if there is an obstacle between. [malufett]
&& (bl->type != BL_NPC) ) // If type is a NPC, please disregard.
return 0;
@@ -645,7 +645,7 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool
unit->stop_walking(bl,1);
unit->stop_attack(bl);
- if( checkpath && (iMap->getcell(bl->m,dst_x,dst_y,CELL_CHKNOPASS) || !path_search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,easy,CELL_CHKNOREACH)) )
+ if( checkpath && (iMap->getcell(bl->m,dst_x,dst_y,CELL_CHKNOPASS) || !path->search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,easy,CELL_CHKNOREACH)) )
return 0; // unreachable
ud->to_x = dst_x;
@@ -679,7 +679,7 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool
{ // Check if pet needs to be teleported. [Skotlex]
int flag = 0;
struct block_list* bl = &sd->pd->bl;
- if( !checkpath && !path_search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,0,CELL_CHKNOPASS) )
+ if( !checkpath && !path->search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,0,CELL_CHKNOPASS) )
flag = 1;
else if (!check_distance_bl(&sd->bl, bl, AREA_SIZE)) //Too far, teleport.
flag = 2;
@@ -731,7 +731,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag)
sd = BL_CAST(BL_PC, bl);
su = BL_CAST(BL_SKILL, bl);
- result = path_blownpos(bl->m, bl->x, bl->y, dx, dy, count);
+ result = path->blownpos(bl->m, bl->x, bl->y, dx, dy, count);
nx = result>>16;
ny = result&0xffff;
@@ -775,7 +775,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag)
}
}
- count = distance(dx, dy);
+ count = path->distance(dx, dy);
}
return count; // return amount of knocked back cells
@@ -1703,7 +1703,7 @@ bool unit_can_reach_pos(struct block_list *bl,int x,int y, int easy)
if (bl->x == x && bl->y == y) //Same place
return true;
- return path_search(NULL,bl->m,bl->x,bl->y,x,y,easy,CELL_CHKNOREACH);
+ return path->search(NULL,bl->m,bl->x,bl->y,x,y,easy,CELL_CHKNOREACH);
}
/*==========================================
@@ -1741,7 +1741,7 @@ bool unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range,
if (x) *x = tbl->x-dx;
if (y) *y = tbl->y-dy;
- return path_search(NULL,bl->m,bl->x,bl->y,tbl->x-dx,tbl->y-dy,easy,CELL_CHKNOREACH);
+ return path->search(NULL,bl->m,bl->x,bl->y,tbl->x-dx,tbl->y-dy,easy,CELL_CHKNOREACH);
}
/*==========================================
* Calculates position of Pet/Mercenary/Homunculus/Elemental
@@ -1832,7 +1832,7 @@ int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int tick)
if( iStatus->isdead(src) || iStatus->isdead(target) ||
battle->check_target(src,target,BCT_ENEMY) <= 0 || !iStatus->check_skilluse(src, target, 0, 0)
#ifdef OFFICIAL_WALKPATH
- || !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL)
+ || !path->search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL)
#endif
)
return 0; // can't attack under these conditions