summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt9
-rw-r--r--db/const.txt6
-rw-r--r--src/map/battle.c129
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/map.h57
-rw-r--r--src/map/pc.c129
-rw-r--r--src/map/skill.c45
-rw-r--r--src/map/status.c55
8 files changed, 255 insertions, 176 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 103427f52..d05267680 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,15 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/04/21
+ * Updated the HP/SP leech structures to have race-data attached to them.
+ [Skotlex]
+ * Merged all leeching code to new battle_drain function. [Skotlex]
+ * Simplified a bit the code for Signum Crucis [Skotlex]
+ * Added script bonuses: [Skotlex]
+ bonus3 bHPDrainRateRace,<Race>,<Activation Rate>,<Drain %>;
+ bonus3 bSPDrainRateRace,<Race>,<Activation Rate>,<Drain %>;
+ bonus2 bHPDrainValueRace,<Race>,<Value>;
+ bonus2 bSPDrainValueRace,<Race>,<Value>;
* Fixed items not really getting unequipped when they should. [Skotlex]
2006/04/20
* Fixed the equip/unequip scripts not triggering for compounded cards.
diff --git a/db/const.txt b/db/const.txt
index 0746b1f98..33918ed1a 100644
--- a/db/const.txt
+++ b/db/const.txt
@@ -264,6 +264,8 @@ bSPDrainValue 1080
bWeaponAtk 1081
bWeaponAtkRate 1082
bDelayrate 1083
+bHPDrainRateRace 1084
+bSPDrainRateRace 1085
bRestartFullRecover 2000
bNoCastCancel 2001
@@ -292,9 +294,9 @@ bHPLossRate 2023
bAddRace2 2024
bHPGainValue 2025
bSubSize 2026
-
+bHPDrainValueRace 2027
bAddItemHealRate 2028
-
+bSPDrainValueRace 2029
bExpAddRace 2030
bSPGainRace 2031
bSPSubRace2 2032
diff --git a/src/map/battle.c b/src/map/battle.c
index 44704b0b0..a519e3a65 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -653,13 +653,10 @@ int battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int dama
* HP/SP吸収の計算
*------------------------------------------
*/
-int battle_calc_drain(int damage, int rate, int per, int val)
+static int battle_calc_drain(int damage, int rate, int per)
{
int diff = 0;
- if (damage <= 0)
- return 0;
-
if (per && rand()%1000 < rate) {
diff = (damage * per) / 100;
if (diff == 0) {
@@ -669,10 +666,6 @@ int battle_calc_drain(int damage, int rate, int per, int val)
diff = -1;
}
}
-
- if (val /*&& rand()%1000 < rate*/) { //Absolute leech/penalties have 100% chance. [Skotlex]
- diff += val;
- }
return diff;
}
@@ -690,12 +683,12 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
nullpo_retr(0, sd);
// デ?[モンベイン(+3 ?` +30) vs 不死 or 悪魔 (死?lは含めない?H)
- if((skill = pc_checkskill(sd,AL_DEMONBANE)) > 0 && (battle_check_undead(race,status_get_elem_type(target)) || race==6) )
+ if((skill = pc_checkskill(sd,AL_DEMONBANE)) > 0 && (battle_check_undead(race,status_get_elem_type(target)) || race==RC_DEMON) )
damage += (skill*(int)(3+(sd->status.base_level+1)*0.05)); // submitted by orn
//damage += (skill * 3);
// ビ?[ストベイン(+4 ?` +40) vs 動物 or ?ゥ虫
- if((skill = pc_checkskill(sd,HT_BEASTBANE)) > 0 && (race==2 || race==4) ) {
+ if((skill = pc_checkskill(sd,HT_BEASTBANE)) > 0 && (race==RC_BRUTE || race==RC_INSECT) ) {
damage += (skill * 4);
if (sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_HUNTER)
damage += sd->status.str;
@@ -1916,7 +1909,7 @@ static struct Damage battle_calc_weapon_attack(
vit_def = def2*(def2-15)/150;
vit_def = def2/2 + (vit_def>0?rand()%vit_def:0);
- if((battle_check_undead(s_race,status_get_elem_type(src)) || s_race==6) &&
+ if((battle_check_undead(s_race,status_get_elem_type(src)) || s_race==RC_DEMON) &&
(skill=pc_checkskill(tsd,AL_DP)) >0)
vit_def += skill*(int)(3 +(tsd->status.base_level+1)*0.04); // submitted by orn
} else { //Mob-Pet vit-eq
@@ -3021,6 +3014,69 @@ int battle_calc_return_damage(struct block_list *bl, int *damage, int flag) {
}
return rdamage;
}
+
+void battle_drain(TBL_PC *sd, TBL_PC* tsd, int rdamage, int ldamage, int race, int boss)
+{
+ struct weapon_data *wd;
+ int type, thp = 0, tsp = 0, rhp = 0, rsp = 0, hp, sp, i, *damage;
+ for (i = 0; i < 4; i++) {
+ //First two iterations: Right hand
+ if (i < 2) { wd = &sd->right_weapon; damage = &rdamage; }
+ else { wd = &sd->left_weapon; damage = &ldamage; }
+ if (*damage <= 0) continue;
+ //First and Third iterations: race, other two boss/nonboss state
+ if (i == 0 || i == 2)
+ type = race;
+ else
+ type = boss?RC_BOSS:RC_NONBOSS;
+
+ hp = wd->hp_drain[type].value;
+ if (wd->hp_drain[type].rate)
+ hp += battle_calc_drain(*damage,
+ wd->hp_drain[type].rate,
+ wd->hp_drain[type].per);
+
+ sp = wd->sp_drain[type].value;
+ if (wd->sp_drain[type].rate)
+ sp += battle_calc_drain(*damage,
+ wd->sp_drain[type].rate,
+ wd->sp_drain[type].per);
+
+ if (hp) {
+ if (wd->hp_drain[type].type)
+ rhp += hp;
+ thp += hp;
+ }
+ if (sp) {
+ if (wd->sp_drain[type].type)
+ rsp += sp;
+ tsp += sp;
+ }
+ }
+ if (!thp && !tsp) return;
+
+ pc_heal(sd, thp, tsp);
+
+ if (battle_config.show_hp_sp_drain && sd->fd)
+ { //Display gained values only when they are positive [Skotlex]
+ if (thp && thp > sd->status.max_hp - sd->status.hp)
+ thp = sd->status.max_hp - sd->status.hp;
+ if (tsp && tsp > sd->status.max_sp - sd->status.sp)
+ tsp = sd->status.max_sp - sd->status.sp;
+
+ if (thp > 0)
+ clif_heal(sd->fd, SP_HP, thp);
+ if (tsp > 0)
+ clif_heal(sd->fd, SP_SP, tsp);
+ }
+
+ if (tsd) {
+ if (rhp || rsp)
+ pc_heal(tsd, -rhp, -rsp);
+ if (rand()%1000 < sd->sp_vanish_rate)
+ pc_damage_sp(tsd, 0, sd->sp_vanish_per);
+ }
+}
/*==========================================
* 通??U撃??まとめ
*------------------------------------------
@@ -3123,7 +3179,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
wd.dmotion = clif_damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2);
//二?流?カ手とカタ?[ル追撃のミス表示(無?やり?`)
- if(sd && sd->status.weapon >= MAX_WEAPON_TYPE && wd.damage2 == 0)
+ if(sd && sd->status.weapon > MAX_WEAPON_TYPE && wd.damage2 == 0)
clif_damage(src, target, tick+10, wd.amotion, wd.dmotion,0, 1, 0, 0);
if (sd && sd->splash_range > 0 && damage > 0)
@@ -3141,8 +3197,8 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
rate += sd->weapon_coma_ele[ele];
if (sd->weapon_coma_race[race] > 0)
rate += sd->weapon_coma_race[race];
- if (sd->weapon_coma_race[boss?10:11] > 0)
- rate += sd->weapon_coma_race[boss?10:11];
+ if (sd->weapon_coma_race[boss?RC_BOSS:RC_NONBOSS] > 0)
+ rate += sd->weapon_coma_race[boss?RC_BOSS:RC_NONBOSS];
if (rate)
status_change_start(target, SC_COMA, rate, 0, 0, 0, 0, 0, 0);
}
@@ -3177,43 +3233,10 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
}
if (sd) {
if (wd.flag & BF_WEAPON && src != target && damage > 0) {
- int hp = 0, sp = 0;
- if (!battle_config.left_cardfix_to_right) { // 二?流?カ手カ?[ドの吸収系効果を右手に追加しない??
- hp += battle_calc_drain(wd.damage, sd->right_weapon.hp_drain_rate, sd->right_weapon.hp_drain_per, sd->right_weapon.hp_drain_value);
- hp += battle_calc_drain(wd.damage2, sd->left_weapon.hp_drain_rate, sd->left_weapon.hp_drain_per, sd->left_weapon.hp_drain_value);
- sp += battle_calc_drain(wd.damage, sd->right_weapon.sp_drain_rate, sd->right_weapon.sp_drain_per, sd->right_weapon.sp_drain_value);
- sp += battle_calc_drain(wd.damage2, sd->left_weapon.sp_drain_rate, sd->left_weapon.sp_drain_per, sd->left_weapon.sp_drain_value);
- } else { // 二?流?カ手カ?[ドの吸収系効果を右手に追加する??
- int hp_drain_rate = sd->right_weapon.hp_drain_rate + sd->left_weapon.hp_drain_rate;
- int hp_drain_per = sd->right_weapon.hp_drain_per + sd->left_weapon.hp_drain_per;
- int hp_drain_value = sd->right_weapon.hp_drain_value + sd->left_weapon.hp_drain_value;
- int sp_drain_rate = sd->right_weapon.sp_drain_rate + sd->left_weapon.sp_drain_rate;
- int sp_drain_per = sd->right_weapon.sp_drain_per + sd->left_weapon.sp_drain_per;
- int sp_drain_value = sd->right_weapon.sp_drain_value + sd->left_weapon.sp_drain_value;
- hp += battle_calc_drain(wd.damage, hp_drain_rate, hp_drain_per, hp_drain_value);
- sp += battle_calc_drain(wd.damage, sp_drain_rate, sp_drain_per, sp_drain_value);
- }
- if (hp && hp + sd->status.hp > sd->status.max_hp)
- hp = sd->status.max_hp - sd->status.hp;
- if (sp && sp + sd->status.sp > sd->status.max_sp)
- sp = sd->status.max_sp - sd->status.sp;
-
- if (hp || sp)
- pc_heal(sd, hp, sp);
-
- if (battle_config.show_hp_sp_drain)
- { //Display gained values only when they are positive [Skotlex]
- if (hp > 0)
- clif_heal(sd->fd, SP_HP, hp);
- if (sp > 0)
- clif_heal(sd->fd, SP_SP, sp);
- }
-
- if (tsd && sd->sp_drain_type)
- pc_damage_sp(tsd, sp, 0);
-
- if (tsd && rand()%1000 < sd->sp_vanish_rate)
- pc_damage_sp(tsd, 0, sd->sp_vanish_per);
+ if (battle_config.left_cardfix_to_right)
+ battle_drain(sd, tsd, wd.damage, wd.damage, race, is_boss(target));
+ else
+ battle_drain(sd, tsd, wd.damage, wd.damage2, race, is_boss(target));
}
}
if (rdamage > 0) //By sending attack type "none" skill_additional_effect won't be invoked. [Skotlex]
@@ -3246,11 +3269,11 @@ int battle_check_undead(int race,int element)
return 1;
}
else if(battle_config.undead_detect_type == 1) {
- if(race == 1)
+ if(race == RC_UNDEAD)
return 1;
}
else {
- if(element == 9 || race == 1)
+ if(element == 9 || race == RC_UNDEAD)
return 1;
}
return 0;
diff --git a/src/map/battle.h b/src/map/battle.h
index 1cae169d6..5b32fecdf 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -26,6 +26,7 @@ struct block_list;
struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int flag);
int battle_calc_return_damage(struct block_list *bl, int *damage, int flag);
+void battle_drain(struct map_session_data *sd, struct map_session_data *tsd, int rdamage, int ldamage, int race, int boss);
int battle_attr_fix(struct block_list *src, struct block_list *target, int damage,int atk_elem,int def_elem);
diff --git a/src/map/map.h b/src/map/map.h
index 0a7ee5f90..7e133a516 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -282,6 +282,22 @@ enum {
enum { WARP, SHOP, SCRIPT, MONS };
+enum {
+ RC_FORMLESS=0,
+ RC_UNDEAD,
+ RC_BRUTE,
+ RC_PLANT,
+ RC_INSECT,
+ RC_FISH,
+ RC_DEMON,
+ RC_DEMIHUMAN,
+ RC_ANGEL,
+ RC_DRAGON,
+ RC_BOSS,
+ RC_NONBOSS,
+ RC_MAX
+};
+
struct block_list {
struct block_list *next,*prev;
int id;
@@ -417,17 +433,18 @@ struct weapon_data {
int def_ratio_atk_ele;
int def_ratio_atk_race;
int addele[10];
- int addrace[12];
- int addrace2[12];
+ int addrace[RC_MAX];
+ int addrace2[RC_MAX];
int addsize[3];
short ignore_def_mob;
- short hp_drain_rate;
- short hp_drain_per;
- short hp_drain_value;
- short sp_drain_rate;
- short sp_drain_per;
- short sp_drain_value;
+ struct drain_data {
+ short rate;
+ short per;
+ short value;
+ unsigned type:1;
+ } hp_drain[RC_MAX], sp_drain[RC_MAX];
+
short add_damage_classid[MAX_PC_BONUS];
int add_damage_classrate[MAX_PC_BONUS];
int add_damage_class_count;
@@ -579,30 +596,30 @@ struct map_session_data {
int paramb[6];
int parame[6];
int subele[10];
- int subrace[12];
- int subrace2[12];
+ int subrace[RC_MAX];
+ int subrace2[RC_MAX];
int subsize[3];
int addeff[SC_COMMON_MAX-SC_COMMON_MIN+1];
int addeff2[SC_COMMON_MAX-SC_COMMON_MIN+1];
int reseff[SC_COMMON_MAX-SC_COMMON_MIN+1];
int weapon_coma_ele[10];
- int weapon_coma_race[12];
+ int weapon_coma_race[RC_MAX];
int weapon_atk[16];
int weapon_atk_rate[16];
int arrow_addele[10];
- int arrow_addrace[12];
+ int arrow_addrace[RC_MAX];
int arrow_addsize[3];
int arrow_addeff[SC_COMMON_MAX-SC_COMMON_MIN+1];
int arrow_addeff2[SC_COMMON_MAX-SC_COMMON_MIN+1];
int magic_addele[10];
- int magic_addrace[12];
+ int magic_addrace[RC_MAX];
int magic_addsize[3];
- int critaddrace[12];
- int expaddrace[12];
+ int critaddrace[RC_MAX];
+ int expaddrace[RC_MAX];
int itemhealrate[7];
int addeff3[SC_COMMON_MAX-SC_COMMON_MIN+1];
short addeff3_type[SC_COMMON_MAX-SC_COMMON_MIN+1];
- short sp_gain_race[12];
+ short sp_gain_race[RC_MAX];
// zeroed arrays end here.
// zeroed structures start here
struct s_autospell{
@@ -658,7 +675,6 @@ struct map_session_data {
short hp_loss_value;
short sp_loss_value;
short hp_loss_type;
- short sp_drain_type;
short sp_gain_value, hp_gain_value;
short sp_vanish_rate;
short sp_vanish_per;
@@ -1105,8 +1121,8 @@ enum {
SP_DISGUISE,SP_CLASSCHANGE, // 1077-1078
SP_HP_DRAIN_VALUE,SP_SP_DRAIN_VALUE, // 1079-1080
SP_WEAPON_ATK,SP_WEAPON_ATK_RATE, // 1081-1082
- SP_DELAYRATE, // 1083
-
+ SP_DELAYRATE,SP_HP_DRAIN_RATE_RACE,SP_SP_DRAIN_RATE_RACE, // 1083-1085
+
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_INFINITE_ENDURE,SP_UNBREAKABLE_WEAPON,SP_UNBREAKABLE_ARMOR, SP_UNBREAKABLE_HELM, // 2006-2010
SP_UNBREAKABLE_SHIELD, SP_LONG_ATK_RATE, // 2011-2012
@@ -1114,12 +1130,11 @@ enum {
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_IGNORE_DEF_MOB, SP_HP_LOSS_RATE, SP_ADDRACE2, SP_HP_GAIN_VALUE, // 2021-2025
- SP_SUBSIZE, SP_FREE, SP_ADD_ITEM_HEAL_RATE, SP_FREE2, SP_EXP_ADDRACE, // 2026-2030
+ 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 you add more here, notice that 2027&2029 are available.
};
enum {
diff --git a/src/map/pc.c b/src/map/pc.c
index 665e380ff..371816c8b 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1613,18 +1613,22 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
case SP_HP_DRAIN_VALUE:
if(!sd->state.lr_flag) {
- sd->right_weapon.hp_drain_value += val;
+ sd->right_weapon.hp_drain[RC_NONBOSS].value += val;
+ sd->right_weapon.hp_drain[RC_BOSS].value += val;
}
else if(sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain_value += val;
+ sd->right_weapon.hp_drain[RC_NONBOSS].value += val;
+ sd->right_weapon.hp_drain[RC_BOSS].value += val;
}
break;
case SP_SP_DRAIN_VALUE:
if(!sd->state.lr_flag) {
- sd->right_weapon.sp_drain_value += val;
+ sd->right_weapon.sp_drain[RC_NONBOSS].value += val;
+ sd->right_weapon.sp_drain[RC_BOSS].value += val;
}
else if(sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain_value += val;
+ sd->left_weapon.sp_drain[RC_NONBOSS].value += val;
+ sd->left_weapon.sp_drain[RC_BOSS].value += val;
}
break;
case SP_SP_GAIN_VALUE:
@@ -1807,42 +1811,59 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
case SP_HP_DRAIN_RATE:
if(!sd->state.lr_flag) {
- sd->right_weapon.hp_drain_rate += type2;
- sd->right_weapon.hp_drain_per += val;
+ sd->right_weapon.hp_drain[RC_NONBOSS].rate += type2;
+ sd->right_weapon.hp_drain[RC_NONBOSS].per += val;
+ sd->right_weapon.hp_drain[RC_BOSS].rate += type2;
+ sd->right_weapon.hp_drain[RC_BOSS].per += val;
}
else if(sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain_rate += type2;
- sd->left_weapon.hp_drain_per += val;
+ sd->left_weapon.hp_drain[RC_NONBOSS].rate += type2;
+ sd->left_weapon.hp_drain[RC_NONBOSS].per += val;
+ sd->left_weapon.hp_drain[RC_BOSS].rate += type2;
+ sd->left_weapon.hp_drain[RC_BOSS].per += val;
}
break;
case SP_HP_DRAIN_VALUE:
if(!sd->state.lr_flag) {
- sd->right_weapon.hp_drain_value += type2;
+ sd->right_weapon.hp_drain[RC_NONBOSS].value += type2;
+ sd->right_weapon.hp_drain[RC_NONBOSS].type = val;
+ sd->right_weapon.hp_drain[RC_BOSS].value += type2;
+ sd->right_weapon.hp_drain[RC_BOSS].type = val;
}
else if(sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain_value += type2;
+ sd->left_weapon.hp_drain[RC_NONBOSS].value += type2;
+ sd->left_weapon.hp_drain[RC_NONBOSS].type = val;
+ sd->left_weapon.hp_drain[RC_BOSS].value += type2;
+ sd->left_weapon.hp_drain[RC_BOSS].type = val;
}
- sd->sp_drain_type = val;
break;
case SP_SP_DRAIN_RATE:
if(!sd->state.lr_flag) {
- sd->right_weapon.sp_drain_rate += type2;
- sd->right_weapon.sp_drain_per += val;
+ sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_NONBOSS].per += val;
+ sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_BOSS].per += val;
}
else if(sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain_rate += type2;
- sd->left_weapon.sp_drain_per += val;
+ sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_NONBOSS].per += val;
+ sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_BOSS].per += val;
}
- sd->sp_drain_type = 0;
break;
case SP_SP_DRAIN_VALUE:
if(!sd->state.lr_flag) {
- sd->right_weapon.sp_drain_value += type2;
+ sd->right_weapon.sp_drain[RC_NONBOSS].value += type2;
+ sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->right_weapon.sp_drain[RC_BOSS].value += type2;
+ sd->right_weapon.sp_drain[RC_BOSS].type = val;
}
else if(sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain_value += type2;
+ sd->left_weapon.sp_drain[RC_NONBOSS].value += type2;
+ sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->left_weapon.sp_drain[RC_BOSS].value += type2;
+ sd->left_weapon.sp_drain[RC_BOSS].type = val;
}
- sd->sp_drain_type = val;
break;
case SP_SP_VANISH_RATE:
if(sd->state.lr_flag != 2) {
@@ -2005,6 +2026,22 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
sd->sp_loss_rate = val;
}
break;
+ case SP_HP_DRAIN_VALUE_RACE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[type2].value += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[type2].value += val;
+ }
+ break;
+ case SP_SP_DRAIN_VALUE_RACE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[type2].value += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[type2].value += val;
+ }
+ break;
default:
if(battle_config.error_log)
@@ -2040,14 +2077,42 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
break;
case SP_SP_DRAIN_RATE:
if(!sd->state.lr_flag) {
- sd->right_weapon.sp_drain_rate += type2;
- sd->right_weapon.sp_drain_per += type3;
+ sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_NONBOSS].per += type3;
+ sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_BOSS].per += type3;
+ sd->right_weapon.sp_drain[RC_BOSS].type = val;
+
}
else if(sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain_rate += type2;
- sd->left_weapon.sp_drain_per += type3;
+ sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_NONBOSS].per += type3;
+ sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_BOSS].per += type3;
+ sd->left_weapon.sp_drain[RC_BOSS].type = val;
+ }
+ break;
+ case SP_HP_DRAIN_RATE_RACE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[type2].rate += type3;
+ sd->right_weapon.hp_drain[type2].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[type2].rate += type3;
+ sd->left_weapon.hp_drain[type2].per += val;
+ }
+ break;
+ case SP_SP_DRAIN_RATE_RACE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[type2].rate += type3;
+ sd->right_weapon.sp_drain[type2].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[type2].rate += type3;
+ sd->left_weapon.sp_drain[type2].per += val;
}
- sd->sp_drain_type = val;
break;
case SP_ADD_MONSTER_DROP_ITEMGROUP:
if (sd->state.lr_flag != 2)
@@ -6226,12 +6291,6 @@ int pc_equipitem(struct map_session_data *sd,int n,int pos)
run_script(data->equip_script,0,sd->bl.id,0);
}
}
-
- if(sd->sc.count) {
- if (sd->sc.data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
- status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
- }
-
return 0;
}
@@ -6301,11 +6360,12 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
pc_checkallowskill(sd);
if(sd->weapontype1 == 0 && sd->weapontype2 == 0)
skill_enchant_elemental_end(&sd->bl,-1); //武器持ち誓えは無?件で?性付?解除
- if(flag&1) {
+ if(flag&1)
status_calc_pc(sd,0);
- if(sd->sc.count && sd->sc.data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(7,sd->def_ele))
- status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
- }
+
+ if(sd->sc.count && sd->sc.data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(RC_DEMIHUMAN,sd->def_ele))
+ status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
+
//OnUnEquip script [Skotlex]
if (sd->inventory_data[n]) {
struct item_data *data;
@@ -6325,6 +6385,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
run_script(data->unequip_script,0,sd->bl.id,0);
}
}
+
return 0;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index 294c7a888..ee9f34a07 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -1099,7 +1099,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
case NPC_GRANDDARKNESS: /*闇グランドク?ス*/
{
int race = status_get_race(bl);
- if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6)
+ if(battle_check_undead(race,status_get_elem_type(bl)) || race == RC_DEMON)
sc_start(bl,SC_BLIND,100,skilllv,skill_get_time2(skillid,skilllv));
}
break;
@@ -1206,7 +1206,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
{
//??が良く分からないので適?に
int race = status_get_race(bl);
- if (!(battle_check_undead(race, status_get_elem_type(bl)) || race == 6))
+ if (!(battle_check_undead(race, status_get_elem_type(bl)) || race == RC_DEMON))
sc_start(bl, SC_BLEEDING,50, skilllv, skill_get_time2(skillid,skilllv));
}
break;
@@ -1877,7 +1877,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
case AC_DOUBLE:
{
int race = status_get_race(bl);
- if((race == 2 || race == 4) && damage < status_get_hp(bl) && pc_checkskill(sd, HT_POWER)) {
+ if((race == RC_BRUTE || race == RC_INSECT) && damage < status_get_hp(bl) && pc_checkskill(sd, HT_POWER)) {
//TODO: This code was taken from Triple Blows,is this even how it should be? [Skotlex]
sc_start4(src,SC_COMBO,100,HT_POWER,bl->id,0,0,2000);
clif_combo_delay(src,2000);
@@ -2018,31 +2018,10 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
}
if(sd && dmg.flag&BF_WEAPON && src != bl && src == dsrc && damage > 0) {
- int hp = 0,sp = 0;
- if(sd->right_weapon.hp_drain_rate && sd->right_weapon.hp_drain_per > 0 && dmg.damage > 0 && rand()%1000 < sd->right_weapon.hp_drain_rate) {
- hp += (dmg.damage * sd->right_weapon.hp_drain_per)/100;
- if(sd->right_weapon.hp_drain_rate > 0 && hp < 1) hp = 1;
- else if(sd->right_weapon.hp_drain_rate < 0 && hp > -1) hp = -1;
- }
- if(sd->left_weapon.hp_drain_rate && sd->left_weapon.hp_drain_per > 0 && dmg.damage2 > 0 && rand()%1000 < sd->left_weapon.hp_drain_rate) {
- hp += (dmg.damage2 * sd->left_weapon.hp_drain_per)/100;
- if(sd->left_weapon.hp_drain_rate > 0 && hp < 1) hp = 1;
- else if(sd->left_weapon.hp_drain_rate < 0 && hp > -1) hp = -1;
- }
- if(sd->right_weapon.sp_drain_rate > 0 && sd->right_weapon.sp_drain_per > 0 && dmg.damage > 0 && rand()%1000 < sd->right_weapon.sp_drain_rate) {
- sp += (dmg.damage * sd->right_weapon.sp_drain_per)/100;
- if(sd->right_weapon.sp_drain_rate > 0 && sp < 1) sp = 1;
- else if(sd->right_weapon.sp_drain_rate < 0 && sp > -1) sp = -1;
- }
- if(sd->left_weapon.sp_drain_rate > 0 && sd->left_weapon.sp_drain_per > 0 && dmg.damage2 > 0 && rand()%1000 < sd->left_weapon.sp_drain_rate) {
- sp += (dmg.damage2 * sd->left_weapon.sp_drain_per)/100;
- if(sd->left_weapon.sp_drain_rate > 0 && sp < 1) sp = 1;
- else if(sd->left_weapon.sp_drain_rate < 0 && sp > -1) sp = -1;
- }
- if(hp || sp)
- pc_heal(sd,hp,sp);
- if (sd->sp_drain_type && tsd)
- pc_damage_sp(tsd,sp,0);
+ if (battle_config.left_cardfix_to_right)
+ battle_drain(sd, tsd, dmg.damage, dmg.damage, status_get_race(bl), status_get_mode(bl)&MD_BOSS);
+ else
+ battle_drain(sd, tsd, dmg.damage, dmg.damage2, status_get_race(bl), status_get_mode(bl)&MD_BOSS);
}
if (rdamage>0) {
@@ -2881,7 +2860,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s
case PR_BENEDICTIO: /* ?ケ??~福 */
{ //Should attack undead and demons. [Skotlex]
int race = status_get_race(bl);
- if (battle_check_undead(race, status_get_elem_type(bl)) || race == 6)
+ if (battle_check_undead(race, status_get_elem_type(bl)) || race == RC_DEMON)
skill_attack(BF_MAGIC, src, src, bl, skillid, skilllv, tick, flag);
}
break;
@@ -3044,7 +3023,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s
case GS_BULLSEYE:
{
int race = status_get_race(bl);
- if(race == 2 || race == 7)
+ if(race == RC_BRUTE || race == RC_DEMIHUMAN)
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
else
clif_skill_fail(sd,skillid,0,0);
@@ -4259,7 +4238,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
}else if(dstmd)
{
int race = status_get_race(bl);
- if(status_get_lv(src)>status_get_lv(bl) && (race == 6 || race == 7 || race == 8)) {
+ if(status_get_lv(src)>status_get_lv(bl) && (race == RC_DEMON || race == RC_DEMIHUMAN || race == RC_ANGEL)) {
clif_skill_nodamage(src,bl,skillid,skilllv,
sc_start(bl,type,70,skilllv,skill_get_time(skillid,skilllv)));
} else{
@@ -6802,7 +6781,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign
{
int race = status_get_race(bl);
- if (battle_check_undead(race, status_get_elem_type(bl)) || race==6) {
+ if (battle_check_undead(race, status_get_elem_type(bl)) || race==RC_DEMON) {
if (skill_attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0)) {
// reduce healing count if this was meant for damaging [hekate]
sg->val1 -= 2;
@@ -6826,7 +6805,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign
case UNT_MAGNUS:
{
int race = status_get_race(bl);
- if (!battle_check_undead(race,status_get_elem_type(bl)) && race!=6)
+ if (!battle_check_undead(race,status_get_elem_type(bl)) && race!=RC_DEMON)
break;
skill_attack(BF_MAGIC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
break;
diff --git a/src/map/status.c b/src/map/status.c
index 4eec25e6b..14498f490 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -37,11 +37,11 @@ static int hp_coefficient[MAX_PC_CLASS];
static int hp_coefficient2[MAX_PC_CLASS];
static int hp_sigma_val[MAX_PC_CLASS][MAX_LEVEL];
static int sp_coefficient[MAX_PC_CLASS];
-static int aspd_base[MAX_PC_CLASS][MAX_WEAPON_TYPE+1]; //[blackhole89]
+static int aspd_base[MAX_PC_CLASS][MAX_WEAPON_TYPE]; //[blackhole89]
#define MAX_REFINE_BONUS 5
static int refinebonus[MAX_REFINE_BONUS][3]; // 精錬ボーナステーブル(refine_db.txt)
int percentrefinery[5][MAX_REFINE+1]; // 精錬成功率(refine_db.txt)
-static int atkmods[3][MAX_WEAPON_TYPE+1]; // 武器ATKサイズ修正(size_fix.txt)
+static int atkmods[3][MAX_WEAPON_TYPE]; // 武器ATKサイズ修正(size_fix.txt)
static char job_bonus[MAX_PC_CLASS][MAX_LEVEL];
int current_equip_item_index; //Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus]
@@ -501,7 +501,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
if (pc_isinvisible(sd))
return 0;
if (tsc->option&hide_flag
- && (sd->state.perfect_hiding || !(race == 4 || race == 6 || mode&MD_DETECTOR))
+ && (sd->state.perfect_hiding || !(race == RC_INSECT || race == RC_DEMON || mode&MD_DETECTOR))
&& !(mode&MD_BOSS))
return 0;
}
@@ -516,7 +516,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
//Check for chase-walk/hiding/cloaking opponents.
if (tsc && !(mode&MD_BOSS))
{
- if (tsc->option&hide_flag && !(race == 4 || race == 6 || mode&MD_DETECTOR))
+ if (tsc->option&hide_flag && !(race == RC_INSECT || race == RC_DEMON || mode&MD_DETECTOR))
return 0;
}
}
@@ -785,7 +785,6 @@ int status_calc_pc(struct map_session_data* sd,int first)
+ sizeof(sd->hp_loss_value)
+ sizeof(sd->sp_loss_value)
+ sizeof(sd->hp_loss_type)
- + sizeof(sd->sp_drain_type)
+ sizeof(sd->hp_gain_value)
+ sizeof(sd->sp_gain_value)
+ sizeof(sd->add_drop_count)
@@ -1559,10 +1558,10 @@ int status_calc_pc(struct map_session_data* sd,int first)
}
if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){
skill = skill*4;
- sd->right_weapon.addrace[9]+=skill;
- sd->left_weapon.addrace[9]+=skill;
- sd->magic_addrace[9]+=skill;
- sd->subrace[9]+=skill;
+ sd->right_weapon.addrace[RC_DRAGON]+=skill;
+ sd->left_weapon.addrace[RC_DRAGON]+=skill;
+ sd->magic_addrace[RC_DRAGON]+=skill;
+ sd->subrace[RC_DRAGON]+=skill;
}
if(sd->sc.count){
@@ -1579,7 +1578,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
}
if(sd->sc.data[SC_PROVIDENCE].timer!=-1){
sd->subele[6] += sd->sc.data[SC_PROVIDENCE].val2;
- sd->subrace[6] += sd->sc.data[SC_PROVIDENCE].val2;
+ sd->subrace[RC_DEMON] += sd->sc.data[SC_PROVIDENCE].val2;
}
}
@@ -1686,7 +1685,7 @@ int status_calc_str(struct block_list *bl, int str)
str += 10; //Bonus is +!0 regardless of skill level
if(sc->data[SC_BLESSING].timer != -1){
int race = status_get_race(bl);
- if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6)
+ if(battle_check_undead(race,status_get_elem_type(bl)) || race == RC_DEMON)
str >>= 1;
else str += sc->data[SC_BLESSING].val1;
}
@@ -1766,7 +1765,7 @@ int status_calc_int(struct block_list *bl, int int_)
int_ += 5;
if(sc->data[SC_BLESSING].timer != -1){
int race = status_get_race(bl);
- if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6)
+ if(battle_check_undead(race,status_get_elem_type(bl)) || race == RC_DEMON)
int_ >>= 1;
else int_ += sc->data[SC_BLESSING].val1;
}
@@ -1798,7 +1797,7 @@ int status_calc_dex(struct block_list *bl, int dex)
dex -= sc->data[SC_QUAGMIRE].val1*(bl->type==BL_PC?5:10);
if(sc->data[SC_BLESSING].timer != -1){
int race = status_get_race(bl);
- if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6)
+ if(battle_check_undead(race,status_get_elem_type(bl)) || race == RC_DEMON)
dex >>= 1;
else dex += sc->data[SC_BLESSING].val1;
}
@@ -3202,7 +3201,7 @@ int status_get_race(struct block_list *bl)
if(bl->type==BL_MOB)
return ((struct mob_data *)bl)->db->race;
if(bl->type==BL_PC)
- return 7;
+ return RC_DEMIHUMAN;
if(bl->type==BL_PET)
return ((struct pet_data *)bl)->db->race;
return 0;
@@ -3696,12 +3695,12 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
break;
case SC_COMA:
//Dark elementals and Demons are inmune to coma.
- if((elem == 7 || race == 6) && !(flag&1))
+ if((elem == 7 || race == RC_DEMON) && !(flag&1))
return 0;
break;
case SC_SIGNUMCRUCIS:
//Only affects demons and undead.
- if(race != 6 && !undead_flag)
+ if(race != RC_DEMON && !undead_flag)
return 0;
break;
case SC_AETERNA:
@@ -3759,7 +3758,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
return 0;
switch (type) {
case SC_BLESSING:
- if (!undead_flag || race != 6)
+ if (!undead_flag || race != RC_DEMON)
break;
case SC_QUAGMIRE:
case SC_DECREASEAGI:
@@ -3774,7 +3773,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
//Before overlapping fail, one must check for status cured.
switch (type) {
case SC_BLESSING:
- if (!undead_flag && race!=6) {
+ if (!undead_flag && race!=RC_DEMON) {
if (sc->data[SC_CURSE].timer!=-1)
status_change_end(bl,SC_CURSE,-1);
if (sc->data[SC_STONE].timer!=-1 && sc->data[SC_STONE].val2==0)
@@ -5412,16 +5411,6 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
}
break;
- case SC_SIGNUMCRUCIS: /* シグナムクルシス */
- {
- int race = status_get_race(bl);
- if(race == 6 || battle_check_undead(race,status_get_elem_type(bl))) {
- sc->data[type].timer=add_timer(1000*600+tick,status_change_timer, bl->id, data );
- return 0;
- }
- }
- break;
-
case SC_WARM: //SG skills [Komurka]
if( (--sc->data[type].val2)>0){
map_foreachinrange( status_change_timer_sub, bl,
@@ -5540,6 +5529,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
case SC_DODGE:
case SC_AUTOBERSERK: //continues until triggered off manually. [Skotlex]
case SC_NEN:
+ case SC_SIGNUMCRUCIS: /* シグナムクルシス */
sc->data[type].timer=add_timer( 1000*600+tick,status_change_timer, bl->id, data );
return 0;
@@ -5948,7 +5938,7 @@ int status_readdb(void) {
// サイズ補正テ?ブル
for(i=0;i<3;i++)
- for(j=0;j<=MAX_WEAPON_TYPE;j++)
+ for(j=0;j<MAX_WEAPON_TYPE;j++)
atkmods[i][j]=100;
sprintf(path, "%s/size_fix.txt", db_path);
fp=fopen(path,"r");
@@ -5958,19 +5948,18 @@ int status_readdb(void) {
}
i=0;
while(fgets(line, sizeof(line)-1, fp)){
- char *split[MAX_WEAPON_TYPE+1];
+ char *split[MAX_WEAPON_TYPE];
if(line[0]=='/' && line[1]=='/')
continue;
if(atoi(line)<=0)
continue;
memset(split,0,sizeof(split));
- for(j=0,p=line;j<=MAX_WEAPON_TYPE && p;j++){
+ for(j=0,p=line;j<MAX_WEAPON_TYPE && p;j++){
split[j]=p;
p=strchr(p,',');
if(p) *p++=0;
- }
- for(j=0;j<=MAX_WEAPON_TYPE && split[j];j++)
atkmods[i][j]=atoi(split[j]);
+ }
i++;
}
fclose(fp);