summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-03-29 14:53:22 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-03-29 14:53:22 +0000
commit5498a520d7b5bc65d8b8c2ab949cf2986848c104 (patch)
tree344e3e2fc87dc5bc3a515730da90423ee3074dc1 /src/map
parent008f7c84a7220474b1c6a8a0463dc72d3e3364d5 (diff)
downloadhercules-5498a520d7b5bc65d8b8c2ab949cf2986848c104.tar.gz
hercules-5498a520d7b5bc65d8b8c2ab949cf2986848c104.tar.bz2
hercules-5498a520d7b5bc65d8b8c2ab949cf2986848c104.tar.xz
hercules-5498a520d7b5bc65d8b8c2ab949cf2986848c104.zip
- 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5796 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r--src/map/mob.c72
-rw-r--r--src/map/skill.c29
-rw-r--r--src/map/status.c8
-rw-r--r--src/map/unit.c6
4 files changed, 71 insertions, 44 deletions
diff --git a/src/map/mob.c b/src/map/mob.c
index a344375b1..e42df3412 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -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.
if (md->state.provoke_flag && bl->id != md->state.provoke_flag)
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)
md->min_chase=MAX_MINCHASE;
return 0;
@@ -839,7 +839,9 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
(*target) = bl;
md->target_id=bl->id;
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;
}
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)) {
md->target_id=tbl->id;
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)
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.
- 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 (abl && (!tbl || mob_can_changetarget(md, abl, mode))) {
+ if (md->attacked_id == md->target_id)
+ {
+ 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 ||
(dist = distance_bl(&md->bl, abl)) >= 32 ||
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) ||
( //Gangster Paradise check
abl->type == BL_PC && !(mode&MD_BOSS) &&
- ((struct map_session_data*)abl)->state.gangsterparadise
+ ((TBL_PC*)abl)->state.gangsterparadise
)
) { //Can't attack back
if (md->attacked_count++ > 3) {
@@ -1178,15 +1187,13 @@ 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)
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_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)
return 0; //Already attacking the current target.
@@ -1217,43 +1224,44 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
if (tbl->type != BL_ITEM)
{ //Attempt to attack.
//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))
{ //Out of range...
mob_stop_attack(md);
if (!(mode&MD_CANMOVE))
{ //Can't chase. Attempt to use a ranged skill at least?
- if (mobskill_use(md, tick, MSC_LONGRANGEATTACKED) == 0)
- md->attacked_count++; //Increase rude-attacked count as it can't attack back.
+ mobskill_use(md, tick, MSC_LONGRANGEATTACKED);
mob_unlocktarget(md,tick);
return 0;
}
- if (!can_move) //Wait until you can move?
- return 0;
//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;
mobskill_use (md, tick, -1);
+ if (!can_move) //Wait until you can move?
+ return 0;
if (md->ud.walktimer != -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.
) {
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.
i = j = 0;
dx = tbl->x - md->bl.x;
diff --git a/src/map/skill.c b/src/map/skill.c
index aa93b5d1b..dbeee7879 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -737,22 +737,32 @@ int skill_get_range2(struct block_list *bl, int id, int lv) {
return status_get_range(bl);
range *=-1;
}
- //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
- || id == SN_FALCONASSAULT || id == SN_SHARPSHOOTING || id == HT_POWER) {
+ //TODO: Find a way better than hardcoding the list of skills affected by AC_VULTURE
+ switch (id) {
+ 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)
range += pc_checkskill((struct map_session_data *)bl, AC_VULTURE);
else
range += 10; //Assume level 10?
- }
-
+ break;
// 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
- || id == GS_SPREADATTACK || id == GS_GROUNDDRIFT) {
+ case GS_RAPIDSHOWER:
+ case GS_TRACKING:
+ case GS_PIERCINGSHOT:
+ case GS_FULLBUSTER:
+ case GS_SPREADATTACK:
+ case GS_GROUNDDRIFT:
if (bl->type == BL_PC)
range += pc_checkskill((struct map_session_data *)bl, GS_SNAKEEYE);
else
range += 10; //Assume level 10?
+ break;
}
return range;
@@ -5483,6 +5493,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case SG_FEEL:
if (sd) {
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_parse_ReqFeel(sd->fd,sd, skilllv);
}
diff --git a/src/map/status.c b/src/map/status.c
index a0dda48a1..72934420c 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -3490,7 +3490,7 @@ int status_get_sc_tick(struct block_list *bl, int type, int tick)
if (rate >0)
tick -= tick*rate/10000;
else
- tick -= rate;
+ tick += rate;
}
return tick<min?min:tick;
}
@@ -5195,7 +5195,11 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
#ifndef _WIN32
nullpo_retr_f(0, bl, "id=%d data=%d",id,data);
#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)
sd=(struct map_session_data *)bl;
diff --git a/src/map/unit.c b/src/map/unit.c
index d40ba59da..fee09279c 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -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]
ud->to_x = bl->x;
ud->to_y = bl->y;
- if (bl->type == BL_NPC) //Original eA code had this one only for BL_NPCs
- clif_fixpos(bl);
+// if (bl->type == BL_NPC) //Original eA code had this one only for BL_NPCs
+// clif_fixpos(bl);
}
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)
sc = NULL; //Unneeded
//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_inf2(skill_num)&INF2_NO_TARGET_SELF);
if (temp)