Small walkpath optimizations (#5322)
* Thanks to @mattthewaz Co-authored-by: Aleos <aleos89@users.noreply.github.com> Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
parent
7a4bef2ab7
commit
8682a9e02e
176
src/map/unit.cpp
176
src/map/unit.cpp
@ -78,25 +78,28 @@ struct unit_data* unit_bl2ud(struct block_list *bl)
|
||||
*/
|
||||
int unit_walktoxy_sub(struct block_list *bl)
|
||||
{
|
||||
int i;
|
||||
struct walkpath_data wpd;
|
||||
struct unit_data *ud = NULL;
|
||||
|
||||
nullpo_retr(1, bl);
|
||||
ud = unit_bl2ud(bl);
|
||||
if(ud == NULL) return 0;
|
||||
|
||||
unit_data *ud = unit_bl2ud(bl);
|
||||
|
||||
if (ud == nullptr)
|
||||
return 0;
|
||||
|
||||
walkpath_data wpd = { 0 };
|
||||
|
||||
if( !path_search(&wpd,bl->m,bl->x,bl->y,ud->to_x,ud->to_y,ud->state.walk_easy,CELL_CHKNOPASS) )
|
||||
return 0;
|
||||
|
||||
#ifdef OFFICIAL_WALKPATH
|
||||
if( !path_search_long(NULL, bl->m, bl->x, bl->y, ud->to_x, ud->to_y, CELL_CHKNOPASS) // Check if there is an obstacle between
|
||||
&& wpd.path_len > 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.
|
||||
if( bl->type != BL_NPC // If type is a NPC, please disregard.
|
||||
&& wpd.path_len > 14 // Official number of walkable cells is 14 if and only if there is an obstacle between. [malufett]
|
||||
&& !path_search_long(nullptr, bl->m, bl->x, bl->y, ud->to_x, ud->to_y, CELL_CHKNOPASS) ) // Check if there is an obstacle between
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
memcpy(&ud->walkpath,&wpd,sizeof(wpd));
|
||||
ud->walkpath = wpd;
|
||||
|
||||
int i;
|
||||
|
||||
if (ud->target_to && ud->chaserange>1) {
|
||||
// Generally speaking, the walk path is already to an adjacent tile
|
||||
@ -360,30 +363,16 @@ int unit_walktoxy_ontouch(struct block_list *bl, va_list ap)
|
||||
* @param data: Data used in timer calls
|
||||
* @return 0 or unit_walktoxy_sub() or unit_walktoxy()
|
||||
*/
|
||||
static TIMER_FUNC(unit_walktoxy_timer){
|
||||
int i;
|
||||
int x,y,dx,dy;
|
||||
unsigned char icewall_walk_block;
|
||||
struct block_list *bl;
|
||||
struct unit_data *ud;
|
||||
TBL_PC *sd=NULL;
|
||||
TBL_MOB *md=NULL;
|
||||
TBL_NPC *nd=NULL;
|
||||
static TIMER_FUNC(unit_walktoxy_timer)
|
||||
{
|
||||
block_list *bl = map_id2bl(id);
|
||||
|
||||
bl = map_id2bl(id);
|
||||
|
||||
if(bl == NULL)
|
||||
if(bl == nullptr)
|
||||
return 0;
|
||||
|
||||
unit_data *ud = unit_bl2ud(bl);
|
||||
|
||||
switch(bl->type) { // svoid useless cast, we can only be 1 type
|
||||
case BL_PC: sd = BL_CAST(BL_PC, bl); break;
|
||||
case BL_MOB: md = BL_CAST(BL_MOB, bl); break;
|
||||
case BL_NPC: nd = BL_CAST(BL_NPC, bl); break;
|
||||
}
|
||||
|
||||
ud = unit_bl2ud(bl);
|
||||
|
||||
if(ud == NULL)
|
||||
if(ud == nullptr)
|
||||
return 0;
|
||||
|
||||
if(ud->walktimer != tid) {
|
||||
@ -393,7 +382,7 @@ static TIMER_FUNC(unit_walktoxy_timer){
|
||||
|
||||
ud->walktimer = INVALID_TIMER;
|
||||
|
||||
if (bl->prev == NULL)
|
||||
if (bl->prev == nullptr)
|
||||
return 0; // Stop moved because it is missing from the block_list
|
||||
|
||||
if(ud->walkpath.path_pos>=ud->walkpath.path_len)
|
||||
@ -402,26 +391,38 @@ static TIMER_FUNC(unit_walktoxy_timer){
|
||||
if(ud->walkpath.path[ud->walkpath.path_pos]>=DIR_MAX)
|
||||
return 1;
|
||||
|
||||
x = bl->x;
|
||||
y = bl->y;
|
||||
int x = bl->x;
|
||||
int y = bl->y;
|
||||
|
||||
enum directions dir = ud->walkpath.path[ud->walkpath.path_pos];
|
||||
ud->dir = dir;
|
||||
|
||||
dx = dirx[dir];
|
||||
dy = diry[dir];
|
||||
int dx = dirx[dir];
|
||||
int dy = diry[dir];
|
||||
|
||||
map_session_data *sd = nullptr;
|
||||
mob_data *md = nullptr;
|
||||
npc_data *nd = nullptr;
|
||||
|
||||
// Get icewall walk block depending on Status Immune mode (players can't be trapped)
|
||||
if(md && status_has_mode(&md->status,MD_STATUS_IMMUNE))
|
||||
icewall_walk_block = battle_config.boss_icewall_walk_block;
|
||||
else if(md)
|
||||
icewall_walk_block = battle_config.mob_icewall_walk_block;
|
||||
else
|
||||
icewall_walk_block = 0;
|
||||
unsigned char icewall_walk_block = 0;
|
||||
|
||||
switch(bl->type) { // avoid useless cast, we can only be 1 type
|
||||
case BL_PC: sd = BL_CAST(BL_PC, bl); break;
|
||||
case BL_MOB:
|
||||
md = BL_CAST(BL_MOB, bl);
|
||||
|
||||
if (status_has_mode(&md->status,MD_STATUS_IMMUNE))
|
||||
icewall_walk_block = battle_config.boss_icewall_walk_block;
|
||||
else
|
||||
icewall_walk_block = battle_config.mob_icewall_walk_block;
|
||||
break;
|
||||
case BL_NPC: nd = BL_CAST(BL_NPC, bl); break;
|
||||
}
|
||||
|
||||
//Monsters will walk into an icewall from the west and south if they already started walking
|
||||
if(map_getcell(bl->m,x+dx,y+dy,CELL_CHKNOPASS)
|
||||
&& (icewall_walk_block == 0 || !map_getcell(bl->m,x+dx,y+dy,CELL_CHKICEWALL) || dx < 0 || dy < 0))
|
||||
&& (icewall_walk_block == 0 || dx < 0 || dy < 0 || !map_getcell(bl->m,x+dx,y+dy,CELL_CHKICEWALL)))
|
||||
return unit_walktoxy_sub(bl);
|
||||
|
||||
//Monsters can only leave icewalls to the west and south
|
||||
@ -554,6 +555,8 @@ static TIMER_FUNC(unit_walktoxy_timer){
|
||||
if(tid == INVALID_TIMER) // A directly invoked timer is from battle_stop_walking, therefore the rest is irrelevant.
|
||||
return 0;
|
||||
|
||||
int speed;
|
||||
|
||||
//If stepaction is set then we remembered a client request that should be executed on the next step
|
||||
if (ud->stepaction && ud->target_to) {
|
||||
//Delete old stepaction even if not executed yet, the latest command is what counts
|
||||
@ -563,10 +566,10 @@ static TIMER_FUNC(unit_walktoxy_timer){
|
||||
}
|
||||
//Delay stepactions by half a step (so they are executed at full step)
|
||||
if( direction_diagonal( ud->walkpath.path[ud->walkpath.path_pos] ) )
|
||||
i = status_get_speed(bl)*MOVE_DIAGONAL_COST/MOVE_COST/2;
|
||||
speed = status_get_speed(bl)*MOVE_DIAGONAL_COST/MOVE_COST/2;
|
||||
else
|
||||
i = status_get_speed(bl)/2;
|
||||
ud->steptimer = add_timer(tick+i, unit_step_timer, bl->id, 0);
|
||||
speed = status_get_speed(bl)/2;
|
||||
ud->steptimer = add_timer(tick+speed, unit_step_timer, bl->id, 0);
|
||||
}
|
||||
|
||||
if(ud->state.change_walk_target) {
|
||||
@ -581,14 +584,14 @@ static TIMER_FUNC(unit_walktoxy_timer){
|
||||
ud->walkpath.path_pos++;
|
||||
|
||||
if(ud->walkpath.path_pos >= ud->walkpath.path_len)
|
||||
i = -1;
|
||||
speed = -1;
|
||||
else if( direction_diagonal( ud->walkpath.path[ud->walkpath.path_pos] ) )
|
||||
i = status_get_speed(bl)*MOVE_DIAGONAL_COST/MOVE_COST;
|
||||
speed = status_get_speed(bl)*MOVE_DIAGONAL_COST/MOVE_COST;
|
||||
else
|
||||
i = status_get_speed(bl);
|
||||
speed = status_get_speed(bl);
|
||||
|
||||
if(i > 0) {
|
||||
ud->walktimer = add_timer(tick+i,unit_walktoxy_timer,id,i);
|
||||
if(speed > 0) {
|
||||
ud->walktimer = add_timer(tick+speed,unit_walktoxy_timer,id,speed);
|
||||
if( md && DIFF_TICK(tick,md->dmgtick) < 3000 ) // Not required not damaged recently
|
||||
clif_move(ud);
|
||||
} else if(ud->state.running) { // Keep trying to run.
|
||||
@ -696,36 +699,34 @@ TIMER_FUNC(unit_delay_walktobl_timer){
|
||||
*/
|
||||
int unit_walktoxy( struct block_list *bl, short x, short y, unsigned char flag)
|
||||
{
|
||||
struct unit_data* ud = NULL;
|
||||
struct status_change* sc = NULL;
|
||||
struct walkpath_data wpd;
|
||||
TBL_PC *sd = NULL;
|
||||
|
||||
nullpo_ret(bl);
|
||||
|
||||
ud = unit_bl2ud(bl);
|
||||
unit_data* ud = unit_bl2ud(bl);
|
||||
|
||||
if (ud == NULL)
|
||||
if (ud == nullptr)
|
||||
return 0;
|
||||
|
||||
if (bl->type == BL_PC)
|
||||
sd = BL_CAST(BL_PC, bl);
|
||||
|
||||
if ((flag&8) && !map_closest_freecell(bl->m, &x, &y, BL_CHAR|BL_NPC, 1)) //This might change x and y
|
||||
return 0;
|
||||
|
||||
walkpath_data wpd = { 0 };
|
||||
|
||||
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
|
||||
&& wpd.path_len > 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.
|
||||
// NPCs do not need to fulfill the following checks
|
||||
if( bl->type != BL_NPC ){
|
||||
if( wpd.path_len > battle_config.max_walk_path ){
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((wpd.path_len > battle_config.max_walk_path) && (bl->type != BL_NPC))
|
||||
return 0;
|
||||
#ifdef OFFICIAL_WALKPATH
|
||||
// Official number of walkable cells is 14 if and only if there is an obstacle between.
|
||||
if( wpd.path_len > 14 && !path_search_long( nullptr, bl->m, bl->x, bl->y, x, y, CELL_CHKNOPASS ) ){
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (flag&4) {
|
||||
unit_unattackable(bl);
|
||||
@ -745,7 +746,7 @@ int unit_walktoxy( struct block_list *bl, short x, short y, unsigned char flag)
|
||||
ud->to_y = y;
|
||||
unit_stop_attack(bl); //Sets target to 0
|
||||
|
||||
sc = status_get_sc(bl);
|
||||
status_change* sc = status_get_sc(bl);
|
||||
if (sc && sc->data[SC_CONFUSION]) // Randomize the target position
|
||||
map_random_dir(bl, &ud->to_x, &ud->to_y);
|
||||
|
||||
@ -756,15 +757,19 @@ int unit_walktoxy( struct block_list *bl, short x, short y, unsigned char flag)
|
||||
return 1;
|
||||
}
|
||||
|
||||
TBL_PC *sd = BL_CAST(BL_PC, bl);
|
||||
|
||||
// Start timer to recall summon
|
||||
if (sd && sd->md)
|
||||
unit_check_start_teleport_timer(&sd->md->bl);
|
||||
if (sd && sd->ed)
|
||||
unit_check_start_teleport_timer(&sd->ed->bl);
|
||||
if (sd && sd->hd)
|
||||
unit_check_start_teleport_timer(&sd->hd->bl);
|
||||
if (sd && sd->pd)
|
||||
unit_check_start_teleport_timer(&sd->pd->bl);
|
||||
if( sd != nullptr ){
|
||||
if (sd->md != nullptr)
|
||||
unit_check_start_teleport_timer(&sd->md->bl);
|
||||
if (sd->ed != nullptr)
|
||||
unit_check_start_teleport_timer(&sd->ed->bl);
|
||||
if (sd->hd != nullptr)
|
||||
unit_check_start_teleport_timer(&sd->hd->bl);
|
||||
if (sd->pd != nullptr)
|
||||
unit_check_start_teleport_timer(&sd->pd->bl);
|
||||
}
|
||||
|
||||
return unit_walktoxy_sub(bl);
|
||||
}
|
||||
@ -819,15 +824,12 @@ static TIMER_FUNC(unit_walktobl_sub){
|
||||
*/
|
||||
int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, unsigned char flag)
|
||||
{
|
||||
struct unit_data *ud = NULL;
|
||||
struct status_change *sc = NULL;
|
||||
|
||||
nullpo_ret(bl);
|
||||
nullpo_ret(tbl);
|
||||
|
||||
ud = unit_bl2ud(bl);
|
||||
unit_data *ud = unit_bl2ud(bl);
|
||||
|
||||
if(ud == NULL)
|
||||
if(ud == nullptr)
|
||||
return 0;
|
||||
|
||||
if (!status_bl_has_mode(bl,MD_CANMOVE))
|
||||
@ -851,7 +853,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, unsi
|
||||
ud->state.attack_continue = flag&2?1:0; // Chase to attack.
|
||||
unit_stop_attack(bl); //Sets target to 0
|
||||
|
||||
sc = status_get_sc(bl);
|
||||
status_change *sc = status_get_sc(bl);
|
||||
if (sc && sc->data[SC_CONFUSION]) // Randomize the target position
|
||||
map_random_dir(bl, &ud->to_x, &ud->to_y);
|
||||
|
||||
@ -2541,10 +2543,10 @@ bool unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range,
|
||||
return false;
|
||||
|
||||
#ifdef OFFICIAL_WALKPATH
|
||||
if( !path_search_long(NULL, bl->m, bl->x, bl->y, tbl->x-dx, tbl->y-dy, CELL_CHKNOPASS) // Check if there is an obstacle between
|
||||
&& wpd.path_len > 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 false;
|
||||
if( bl->type != BL_NPC // If type is a NPC, please disregard.
|
||||
&& wpd.path_len > 14 // Official number of walkable cells is 14 if and only if there is an obstacle between. [malufett]
|
||||
&& !path_search_long(nullptr, bl->m, bl->x, bl->y, tbl->x-dx, tbl->y-dy, CELL_CHKNOPASS) ) // Check if there is an obstacle between
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user