Browse Source

* Updated Sharp Shooting AoE code
* Tidied up explicit typecasts in status_get_max_hp
* Non-MVP / miniboss summoned monsters should give exp
* Fixed a typo that was blocking packet version 5 clients (628sak) from logging in

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@1042 54d463be-8e91-2dee-dedb-b68131a5f0ec

(no author) 20 years ago
parent
commit
186b5767f3
8 changed files with 137 additions and 61 deletions
  1. 12 0
      Changelog.txt
  2. 1 1
      db/skill_cast_db.txt
  3. 1 1
      db/skill_db.txt
  4. 2 2
      src/map/battle.c
  5. 1 1
      src/map/clif.c
  6. 8 2
      src/map/mob.c
  7. 44 2
      src/map/skill.c
  8. 68 52
      src/map/status.c

+ 12 - 0
Changelog.txt

@@ -1,5 +1,17 @@
 Date	Added
 
+02/05
+        * Updated Sharp Shooting AoE code, thanks to Neodis / k-Athena [celest]
+          - Update: Adapt jA's path_search algorithm and removed the need of struct
+            'dev' in map_session_data
+          - Update: Increase range to 14
+        * Tidied up explicit typecasts in status_get_max_hp, thanks to Ilpalazzo-sama
+          [celest]
+        * Non-MVP / miniboss summoned monsters should give exp, my mistake ^^; [celest]
+          Note:- minibosses are considered a 'Boss' as well, not just MVP's
+        * Fixed a typo that was preventing packet version 5 clients (628sak) from
+          logging in (it was supposed to only block those with 4 or below) [celest]
+
 02/04
         * Fixed more compile signed/unsigned errors [SVN 1040: MouseJstr]
 	* TXT convertors now read the import command in inter_athena.conf

+ 1 - 1
db/skill_cast_db.txt

@@ -242,7 +242,7 @@
 379,0,1000:1200:1400:1600:1800:2000:2200:2400:2600:2800,0,0	//ASC_BREAKER
 380,0,0,30000,0 //SN_SIGHT#トゥルーサイト# 
 381,1000,1200,0,0,0	//SN_FALCONASSAULT
-382,2000,0,0,0	//SN_SHARPSHOOTING
+382,2000,500,0,0	//SN_SHARPSHOOTING
 383,2000:2400:2800:3200:3600:4000:4400:4800:5200:5600,0,130000:160000:190000:220000:250000:280000:310000:340000:370000:400000,0	//SN_WINDWALK#ウインドウォーク#
 384,5000:5000:6000:6000:7000:7000:8000:8000:9000:10000,0,15000:20000:25000:30000:35000:40000:45000:50000:55000:60000,5000	//WS_MELTDOWN#メルトダウン#
 

+ 1 - 1
db/skill_db.txt

@@ -439,7 +439,7 @@
 379,5,6,1,0,0,10,1,no,0,0,0,weapon,0	//ASC_BREAKER#?ウルブレ?カ?#
 380,0,6,4,0,1,10,1,no,0,0,0,weapon,0	//SN_SIGHT#トゥル?サイト#
 381,9,8,1,0,0,5,1:2:3:4:5,yes,0,0,0,misc,0	//SN_FALCONASSAULT#フ?ルコンアサルト#
-382,9,8,1,0,0,5,1,no,0,0,0,weapon,0	//SN_SHARPSHOOTING#シャ?プシュ?ティング#
+382,14,8,1,0,0,5,1,no,0,0,0,weapon,0	//SN_SHARPSHOOTING#シャ?プシュ?ティング#
 383,0,6,4,0,1,10,1,yes,0,0,0,magic,0	//SN_WINDWALK#ウインドウォ?ク#
 384,0,0,4,0,1,10,1,yes,0,0,0,magic,0	//WS_MELTDOWN#メルト?ウン#
 385,0,0,4,0,1,1,1,yes,0,0,0,magic,0	//WS_CREATECOIN#クリエイトコイン#

+ 2 - 2
src/map/battle.c

@@ -1793,14 +1793,14 @@ static struct Damage battle_calc_pc_weapon_attack(
 				cri <<= 1;
 		}
 
-		if(skill_num == SN_SHARPSHOOTING && rand()%100 < 50)
+		if(skill_num == SN_SHARPSHOOTING)
 			cri += 200;
 	}
 
 	if(tsd && tsd->critical_def)
 		cri = cri * (100-tsd->critical_def) / 100;
 
