- Some cleaning of the mob_ai. Mobs should stop chasing once you are beyond their min_chase range. Improved rude-attacked checking when mobs can't move.

- range3 is now used as min-chase value of mobs.
- Added a debug message when status_change_timer fails.
- Fixed tick direct modifications increasing duration instead of decreasing it.
- Fixed inf2 of Jump-Kick to make it a "combo-skill" so that it may do a BCT_ENEMY check.
- When sd->state.skill_flag is set, auto-targetting through combo-skills is disabled. 
- You can't SG_FEEL maps already memorized.


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5796 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2006-03-29 14:53:22 +00:00
parent 9426cf84ad
commit b286e0af1e
7 changed files with 85 additions and 45 deletions

View File

@ -3,6 +3,16 @@ Date Added
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/03/29
* Some cleaning of the mob_ai. Mobs should stop chasing once you are beyond
their min_chase range. Improved rude-attacked checking when mobs can't
move. [Skotlex]
* range3 is now used as min-chase value of mobs. [Skotlex]
* Added a debug message when status_change_timer fails. Report it next time
it shows up. [Skotlex]
* Fixed tick direct modifications increasing duration instead of decreasing
it. [Skotlex]
* You can't SG_FEEL maps already memorized. [Skotlex]
2006/03/28 2006/03/28
* Fixed the Family recall warp skills. [Skotlex] * Fixed the Family recall warp skills. [Skotlex]
* Fixed pc_percentheal giving life when the rates are negative. [Skotlex] * Fixed pc_percentheal giving life when the rates are negative. [Skotlex]

View File

@ -26,6 +26,9 @@
========================= =========================
03/29
* Fixed inf2 of Jump-Kick to make it a "combo-skill" so that it may do a
BCT_ENEMY check. [Skotlex]
03/28 03/28
* Changed droprate of Einbroch/Lighthalzen monsters. [Vicious] * Changed droprate of Einbroch/Lighthalzen monsters. [Vicious]
03/27 * Removed EVENT bonuses from event items: [Lupus] 03/27 * Removed EVENT bonuses from event items: [Lupus]

View File

@ -440,7 +440,7 @@
418,0,6,4,0,1,0,1,1,no,0,0,0,weapon,0 //TK_READYCOUNTER#Prepare Counter Kick# 418,0,6,4,0,1,0,1,1,no,0,0,0,weapon,0 //TK_READYCOUNTER#Prepare Counter Kick#
419,-2,6,4,-1,0,0,7,1,no,0,512,0,weapon,0 //TK_COUNTER#Counter Kick# 419,-2,6,4,-1,0,0,7,1,no,0,512,0,weapon,0 //TK_COUNTER#Counter Kick#
420,0,6,4,0,1,0,1,1,no,0,0,0,weapon,0 //TK_DODGE#Break Fall# 420,0,6,4,0,1,0,1,1,no,0,0,0,weapon,0 //TK_DODGE#Break Fall#
421,10,6,4,-1,0,0,7,1,no,0,0,0,weapon,0 //TK_JUMPKICK#Flying Side Kick# 421,10,6,4,-1,0,0,7,1,no,0,512,0,weapon,0 //TK_JUMPKICK#Flying Side Kick#
422,0,0,0,0,0,1,10,0,no,0,0,0,none,0 //TK_HPTIME#Peaceful Rest# 422,0,0,0,0,0,1,10,0,no,0,0,0,none,0 //TK_HPTIME#Peaceful Rest#
423,0,0,0,0,0,1,10,0,no,0,0,0,none,0 //TK_SPTIME#Enjoyable Rest# 423,0,0,0,0,0,1,10,0,no,0,0,0,none,0 //TK_SPTIME#Enjoyable Rest#
424,0,0,0,0,0,0,5,0,no,0,0,0,weapon,0 //TK_POWER#Fighting Chant# 424,0,0,0,0,0,0,5,0,no,0,0,0,weapon,0 //TK_POWER#Fighting Chant#

View File

