소스 검색

Fixed bug report: http://rathena.org/board/tracker/issue-5958-rg-shield-spell-level-3
Added fix for shadow equipment slots in itemdb_parse_dbrow: if an item isn't shadow gear but have shadow equipment slot map-server will mark it as IT_ETC.

Lilith- 11 년 전
부모
커밋
fff04377ed
6개의 변경된 파일96개의 추가작업 그리고 92개의 파일을 삭제
  1. 1 1
      db/re/skill_db.txt
  2. 12 2
      src/map/battle.c
  3. 6 0
      src/map/itemdb.c
  4. 1 1
      src/map/pc.h
  5. 73 87
      src/map/skill.c
  6. 3 1
      src/map/status.c

+ 1 - 1
db/re/skill_db.txt

@@ -1072,7 +1072,7 @@
 2312,5,6,1,-1,0,0,5,1,no,0,0,0,weapon,0,0x0,	LG_PINPOINTATTACK,Pinpoint Attack
 2313,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,	LG_FORCEOFVANGUARD,Force of Vanguard
 2314,1,6,1,-1,0,0,1,1,no,0,0,0,weapon,0,0x0,	LG_RAGEBURST,Rage Burst
-2315,0,6,4,0,0x2,3,3,1,yes,0,0,0,none,2,0x0,	LG_SHIELDSPELL,Shield Spell
+2315,0,6,4,0:6:0,0x2,3,3,1,yes,0,0,0,none,2,0x0,	LG_SHIELDSPELL,Shield Spell
 2316,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,	LG_EXEEDBREAK,Exceed Break
 2317,0,6,2,-1,0x2,0,5,1,yes,0,0,0,none,3:4:5:6:7,0x0,	LG_OVERBRAND,Over Brand
 2318,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0,0x0,	LG_PRESTIGE,Prestige

+ 12 - 2
src/map/battle.c

@@ -1206,8 +1206,13 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 					if (((TBL_MOB*)bl)->class_==mob_splendide[i]) {
 						DAMAGE_ADDRATE(sce->val1)
 						break;
-					}
 		}
+		/* Self Buff that destroys the armor of any target hit with melee or ranged physical attacks */
+		if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 && flag&BF_WEAPON ) {
+			skill_break_equip(src,bl, EQP_ARMOR, 10000, BCT_ENEMY); // 100% chance (http://irowiki.org/wiki/Shield_Spell#Level_3_spells_.28refine_based.29)
+			status_change_end(src,SC_SHIELDSPELL_REF,INVALID_TIMER);
+		}
+	}
 		if( sc->data[SC_POISONINGWEAPON]
 			&& ((flag&BF_WEAPON) && (!skill_id || skill_id == GC_VENOMPRESSURE)) //chk skill type poison_smoke is a unit
 			&& (damage > 0 && rnd()%100 < sc->data[SC_POISONINGWEAPON]->val3 )) //did some dammage and chance ok (why no additional effect ??
@@ -3396,7 +3401,7 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
 				if( shield_data )
 					skillratio += shield_data->def * 10;
 			} else
-				skillratio += 2400;	//2500%
+				skillratio = 0; // Prevent damage since level 2 is MATK. [Aleos]
 			break;
 		case LG_MOONSLASHER:
 			skillratio += -100 + (120 * skill_lv + ((sd) ? pc_checkskill(sd,LG_OVERBRAND) : 5) * 80);
@@ -5917,6 +5922,11 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
 						rdamage += rd1 * 70 / 100; // Target receives 70% of the amplified damage. [Rytech]
 					}
 				}
+
+                if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 && !(src->type == BL_MOB && is_boss(src)) ){
+						rdamage += damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100;
+						if (rdamage < 1) rdamage = 1;
+                }
 			}
 		}
 	} else {

+ 6 - 0
src/map/itemdb.c

@@ -1080,6 +1080,12 @@ static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scr
 		id->type = IT_ETC;
 	}
 
+	if( id->type != IT_SHADOWGEAR && id->equip&EQP_SHADOW_GEAR )
+	{
+		ShowWarning("Item %d (%s) have invalid equipment slot! Making it an etc item.\n", nameid, id->jname);
+		id->type = IT_ETC;
+	}
+
 	id->wlv = cap_value(atoi(str[15]), REFINE_TYPE_ARMOR, REFINE_TYPE_MAX);
 #ifdef RENEWAL
 	itemdb_re_split_atoi(str[16],&id->elv,&id->elvmax);

+ 1 - 1
src/map/pc.h

