Bug Fixes

* Fixed Shield Spell not being able to be casted. Can now be casted even with skill_unconditional permission while wearing no shield. (bugreport:9198)
* Fixed divest chance of Earth Strain to official. (bugreport:8999)
* Cleaned up ATK and WATK calculation for some skills to only work in pre-renewal.
* Fixed Magnum Break not giving 20% Fire property damage. (bugreport:9199)
This commit is contained in:
aleos89 2014-08-12 12:32:47 -04:00
parent a0cefe9479
commit adabedba23
3 changed files with 158 additions and 101 deletions

View File

@ -4013,6 +4013,11 @@ struct Damage battle_attack_sc_bonus(struct Damage wd, struct block_list *src, u
//The following are applied on top of current damage and are stackable.
if (sc) {
#ifdef RENEWAL
if (sc->data[SC_WATK_ELEMENT])
if (skill_id != ASC_METEORASSAULT)
ATK_ADDRATE(wd.weaponAtk, wd.weaponAtk2, sc->data[SC_WATK_ELEMENT]->val2);
#endif
#ifndef RENEWAL
if( sc->data[SC_TRUESIGHT] )
ATK_ADDRATE(wd.damage, wd.damage2, 2*sc->data[SC_TRUESIGHT]->val1);

View File

@ -1298,7 +1298,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
const int pos[5] = { EQP_WEAPON, EQP_HELM, EQP_SHIELD, EQP_ARMOR, EQP_ACC };
for( i = 0; i < skill_lv; i++ )
skill_strip_equip(src,bl,pos[i],6 * skill_lv + status_get_lv(src) / 4 + status_get_dex(src) / 10,skill_lv,skill_get_time2(skill_id,skill_lv));
skill_strip_equip(src,bl,pos[i],5 * skill_lv,skill_lv,skill_get_time2(skill_id,skill_lv));
}
break;
case WL_JACKFROST:
@ -6013,7 +6013,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id, skill_lv), BL_SKILL|BL_CHAR,
src,skill_id,skill_lv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
clif_skill_nodamage (src,src,skill_id,skill_lv,1);
// Initiate 10% of your damage becomes fire element.
// Initiate 20% of your damage becomes fire element.
sc_start4(src,src,SC_WATK_ELEMENT,100,3,20,0,0,skill_get_time2(skill_id, skill_lv));
if( sd )
skill_blockpc_start(sd, skill_id, skill_get_time(skill_id, skill_lv));
@ -9172,105 +9172,117 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case LG_SHIELDSPELL:
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;
short index = sd->equip_index[EQI_HAND_L];
if (sd) {
int opt = 0;
short index = sd->equip_index[EQI_HAND_L], shield_def = 0, shield_mdef = 0, shield_refine = 0;
struct item_data *shield_data = NULL;
if( index < 0 || !(shield_data = sd->inventory_data[index]) || shield_data->type == IT_ARMOR ) { // No shield?
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR)
shield_data = sd->inventory_data[index];
if (!shield_data || shield_data->type != IT_ARMOR) // Group with 'skill_unconditional' gets these as default
shield_def = shield_mdef = shield_refine = 10;
else {
shield_def = shield_data->def;
shield_mdef = sd->bonus.shieldmdef;
shield_refine = sd->status.inventory[sd->equip_index[EQI_HAND_L]].refine;
}
if (flag&1) {
sc_start(src,bl,SC_SILENCE,100,skill_lv,shield_mdef * 30000);
break;
}
switch( skill_lv ) {
case 1: // DEF based
val = shield_data->def;
if( !val ) {
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
break;
}
switch( opt ) {
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;
if( sc_start(src,bl,SC_SHIELDSPELL_DEF,100,opt,INVALID_TIMER) )
opt = rnd()%3 + 1; // Generates a number between 1 - 3. The number generated will determine which effect will be triggered.
switch(skill_lv) {
case 1: { // DEF Based
int splashrange = 0;
#ifdef RENEWAL
if (shield_def >= 0 && shield_def <= 40)
#else
if (shield_def >= 0 && shield_def <= 4)
#endif
splashrange = 1;
#ifdef RENEWAL
else if (shield_def >= 41 && shield_def <= 80)
#else
else if (shield_def >= 5 && shield_def <= 9)
#endif
splashrange = 2;
else
splashrange = 3;
switch(opt) {
case 1: // Splash AoE ATK
sc_start(src,bl,SC_SHIELDSPELL_DEF,100,opt,INVALID_TIMER);
clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
map_foreachinrange(skill_area_sub,src,splashrange,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);
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_damage_id);
break;
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: // 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 2: // % Damage Reflecting Increase
#ifdef RENEWAL
sc_start2(src,bl,SC_SHIELDSPELL_DEF,100,opt,shield_def / 10,shield_def * 1000);
#else
sc_start2(src,bl,SC_SHIELDSPELL_DEF,100,opt,shield_def,shield_def * 1000 * 10);
#endif
break;
case 3: // Equipment Attack Increase
#ifdef RENEWAL
sc_start2(src,bl,SC_SHIELDSPELL_DEF,100,opt,shield_def,shield_def * 3000);
#else
sc_start2(src,bl,SC_SHIELDSPELL_DEF,100,opt,shield_def * 10,shield_def * 3000 * 10);
#endif
break;
}
}
break;
case 2: // MDEF based
val = sd->bonus.shieldmdef;
if( !val ) {
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
case 2: { // MDEF Based
int splashrange = 0;
if (shield_mdef >= 1 && shield_mdef <= 3)
splashrange = 1;
else if (shield_mdef >= 4 && shield_mdef <= 5)
splashrange = 2;
else
splashrange = 3;
switch(opt) {
case 1: // Splash AoE MATK
sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER);
clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
map_foreachinrange(skill_area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER);
break;
case 2: // Splash AoE Lex Divina
sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,shield_mdef * 2000);
clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
map_foreachinrange(skill_area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id);
break;
case 3: // Casts Magnificat.
if (sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,shield_mdef * 30000))
clif_skill_nodamage(src,bl,PR_MAGNIFICAT,skill_lv,
sc_start(src,bl,SC_MAGNIFICAT,100,1,shield_mdef * 30000));
break;
}
}
break;
case 3: // Refine Based
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,shield_refine * 30000);
break;
case 2: // Increases DEF and Status Effect resistance depending on Shield refine rate.
#ifdef RENEWAL
sc_start4(src,bl,SC_SHIELDSPELL_REF,100,opt,shield_refine * 10 * status_get_lv(src) / 100,(shield_refine * 2) + (sstatus->luk / 10),0,shield_refine * 20000);
#else
sc_start4(src,bl,SC_SHIELDSPELL_REF,100,opt,shield_refine,(shield_refine * 2) + (sstatus->luk / 10),0,shield_refine * 20000);
#endif
break;
case 3: // Recovers HP depending on Shield refine rate.
sc_start(src,bl,SC_SHIELDSPELL_REF,100,opt,INVALID_TIMER); //HP Recovery.
status_heal(bl,sstatus->max_hp * ((status_get_lv(src) / 10) + (shield_refine + 1)) / 100,0,2);
status_change_end(bl,SC_SHIELDSPELL_REF,INVALID_TIMER);
break;
}
if( val < 4 )
splash = 1;
else if( val < 6 )
splash = 2;
else
splash = 3;
switch( opt ) {
case 1: // Deals Holy property magic damage around Self.
if( sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER) )
status_change_end(bl,SC_SHIELDSPELL_MDEF,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|2, skill_castend_damage_id);
break;
case 2: // Casts Lex Divina around Self.
if( sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER) )
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_nodamage_id);
break;
case 3: // Casts Magnificat.
if( sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER) )
status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER);
clif_skill_nodamage(src,bl,PR_MAGNIFICAT,skill_lv,sc_start(src,bl,SC_MAGNIFICAT,100,1,sd->bonus.shieldmdef * 30000));
break;
}
break;
case 3: // refine based
{
struct item *shield = NULL;
if( sd->equip_index[EQI_HAND_L] < 0 || !(shield = &sd->status.inventory[sd->equip_index[EQI_HAND_L]]) || !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.
if( sc_start(src,bl,SC_SHIELDSPELL_REF,100,opt,INVALID_TIMER) )
status_change_end(bl,SC_SHIELDSPELL_REF,INVALID_TIMER);
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);
@ -14303,6 +14315,18 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
}
sd->spiritball_old = require.spiritball = sd->spiritball;
break;
case LG_SHIELDSPELL: {
short index = sd->equip_index[EQI_HAND_L];
struct item_data *shield_data = NULL;
if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR)
shield_data = sd->inventory_data[index];
if (!shield_data || shield_data->type != IT_ARMOR) { // Skill will first check if a shield is equipped. If none is found the skill will fail.
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
}
break;
case LG_RAYOFGENESIS:
if( sc && sc->data[SC_INSPIRATION] )
return true; // Don't check for partner.

