diff options
-rw-r--r-- | Changelog-Trunk.txt | 4 | ||||
-rw-r--r-- | db/Changelog.txt | 2 | ||||
-rw-r--r-- | db/item_db.txt | 2 | ||||
-rw-r--r-- | doc/item_bonus.txt | 43 | ||||
-rw-r--r-- | src/map/battle.c | 124 | ||||
-rw-r--r-- | src/map/pc.c | 83 | ||||
-rw-r--r-- | src/map/pc.h | 9 | ||||
-rw-r--r-- | src/map/status.c | 1 |
8 files changed, 253 insertions, 15 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index b4b9ae837..e934518d0 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,9 +3,11 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. +2010/08/18 + * Rev. 14381 Added bonus3 bAdd/SubEle, which allows you to specify a battle flag as well! Dun dun dun! [L0ne_W0lf] + - The bonuses are addititive to existing bAdd/SubEles, as that's how it appears to work. 2010/08/16 * Fixed an exploit where unauthorized GMs can give zeny through auction. [Inkfish] -2010/08/16 * Rev. 14378 Attempting to tackle, and fix some simple errors in skills. [L0ne_W0lf] - Stormgust hit counter no longer resets under new casts of stormgust. - RG_STEALCOIN will now cause the monster to aggro player on success. (bugreport:3547) diff --git a/db/Changelog.txt b/db/Changelog.txt index 660edbeb8..668c84103 100644 --- a/db/Changelog.txt +++ b/db/Changelog.txt @@ -8,6 +8,8 @@ 1475 Equestrian's Spear: NEED INFO. 13005 Angelic Wing Dagger: NEED INFO. ======================= +2010/08/18 + * Rev. 14381 Updated Asprika to use new bonus3 bSubEle. [L0ne_W0lf] 2010/08/16 * Rev. 14378 Flag some skills so they won't be given with @allskills. (bugreport:3933) [L0ne_W0lf] 2010/07/30 diff --git a/db/item_db.txt b/db/item_db.txt index b49a5783e..bb5cfa7cf 100644 --- a/db/item_db.txt +++ b/db/item_db.txt @@ -1405,7 +1405,7 @@ 2538,Commander_Manteau,Captain's Manteau,5,0,,0,,4,,1,0x026654E2,7,2,4,,80,1,0,{ bonus bMaxHP,50; bonus bMdef,1; bonus2 bSubRace,RC_DemiHuman,1; },{},{} 2539,Commander_Manteau_,Commander's Manteau,5,0,,0,,3,,1,0x00898B1C,7,2,4,,80,1,0,{ bonus bMaxHP,50; bonus bMdef,1; bonus2 bSubRace,RC_DemiHuman,1; },{},{} 2540,Sheriff_Manteau,Sheriff's Manteau,5,0,,0,,3,,1,0x01000000,7,2,4,,80,1,0,{ bonus bMaxHP,50; bonus bMdef,1; bonus2 bSubRace,RC_DemiHuman,1; },{},{} -2541,Asprika,Asprika,5,0,,400,,5,,0,0xFFFFFFFF,7,2,4,,94,0,0,{ bonus bMdef,5; bonus2 bSubEle,Ele_Neutral,30; bonus2 bSubEle,Ele_Water,30; bonus2 bSubEle,Ele_Earth,30; bonus2 bSubEle,Ele_Fire,30; bonus2 bSubEle,Ele_Wind,30; bonus2 bSubEle,Ele_Poison,30; bonus2 bSubEle,Ele_Holy,30; bonus2 bSubEle,Ele_Dark,30; bonus2 bSubEle,Ele_Ghost,30; bonus2 bSubEle,Ele_Undead,30; bonus bFlee,30; skill "AL_TELEPORT",1; bonus bUnbreakableGarment,0; },{},{} +2541,Asprika,Asprika,5,0,,400,,5,,0,0xFFFFFFFF,7,2,4,,94,0,0,{ bonus bMdef,5; bonus3 bSubEle,Ele_Neutral,30,BF_SHORT; bonus3 bSubEle,Ele_Water,30,BF_SHORT; bonus3 bSubEle,Ele_Earth,30,BF_SHORT; bonus3 bSubEle,Ele_Fire,30,BF_SHORT; bonus3 bSubEle,Ele_Wind,30,BF_SHORT; bonus3 bSubEle,Ele_Poison,30,BF_SHORT; bonus3 bSubEle,Ele_Holy,30,BF_SHORT; bonus3 bSubEle,Ele_Dark,30,BF_SHORT; bonus3 bSubEle,Ele_Ghost,30,BF_SHORT; bonus3 bSubEle,Ele_Undead,30,BF_SHORT; bonus bFlee,30; skill "AL_TELEPORT",1; bonus bUnbreakableGarment,0; },{},{} 2542,Flame_Manteau,Flame Manteau of Naght Sieger,5,20,,70,,4,,1,0xFFFFFFFE,2,2,4,,70,1,0,{ bonus bMaxHPRate,5; bonus bMdef,2; bonus bMatkRate,1; bonus2 bAddEle,Ele_Fire,2; },{},{} 2543,Sylphid_Manteau,Sylphid Manteau,5,20,,0,,9,,0,0xFFFFFFFF,7,2,4,,0,0,0,{ bonus bFlee,13; bonus2 bSubEle,Ele_Neutral,13; bonus bFlee2,1; },{},{} 2544,Leather_Of_Tendrilion,Leather of Tendrilion,5,20,,300,,3,,1,0x00CFDF80,2,2,4,,0,1,0,{ bonus2 bSubEle,Ele_Water,5; bonus2 bSubEle,Ele_Earth,5; bonus2 bSubRace,RC_Plant,5; bonus2 bSubRace,RC_Brute,5; },{},{} diff --git a/doc/item_bonus.txt b/doc/item_bonus.txt index cb1b4218a..d9224e196 100644 --- a/doc/item_bonus.txt +++ b/doc/item_bonus.txt @@ -333,3 +333,46 @@ bonus2 bSPDrainValue,n,x; When hitting a monster by physical attack, ... 1=you drain n SP from target bonus2 bIgnoreDefRate,n,x; Disregard x% of the target's DEF if the target belongs to race n; + +bonus3 bAddEle,n,x,t; +x% physical damage against element n + n: 0=Neutral, 1=Water, 2=Earth, 3=Fire, 4=Wind, 5=Poison, + 6=Holy, 7=Dark, 8=Spirit, 9=Undead + t: Trigger criteria: + BF_SHORT: Trigger on melee attack + BF_LONG: Trigger on ranged attack + ( Default: BF_SHORT+BF_LONG ) + + BF_WEAPON: Trigger on weapon skills + BF_MAGIC: Trigger on magic skills + BF_MISC: Trigger on misc skills + ( Default: BF_WEAPON ) + + BF_NORMAL: Trigger on normal + attacks. + BF_SKILL: Trigger on skills + (Default: BF_SKILL if type is BF_MISC or BF_MAGIC, BF_NORMAL if type is BF_WEAPON) + + i: 1=cast on enemy, not on self + 2=use random skill lv in [1..y] + 3=1+2 (random lv on enemy) +bonus3 bSubEle,n,x,t; x% Damage reduction against element n. + n: 0=Neutral, 1=Water, 2=Earth, 3=Fire, 4=Wind, 5=Poison, + 6=Holy, 7=Dark, 8=Spirit, 9=Undead + t: Trigger criteria: + BF_SHORT: Trigger on melee attack + BF_LONG: Trigger on ranged attack + ( Default: BF_SHORT+BF_LONG ) + + BF_WEAPON: Trigger on weapon skills + BF_MAGIC: Trigger on magic skills + BF_MISC: Trigger on misc skills + ( Default: BF_WEAPON ) + + BF_NORMAL: Trigger on normal + attacks. + BF_SKILL: Trigger on skills + (Default: BF_SKILL if type is BF_MISC or BF_MAGIC, BF_NORMAL if type is BF_WEAPON) + + i: 1=cast on enemy, not on self + 2=use random skill lv in [1..y] + 3=1+2 (random lv on enemy) diff --git a/src/map/battle.c b/src/map/battle.c index 0f800b759..12f16f83d 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2001,12 +2001,23 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if( (wd.damage || wd.damage2) && !(nk&NK_NO_CARDFIX_ATK) ) { int cardfix = 1000, cardfix_ = 1000; - int t_race2 = status_get_race2(target); + int t_race2 = status_get_race2(target); if(sd->state.arrow_atk) { cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->arrow_addrace[tstatus->race])/100; if (!(nk&NK_NO_ELEFIX)) - cardfix=cardfix*(100+sd->right_weapon.addele[tstatus->def_ele]+sd->arrow_addele[tstatus->def_ele])/100; + { + int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->arrow_addele[tstatus->def_ele]; + for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) { + if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue; + if(!(sd->right_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK && + sd->right_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK && + sd->right_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK)) + continue; + ele_fix += sd->right_weapon.addele2[i].rate; + } + cardfix=cardfix*(100+ele_fix)/100; + } cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->arrow_addsize[tstatus->size])/100; cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100; cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->arrow_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100; @@ -2017,9 +2028,19 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo { // Melee attack if( !battle_config.left_cardfix_to_right ) { - cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100; - if (!(nk&NK_NO_ELEFIX)) - cardfix=cardfix*(100+sd->right_weapon.addele[tstatus->def_ele])/100; + cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100; + if (!(nk&NK_NO_ELEFIX)) { + int ele_fix = sd->right_weapon.addele[tstatus->def_ele]; + for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) { + if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue; + if(!(sd->right_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK && + sd->right_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK && + sd->right_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK)) + continue; + ele_fix += sd->right_weapon.addele2[i].rate; + } + cardfix=cardfix*(100+ele_fix)/100; + } cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size])/100; cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2])/100; cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100; @@ -2028,9 +2049,19 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if( flag.lh ) { - cardfix_=cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100; - if (!(nk&NK_NO_ELEFIX)) - cardfix_=cardfix_*(100+sd->left_weapon.addele[tstatus->def_ele])/100; + cardfix_=cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100; + if (!(nk&NK_NO_ELEFIX)) { + int ele_fix_lh = sd->left_weapon.addele[tstatus->def_ele]; + for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) { + if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue; + if(!(sd->left_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK && + sd->left_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK && + sd->left_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK)) + continue; + ele_fix_lh += sd->left_weapon.addele2[i].rate; + } + cardfix=cardfix*(100+ele_fix_lh)/100; + } cardfix_=cardfix_*(100+sd->left_weapon.addsize[tstatus->size])/100; cardfix_=cardfix_*(100+sd->left_weapon.addrace2[t_race2])/100; cardfix_=cardfix_*(100+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100; @@ -2040,8 +2071,26 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo } else { + int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele]; + for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) { + if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue; + if(!(sd->right_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK && + sd->right_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK && + sd->right_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK)) + continue; + ele_fix += sd->right_weapon.addele2[i].rate; + } + for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) { + if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue; + if(!(sd->left_weapon.addele2[i].flag&wd.flag&BF_WEAPONMASK && + sd->left_weapon.addele2[i].flag&wd.flag&BF_RANGEMASK && + sd->left_weapon.addele2[i].flag&wd.flag&BF_SKILLMASK)) + continue; + ele_fix += sd->left_weapon.addele2[i].rate; + } + cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->left_weapon.addrace[tstatus->race])/100; - cardfix=cardfix*(100+sd->right_weapon.addele[tstatus->def_ele]+sd->left_weapon.addele[tstatus->def_ele])/100; + cardfix=cardfix*(100+ele_fix)/100; cardfix=cardfix*(100+sd->right_weapon.addsize[tstatus->size]+sd->left_weapon.addsize[tstatus->size])/100; cardfix=cardfix*(100+sd->right_weapon.addrace2[t_race2]+sd->left_weapon.addrace2[t_race2])/100; cardfix=cardfix*(100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100; @@ -2097,9 +2146,31 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if( !(nk&NK_NO_ELEFIX) ) { - cardfix=cardfix*(100-tsd->subele[s_ele])/100; + int ele_fix = tsd->subele[s_ele]; + for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++) + { + if(tsd->subele2[i].ele != s_ele) continue; + if(!(tsd->subele2[i].flag&wd.flag&BF_WEAPONMASK && + tsd->subele2[i].flag&wd.flag&BF_RANGEMASK && + tsd->subele2[i].flag&wd.flag&BF_SKILLMASK)) + continue; + ele_fix += tsd->subele2[i].rate; + } + cardfix=cardfix*(100-ele_fix)/100; if( flag.lh && s_ele_ != s_ele ) - cardfix=cardfix*(100-tsd->subele[s_ele_])/100; + { + int ele_fix_lh = tsd->subele[s_ele_]; + for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++) + { + if(tsd->subele2[i].ele != s_ele_) continue; + if(!(tsd->subele2[i].flag&wd.flag&BF_WEAPONMASK && + tsd->subele2[i].flag&wd.flag&BF_RANGEMASK && + tsd->subele2[i].flag&wd.flag&BF_SKILLMASK)) + continue; + ele_fix_lh += tsd->subele2[i].rate; + } + cardfix=cardfix*(100-ele_fix_lh)/100; + } } cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100; cardfix=cardfix*(100-tsd->subrace2[s_race2])/100; @@ -2532,7 +2603,19 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list int cardfix=1000; if (!(nk&NK_NO_ELEFIX)) - cardfix=cardfix*(100-tsd->subele[s_ele])/100; + { + int ele_fix = tsd->subele[s_ele]; + for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++) + { + if(tsd->subele2[i].ele != s_ele) continue; + if(!(tsd->subele2[i].flag&ad.flag&BF_WEAPONMASK && + tsd->subele2[i].flag&ad.flag&BF_RANGEMASK && + tsd->subele2[i].flag&ad.flag&BF_SKILLMASK)) + continue; + ele_fix += tsd->subele2[i].rate; + } + cardfix=cardfix*(100-ele_fix)/100; + } cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100; cardfix=cardfix*(100-tsd->subrace2[s_race2])/100; cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100; @@ -2769,7 +2852,22 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * int cardfix = 10000; int race2 = status_get_race2(src); if (!(nk&NK_NO_ELEFIX)) - cardfix=cardfix*(100-tsd->subele[s_ele])/100; + { + if (!(nk&NK_NO_ELEFIX)) + { + int ele_fix = tsd->subele[s_ele]; + for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++) + { + if(tsd->subele2[i].ele != s_ele) continue; + if(!(tsd->subele2[i].flag&md.flag&BF_WEAPONMASK && + tsd->subele2[i].flag&md.flag&BF_RANGEMASK && + tsd->subele2[i].flag&md.flag&BF_SKILLMASK)) + continue; + ele_fix += tsd->subele2[i].rate; + } + cardfix=cardfix*(100-ele_fix)/100; + } + } cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100; cardfix=cardfix*(100-tsd->subrace2[race2])/100; cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100; diff --git a/src/map/pc.c b/src/map/pc.c index 04027c42d..70a433c0e 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1729,6 +1729,71 @@ int pc_endautobonus(int tid, unsigned int tick, int id, intptr data) return 0; } +int pc_bonus_addele(struct map_session_data* sd, unsigned char ele, short rate, short flag) +{ + int i; + struct weapon_data* wd; + + wd = (sd->state.lr_flag ? &sd->left_weapon : &sd->right_weapon); + + ARR_FIND(0, MAX_PC_BONUS, i, wd->addele2[i].rate == 0); + + if (i == MAX_PC_BONUS) + { + ShowWarning("pc_addele: Reached max (%d) possible bonuses for this player.\n", MAX_PC_BONUS); + return 0; + } + + if (!(flag&BF_RANGEMASK)) + flag |= BF_SHORT|BF_LONG; + if (!(flag&BF_WEAPONMASK)) + flag |= BF_WEAPON; + if (!(flag&BF_SKILLMASK)) + { + if (flag&(BF_MAGIC|BF_MISC)) + flag |= BF_SKILL; + if (flag&BF_WEAPON) + flag |= BF_NORMAL|BF_SKILL; + } + + wd->addele2[i].ele = ele; + wd->addele2[i].rate = rate; + wd->addele2[i].flag = flag; + + return 0; +} + +int pc_bonus_subele(struct map_session_data* sd, unsigned char ele, short rate, short flag) +{ + int i; + + ARR_FIND(0, MAX_PC_BONUS, i, sd->subele2[i].rate == 0); + + if (i == MAX_PC_BONUS) + { + ShowWarning("pc_subele: Reached max (%d) possible bonuses for this player.\n", MAX_PC_BONUS); + return 0; + } + + if (!(flag&BF_RANGEMASK)) + flag |= BF_SHORT|BF_LONG; + if (!(flag&BF_WEAPONMASK)) + flag |= BF_WEAPON; + if (!(flag&BF_SKILLMASK)) + { + if (flag&(BF_MAGIC|BF_MISC)) + flag |= BF_SKILL; + if (flag&BF_WEAPON) + flag |= BF_NORMAL|BF_SKILL; + } + + sd->subele2[i].ele = ele; + sd->subele2[i].rate = rate; + sd->subele2[i].flag = flag; + + return 0; +} + /*========================================== * ? 備品による能力等のボ?ナス設定 *------------------------------------------*/ @@ -2856,6 +2921,24 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) if( sd->state.lr_flag != 2 ) pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, val, type2, 2); break; + + case SP_ADDELE: + if (type2 > ELE_MAX) { + ShowWarning("pc_bonus3 (SP_ADDELE): element %d is out of range.\n", type2); + break; + } + if (sd->state.lr_flag != 2) + pc_bonus_addele(sd, (unsigned char)type2, type3, val); + break; + + case SP_SUBELE: + if (type2 > ELE_MAX) { + ShowWarning("pc_bonus3 (SP_SUBELE): element %d is out of range.\n", type2); + break; + } + if (sd->state.lr_flag != 2) + pc_bonus_subele(sd, (unsigned char)type2, type3, val); + break; default: ShowWarning("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val); diff --git a/src/map/pc.h b/src/map/pc.h index 65d21739a..1328e9367 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -44,6 +44,11 @@ struct weapon_data { struct { short class_, rate; } add_dmg[MAX_PC_BONUS]; + + struct { + short flag, rate; + unsigned char ele; + } addele2[MAX_PC_BONUS]; }; struct s_autospell { @@ -250,6 +255,10 @@ struct map_session_data { int nameid; int rate; } itemhealrate[MAX_PC_BONUS]; + struct { + short flag, rate; + unsigned char ele; + } subele2[MAX_PC_BONUS]; // zeroed structures end here // manually zeroed structures start here. struct s_autobonus autobonus[MAX_PC_BONUS], autobonus2[MAX_PC_BONUS], autobonus3[MAX_PC_BONUS]; //Auto script on attack, when attacked, on skill usage diff --git a/src/map/status.c b/src/map/status.c index f1315f23f..f65771045 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1804,6 +1804,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) + sizeof(sd->add_mdmg) + sizeof(sd->add_drop) + sizeof(sd->itemhealrate) + + sizeof(sd->subele2) ); // vars zeroing. ints, shorts, chars. in that order. |