summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/battle.c16
-rw-r--r--src/map/map.h27
-rw-r--r--src/map/mob.c8
-rw-r--r--src/map/pc.c134
-rw-r--r--src/map/pc.h1
-rw-r--r--src/map/skill.c20
-rw-r--r--src/map/status.c33
7 files changed, 163 insertions, 76 deletions
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;i<sd->add_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;