From 7689b26c216bb9de59d7ddfcbe9c45c18cfb7cc4 Mon Sep 17 00:00:00 2001 From: skotlex Date: Mon, 3 Sep 2007 20:00:33 +0000 Subject: - Added bonuses bSPRegenRate, bHPRegenRate. They behave like the opposite of bHPLossRate/bSPLossRate, making you gain x Hp/Sp every y ms. - Added bonus bIgnoreMdefRate, used to ignore a % of the target's mdef when using magic attacks (bonus2 will ignore part of the mdef of all targets, bonus3 receives a race argument) - You can now use bonus2 bCastRate to adjust the cast rate of a single skill. - Cleaned the code for bleeding (hp-loss) and extended it to handle regen as well. - Some small cleanups in the pc_bonus functions - Removed bonus3 bHpLossRate since it was doing nothing and is not used. - Corrected bGetZeny bonus to be like in Aegis. The amount received is from 1 to the given amount, you can use negative zeny values to use an amount dependant on mob's level (amount*lv). - Updated doc/item_bonus.txt with all these changes - Anti-Magic/Stone-Skin now increase/decrease def/mdef only and in an absolute mode (+20*lv rather than +20%*lv). Also the duration is greatly decreased (x/15) when used on players. - Now when a player uses a strip skill without having it in the skill tree (auto-casted) the duration will be 0, the equipment will be stripped without causing the status change that blocks reequipping. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11112 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/battle.c | 16 ++++++- src/map/map.h | 27 +++++------ src/map/mob.c | 8 +++- src/map/pc.c | 134 +++++++++++++++++++++++++++++++++++++++---------------- src/map/pc.h | 1 + src/map/skill.c | 20 +++++++-- src/map/status.c | 33 ++++++++------ 7 files changed, 163 insertions(+), 76 deletions(-) (limited to 'src/map') diff --git a/src/map/battle.c b/src/map/battle.c index 3f9441aa4..4ec4e652d 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2333,10 +2333,22 @@ struct Damage battle_calc_magic_attack( } if(!flag.imdef){ + int mdef = tstatus->mdef; + int mdef2= tstatus->mdef2; + if(sd) { + i = sd->ignore_mdef[is_boss(target)?RC_BOSS:RC_NONBOSS]; + i+= sd->ignore_mdef[tstatus->race]; + if (i) + { + if (i > 100) i = 100; + mdef -= mdef * i/100; + mdef2-= mdef2* i/100; + } + } if(battle_config.magic_defense_type) - ad.damage = ad.damage - tstatus->mdef*battle_config.magic_defense_type - tstatus->mdef2; + ad.damage = ad.damage - mdef*battle_config.magic_defense_type - mdef2; else - ad.damage = ad.damage * (100-tstatus->mdef)/100 - tstatus->mdef2; + ad.damage = ad.damage * (100-mdef)/100 - mdef2; } if(skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS) diff --git a/src/map/map.h b/src/map/map.h index 5a8c55315..8dc60b7cf 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -659,6 +659,7 @@ struct map_session_data { int magic_addsize[3]; int critaddrace[RC_MAX]; int expaddrace[RC_MAX]; + int ignore_mdef[RC_MAX]; int itemgrouphealrate[MAX_ITEMGROUP]; short sp_gain_race[RC_MAX]; // zeroed arrays end here. @@ -671,8 +672,14 @@ struct map_session_data { unsigned char flag; } addeff[MAX_PC_BONUS], addeff2[MAX_PC_BONUS]; struct { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills. - short id, val; - } skillatk[MAX_PC_BONUS], skillheal[5], skillblown[MAX_PC_BONUS]; + unsigned short id; + short val; + } skillatk[MAX_PC_BONUS], skillheal[5], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS]; + struct { + short value; + int rate; + int tick; + } hp_loss, sp_loss, hp_regen, sp_regen; struct { short class_, rate; } add_def[MAX_PC_BONUS], add_mdef[MAX_PC_BONUS], @@ -704,17 +711,12 @@ struct map_session_data { int random_attack_increase_add,random_attack_increase_per; // [Valaris] int break_weapon_rate,break_armor_rate; int crit_atk_rate; - int hp_loss_rate; - int sp_loss_rate; int classchange; // [Valaris] int speed_add_rate, aspd_add; unsigned int setitem_hash, setitem_hash2; //Split in 2 because shift operations only work on int ranges. [Skotlex] short splash_range, splash_add_range; short add_steal_rate; - short hp_loss_value; - short sp_loss_value; - short hp_loss_type; short sp_gain_value, hp_gain_value; short sp_vanish_rate; short sp_vanish_per; @@ -733,9 +735,6 @@ struct map_session_data { int matk_rate; int critical_rate,hit_rate,flee_rate,flee2_rate,def_rate,def2_rate,mdef_rate,mdef2_rate; - int hp_loss_tick; - int sp_loss_tick; - int itemid; short itemindex; //Used item's index in sd->inventory [Skotlex] @@ -1171,7 +1170,7 @@ enum _sp { SP_CRITICAL_DEF,SP_NEAR_ATK_DEF,SP_LONG_ATK_DEF, // 1019-1021 SP_DOUBLE_RATE, SP_DOUBLE_ADD_RATE, SP_SKILL_HEAL, SP_MATK_RATE, // 1022-1025 SP_IGNORE_DEF_ELE,SP_IGNORE_DEF_RACE, // 1026-1027 - SP_ATK_RATE,SP_SPEED_ADDRATE,SP_FREE3, // 1028-1030 + SP_ATK_RATE,SP_SPEED_ADDRATE,SP_SP_REGEN_RATE, // 1028-1030 SP_MAGIC_ATK_DEF,SP_MISC_ATK_DEF, // 1031-1032 SP_IGNORE_MDEF_ELE,SP_IGNORE_MDEF_RACE, // 1033-1034 SP_MAGIC_ADDELE,SP_MAGIC_ADDRACE,SP_MAGIC_ADDSIZE, // 1035-1037 @@ -1187,6 +1186,7 @@ enum _sp { SP_HP_DRAIN_VALUE,SP_SP_DRAIN_VALUE, // 1079-1080 SP_WEAPON_ATK,SP_WEAPON_ATK_RATE, // 1081-1082 SP_DELAYRATE,SP_HP_DRAIN_RATE_RACE,SP_SP_DRAIN_RATE_RACE, // 1083-1085 + SP_IGNORE_MDEF_RATE, //1086 SP_RESTART_FULL_RECOVER=2000,SP_NO_CASTCANCEL,SP_NO_SIZEFIX,SP_NO_MAGIC_DAMAGE,SP_NO_WEAPON_DAMAGE,SP_NO_GEMSTONE, // 2000-2005 SP_NO_CASTCANCEL2,SP_NO_MISC_DAMAGE,SP_UNBREAKABLE_WEAPON,SP_UNBREAKABLE_ARMOR, SP_UNBREAKABLE_HELM, // 2006-2010 @@ -1194,15 +1194,12 @@ enum _sp { SP_CRIT_ATK_RATE, SP_CRITICAL_ADDRACE, SP_NO_REGEN, SP_ADDEFF_WHENHIT, SP_AUTOSPELL_WHENHIT, // 2013-2017 SP_SKILL_ATK, SP_UNSTRIPABLE, SP_ADD_DAMAGE_BY_CLASS, // 2018-2020 - SP_SP_GAIN_VALUE, SP_FREE, SP_HP_LOSS_RATE, SP_ADDRACE2, SP_HP_GAIN_VALUE, // 2021-2025 + SP_SP_GAIN_VALUE, SP_HP_REGEN_RATE, SP_HP_LOSS_RATE, SP_ADDRACE2, SP_HP_GAIN_VALUE, // 2021-2025 SP_SUBSIZE, SP_HP_DRAIN_VALUE_RACE, SP_ADD_ITEM_HEAL_RATE, SP_SP_DRAIN_VALUE_RACE, SP_EXP_ADDRACE, // 2026-2030 SP_SP_GAIN_RACE, SP_SUBRACE2, SP_ADDEFF_WHENHIT_SHORT, // 2031-2033 SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD, // 2034-2037 SP_INTRAVISION, SP_ADD_MONSTER_DROP_ITEMGROUP, SP_SP_LOSS_RATE, // 2038-2040 SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE //2041 - //Before adding another, note that these are free: - //1030 (SP_FREE3, previous AspdAddRate) - //2022 (SP_FREE, previous bDefIgnoreMob) }; enum _look { diff --git a/src/map/mob.c b/src/map/mob.c index 01679708b..1802500cc 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2033,9 +2033,13 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) } } - // process script-granted zeny bonus (get_zeny_num per level +/-10%) [Skotlex] + // process script-granted zeny bonus (get_zeny_num) [Skotlex] if(sd->get_zeny_num && rand()%100 < sd->get_zeny_rate) - pc_getzeny(sd,md->level*sd->get_zeny_num*(90+rand()%21)/100); + { + i = sd->get_zeny_num > 0?sd->get_zeny_num:-md->level*sd->get_zeny_num; + if (!i) i = 1; + pc_getzeny(sd, 1+rand()%i); + } } // process items looted by the mob diff --git a/src/map/pc.c b/src/map/pc.c index 30d012b5e..5a43f0af3 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1632,6 +1632,12 @@ int pc_bonus(struct map_session_data *sd,int type,int val) if(sd->state.lr_flag != 2) sd->misc_def_rate += val; break; + case SP_IGNORE_MDEF_RATE: + if(sd->state.lr_flag != 2) { + sd->ignore_mdef[RC_NONBOSS] += val; + sd->ignore_mdef[RC_BOSS] += val; + } + break; case SP_IGNORE_MDEF_ELE: if(val >= ELE_MAX) { if(battle_config.error_log) @@ -2203,7 +2209,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) break; } if(sd->state.lr_flag != 2) - pc_bonus_addeff(sd->addeff2, MAX_PC_BONUS, type2, val, 0, + pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), type2, val, 0, ATF_SHORT|ATF_TARGET); break; case SP_SKILL_ATK: @@ -2239,21 +2245,39 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) } break; case SP_ADD_SKILL_BLOW: - for (i = 0; i < MAX_PC_BONUS && sd->skillblown[i].id != 0 && sd->skillblown[i].id != type2; i++); - if (i == MAX_PC_BONUS) + if(sd->state.lr_flag == 2) + break; + for (i = 0; i < ARRAYLENGTH(sd->skillblown) && sd->skillblown[i].id && sd->skillblown[i].id != type2; i++); + if (i == ARRAYLENGTH(sd->skillblown)) { //Better mention this so the array length can be updated. [Skotlex] - ShowDebug("run_script: bonus2 bSkillBlown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", MAX_PC_BONUS, type2, val); + ShowDebug("run_script: bonus2 bSkillBlown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillblown), type2, val); break; } - if(sd->state.lr_flag != 2) { - if (sd->skillblown[i].id == type2) - sd->skillblown[i].val += val; - else { - sd->skillblown[i].id = type2; - sd->skillblown[i].val = val; - } + if(sd->skillblown[i].id == type2) + sd->skillblown[i].val += val; + else { + sd->skillblown[i].id = type2; + sd->skillblown[i].val = val; } break; + + case SP_CASTRATE: + if(sd->state.lr_flag == 2) + break; + for (i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id && sd->skillblown[i].id != type2; i++); + if (i == ARRAYLENGTH(sd->skillcast)) + { //Better mention this so the array length can be updated. [Skotlex] + ShowDebug("run_script: bonus2 bCastRate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcast), type2, val); + break; + } + if(sd->skillcast[i].id == type2) + sd->skillcast[i].val += val; + else { + sd->skillcast[i].id = type2; + sd->skillcast[i].val = val; + } + break; + case SP_ADD_DAMAGE_BY_CLASS: if(sd->state.lr_flag != 2) { for(i=0;iadd_dmg_count;i++) { @@ -2271,8 +2295,14 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) break; case SP_HP_LOSS_RATE: if(sd->state.lr_flag != 2) { - sd->hp_loss_value = type2; - sd->hp_loss_rate = val; + sd->hp_loss.value = type2; + sd->hp_loss.rate = val; + } + break; + case SP_HP_REGEN_RATE: + if(sd->state.lr_flag != 2) { + sd->hp_regen.value = type2; + sd->hp_regen.rate = val; } break; case SP_ADDRACE2: @@ -2325,8 +2355,14 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) break; case SP_SP_LOSS_RATE: if(sd->state.lr_flag != 2) { - sd->sp_loss_value = type2; - sd->sp_loss_rate = val; + sd->sp_loss.value = type2; + sd->sp_loss.rate = val; + } + break; + case SP_SP_REGEN_RATE: + if(sd->state.lr_flag != 2) { + sd->sp_regen.value = type2; + sd->sp_regen.rate = val; } break; case SP_HP_DRAIN_VALUE_RACE: @@ -2345,6 +2381,10 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->left_weapon.sp_drain[type2].value += val; } break; + case SP_IGNORE_MDEF_RATE: + if(sd->state.lr_flag != 2) + sd->ignore_mdef[type2] += val; + break; default: if(battle_config.error_log) @@ -2371,13 +2411,6 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) if(sd->state.lr_flag != 2) pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, skill_get_inf(type2)&INF_SELF_SKILL?-type2:type2, type3, val, 0, current_equip_card_id); break; - case SP_HP_LOSS_RATE: - if(sd->state.lr_flag != 2) { - sd->hp_loss_value = type2; - sd->hp_loss_rate = type3; - sd->hp_loss_type = val; - } - break; case SP_SP_DRAIN_RATE: if(!sd->state.lr_flag) { sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2; @@ -4919,7 +4952,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) if (sd->menuskill_id) sd->menuskill_id = sd->menuskill_val = 0; //Reset ticks. - sd->hp_loss_tick = sd->sp_loss_tick = 0; + sd->hp_loss.tick = sd->sp_loss.tick = sd->hp_regen.tick = sd->sp_regen.tick = 0; pc_setglobalreg(sd,"PC_DIE_COUNTER",++sd->die_counter); @@ -6828,25 +6861,19 @@ void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick) { int hp = 0, sp = 0; - if (sd->hp_loss_value > 0) { - sd->hp_loss_tick += diff_tick; - if (sd->hp_loss_tick >= sd->hp_loss_rate) { - do { - hp += sd->hp_loss_value; - sd->hp_loss_tick -= sd->hp_loss_rate; - } while (sd->hp_loss_tick >= sd->hp_loss_rate); - sd->hp_loss_tick = 0; + if (sd->hp_loss.value) { + sd->hp_loss.tick += diff_tick; + while (sd->hp_loss.tick >= sd->hp_loss.rate) { + hp += sd->hp_loss.value; + sd->hp_loss.tick -= sd->hp_loss.rate; } } - if (sd->sp_loss_value > 0) { - sd->sp_loss_tick += diff_tick; - if (sd->sp_loss_tick >= sd->sp_loss_rate) { - do { - sp += sd->sp_loss_value; - sd->sp_loss_tick -= sd->sp_loss_rate; - } while (sd->sp_loss_tick >= sd->sp_loss_rate); - sd->sp_loss_tick = 0; + if (sd->sp_loss.value) { + sd->sp_loss.tick += diff_tick; + while (sd->sp_loss.tick >= sd->sp_loss.rate) { + sp += sd->sp_loss.value; + sd->sp_loss.tick -= sd->sp_loss.rate; } } @@ -6856,6 +6883,35 @@ void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick) return; } +//Character regen. Flag is used to know which types of regen can take place. +//&1: HP regen +//&2: SP regen +void pc_regen (struct map_session_data *sd, unsigned int diff_tick, int flag) +{ + int hp = 0, sp = 0; + + if (sd->hp_regen.value && flag&1) { + sd->hp_regen.tick += diff_tick; + while (sd->hp_regen.tick >= sd->hp_regen.rate) { + hp += sd->hp_regen.value; + sd->hp_regen.tick -= sd->hp_regen.rate; + } + } + + if (sd->sp_regen.value && flag&2) { + sd->sp_regen.tick += diff_tick; + while (sd->sp_regen.tick >= sd->sp_regen.rate) { + sp += sd->sp_regen.value; + sd->sp_regen.tick -= sd->sp_regen.rate; + } + } + + if (hp > 0 || sp > 0) + status_heal(&sd->bl, hp, sp, 2); + + return; +} + /*========================================== * セ?ブポイントの保存 *------------------------------------------*/ diff --git a/src/map/pc.h b/src/map/pc.h index bced5ec01..3b404388d 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -264,6 +264,7 @@ struct map_session_data *pc_get_mother(struct map_session_data *sd); struct map_session_data *pc_get_child(struct map_session_data *sd); void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick); +void pc_regen (struct map_session_data *sd, unsigned int diff_tick, int flag); int pc_set_gm_level(int account_id, int level); void pc_setstand(struct map_session_data *sd); diff --git a/src/map/skill.c b/src/map/skill.c index 4efd8413b..02d41c671 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4604,8 +4604,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in type = EQP_WEAPON|EQP_SHIELD|EQP_ARMOR|EQP_HELM; break; } + //Note that autospells don't use a duration if (!clif_skill_nodamage(src,bl,skillid,skilllv, - skill_strip_equip(bl, type, i, skilllv, skill_get_time(skillid,skilllv))) + skill_strip_equip(bl, type, i, skilllv, + sd&&!pc_checkskill(sd, skillid)?0:skill_get_time(skillid,skilllv))) && sd) clif_skill_fail(sd,skillid,0,0); //Nothing stripped. break; @@ -8789,10 +8791,20 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) } // calculate cast time reduced by item/card bonuses - if (!(skill_get_castnodex(skill_id, skill_lv)&4)) - if (sd && sd->castrate != 100) + if (!(skill_get_castnodex(skill_id, skill_lv)&4) && sd) + { + int i; + if (sd->castrate != 100) time = time * sd->castrate / 100; - + for(i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++) + { + if (sd->skillcast[i].id == skill_id) + { + time+= time * sd->skillcast[i].val / 100; + break; + } + } + } // config cast time multiplier if (battle_config.cast_rate != 100) time = time * battle_config.cast_rate / 100; diff --git a/src/map/status.c b/src/map/status.c index 3b62cfe81..7fe903c2d 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -384,7 +384,7 @@ void initChangeTables(void) add_sc(NPC_MAGICMIRROR, SC_MAGICMIRROR); set_sc(NPC_SLOWCAST, SC_SLOWCAST, SI_SLOWCAST, SCB_NONE); set_sc(NPC_CRITICALWOUND, SC_CRITICALWOUND, SI_CRITICALWOUND, SCB_NONE); - set_sc(NPC_STONESKIN, SC_ARMORCHANGE, SI_BLANK, SCB_DEF|SCB_MDEF|SCB_DEF2|SCB_MDEF2); + set_sc(NPC_STONESKIN, SC_ARMORCHANGE, SI_BLANK, SCB_DEF|SCB_MDEF); add_sc(NPC_ANTIMAGIC, SC_ARMORCHANGE); add_sc(NPC_WIDECURSE, SC_CURSE); add_sc(NPC_WIDESTUN, SC_STUN); @@ -1657,6 +1657,7 @@ int status_calc_pc(struct map_session_data* sd,int first) + sizeof(sd->magic_addsize) + sizeof(sd->critaddrace) + sizeof(sd->expaddrace) + + sizeof(sd->ignore_mdef) + sizeof(sd->itemgrouphealrate) + sizeof(sd->sp_gain_race) ); @@ -1697,6 +1698,7 @@ int status_calc_pc(struct map_session_data* sd,int first) + sizeof(sd->skillatk) + sizeof(sd->skillheal) + sizeof(sd->skillblown) + + sizeof(sd->skillcast) + sizeof(sd->add_def) + sizeof(sd->add_mdef) + sizeof(sd->add_dmg) @@ -1734,8 +1736,6 @@ int status_calc_pc(struct map_session_data* sd,int first) + sizeof(sd->break_weapon_rate) + sizeof(sd->break_armor_rate) + sizeof(sd->crit_atk_rate) - + sizeof(sd->hp_loss_rate) - + sizeof(sd->sp_loss_rate) + sizeof(sd->classchange) + sizeof(sd->speed_add_rate) + sizeof(sd->aspd_add) @@ -1745,9 +1745,6 @@ int status_calc_pc(struct map_session_data* sd,int first) + sizeof(sd->splash_range) + sizeof(sd->splash_add_range) + sizeof(sd->add_steal_rate) - + sizeof(sd->hp_loss_value) - + sizeof(sd->sp_loss_value) - + sizeof(sd->hp_loss_type) + sizeof(sd->hp_gain_value) + sizeof(sd->sp_gain_value) + sizeof(sd->sp_vanish_rate) @@ -3556,7 +3553,7 @@ static signed char status_calc_def(struct block_list *bl, struct status_change * if(sc->data[SC_STEELBODY].timer!=-1) return 90; if(sc->data[SC_ARMORCHANGE].timer!=-1) - def += def * sc->data[SC_ARMORCHANGE].val2/100; + def += sc->data[SC_ARMORCHANGE].val2; if(sc->data[SC_DRUMBATTLE].timer!=-1) def += sc->data[SC_DRUMBATTLE].val3; if(sc->data[SC_DEFENCE].timer != -1) //[orn] @@ -3592,8 +3589,6 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change return 0; if(sc->data[SC_ETERNALCHAOS].timer!=-1) return 0; - if(sc->data[SC_ARMORCHANGE].timer!=-1) - def2 += def2 * sc->data[SC_ARMORCHANGE].val2/100; if(sc->data[SC_SUN_COMFORT].timer!=-1) def2 += sc->data[SC_SUN_COMFORT].val2; if(sc->data[SC_ANGELUS].timer!=-1) @@ -3633,7 +3628,7 @@ static signed char status_calc_mdef(struct block_list *bl, struct status_change if(sc->data[SC_SKA].timer != -1) // [marquis007] return 90; if(sc->data[SC_ARMORCHANGE].timer!=-1) - mdef += mdef * sc->data[SC_ARMORCHANGE].val3/100; + mdef += sc->data[SC_ARMORCHANGE].val3; if(sc->data[SC_STONE].timer!=-1 && sc->opt1 == OPT1_STONE) mdef += 25*mdef/100; if(sc->data[SC_FREEZE].timer!=-1) @@ -3651,8 +3646,6 @@ static signed short status_calc_mdef2(struct block_list *bl, struct status_chang if(sc->data[SC_BERSERK].timer!=-1) return 0; - if(sc->data[SC_ARMORCHANGE].timer!=-1) - mdef2 += mdef2 * sc->data[SC_ARMORCHANGE].val3/100; if(sc->data[SC_MINDBREAKER].timer!=-1) mdef2 -= mdef2 * sc->data[SC_MINDBREAKER].val3/100; @@ -4466,6 +4459,10 @@ int status_get_sc_def(struct block_list *bl, int type, int rate, int tick, int f tick /= 5; sc_def = status->agi; break; + case SC_ARMORCHANGE: + if (sd) //Duration greatly reduced for players. + tick /= 15; + //No defense against it. default: //Effect that cannot be reduced? Likely a buff. if (!(rand()%10000 < rate)) @@ -4711,6 +4708,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val } if (!opt_flag) return 0; } + if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; case SC_STRIPSHIELD: if (sd) { @@ -4723,6 +4721,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val return 0; pc_unequipitem(sd,i,3); } + if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; case SC_STRIPARMOR: if (sd) { @@ -4734,6 +4733,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val return 0; pc_unequipitem(sd,i,3); } + if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; case SC_STRIPHELM: if (sd) { @@ -4745,6 +4745,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val return 0; pc_unequipitem(sd,i,3); } + if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; } @@ -7132,8 +7133,8 @@ static int status_natural_heal(DBKey key,void * data,va_list ap) )) flag=0; - if (sd && (sd->hp_loss_value > 0 || sd->sp_loss_value > 0)) - pc_bleeding(sd, natural_heal_diff_tick); + if (sd && (sd->hp_loss.value || sd->sp_loss.value)) + pc_bleeding(sd, natural_heal_diff_tick); if(flag&(RGN_SHP|RGN_SSP) && regen->ssregen && (vd = status_get_viewdata(bl)) && vd->dead_sit == 2) @@ -7236,6 +7237,10 @@ static int status_natural_heal(DBKey key,void * data,va_list ap) } } + //Bonus skill-like regen + if (sd && (sd->hp_regen.value || sd->sp_regen.value)) + pc_regen(sd, natural_heal_diff_tick, (flag&RGN_SHP?1:0)|(flag&RGN_SSP?2:0)); + if (!regen->sregen) return flag; -- cgit v1.2.3-60-g2f50