Fixes NPC_RUN behavior (#5236)

* Fixes #3622 and fixes #5220.
* Monsters now properly escape from the attacker.
* NPC_RUN should determine distance based on skill level > 1.
* Resolves Sphere Mine when summoned by an Alchemist not escaping.
Thanks to @Balferian, @Indigo000, and @Daegaladh!
This commit is contained in:
Aleos
2020-07-28 14:57:09 -04:00
committed by GitHub
parent 2e88b27b9b
commit fcdcce2cfa
6 changed files with 25 additions and 13 deletions

View File

@@ -714,12 +714,11 @@
1141,Marina@NPC_CRITICALSLASH,attack,170,1,500,500,5000,no,target,always,0,,,,,,6,
1141,Marina@NPC_EMOTION,walk,197,1,2000,0,5000,yes,self,always,0,19,,,,,,
1141,Marina@NPC_WATERATTACK,attack,184,2,500,500,5000,no,target,always,0,,,,,,6,
1142,Marine Sphere@NPC_RUN,idle,354,7,10000,0,30000,no,master,alchemist,,,,,,,26,
1142,Marine Sphere@NPC_SELFDESTRUCTION,any,173,1,10000,3000,0,no,self,afterskill,354,,,,,,,
1142,Marine Sphere@NPC_RANDOMMOVE,idle,331,1,10000,0,30000,yes,target,alchemist,,,,,,,,
1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,3000,0,yes,self,alchemist,,,,,,,,
1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,500,2000,5000,no,self,myhpltmaxrate,99,,,,,,,
1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,2000,5000,no,self,skillused,173,,,,,,,
//1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,0,0,yes,self,always,0,,,,,,,
//1142,Marine Sphere@NPC_SPEEDUP,any,332,1,10000,0,700,yes,self,always,0,,,,,,,
1142,Marine Sphere@NPC_SPEEDUP,idle,332,1,10000,0,700,yes,target,always,,,,,,,,
1143,Marionette@HT_FREEZINGTRAP,idle,121,5,500,0,300000,yes,around2,always,0,,,,,,29,
1143,Marionette@MG_FIREWALL,chase,18,5,500,500,5000,yes,target,always,0,,,,,,2,
1143,Marionette@NPC_TELEKINESISATTACK,attack,191,5,500,0,5000,yes,target,always,0,,,,,,6,

View File

@@ -714,12 +714,11 @@
1141,Marina@NPC_CRITICALSLASH,attack,170,1,500,500,5000,no,target,always,0,,,,,,6,
1141,Marina@NPC_EMOTION,walk,197,1,2000,0,5000,yes,self,always,0,19,,,,,,
1141,Marina@NPC_WATERATTACK,attack,184,2,500,500,5000,no,target,always,0,,,,,,6,
1142,Marine Sphere@NPC_RUN,idle,354,7,10000,0,30000,no,master,alchemist,,,,,,,26,
1142,Marine Sphere@NPC_SELFDESTRUCTION,any,173,1,10000,3000,0,no,self,afterskill,354,,,,,,,
1142,Marine Sphere@NPC_RANDOMMOVE,idle,331,1,10000,0,30000,yes,target,alchemist,,,,,,,,
1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,3000,0,yes,self,alchemist,,,,,,,,
1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,500,2000,5000,no,self,myhpltmaxrate,99,,,,,,,
1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,2000,5000,no,self,skillused,173,,,,,,,
//1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,0,0,yes,self,always,0,,,,,,,
//1142,Marine Sphere@NPC_SPEEDUP,any,332,1,10000,0,700,yes,self,always,0,,,,,,,
1142,Marine Sphere@NPC_SPEEDUP,idle,332,1,10000,0,700,yes,target,always,,,,,,,,
1143,Marionette@HT_FREEZINGTRAP,idle,121,5,500,0,300000,yes,around2,always,0,,,,,,29,
1143,Marionette@MG_FIREWALL,chase,18,5,500,500,5000,yes,target,always,0,,,,,,2,
1143,Marionette@NPC_TELEKINESISATTACK,attack,191,5,500,0,5000,yes,target,always,0,,,,,,6,

View File

@@ -2433,6 +2433,7 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
if( md->special_state.ai == AI_SPHERE ) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex]
md->state.alchemist = 1;
mobskill_use(md, gettick(), MSC_ALCHEMIST);
unit_escape(&md->bl, src, 7, 2);
}
}

View File

@@ -8800,8 +8800,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case NPC_RUN:
if (md && unit_escape(src, bl, rnd()%10 + 1))
mob_unlocktarget(md, tick);
if (md) {
block_list* tbl = map_id2bl(md->target_id);
if (tbl) {
mob_unlocktarget(md, tick);
unit_escape(src, tbl, skill_lv > 1 ? skill_lv : AREA_SIZE, 2); // Send distance in skill level > 1
}
}
break;
case NPC_TRANSFORMATION:

View File

@@ -977,16 +977,17 @@ bool unit_run(struct block_list *bl, struct map_session_data *sd, enum sc_type t
* @param bl: Object that is running away from target
* @param target: Target
* @param dist: How far bl should run
* @param flag: unit_walktoxy flag
* @return 1: Success 0: Fail
*/
int unit_escape(struct block_list *bl, struct block_list *target, short dist)
int unit_escape(struct block_list *bl, struct block_list *target, short dist, uint8 flag)
{
uint8 dir = map_calc_dir(target, bl->x, bl->y);
while( dist > 0 && map_getcell(bl->m, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], CELL_CHKNOREACH) )
dist--;
return ( dist > 0 && unit_walktoxy(bl, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], 0) );
return ( dist > 0 && unit_walktoxy(bl, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], flag) );
}
/**
@@ -1546,6 +1547,12 @@ int unit_set_walkdelay(struct block_list *bl, t_tick tick, t_tick delay, int typ
} else {
// Don't set walk delays when already trapped.
if (!unit_can_move(bl)) {
if (bl->type == BL_MOB) {
mob_data *md = BL_CAST(BL_MOB, bl);
if (md && md->state.alchemist == 1) // Sphere Mine needs to escape, don't stop it
return 0;
}
unit_stop_walking(bl,4); //Unit might still be moving even though it can't move
return 0;
}

View File

@@ -121,7 +121,7 @@ int unit_can_move(struct block_list *bl);
int unit_is_walking(struct block_list *bl);
int unit_set_walkdelay(struct block_list *bl, t_tick tick, t_tick delay, int type);
int unit_escape(struct block_list *bl, struct block_list *target, short dist);
int unit_escape(struct block_list *bl, struct block_list *target, short dist, uint8 flag = 0);
// Instant unit changes
bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool checkpath);