Updated homunculus walk behavior

* Fixes #1950.
* Updated homunculus walk behavior to closer mimic official behavior.
* Homunculus will now stop in a random 3x3 area around the master.
* Homunculus will no longer get stuck when looking for an empty cell when supporting the master during attacks.
Thanks to @dragonis1701!
This commit is contained in:
aleos
2017-08-08 18:54:12 -04:00
parent 71421a4268
commit 80a6932658
7 changed files with 13 additions and 64 deletions

View File

@@ -14629,7 +14629,7 @@ void clif_parse_HomMoveToMaster(int fd, struct map_session_data *sd){
else
return;
unit_calc_pos(bl, sd->bl.x, sd->bl.y, sd->ud.dir);
unit_calc_pos(bl, sd->bl.x, sd->bl.y);
ud = unit_bl2ud(bl);
unit_walktoxy(bl, ud->to_x, ud->to_y, 4);
}

View File

@@ -243,7 +243,7 @@ int elemental_data_received(struct s_elemental *ele, bool flag) {
ed->bl.m = sd->bl.m;
ed->bl.x = sd->bl.x;
ed->bl.y = sd->bl.y;
unit_calc_pos(&ed->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
unit_calc_pos(&ed->bl, sd->bl.x, sd->bl.y);
ed->bl.x = ed->ud.to_x;
ed->bl.y = ed->ud.to_y;

View File

@@ -1033,7 +1033,7 @@ void hom_alloc(struct map_session_data *sd, struct s_homunculus *hom)
hd->bl.m = sd->bl.m;
hd->bl.x = sd->bl.x;
hd->bl.y = sd->bl.y;
unit_calc_pos(&hd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
unit_calc_pos(&hd->bl, sd->bl.x, sd->bl.y);
hd->bl.x = hd->ud.to_x;
hd->bl.y = hd->ud.to_y;

View File

@@ -372,7 +372,7 @@ bool mercenary_recv_data(struct s_mercenary *merc, bool flag)
md->bl.m = sd->bl.m;
md->bl.x = sd->bl.x;
md->bl.y = sd->bl.y;
unit_calc_pos(&md->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
unit_calc_pos(&md->bl, sd->bl.x, sd->bl.y);
md->bl.x = md->ud.to_x;
md->bl.y = md->ud.to_y;

View File

@@ -449,7 +449,7 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *pet)
pd->bl.m = sd->bl.m;
pd->bl.x = sd->bl.x;
pd->bl.y = sd->bl.y;
unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y);
pd->bl.x = pd->ud.to_x;
pd->bl.y = pd->ud.to_y;
@@ -1148,7 +1148,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
if(pd->ud.walktimer != INVALID_TIMER && check_distance_blxy(&sd->bl, pd->ud.to_x,pd->ud.to_y, 3))
return 0; // Already walking to him
unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y);
if(!unit_walktoxy(&pd->bl,pd->ud.to_x,pd->ud.to_y,0))
pet_randomwalk(pd,tick);

View File

@@ -2384,12 +2384,10 @@ bool unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range,
* @param bl: Object to calculate position
* @param tx: X coordinate to go to
* @param ty: Y coordinate to go to
* @param dir: Direction which to be 2 cells from master's position
* @return Success(0); Fail(1);
*/
int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir)
int unit_calc_pos(struct block_list *bl, int tx, int ty)
{
int dx, dy, x, y;
struct unit_data *ud = unit_bl2ud(bl);
nullpo_ret(ud);
@@ -2400,64 +2398,15 @@ int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir)
ud->to_x = tx;
ud->to_y = ty;
// 2 cells from Master Position
dx = -dirx[dir] * 2;
dy = -diry[dir] * 2;
x = tx + dx;
y = ty + dy;
map_search_freecell(bl, bl->m, &ud->to_x, &ud->to_y, 3, 3, 1|2|4);
if( !unit_can_reach_pos(bl, x, y, 0) ) {
if( dx > 0 )
x--;
else if( dx < 0 )
x++;
if (!unit_can_reach_pos(bl, ud->to_x, ud->to_y, 0)) { // Attempt once more
map_search_freecell(bl, bl->m, &ud->to_x, &ud->to_y, 3, 3, 1|2|4);
if( dy > 0 )
y--;
else if( dy < 0 )
y++;
if( !unit_can_reach_pos(bl, x, y, 0) ) {
int i;
for( i = 0; i < 12; i++ ) {
int k = rnd()%8; // Pick a Random Dir
dx = -dirx[k] * 2;
dy = -diry[k] * 2;
x = tx + dx;
y = ty + dy;
if( unit_can_reach_pos(bl, x, y, 0) )
break;
else {
if( dx > 0 )
x--;
else if( dx < 0 )
x++;
if( dy > 0 )
y--;
else if( dy < 0 )
y++;
if( unit_can_reach_pos(bl, x, y, 0) )
break;
}
}
if( i == 12 ) {
x = tx; y = tx; // Exactly Master Position
if( !unit_can_reach_pos(bl, x, y, 0) )
return 1;
}
}
if (!unit_can_reach_pos(bl, ud->to_x, ud->to_y, 0))
return 1;
}
ud->to_x = x;
ud->to_y = y;
return 0;
}

View File

@@ -112,7 +112,7 @@ int unit_walktoxy(struct block_list *bl, short x, short y, unsigned char flag);
int unit_walktobl(struct block_list *bl, struct block_list *target, int range, unsigned char flag);
void unit_run_hit(struct block_list *bl, struct status_change *sc, struct map_session_data *sd, enum sc_type type);
bool unit_run(struct block_list *bl, struct map_session_data *sd, enum sc_type type);
int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir);
int unit_calc_pos(struct block_list *bl, int tx, int ty);
int unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data);
int unit_delay_walktobl_timer(int tid, unsigned int tick, int id, intptr_t data);