From 8c2918aa0f1c3eb7c2d66a6aecb46bfff6fe1523 Mon Sep 17 00:00:00 2001 From: skotlex Date: Fri, 21 Apr 2006 18:42:35 +0000 Subject: - Updated the HP/SP leech structures to have race-data attached to them. - Merged all leeching code to battle_drain function. - Added an enum for races (they match the RC entries in const.txt, except they are in all caps) - Cleaned up atk_mods and aspd_base to be MAX_WEAPON_TYPE sized rather than MAX_WEAPON_TYPE+1 - Simplified a bit the code for Signum Crucis - Added script bonuses: bonus3 bHPDrainRateRace,,, bonus3 bSPDrainRateRace,,, bonus2 bHPDrainValueRace,, bonus2 bSPDrainValueRace,, git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6221 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 9 ++++ db/const.txt | 6 ++- src/map/battle.c | 129 +++++++++++++++++++++++++++++++--------------------- src/map/battle.h | 1 + src/map/map.h | 57 ++++++++++++++--------- src/map/pc.c | 129 ++++++++++++++++++++++++++++++++++++++-------------- src/map/skill.c | 45 +++++------------- src/map/status.c | 55 +++++++++------------- 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,,,; + bonus3 bSPDrainRateRace,,,; + bonus2 bHPDrainValueRace,,; + bonus2 bSPDrainValueRace,,; * 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