View File

@ -240,7 +240,12 @@ void initChangeTables(void)
add_sc( TF_POISON , SC_POISON );
set_sc( KN_TWOHANDQUICKEN , SC_TWOHANDQUICKEN , SI_TWOHANDQUICKEN , SCB_ASPD );
set_sc( KN_AUTOCOUNTER , SC_AUTOCOUNTER , SI_AUTOCOUNTER , SCB_NONE );
set_sc( PR_IMPOSITIO , SC_IMPOSITIO , SI_IMPOSITIO , SCB_WATK );
set_sc( PR_IMPOSITIO , SC_IMPOSITIO , SI_IMPOSITIO ,
#ifndef RENEWAL
SCB_WATK );
#else
SCB_NONE );
#endif
set_sc( PR_SUFFRAGIUM , SC_SUFFRAGIUM , SI_SUFFRAGIUM , SCB_NONE );
set_sc( PR_ASPERSIO , SC_ASPERSIO , SI_ASPERSIO , SCB_ATK_ELE );
set_sc( PR_BENEDICTIO , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE );
@ -347,7 +352,12 @@ void initChangeTables(void)
set_sc( BD_ENCORE , SC_DANCING , SI_BDPLAYING , SCB_SPEED|SCB_REGEN );
set_sc( BD_RICHMANKIM , SC_RICHMANKIM , SI_RICHMANKIM , SCB_NONE );
set_sc( BD_ETERNALCHAOS , SC_ETERNALCHAOS , SI_ETERNALCHAOS , SCB_DEF2 );
set_sc( BD_DRUMBATTLEFIELD , SC_DRUMBATTLE , SI_DRUMBATTLEFIELD , SCB_WATK|SCB_DEF );
set_sc( BD_DRUMBATTLEFIELD , SC_DRUMBATTLE , SI_DRUMBATTLEFIELD ,
#ifndef RENEWAL
SCB_WATK|SCB_DEF );
#else
SCB_DEF );
#endif
set_sc( BD_RINGNIBELUNGEN , SC_NIBELUNGEN , SI_RINGNIBELUNGEN , SCB_WATK );
set_sc( BD_ROKISWEIL , SC_ROKISWEIL , SI_ROKISWEIL , SCB_NONE );
set_sc( BD_INTOABYSS , SC_INTOABYSS , SI_INTOABYSS , SCB_NONE );
@ -453,10 +463,20 @@ void initChangeTables(void)
add_sc( GS_CRACKER , SC_STUN );
add_sc( GS_DISARM , SC_STRIPWEAPON );
add_sc( GS_PIERCINGSHOT , SC_BLEEDING );
set_sc( GS_MADNESSCANCEL , SC_MADNESSCANCEL , SI_MADNESSCANCEL , SCB_BATK|SCB_ASPD );
set_sc( GS_MADNESSCANCEL , SC_MADNESSCANCEL , SI_MADNESSCANCEL ,
#ifndef RENEWAL
SCB_BATK|SCB_ASPD );
#else
SCB_ASPD );
#endif
set_sc( GS_ADJUSTMENT , SC_ADJUSTMENT , SI_ADJUSTMENT , SCB_HIT|SCB_FLEE );
set_sc( GS_INCREASING , SC_INCREASING , SI_ACCURACY , SCB_AGI|SCB_DEX|SCB_HIT );
set_sc( GS_GATLINGFEVER , SC_GATLINGFEVER , SI_GATLINGFEVER , SCB_BATK|SCB_FLEE|SCB_SPEED|SCB_ASPD );
set_sc( GS_GATLINGFEVER , SC_GATLINGFEVER , SI_GATLINGFEVER ,
#ifndef RENEWAL
SCB_BATK|SCB_FLEE|SCB_SPEED|SCB_ASPD );
#else
SCB_FLEE|SCB_SPEED|SCB_ASPD );
#endif
add_sc( NJ_TATAMIGAESHI , SC_TATAMIGAESHI );
set_sc( NJ_SUITON , SC_SUITON , SI_BLANK , SCB_AGI|SCB_SPEED );
add_sc( NJ_HYOUSYOURAKU , SC_FREEZE );
@ -5099,10 +5119,12 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk += sc->data[SC_ATKPOTION]->val1;
if(sc->data[SC_BATKFOOD])
batk += sc->data[SC_BATKFOOD]->val1;
#ifndef RENEWAL
if(sc->data[SC_GATLINGFEVER])
batk += sc->data[SC_GATLINGFEVER]->val3;
if(sc->data[SC_MADNESSCANCEL])
batk += 100;
#endif
if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
batk += 50;
if(bl->type == BL_ELEM
@ -5170,12 +5192,14 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
if(!sc || !sc->count)
return cap_value(watk,0,USHRT_MAX);
#ifndef RENEWAL
if(sc->data[SC_IMPOSITIO])
watk += sc->data[SC_IMPOSITIO]->val2;
if(sc->data[SC_WATKFOOD])
watk += sc->data[SC_WATKFOOD]->val1;
if(sc->data[SC_DRUMBATTLE])
watk += sc->data[SC_DRUMBATTLE]->val2;
#endif
if(sc->data[SC_WATKFOOD])
watk += sc->data[SC_WATKFOOD]->val1;
if(sc->data[SC_VOLCANO])
watk += sc->data[SC_VOLCANO]->val2;
if(sc->data[SC_MERC_ATKUP])
@ -5327,10 +5351,9 @@ static unsigned short status_calc_matk(struct block_list *bl, struct status_chan
matk += 50;
if (sc->data[SC_ODINS_POWER])
matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; // 70 lvl1, 100lvl2
if (sc->data[SC_MOONLITSERENADE])
matk += sc->data[SC_MOONLITSERENADE]->val3;
if (sc->data[SC_IZAYOI])
matk += 25 * sc->data[SC_IZAYOI]->val1;
#endif
if (sc->data[SC_ZANGETSU])
matk += sc->data[SC_ZANGETSU]->val3;
if (sc->data[SC_QUEST_BUFF1])
@ -5339,13 +5362,14 @@ static unsigned short status_calc_matk(struct block_list *bl, struct status_chan
matk += sc->data[SC_QUEST_BUFF2]->val1;
if (sc->data[SC_QUEST_BUFF3])
matk += sc->data[SC_QUEST_BUFF3]->val1;
#endif
if (sc->data[SC_MAGICPOWER] && sc->data[SC_MAGICPOWER]->val4)
matk += matk * sc->data[SC_MAGICPOWER]->val3/100;
if (sc->data[SC_MINDBREAKER])
matk += matk * sc->data[SC_MINDBREAKER]->val2/100;
if (sc->data[SC_INCMATKRATE])
matk += matk * sc->data[SC_INCMATKRATE]->val1/100;
if (sc->data[SC_MOONLITSERENADE])
matk += sc->data[SC_MOONLITSERENADE]->val3/100;
if (sc->data[SC_MTF_MATK])
matk += matk * 25 / 100;
@ -8918,7 +8942,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
val2 = 5*val1; // def increase
break;
case SC_IMPOSITIO:
#ifndef RENEWAL
val2 = 5*val1; // Watk increase
#endif
break;
case SC_MELTDOWN:
val2 = 100*val1; // Chance to break weapon
@ -8944,7 +8970,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
// gs_something1 [Vicious]
case SC_GATLINGFEVER:
val2 = 20*val1; // Aspd increase
#ifndef RENEWAL
val3 = 20+10*val1; // Atk increase
#endif
val4 = 5*val1; // Flee decrease
break;