-	if(da == 0 && (skill_num==0 || skill_num == KN_AUTOCOUNTER || skill_num == SN_SHARPSHOOTING) && skill_lv >= 0 && //ダブルアタックが発動していない
+	if(da == 0 && (skill_num==0 || skill_num == KN_AUTOCOUNTER || skill_num == SN_SHARPSHOOTING) && //ダブルアタックが発動していない
 		(rand() % 1000) < cri)	// 判定(スキルの場合は無視)
 	{
 		damage += atkmax;

+ 1 - 1
src/map/clif.c

@@ -10662,7 +10662,7 @@ static int clif_parse(int fd) {
 		}
 
 		// check if version is accepted
-		if (packet_ver <= 5 ||	// reject really old client versions
+		if (packet_ver < 5 ||	// reject really old client versions
 			(packet_ver <= 9 && (battle_config.packet_ver_flag &	1) == 0) ||	// older than 6sept04
 			(packet_ver == 10 && (battle_config.packet_ver_flag &	2) == 0) ||
 			(packet_ver == 11 && (battle_config.packet_ver_flag &	4) == 0) ||

+ 8 - 2
src/map/mob.c

@@ -2158,6 +2158,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
 	int mvp_damage,max_hp;
 	unsigned int tick = gettick();
 	struct map_session_data *mvp_sd = NULL, *second_sd = NULL,*third_sd = NULL;
+	struct block_list *master = NULL;
 	double tdmg,temp;
 	struct item item;
 	int ret;
@@ -2470,7 +2471,11 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
 		if(sd && battle_config.pk_mode && (mob_db[md->class_].lv - sd->status.base_level >= 20)) {
 			job_exp*=1.15; // pk_mode additional exp if monster >20 levels [Valaris]
 		}
-		if(md->master_id || (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1)) { // for summoned creatures [Valaris]
+		if(md->master_id) {
+			master = map_id2bl(md->master_id);
+		}
+		if((master && status_get_mode(master)&0x20) ||	// check if its master is a boss (MVP's and minibosses)
+			(md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1)) { // for summoned creatures [Valaris]
 			base_exp = 0;
 			job_exp = 0;
 		}
@@ -2530,7 +2535,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
 			struct delay_item_drop *ditem;
 			int drop_rate;
 
-			if(md->master_id || (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1))	// Added [Valaris]
+			if((master && status_get_mode(master)&0x20) ||	// check if its master is a boss (MVP's and minibosses)
+				(md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1))	// Added [Valaris]
 				break;	// End
 
 			if(mob_db[md->class_].dropitem[i].nameid <= 0)

+ 44 - 2
src/map/skill.c

@@ -33,8 +33,8 @@
 #endif
 
 #define SKILLUNITTIMER_INVERVAL	100
-
 #define STATE_BLIND 0x10
+#define swap(x,y) { int t; t = x; x = y; y = t; }
 
 /* スキル番?=>ステ?タス異常番??換テ?ブル */
 int SkillStatusChangeTable[]={	/* skill.hのenumのSC_***とあわせること */
@@ -1673,6 +1673,9 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
 	case NPC_SELFDESTRUCTION:
 	case NPC_SELFDESTRUCTION2:
 		break;
+	case SN_SHARPSHOOTING:
+		clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,0,0,0);
+		break;
 	default:
 		clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, (lv!=0)?lv:skilllv, (skillid==0)? 5:type );
 	}
@@ -2284,13 +2287,52 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s
 	case LK_JOINTBEAT:	/* ジョイントビ?ト */
 //	case PA_PRESSURE:	/* プレッシャ? */
 //	case PA_SACRIFICE:	/* サクリファイス */
-	case SN_SHARPSHOOTING:			/* シャ?プシュ?ティング */
+//	case SN_SHARPSHOOTING:			/* シャ?プシュ?ティング */
 	case CG_ARROWVULCAN:			/* アロ?バルカン */
 	case ASC_BREAKER:				/* ソウルブレ?カ? */
 	case HW_MAGICCRASHER:		/* マジッククラッシャ? */
 	case ITM_TOMAHAWK:
 		skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
 		break;
+
+	case SN_SHARPSHOOTING:			/* シャ?プシュ?ティング */
+		{
+			int dx, dy, wx = 0, wy = 0;
+			int weight, num = 0;
+			int x1 = src->x, y1 = src->y;
+			int x0 = bl->x, y0 = bl->y;
+
+			dx = (x1 - x0);
+			if (dx < 0) {
+				swap(x0, x1);
+				swap(y0, y1);
+				dx = -dx;
+			}
+			dy = (y1 - y0);
+			weight = dx > abs(dy) ? dx : abs(y1 - y0);
+			while ((x0 != x1 || y0 != y1) && num < skill_get_range(skillid)) {
+				wx += dx;
+				wy += dy;
+				if (wx >= weight) {
+					wx -= weight; x0 ++;
+				}
+				if (wy >= weight) {
+					wy -= weight; y0 ++;
+				} else if (wy < 0) {
+					wy += weight; y0 --;
+				}
+				if (x0 == x1) {
+					if (dy > 0) { y0++; }
+					else { y0--; }
+				}
+				map_foreachinarea (skill_attack_area,src->m,x0,y0,x0,y0,0,
+						BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY);
+				num++;	// make sure it doesn't run infinitely
+			}
+			clif_skill_nodamage(src,bl,skillid,skilllv,1);
+		}
+		break;
+
 	case PA_PRESSURE:	/* プレッシャ? */
 		skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
 		if (rand()%100 < 50)

+ 68 - 52
src/map/status.c

@@ -1383,16 +1383,22 @@ int status_get_hp(struct block_list *bl)
 int status_get_max_hp(struct block_list *bl)
 {
 	nullpo_retr(1, bl);
+
 	if(bl->type==BL_PC && ((struct map_session_data *)bl))
 		return ((struct map_session_data *)bl)->status.max_hp;
 	else {
-		struct status_change *sc_data=status_get_sc_data(bl);
-		int max_hp=1;
-		if(bl->type==BL_MOB && ((struct mob_data*)bl)) {
-			max_hp = mob_db[((struct mob_data*)bl)->class_].max_hp;
+		struct status_change *sc_data;		
+		int max_hp = 1;
+
+		if(bl->type == BL_MOB) {
+			struct mob_data *md;
+			nullpo_retr(1, md = (struct mob_data *)bl);
+			max_hp = mob_db[md->class_].max_hp;
+
 			if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris]
-				max_hp+=(((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv)*status_get_vit(bl);
-			if(mob_db[((struct mob_data*)bl)->class_].mexp > 0) {
+				max_hp += (md->level - mob_db[md->class_].lv) * status_get_vit(bl);
+
+			if(mob_db[md->class_].mexp > 0) {
 				if(battle_config.mvp_hp_rate != 100)
 					max_hp = (max_hp * battle_config.mvp_hp_rate)/100;
 			}
@@ -1401,9 +1407,12 @@ int status_get_max_hp(struct block_list *bl)
 					max_hp = (max_hp * battle_config.monster_hp_rate)/100;
 			}
 		}
-		else if(bl->type==BL_PET && ((struct pet_data*)bl)) {
-			max_hp = mob_db[((struct pet_data*)bl)->class_].max_hp;
-			if(mob_db[((struct pet_data*)bl)->class_].mexp > 0) {
+		else if(bl->type == BL_PET) {
+			struct pet_data *pd;
+			nullpo_retr(1, pd = (struct pet_data*)bl);
+			max_hp = mob_db[pd->class_].max_hp;
+
+			if(mob_db[pd->class_].mexp > 0) {
 				if(battle_config.mvp_hp_rate != 100)
 					max_hp = (max_hp * battle_config.mvp_hp_rate)/100;
 			}
@@ -1412,11 +1421,13 @@ int status_get_max_hp(struct block_list *bl)
 					max_hp = (max_hp * battle_config.monster_hp_rate)/100;
 			}
 		}
+
+		sc_data = status_get_sc_data(bl);
 		if(sc_data) {
-			if(sc_data[SC_APPLEIDUN].timer!=-1)
-				max_hp += ((5+sc_data[SC_APPLEIDUN].val1*2+((sc_data[SC_APPLEIDUN].val2+1)>>1)
-						+sc_data[SC_APPLEIDUN].val3/10) * max_hp)/100;
-			if(sc_data[SC_GOSPEL].timer!=-1 &&
+			if(sc_data[SC_APPLEIDUN].timer != -1)
+				max_hp += ((5 + sc_data[SC_APPLEIDUN].val1 * 2 + ((sc_data[SC_APPLEIDUN].val2 + 1) >> 1)
+					+ sc_data[SC_APPLEIDUN].val3 / 10) * max_hp)/100;
+			if(sc_data[SC_GOSPEL].timer != -1 &&
 				sc_data[SC_GOSPEL].val4 == BCT_PARTY &&
 				sc_data[SC_GOSPEL].val3 == 4)
 				max_hp += max_hp * 25 / 100;
@@ -2108,36 +2119,39 @@ int status_get_mdef(struct block_list *bl)
  */
 int status_get_def2(struct block_list *bl)
 {
-	struct status_change *sc_data;
-	int def2=1;
-
+	int def2 = 1;
 	nullpo_retr(1, bl);
-	sc_data=status_get_sc_data(bl);
+	
 	if(bl->type==BL_PC)
-		def2 = ((struct map_session_data *)bl)->def2;
-	else if(bl->type==BL_MOB)
-		def2 = mob_db[((struct mob_data *)bl)->class_].vit;
-	else if(bl->type==BL_PET)
-		def2 = mob_db[((struct pet_data *)bl)->class_].vit;
-
-	if(bl->type != BL_PC && sc_data) {
-		if( sc_data[SC_ANGELUS].timer!=-1)
-			def2 = def2*(110+5*sc_data[SC_ANGELUS].val1)/100;
-		if( sc_data[SC_PROVOKE].timer!=-1)
-			def2 = (def2*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100;
-		if(sc_data[SC_POISON].timer!=-1)
-			def2 = def2*75/100;
-		//コンセントレーション時は減算
-		if( sc_data[SC_CONCENTRATION].timer!=-1)
-			def2 = def2*(100 - 5*sc_data[SC_CONCENTRATION].val1)/100;
-
-		if(sc_data[SC_GOSPEL].timer!=-1) {
-			if (sc_data[SC_GOSPEL].val4 == BCT_PARTY &&
-				sc_data[SC_GOSPEL].val3 == 11)
-				def2 += def2*25/100;
-			else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY &&
-				sc_data[SC_GOSPEL].val3 == 5)
-				def2 = 0;
+		return ((struct map_session_data *)bl)->def2;
+	else {
+		struct status_change *sc_data;
+
+		if(bl->type==BL_MOB)
+			def2 = mob_db[((struct mob_data *)bl)->class_].vit;
+		else if(bl->type==BL_PET)
+			def2 = mob_db[((struct pet_data *)bl)->class_].vit;
+
+		sc_data = status_get_sc_data(bl);
+		if(sc_data) {
+			if(sc_data[SC_ANGELUS].timer != -1)
+				def2 = def2*(110+5*sc_data[SC_ANGELUS].val1)/100;
+			if(sc_data[SC_PROVOKE].timer!=-1)
+				def2 = (def2*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100;
+			if(sc_data[SC_POISON].timer!=-1)
+				def2 = def2*75/100;
+			//コンセントレーション時は減算
+			if( sc_data[SC_CONCENTRATION].timer!=-1)
+				def2 = def2*(100 - 5*sc_data[SC_CONCENTRATION].val1)/100;
+
+			if(sc_data[SC_GOSPEL].timer!=-1) {
+				if (sc_data[SC_GOSPEL].val4 == BCT_PARTY &&
+					sc_data[SC_GOSPEL].val3 == 11)
+					def2 += def2*25/100;
+				else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY &&
+					sc_data[SC_GOSPEL].val3 == 5)
+					def2 = 0;
+			}
 		}
 	}
 	if(def2 < 1) def2 = 1;
@@ -2150,20 +2164,22 @@ int status_get_def2(struct block_list *bl)
  */
 int status_get_mdef2(struct block_list *bl)
 {
-	int mdef2=0;
-	struct status_change *sc_data=status_get_sc_data(bl);
-
+	int mdef2 = 0;
 	nullpo_retr(0, bl);
-	if(bl->type==BL_MOB)
-		mdef2 = mob_db[((struct mob_data *)bl)->class_].int_ + (mob_db[((struct mob_data *)bl)->class_].vit>>1);
-	else if(bl->type==BL_PC)
-		mdef2 = ((struct map_session_data *)bl)->mdef2 + (((struct map_session_data *)bl)->paramc[2]>>1);
-	else if(bl->type==BL_PET)
-		mdef2 = mob_db[((struct pet_data *)bl)->class_].int_ + (mob_db[((struct pet_data *)bl)->class_].vit>>1);
-	if(sc_data) {
-			if( sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC)
+
+	if(bl->type == BL_PC)
+		return ((struct map_session_data *)bl)->mdef2 + (((struct map_session_data *)bl)->paramc[2]>>1);
+	else {
+		struct status_change *sc_data = status_get_sc_data(bl);
+		if(bl->type == BL_MOB)
+			mdef2 = mob_db[((struct mob_data *)bl)->class_].int_ + (mob_db[((struct mob_data *)bl)->class_].vit>>1);
+		else if(bl->type == BL_PET)
+			mdef2 = mob_db[((struct pet_data *)bl)->class_].int_ + (mob_db[((struct pet_data *)bl)->class_].vit>>1);
+		if(sc_data) {
+			if(sc_data[SC_MINDBREAKER].timer!=-1)
 				mdef2 -= (mdef2*6*sc_data[SC_MINDBREAKER].val1)/100;
 		}
+	}
 	if(mdef2 < 0) mdef2 = 0;
 		return mdef2;
 }