ソースを参照

- 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

skotlex 19 年 前
コミット
b286e0af1e
7 ファイル変更85 行追加45 行削除
  1. 10 0
      Changelog-Trunk.txt
  2. 3 0
      db/Changelog.txt
  3. 1 1
      db/skill_db.txt
  4. 40 32
      src/map/mob.c
  5. 22 7
      src/map/skill.c
  6. 6 2
      src/map/status.c
  7. 3 3
      src/map/unit.c

+ 10 - 0
Changelog-Trunk.txt

@@ -3,6 +3,16 @@ Date	Added
 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. 
 
+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
 	* Fixed the Family recall warp skills. [Skotlex]
 	* Fixed pc_percentheal giving life when the rates are negative. [Skotlex]

+ 3 - 0
db/Changelog.txt

@@ -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
 	* Changed droprate of Einbroch/Lighthalzen monsters. [Vicious]
 03/27	* Removed EVENT bonuses from event items: [Lupus]

+ 1 - 1
db/skill_db.txt

@@ -440,7 +440,7 @@
 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#
 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#
 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#

+ 40 - 32
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;

+ 22 - 7
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);
 			}

+ 6 - 2
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;

+ 3 - 3
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)