@ -800,7 +800,7 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist)
md->target_id = bl->id; // Since there was no disturbance, it locks on to target. md->target_id = bl->id; // Since there was no disturbance, it locks on to target.
if (md->state.provoke_flag && bl->id != md->state.provoke_flag) if (md->state.provoke_flag && bl->id != md->state.provoke_flag)
md->state.provoke_flag = 0; md->state.provoke_flag = 0;
md->min_chase=dist+md->db->range2; md->min_chase=dist+md->db->range3;
if(md->min_chase>MAX_MINCHASE) if(md->min_chase>MAX_MINCHASE)
md->min_chase=MAX_MINCHASE; md->min_chase=MAX_MINCHASE;
return 0; return 0;
@ -839,7 +839,9 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
(*target) = bl; (*target) = bl;
md->target_id=bl->id; md->target_id=bl->id;
md->state.aggressive = (status_get_mode(&md->bl)&MD_ANGRY)?1:0; md->state.aggressive = (status_get_mode(&md->bl)&MD_ANGRY)?1:0;
md->min_chase= md->db->range3; md->min_chase= dist + md->db->range3;
if(md->min_chase>MAX_MINCHASE)
md->min_chase=MAX_MINCHASE;
return 1; return 1;
} }
break; break;
@ -1001,7 +1003,7 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
if (tbl && status_check_skilluse(&md->bl, tbl, 0, 0)) { if (tbl && status_check_skilluse(&md->bl, tbl, 0, 0)) {
md->target_id=tbl->id; md->target_id=tbl->id;
md->state.aggressive = (status_get_mode(&md->bl)&MD_ANGRY)?1:0; md->state.aggressive = (status_get_mode(&md->bl)&MD_ANGRY)?1:0;
md->min_chase=md->db->range2+distance_bl(&md->bl, tbl); md->min_chase=md->db->range3+distance_bl(&md->bl, tbl);
if(md->min_chase>MAX_MINCHASE) if(md->min_chase>MAX_MINCHASE)
md->min_chase=MAX_MINCHASE; md->min_chase=MAX_MINCHASE;
} }
@ -1130,10 +1132,17 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
} }
// Check for target change. // Check for target change.
if (md->attacked_id && mode&MD_CANATTACK && md->attacked_id != md->target_id) if (md->attacked_id && mode&MD_CANATTACK)
{ {
abl = map_id2bl(md->attacked_id); if (md->attacked_id == md->target_id)
if (abl && (!tbl || mob_can_changetarget(md, abl, mode))) { {
if (!can_move && !battle_check_range (&md->bl, tbl, md->db->range))
{ //Rude-attacked.
if (md->attacked_count++ > 3)
mobskill_use(md, tick, MSC_RUDEATTACKED);
}
} else
if ((abl= map_id2bl(md->attacked_id)) && (!tbl || mob_can_changetarget(md, abl, mode))) {
if (md->bl.m != abl->m || abl->prev == NULL || if (md->bl.m != abl->m || abl->prev == NULL ||
(dist = distance_bl(&md->bl, abl)) >= 32 || (dist = distance_bl(&md->bl, abl)) >= 32 ||
battle_check_target(bl, abl, BCT_ENEMY) <= 0 || battle_check_target(bl, abl, BCT_ENEMY) <= 0 ||
@ -1141,7 +1150,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
!mob_can_reach(md, abl, dist+2, MSS_RUSH) || !mob_can_reach(md, abl, dist+2, MSS_RUSH) ||
( //Gangster Paradise check ( //Gangster Paradise check
abl->type == BL_PC && !(mode&MD_BOSS) && abl->type == BL_PC && !(mode&MD_BOSS) &&
((struct map_session_data*)abl)->state.gangsterparadise ((TBL_PC*)abl)->state.gangsterparadise
) )
) { //Can't attack back ) { //Can't attack back
if (md->attacked_count++ > 3) { if (md->attacked_count++ > 3) {
@ -1178,13 +1187,11 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
} }
} }
} }
}
if (md->attacked_id) {
if (md->state.aggressive && md->attacked_id == md->target_id) if (md->state.aggressive && md->attacked_id == md->target_id)
md->state.aggressive = 0; //No longer aggressive, change to retaliate AI. md->state.aggressive = 0; //No longer aggressive, change to retaliate AI.
//Clear it since it's been checked for already.
md->attacked_players = 0; md->attacked_players = 0;
md->attacked_id = 0; //Clear it since it's been checked for already. md->attacked_id = 0;
} }
if (md->ud.attacktimer != -1 && tbl && md->ud.attacktarget == tbl->id) if (md->ud.attacktimer != -1 && tbl && md->ud.attacktarget == tbl->id)
@ -1217,43 +1224,44 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
if (tbl->type != BL_ITEM) if (tbl->type != BL_ITEM)
{ //Attempt to attack. { //Attempt to attack.
//At this point we know the target is attackable, we just gotta check if the range matches. //At this point we know the target is attackable, we just gotta check if the range matches.
if (!check_distance_bl(&md->bl, tbl, view_range))
{ //Run towards the enemy when out of range?
if (!can_move) {
mob_unlocktarget(md, tick);
return 0;
}
dx = tbl->x - md->bl.x -1;
dy = tbl->y - md->bl.y -1;
unit_walktoxy(&md->bl, md->bl.x+dx, md->bl.y+dy, 0);
return 0;
}
if (!battle_check_range (&md->bl, tbl, md->db->range)) if (!battle_check_range (&md->bl, tbl, md->db->range))
{ //Out of range... { //Out of range...
mob_stop_attack(md); mob_stop_attack(md);
if (!(mode&MD_CANMOVE)) if (!(mode&MD_CANMOVE))
{ //Can't chase. Attempt to use a ranged skill at least? { //Can't chase. Attempt to use a ranged skill at least?
if (mobskill_use(md, tick, MSC_LONGRANGEATTACKED) == 0) mobskill_use(md, tick, MSC_LONGRANGEATTACKED);
md->attacked_count++; //Increase rude-attacked count as it can't attack back.
mob_unlocktarget(md,tick); mob_unlocktarget(md,tick);
return 0; return 0;
} }
if (!can_move) //Wait until you can move?
return 0;
//Follow up //Follow up
if (!mob_can_reach(md, tbl, md->min_chase, MSS_RUSH))
{ //Give up.
mob_unlocktarget(md,tick);
return 0;
}
if (!check_distance_bl(&md->bl, tbl, view_range))
{ //Run towards the enemy when out of range?
if (!can_move)
{ //Give it up.
mob_unlocktarget(md,tick);
return 0;
}
dx = tbl->x - md->bl.x -1;
dy = tbl->y - md->bl.y -1;
unit_walktoxy(&md->bl, md->bl.x+dx, md->bl.y+dy, 0);
return 0;
}
md->state.skillstate = md->state.aggressive?MSS_FOLLOW:MSS_RUSH; md->state.skillstate = md->state.aggressive?MSS_FOLLOW:MSS_RUSH;
mobskill_use (md, tick, -1); mobskill_use (md, tick, -1);
if (!can_move) //Wait until you can move?
return 0;
if (md->ud.walktimer != -1 && if (md->ud.walktimer != -1 &&
(!battle_config.mob_ai&1 || (!battle_config.mob_ai&1 ||
check_distance_blxy(tbl, md->ud.to_x, md->ud.to_y, md->db->range)) //Current target tile is still within attack range. check_distance_blxy(tbl, md->ud.to_x, md->ud.to_y, md->db->range)) //Current target tile is still within attack range.
) { ) {
return 0; //No need to follow, already doing it? return 0; //No need to follow, already doing it?
} }
if (!mob_can_reach(md, tbl, md->min_chase, MSS_RUSH))
{ //Can't reach
mob_unlocktarget(md,tick);
return 0;
}
//Target reachable. Locate suitable spot to move to. //Target reachable. Locate suitable spot to move to.
i = j = 0; i = j = 0;
dx = tbl->x - md->bl.x; dx = tbl->x - md->bl.x;

View File

@ -737,22 +737,32 @@ int skill_get_range2(struct block_list *bl, int id, int lv) {
return status_get_range(bl); return status_get_range(bl);
range *=-1; range *=-1;
} }
//TODO: Find a way better than hardcoding the list of skills affected by AC_VULTURE. //TODO: Find a way better than hardcoding the list of skills affected by AC_VULTURE
if (id == AC_SHOWER || id == AC_DOUBLE || id == HT_BLITZBEAT || id == AC_CHARGEARROW switch (id) {
|| id == SN_FALCONASSAULT || id == SN_SHARPSHOOTING || id == HT_POWER) { case AC_SHOWER:
case AC_DOUBLE:
case HT_BLITZBEAT:
case AC_CHARGEARROW:
case SN_FALCONASSAULT:
case SN_SHARPSHOOTING:
case HT_POWER:
if (bl->type == BL_PC) if (bl->type == BL_PC)
range += pc_checkskill((struct map_session_data *)bl, AC_VULTURE); range += pc_checkskill((struct map_session_data *)bl, AC_VULTURE);
else else
range += 10; //Assume level 10? range += 10; //Assume level 10?
} break;
// added to allow GS skills to be effected by the range of Snake Eyes [Reddozen] // added to allow GS skills to be effected by the range of Snake Eyes [Reddozen]
if (id == GS_RAPIDSHOWER || id == GS_TRACKING || id == GS_PIERCINGSHOT || id == GS_FULLBUSTER case GS_RAPIDSHOWER:
|| id == GS_SPREADATTACK || id == GS_GROUNDDRIFT) { case GS_TRACKING:
case GS_PIERCINGSHOT:
case GS_FULLBUSTER:
case GS_SPREADATTACK:
case GS_GROUNDDRIFT:
if (bl->type == BL_PC) if (bl->type == BL_PC)
range += pc_checkskill((struct map_session_data *)bl, GS_SNAKEEYE); range += pc_checkskill((struct map_session_data *)bl, GS_SNAKEEYE);
else else
range += 10; //Assume level 10? range += 10; //Assume level 10?
break;
} }
return range; return range;
@ -5483,6 +5493,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case SG_FEEL: case SG_FEEL:
if (sd) { if (sd) {
if(!sd->feel_map[skilllv-1].index) { if(!sd->feel_map[skilllv-1].index) {
for (i = 0; i<3 && sd->feel_map[i].index != sd->mapindex; i++);
if (i < 3) { //Avoid memorizing already known maps. [Skotlex]
clif_skill_fail(sd, skillid, 0, 0);
break;
}
clif_skill_nodamage(src,bl,skillid,skilllv,1); clif_skill_nodamage(src,bl,skillid,skilllv,1);
clif_parse_ReqFeel(sd->fd,sd, skilllv); clif_parse_ReqFeel(sd->fd,sd, skilllv);
} }

View File

@ -3490,7 +3490,7 @@ int status_get_sc_tick(struct block_list *bl, int type, int tick)
if (rate >0) if (rate >0)
tick -= tick*rate/10000; tick -= tick*rate/10000;
else else
tick -= rate; tick += rate;
} }
return tick<min?min:tick; return tick<min?min:tick;
} }
@ -5195,7 +5195,11 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
#ifndef _WIN32 #ifndef _WIN32
nullpo_retr_f(0, bl, "id=%d data=%d",id,data); nullpo_retr_f(0, bl, "id=%d data=%d",id,data);
#endif #endif
nullpo_retr(0, sc=status_get_sc(bl)); sc=status_get_sc(bl);
if (!sc)
{ //Temporal debug until case is resolved. [Skotlex]
ShowDebug("status_change_timer: Null pointer id: %d data: %d bl-type: %d\n", id, data, bl?bl->type:-1);
}
if(bl->type==BL_PC) if(bl->type==BL_PC)
sd=(struct map_session_data *)bl; sd=(struct map_session_data *)bl;

View File

@ -241,8 +241,8 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
{ //Stopped walking. Update to_x and to_y to current location [Skotlex] { //Stopped walking. Update to_x and to_y to current location [Skotlex]
ud->to_x = bl->x; ud->to_x = bl->x;
ud->to_y = bl->y; ud->to_y = bl->y;
if (bl->type == BL_NPC) //Original eA code had this one only for BL_NPCs // if (bl->type == BL_NPC) //Original eA code had this one only for BL_NPCs
clif_fixpos(bl); // clif_fixpos(bl);
} }
return 0; return 0;
} }
@ -680,7 +680,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int
if (sc && !sc->count) if (sc && !sc->count)
sc = NULL; //Unneeded sc = NULL; //Unneeded
//temp: used to signal combo-skills right now. //temp: used to signal combo-skills right now.
temp = (target_id == src->id temp = (target_id == src->id && !(sd && sd->state.skill_flag)
&& skill_get_inf(skill_num)&INF_SELF_SKILL && skill_get_inf(skill_num)&INF_SELF_SKILL
&& skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF); && skill_get_inf2(skill_num)&INF2_NO_TARGET_SELF);
if (temp) if (temp)