Bug Fixes

* Fixes #587 - Corrected Amistr Defence to properly calculate VIT for renewal and DEF for pre-renewal.
* Fixes #588 - Fixed skills not being properly removed when being copied by Plagiarism or Reproduce.
* Fixes #589 - Blessing no longer gives stat bonuses when Curse is active.
* Fixes #599 - Fixed a possible crash by Praefatio.
* Fixes #601 - Exceed Break now cancels when switching weapons and is properly removed on misses.
This commit is contained in:
aleos89 2015-08-28 15:05:24 -04:00
parent 3a4847ebde
commit eb0a79f1bf
4 changed files with 74 additions and 63 deletions

View File

@ -3300,10 +3300,6 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
status_change_end(src,SC_CRUSHSTRIKE,INVALID_TIMER); status_change_end(src,SC_CRUSHSTRIKE,INVALID_TIMER);
skill_break_equip(src,src,EQP_WEAPON,2000,BCT_SELF); skill_break_equip(src,src,EQP_WEAPON,2000,BCT_SELF);
} }
if (sc->data[SC_EXEEDBREAK] && !skill_id) {
skillratio += -100 + sc->data[SC_EXEEDBREAK]->val1;
status_change_end(src,SC_EXEEDBREAK,INVALID_TIMER);
}
//!TODO: Verify this placement & skills that affected by these effects [Cydh] //!TODO: Verify this placement & skills that affected by these effects [Cydh]
if (sc->data[SC_HEAT_BARREL]) if (sc->data[SC_HEAT_BARREL])
skillratio += 200; skillratio += 200;
@ -7060,6 +7056,10 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
wd = battle_calc_attack(BF_WEAPON, src, target, 0, 0, flag); wd = battle_calc_attack(BF_WEAPON, src, target, 0, 0, flag);
if( sc && sc->count ) { if( sc && sc->count ) {
if (sc->data[SC_EXEEDBREAK]) {
wd.damage *= sc->data[SC_EXEEDBREAK]->val1 / 100;
status_change_end(src, SC_EXEEDBREAK, INVALID_TIMER);
}
if( sc->data[SC_SPELLFIST] ) { if( sc->data[SC_SPELLFIST] ) {
if( --(sc->data[SC_SPELLFIST]->val1) >= 0 ){ if( --(sc->data[SC_SPELLFIST]->val1) >= 0 ){
struct Damage ad = battle_calc_attack(BF_MAGIC,src,target,sc->data[SC_SPELLFIST]->val3,sc->data[SC_SPELLFIST]->val4,flag|BF_SHORT); struct Damage ad = battle_calc_attack(BF_MAGIC,src,target,sc->data[SC_SPELLFIST]->val3,sc->data[SC_SPELLFIST]->val4,flag|BF_SHORT);

View File

@ -5480,7 +5480,7 @@ uint8 pc_checkskill(struct map_session_data *sd, uint16 skill_id)
} }
/** /**
* Chk if we still have the correct weapon to continue the skill (actually status) * Check if we still have the correct weapon to continue the skill (actually status)
* If not ending it * If not ending it
* @param sd * @param sd
* @return 0:error, 1:check done * @return 0:error, 1:check done
@ -5497,7 +5497,6 @@ static void pc_checkallowskill(struct map_session_data *sd)
SC_ADRENALINE2, SC_ADRENALINE2,
SC_DANCING, SC_DANCING,
SC_GATLINGFEVER, SC_GATLINGFEVER,
SC_FEARBREEZE
}; };
uint8 i; uint8 i;
nullpo_retv(sd); nullpo_retv(sd);
@ -9468,45 +9467,38 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos)
* 2 - force unequip * 2 - force unequip
* return: false - fail; true - success * return: false - fail; true - success
*------------------------------------------*/ *------------------------------------------*/
bool pc_unequipitem(struct map_session_data *sd,int n,int flag) { bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
int i,iflag; int i, iflag;
bool status_cacl = false; bool status_cacl = false;
nullpo_retr(false,sd); nullpo_retr(false,sd);
if( n < 0 || n >= MAX_INVENTORY ) { if (n < 0 || n >= MAX_INVENTORY) {
clif_unequipitemack(sd,0,0,0); clif_unequipitemack(sd,0,0,0);
return false; return false;
} }
if (!sd->status.inventory[n].equip) {
clif_unequipitemack(sd,n,0,0);
return false; //Nothing to unequip
}
// status change that makes player cannot unequip equipment // status change that makes player cannot unequip equipment
if( !(flag&2) && sd->sc.count && ( if (!(flag&2) && sd->sc.count &&
sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_BERSERK] ||
sd->sc.data[SC_SATURDAYNIGHTFEVER] || sd->sc.data[SC_SATURDAYNIGHTFEVER] ||
sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC__BLOODYLUST] ||
sd->sc.data[SC_KYOUGAKU] || sd->sc.data[SC_KYOUGAKU] ||
(sd->sc.data[SC_PYROCLASTIC] && sd->inventory_data[n]->type == IT_WEAPON)) ) // can't switch weapon (sd->sc.data[SC_PYROCLASTIC] &&
sd->inventory_data[n]->type == IT_WEAPON))) // can't switch weapon
{ {
clif_unequipitemack(sd,n,0,0); clif_unequipitemack(sd,n,0,0);
return false; return false;
} }
if (&sd->sc) {
if (sd->sc.data[SC_HOVERING] && sd->inventory_data[n]->type == IT_ARMOR && sd->inventory_data[n]->nameid == ITEMID_HOVERING_BOOSTER)
status_change_end(&sd->bl, SC_HOVERING, INVALID_TIMER);
if (sd->sc.data[SC_HEAT_BARREL])
status_change_end(&sd->bl,SC_HEAT_BARREL,INVALID_TIMER);
if (sd->sc.data[SC_P_ALTER] && (sd->inventory_data[n]->type == IT_WEAPON || sd->inventory_data[n]->type == IT_AMMO))
status_change_end(&sd->bl,SC_P_ALTER,INVALID_TIMER);
}
if(battle_config.battle_log) if (battle_config.battle_log)
ShowInfo("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->status.inventory[n].equip); ShowInfo("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->status.inventory[n].equip);
if(!sd->status.inventory[n].equip){ //Nothing to unequip for(i = 0; i < EQI_MAX; i++) {
clif_unequipitemack(sd,n,0,0); if (sd->status.inventory[n].equip & equip_pos[i])
return false;
}
for(i=0;i<EQI_MAX;i++) {
if(sd->status.inventory[n].equip & equip_pos[i])
sd->equip_index[i] = -1; sd->equip_index[i] = -1;
} }
@ -9566,20 +9558,32 @@ bool pc_unequipitem(struct map_session_data *sd,int n,int flag) {
clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1); clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1);
if((sd->status.inventory[n].equip & EQP_ARMS) && sd->inventory_data[n]->type == IT_WEAPON && //On weapon change (right and left hand) status_change_end(&sd->bl,SC_HEAT_BARREL,INVALID_TIMER);
(!sd->sc.data[SC_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!) // On weapon change (right and left hand)
skill_enchant_elemental_end(&sd->bl,SC_NONE); if ((sd->status.inventory[n].equip & EQP_ARMS) && sd->inventory_data[n]->type == IT_WEAPON) {
if (!sd->sc.data[SC_SEVENWIND] || sd->sc.data[SC_ASPERSIO]) //Check for seven wind (but not level seven!)
skill_enchant_elemental_end(&sd->bl, SC_NONE);
status_change_end(&sd->bl, SC_FEARBREEZE, INVALID_TIMER);
status_change_end(&sd->bl, SC_EXEEDBREAK, INVALID_TIMER);
status_change_end(&sd->bl, SC_P_ALTER, INVALID_TIMER);
}
if(sd->status.inventory[n].equip & EQP_ARMOR) { // On armor change
// On Armor Change... if (sd->status.inventory[n].equip & EQP_ARMOR) {
status_change_end(&sd->bl, SC_BENEDICTIO, INVALID_TIMER); if (sd->sc.data[SC_HOVERING] && sd->inventory_data[n]->nameid == ITEMID_HOVERING_BOOSTER)
status_change_end(&sd->bl, SC_HOVERING, INVALID_TIMER);
//status_change_end(&sd->bl, SC_BENEDICTIO, INVALID_TIMER); // No longer is removed? Need confirmation
status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER); status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER);
} }
// On ammo change
if (sd->inventory_data[n]->type == IT_AMMO)
status_change_end(&sd->bl, SC_P_ALTER, INVALID_TIMER);
if( sd->state.autobonus&sd->status.inventory[n].equip ) if( sd->state.autobonus&sd->status.inventory[n].equip )
sd->state.autobonus &= ~sd->status.inventory[n].equip; //Check for activated autobonus [Inkfish] sd->state.autobonus &= ~sd->status.inventory[n].equip; //Check for activated autobonus [Inkfish]
sd->status.inventory[n].equip=0; sd->status.inventory[n].equip = 0;
iflag = sd->npc_item_flag; iflag = sd->npc_item_flag;
/* check for combos (MUST be before status_calc_pc) */ /* check for combos (MUST be before status_calc_pc) */
@ -9592,6 +9596,7 @@ bool pc_unequipitem(struct map_session_data *sd,int n,int flag) {
else { else {
for( i = 0; i < sd->inventory_data[n]->slot; i++ ) { for( i = 0; i < sd->inventory_data[n]->slot; i++ ) {
struct item_data *data; struct item_data *data;
if (!sd->status.inventory[n].card[i]) if (!sd->status.inventory[n].card[i])
continue; continue;
if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) { if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) {

View File

@ -2766,10 +2766,10 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s
case 1: //Copied by Plagiarism case 1: //Copied by Plagiarism
{ {
if (tsd->cloneskill_idx > 0 && tsd->status.skill[tsd->cloneskill_idx].flag == SKILL_FLAG_PLAGIARIZED) { if (tsd->cloneskill_idx > 0 && tsd->status.skill[tsd->cloneskill_idx].flag == SKILL_FLAG_PLAGIARIZED) {
clif_deleteskill(tsd,tsd->status.skill[tsd->cloneskill_idx].id);
tsd->status.skill[tsd->cloneskill_idx].id = 0; tsd->status.skill[tsd->cloneskill_idx].id = 0;
tsd->status.skill[tsd->cloneskill_idx].lv = 0; tsd->status.skill[tsd->cloneskill_idx].lv = 0;
tsd->status.skill[tsd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT; tsd->status.skill[tsd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT;
clif_deleteskill(tsd,tsd->status.skill[tsd->cloneskill_idx].id);
} }
lv = min(skill_lv,pc_checkskill(tsd,RG_PLAGIARISM)); //Copied level never be > player's RG_PLAGIARISM level lv = min(skill_lv,pc_checkskill(tsd,RG_PLAGIARISM)); //Copied level never be > player's RG_PLAGIARISM level
@ -2786,10 +2786,10 @@ static void skill_do_copy(struct block_list* src,struct block_list *bl, uint16 s
//Skill level copied depends on Reproduce skill that used //Skill level copied depends on Reproduce skill that used
lv = (tsc) ? tsc->data[SC__REPRODUCE]->val1 : 1; lv = (tsc) ? tsc->data[SC__REPRODUCE]->val1 : 1;
if( tsd->reproduceskill_idx > 0 && tsd->status.skill[tsd->reproduceskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) { if( tsd->reproduceskill_idx > 0 && tsd->status.skill[tsd->reproduceskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) {
clif_deleteskill(tsd,tsd->status.skill[tsd->reproduceskill_idx].id);
tsd->status.skill[tsd->reproduceskill_idx].id = 0; tsd->status.skill[tsd->reproduceskill_idx].id = 0;
tsd->status.skill[tsd->reproduceskill_idx].lv = 0; tsd->status.skill[tsd->reproduceskill_idx].lv = 0;
tsd->status.skill[tsd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT; tsd->status.skill[tsd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT;
clif_deleteskill(tsd,tsd->status.skill[tsd->reproduceskill_idx].id);
} }
//Level dependent and limitation. //Level dependent and limitation.
@ -8779,7 +8779,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break; break;
case AB_ANCILLA: case AB_ANCILLA:
if( sd ) { if( sd ) {
clif_skill_nodamage(src,bl,skill_id,skill_lv,1); clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
skill_produce_mix(sd, skill_id, ITEMID_ANCILLA, 0, 0, 0, 1, -1); skill_produce_mix(sd, skill_id, ITEMID_ANCILLA, 0, 0, 0, 1, -1);
} }
@ -8799,16 +8799,16 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break; break;
case AB_PRAEFATIO: case AB_PRAEFATIO:
if( sd == NULL || sd->status.party_id == 0 || flag&1 ) if( !sd || sd->status.party_id == 0 || flag&1 )
clif_skill_nodamage(bl, bl, skill_id, skill_lv, sc_start4(src, bl, type, 100, skill_lv, 0, 0, ( sd->status.party_id ? party_foreachsamemap(party_sub_count, sd, 0) : 1 ), skill_get_time(skill_id, skill_lv))); clif_skill_nodamage(bl, bl, skill_id, skill_lv, sc_start4(src, bl, type, 100, skill_lv, 0, 0, (sd && sd->status.party_id ? party_foreachsamemap(party_sub_count, sd, 0) : 1 ), skill_get_time(skill_id, skill_lv)));
else if( sd ) else if( sd )
party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id); party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
break; break;
case AB_CHEAL: case AB_CHEAL:
if( sd == NULL || sd->status.party_id == 0 || flag&1 ) { if( !sd || sd->status.party_id == 0 || flag&1 ) {
if( sd && tstatus && !battle_check_undead(tstatus->race, tstatus->def_ele) && !tsc->data[SC_BERSERK] ) { if( sd && tstatus && !battle_check_undead(tstatus->race, tstatus->def_ele) && !tsc->data[SC_BERSERK] ) {
int partycount = ( sd->status.party_id ? party_foreachsamemap(party_sub_count, sd, 0) : 0 ); int partycount = (sd->status.party_id ? party_foreachsamemap(party_sub_count, sd, 0) : 0);
i = skill_calc_heal(src, bl, AL_HEAL, pc_checkskill(sd, AL_HEAL), true); i = skill_calc_heal(src, bl, AL_HEAL, pc_checkskill(sd, AL_HEAL), true);
@ -8822,16 +8822,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
i = ~i + 1; i = ~i + 1;
status_heal(bl, i, 0, 0); status_heal(bl, i, 0, 0);
} }
} } else if( sd )
else if( sd )
party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id); party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
break; break;
case AB_ORATIO: case AB_ORATIO:
if( flag&1 ) if( flag&1 )
sc_start(src,bl, type, 40 + 5 * skill_lv, skill_lv, skill_get_time(skill_id, skill_lv)); sc_start(src,bl, type, 40 + 5 * skill_lv, skill_lv, skill_get_time(skill_id, skill_lv));
else else {
{
map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id, skill_lv), BL_CHAR, 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); src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
clif_skill_nodamage(src, bl, skill_id, skill_lv, 1); clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
@ -8839,7 +8837,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break; break;
case AB_LAUDAAGNUS: case AB_LAUDAAGNUS:
if( flag&1 || sd == NULL || !sd->status.party_id ) { if( flag&1 || !sd || !sd->status.party_id ) {
if( tsc && (tsc->data[SC_FREEZE] || tsc->data[SC_STONE] || tsc->data[SC_BLIND] || if( tsc && (tsc->data[SC_FREEZE] || tsc->data[SC_STONE] || tsc->data[SC_BLIND] ||
tsc->data[SC_BURNING] || tsc->data[SC_FREEZING] || tsc->data[SC_CRYSTALIZE])) { tsc->data[SC_BURNING] || tsc->data[SC_FREEZING] || tsc->data[SC_CRYSTALIZE])) {
// Success Chance: (40 + 10 * Skill Level) % // Success Chance: (40 + 10 * Skill Level) %
@ -8850,7 +8848,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_change_end(bl, SC_BURNING, INVALID_TIMER); status_change_end(bl, SC_BURNING, INVALID_TIMER);
status_change_end(bl, SC_FREEZING, INVALID_TIMER); status_change_end(bl, SC_FREEZING, INVALID_TIMER);
status_change_end(bl, SC_CRYSTALIZE, INVALID_TIMER); status_change_end(bl, SC_CRYSTALIZE, INVALID_TIMER);
}else //Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets } else //Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets
clif_skill_nodamage(bl, bl, skill_id, skill_lv, clif_skill_nodamage(bl, bl, skill_id, skill_lv,
sc_start(src,bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv))); sc_start(src,bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)));
} else if( sd ) } else if( sd )
@ -8859,7 +8857,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break; break;
case AB_LAUDARAMUS: case AB_LAUDARAMUS:
if( flag&1 || sd == NULL || !sd->status.party_id ) { if( flag&1 || !sd || !sd->status.party_id ) {
if( tsc && (tsc->data[SC_SLEEP] || tsc->data[SC_STUN] || tsc->data[SC_MANDRAGORA] || tsc->data[SC_SILENCE] || tsc->data[SC_DEEPSLEEP]) ){ if( tsc && (tsc->data[SC_SLEEP] || tsc->data[SC_STUN] || tsc->data[SC_MANDRAGORA] || tsc->data[SC_SILENCE] || tsc->data[SC_DEEPSLEEP]) ){
// Success Chance: (40 + 10 * Skill Level) % // Success Chance: (40 + 10 * Skill Level) %
if( rnd()%100 > 40+10*skill_lv ) break; if( rnd()%100 > 40+10*skill_lv ) break;
@ -8868,7 +8866,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_change_end(bl, SC_MANDRAGORA, INVALID_TIMER); status_change_end(bl, SC_MANDRAGORA, INVALID_TIMER);
status_change_end(bl, SC_SILENCE, INVALID_TIMER); status_change_end(bl, SC_SILENCE, INVALID_TIMER);
status_change_end(bl, SC_DEEPSLEEP, INVALID_TIMER); status_change_end(bl, SC_DEEPSLEEP, INVALID_TIMER);
}else // Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets } else // Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets
clif_skill_nodamage(bl, bl, skill_id, skill_lv, clif_skill_nodamage(bl, bl, skill_id, skill_lv,
sc_start(src,bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv))); sc_start(src,bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)));
} else if( sd ) } else if( sd )
@ -8877,8 +8875,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break; break;
case AB_CLEARANCE: case AB_CLEARANCE:
if( flag&1 || (i = skill_get_splash(skill_id, skill_lv)) < 1 ) if( flag&1 || (i = skill_get_splash(skill_id, skill_lv)) < 1 ) { // As of the behavior in official server Clearance is just a super version of Dispell skill. [Jobbie]
{ //As of the behavior in official server Clearance is just a super version of Dispell skill. [Jobbie]
if( bl->type != BL_MOB && battle_check_target(src,bl,BCT_PARTY) <= 0 ) // Only affect mob or party. if( bl->type != BL_MOB && battle_check_target(src,bl,BCT_PARTY) <= 0 ) // Only affect mob or party.
break; break;

View File

@ -536,7 +536,12 @@ void initChangeTables(void)
set_sc( HLIF_CHANGE , SC_CHANGE , SI_BLANK , SCB_VIT|SCB_INT ); set_sc( HLIF_CHANGE , SC_CHANGE , SI_BLANK , SCB_VIT|SCB_INT );
set_sc( HFLI_FLEET , SC_FLEET , SI_BLANK , SCB_ASPD|SCB_BATK|SCB_WATK ); set_sc( HFLI_FLEET , SC_FLEET , SI_BLANK , SCB_ASPD|SCB_BATK|SCB_WATK );
set_sc( HFLI_SPEED , SC_SPEED , SI_BLANK , SCB_FLEE ); set_sc( HFLI_SPEED , SC_SPEED , SI_BLANK , SCB_FLEE );
set_sc( HAMI_DEFENCE , SC_DEFENCE , SI_BLANK , SCB_DEF ); set_sc( HAMI_DEFENCE , SC_DEFENCE , SI_BLANK ,
#ifndef RENEWAL
SCB_DEF );
#else
SCB_VIT );
#endif
set_sc( HAMI_BLOODLUST , SC_BLOODLUST , SI_BLANK , SCB_BATK|SCB_WATK ); set_sc( HAMI_BLOODLUST , SC_BLOODLUST , SI_BLANK , SCB_BATK|SCB_WATK );
/* Homunculus S */ /* Homunculus S */
@ -5853,7 +5858,7 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
def += sc->data[SC_DRUMBATTLE]->val3; def += sc->data[SC_DRUMBATTLE]->val3;
#ifndef RENEWAL #ifndef RENEWAL
if(sc->data[SC_DEFENCE]) if(sc->data[SC_DEFENCE])
def += sc->data[SC_DEFENCE]->val2 ; def += sc->data[SC_DEFENCE]->val2;
#endif #endif
if(sc->data[SC_INCDEFRATE]) if(sc->data[SC_INCDEFRATE])
def += def * sc->data[SC_INCDEFRATE]->val1/100; def += def * sc->data[SC_INCDEFRATE]->val1/100;
@ -8194,10 +8199,14 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
case SC_BLESSING: case SC_BLESSING:
// !TODO: Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM // !TODO: Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
// !but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm] // !but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) { if ((!undead_flag && status->race != RC_DEMON) || bl->type == BL_PC) {
status_change_end(bl, SC_CURSE, INVALID_TIMER); status_change_end(bl, SC_CURSE, INVALID_TIMER);
if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
status_change_end(bl, SC_STONE, INVALID_TIMER); status_change_end(bl, SC_STONE, INVALID_TIMER);
if (sc->data[SC_CURSE]) {
status_change_end(bl, SC_CURSE, INVALID_TIMER);
return 1; // End Curse and do not give stat boost
}
} }
if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH) if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
status_change_end(bl, SC_SPIRIT, INVALID_TIMER); status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
@ -9815,14 +9824,14 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
tick_time = 10000; // [GodLesZ] tick time tick_time = 10000; // [GodLesZ] tick time
break; break;
case SC_EXEEDBREAK: case SC_EXEEDBREAK:
{ val1 = 100 * val1;
short idx = -1; if (sd) { // Players
val1 *= 100; // 100 * skill_lv short index = sd->equip_index[EQI_HAND_R];
if( sd && (idx = sd->equip_index[EQI_HAND_R]) >= 0 && sd->inventory_data[idx] ) {
val1 += (sd->inventory_data[idx]->weight/10 * sd->inventory_data[idx]->wlv * status_get_lv(bl) / 100); if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON)
val1 += 10 * sd->status.job_level; val1 += 10 * sd->status.job_level + sd->inventory_data[index]->weight / 10 * sd->inventory_data[index]->wlv * status_get_lv(bl) / 100;
} } else // Monster
} val1 += 500;
break; break;
case SC_PRESTIGE: case SC_PRESTIGE:
val2 = (status->int_ + status->luk) * val1 / 20 * status_get_lv(bl) / 200 + val1; // Chance to evade magic damage. val2 = (status->int_ + status->luk) * val1 / 20 * status_get_lv(bl) / 200 + val1; // Chance to evade magic damage.