@@ -665,7 +665,7 @@ struct {
 #define EQP_HELM (EQP_HEAD_LOW|EQP_HEAD_MID|EQP_HEAD_TOP)
 #define EQP_ACC (EQP_ACC_L|EQP_ACC_R)
 #define EQP_COSTUME (EQP_COSTUME_HEAD_TOP|EQP_COSTUME_HEAD_MID|EQP_COSTUME_HEAD_LOW|EQP_COSTUME_GARMENT)
-//#define EQP_SHADOW_GEAR (EQP_SHADOW_ARMOR|EQP_SHADOW_WEAPON|EQP_SHADOW_SHIELD|EQP_SHADOW_SHOES|EQP_SHADOW_ACC_R|EQP_SHADOW_ACC_L)
+#define EQP_SHADOW_GEAR (EQP_SHADOW_ARMOR|EQP_SHADOW_WEAPON|EQP_SHADOW_SHIELD|EQP_SHADOW_SHOES|EQP_SHADOW_ACC_R|EQP_SHADOW_ACC_L)
 #define EQP_SHADOW_ACC (EQP_SHADOW_ACC_R|EQP_SHADOW_ACC_L)
 
 /// Equip positions that use a visible sprite

+ 73 - 87
src/map/skill.c

@@ -8798,110 +8798,96 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 
 	case LG_SHIELDSPELL:
-		if( flag&1 ) {
-			int duration = (sd) ? sd->bonus.shieldmdef * 2000 : 10000;
-			sc_start(src,bl,SC_SILENCE,100,skill_lv,duration);
-		} else if( sd ) {
-			int opt = skill_lv;
-			int rate = rnd()%100;
-			int val, brate;
+		if( flag&1 )
+			sc_start(src,bl,SC_SILENCE,100,skill_lv,(sd)?sd->bonus.shieldmdef * 2000 : 10000);
+		else if( sd ) {
+			int opt = rnd()%3 + 1;
+			int val = 0, splash = 0;
+			struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
+			if( !shield_data || shield_data->type != IT_ARMOR ) {	// No shield?
+				clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
+				break;
+			}
 			switch( skill_lv ) {
-				case 1:
-					{
-						struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
-						if( !shield_data || shield_data->type != IT_ARMOR ) {	// No shield?
-							clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
-							break;
-						}
-						brate = shield_data->def * 10;
-						if( rate < 50 )
-							opt = 1;
-						else if( rate < 75 )
-							opt = 2;
-						else
-							opt = 3;
-
-						switch( opt ) {
-							case 1:
-								sc_start(src,bl,SC_SHIELDSPELL_DEF,100,opt,-1);
-								clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
-								if( rate < brate )
-									map_foreachinrange(skill_area_sub,src,skill_get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
-								status_change_end(bl,SC_SHIELDSPELL_DEF,INVALID_TIMER);
-								break;
-							case 2:
-								val = shield_data->def / 10; // % Reflected damage.
-								sc_start2(src,bl,SC_SHIELDSPELL_DEF,brate,opt,val,shield_data->def * 1000);
-								break;
-							case 3:
-								val = shield_data->def; // Attack increase.
-								sc_start2(src,bl,SC_SHIELDSPELL_DEF,brate,opt,val,shield_data->def * 3000);
-								break;
-						}
+				case 1: // DEF based
+					val = shield_data->def;
+					if( !val ) {
+						clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
+						break;
 					}
-					break;
-
-				case 2:
-					brate = sd->bonus.shieldmdef * 20;
-					if( rate < 30 )
-						opt = 1;
-					else if( rate < 60 )
-						opt = 2;
-					else
-						opt = 3;
 					switch( opt ) {
-						case 1:
-							sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,-1);
+						case 1: // Deals Neutral property damage around Self. Knocks them back 2 cells.
+							if( val < 41 )
+								splash = 1;
+							else if( val < 81 )
+								splash = 2;
+							else
+								splash = 3;
 							clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
-							if( rate < brate )
-								map_foreachinrange(skill_area_sub,src,skill_get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|2,skill_castend_damage_id);
-							status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER);
+							map_foreachinrange(skill_area_sub,src,splash,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
 							break;
-						case 2:
-							sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,-1);
-							clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
-							if( rate < brate )
-								map_foreachinrange(skill_area_sub,src,skill_get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id);
+						case 2: // Reflects melee attacks. (Does not work against Bosses).
+							val = shield_data->def / 10;
+							sc_start2(src,bl,SC_SHIELDSPELL_DEF,100,opt,val,shield_data->def * 1000);
 							break;
-						case 3:
-							if( sc_start(src,bl,SC_SHIELDSPELL_MDEF,brate,opt,sd->bonus.shieldmdef * 30000) )
-								clif_skill_nodamage(src,bl,PR_MAGNIFICAT,skill_lv,
-								sc_start(src,bl,SC_MAGNIFICAT,100,1,sd->bonus.shieldmdef * 30000));
+						case 3: // Increases ATK for the spell duration.
+							val = shield_data->def;
+							sc_start2(src,bl,SC_SHIELDSPELL_DEF,100,opt,val,shield_data->def * 3000);
 							break;
 					}
 					break;
 
-				case 3:
-				{
-					struct item *it = &sd->status.inventory[sd->equip_index[EQI_HAND_L]];
-					if( !it ) {	// No shield?
-						clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+				case 2: // MDEF based
+					val = sd->bonus.shieldmdef;
+					if( !val ) {
+						clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
 						break;
 					}
-					brate = it->refine * 5;
-					if( rate < 25 )
-						opt = 1;
-					else if( rate < 50 )
-						opt = 2;
+					if( val < 4 )
+						splash = 1;
+					else if( val < 6 )
+						splash = 2;
 					else
-						opt = 3;
+						splash = 3;
+
 					switch( opt ) {
-						case 1:
-							val = 105 * it->refine / 10;
-							sc_start2(src,bl,SC_SHIELDSPELL_REF,brate,opt,val,skill_get_time(skill_id,skill_lv));
+						case 1: // Deals Holy property magic damage around Self.
+							clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+							map_foreachinrange(skill_area_sub,src,splash,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|2,skill_castend_damage_id);
 							break;
-						case 2: case 3:
-							if( rate < brate )
-							{
-								val = sstatus->max_hp * (11 + it->refine) / 100;
-								status_heal(bl, val, 0, 3);
-							}
+						case 2: // Casts Lex Divina around Self.
+							//sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER);
+							clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+							map_foreachinrange(skill_area_sub,src,splash,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id);
+							break;
+						case 3: // Casts Magnificat.
+							clif_skill_nodamage(src,bl,PR_MAGNIFICAT,skill_lv,sc_start(src,bl,SC_MAGNIFICAT,100,1,sd->bonus.shieldmdef * 30000));
 							break;
-						/*case 3:
-							// Full protection. I need confirm what effect should be here. Moved to case 2 to until we got it.
-							break;*/
 					}
-				}
+					break;
+
+				case 3: // refine based
+					{
+						struct item *shield = &sd->status.inventory[sd->equip_index[EQI_HAND_L]];
+						if( !shield || !shield->refine ) {
+							clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+							break;
+						}
+						switch( opt ) {
+							case 1: // Allows you to break armor at a 100% rate when you do damage.
+								sc_start(src,bl,SC_SHIELDSPELL_REF,100,opt,min(shield->refine * 1500,30000)); // 30 sec duration on +20 shield.
+								break;
+							case 2: // Increases DEF and Status Effect resistance depending on Shield refine rate.
+								val = (10 * shield->refine) + (status_get_lv(src) / 100);
+								splash = (2 * shield->refine) + (status_get_luk(src) / 10);
+								sc_start4(src,bl,SC_SHIELDSPELL_REF,100,opt,val,splash,0,shield->refine * 20000);
+								break;
+							case 3: // Recovers HP depending on Shield refine rate.
+								val = sstatus->max_hp * (status_get_lv(src) / 10 + shield->refine) / 100;
+								status_heal(bl,val,0,2);
+								break;
+						}
+					}
 				break;
 			}
 			clif_skill_nodamage(src,bl,skill_id,skill_lv,1);

+ 3 - 1
src/map/status.c

@@ -5356,7 +5356,7 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
 		return 0;
 	if(sc->data[SC_SUN_COMFORT])
 		def2 += sc->data[SC_SUN_COMFORT]->val2;
-	if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 )
+	if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2 )
 		def2 += sc->data[SC_SHIELDSPELL_REF]->val2;
 	if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
 		def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
@@ -6987,6 +6987,8 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
 			sc_def += sc->data[SC_SCRESIST]->val1*100; // Status resist
 		else if (sc->data[SC_SIEGFRIED])
 			sc_def += sc->data[SC_SIEGFRIED]->val3*100; // Status resistance.
+		else if (sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2)
+			sc_def += sc->data[SC_SIEGFRIED]->val3*100;
 	}
 
 	// When tick def not set, reduction is the same for both.