From b5636c1a16c969ae068485bb7165443f8a8a7e7e Mon Sep 17 00:00:00 2001 From: skotlex Date: Wed, 22 Feb 2006 20:39:55 +0000 Subject: - Removed pc_break_equip, added function skill_break_equip which handles rates, defenses and all that. On non-players it causes the strip effect for the corresponding skill lv1. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5374 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/battle.c | 38 ++++++----------- src/map/pc.c | 51 ---------------------- src/map/pc.h | 7 --- src/map/skill.c | 128 ++++++++++++++++++++++++++++++++++++++++++------------- src/map/skill.h | 1 + 5 files changed, 113 insertions(+), 112 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index d7c97e284..c578167d7 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2258,9 +2258,9 @@ static struct Damage battle_calc_weapon_attack( mob_class_change(((struct mob_data *)target),class_); } - if (sd && (battle_config.equip_self_break_rate || battle_config.equip_skill_break_rate) && - (wd.damage > 0 || wd.damage2 > 0)) { - if (battle_config.equip_self_break_rate) { // Self weapon breaking + if (wd.damage > 0 || wd.damage2 > 0) { + if (sd && battle_config.equip_self_break_rate) + { // Self weapon breaking int breakrate = battle_config.equip_natural_break_rate; if (sc) { if(sc->data[SC_OVERTHRUST].timer!=-1) @@ -2268,35 +2268,25 @@ static struct Damage battle_calc_weapon_attack( if(sc->data[SC_MAXOVERTHRUST].timer!=-1) breakrate += 10; } - if(rand() % 10000 < breakrate * battle_config.equip_self_break_rate / 100 || breakrate >= 10000) - pc_breakweapon(sd); + skill_break_equip(src, EQP_WEAPON, breakrate, BCT_SELF); } - if (battle_config.equip_skill_break_rate) { // Target equipment breaking + if (battle_config.equip_skill_break_rate) + { // Target equipment breaking int breakrate[2] = {0,0}; // weapon = 0, armor = 1 - int breaktime = 5000; - - breakrate[0] += sd->break_weapon_rate; // Break rate from equipment - breakrate[1] += sd->break_armor_rate; + if (sd) { // Break rate from equipment + breakrate[0] += sd->break_weapon_rate; + breakrate[1] += sd->break_armor_rate; + } if (sc) { if (sc->data[SC_MELTDOWN].timer!=-1) { breakrate[0] += 100*sc->data[SC_MELTDOWN].val1; breakrate[1] += 70*sc->data[SC_MELTDOWN].val1; - breaktime = skill_get_time2(WS_MELTDOWN,1); } } - if(rand() % 10000 < breakrate[0] * battle_config.equip_skill_break_rate / 100 || breakrate[0] >= 10000) { - if (target->type == BL_PC) - pc_breakweapon((struct map_session_data *)target); - else - status_change_start(target,SC_STRIPWEAPON,100,1,75,0,0,breaktime,0); - } - if(rand() % 10000 < breakrate[1] * battle_config.equip_skill_break_rate/100 || breakrate[1] >= 10000) { - if (target->type == BL_PC) { - struct map_session_data *tsd = (struct map_session_data *)target; - pc_breakarmor(tsd); - } else - status_change_start(target,SC_STRIPSHIELD,100,1,75,0,0,breaktime,0); - } + if (breakrate[0]) + skill_break_equip(target, EQP_WEAPON, breakrate[0], BCT_ENEMY); + if (breakrate[1]) + skill_break_equip(target, EQP_ARMOR, breakrate[1], BCT_ENEMY); } } return wd; diff --git a/src/map/pc.c b/src/map/pc.c index d0abfac82..b89639ebc 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -642,57 +642,6 @@ int pc_isequip(struct map_session_data *sd,int n) return 1; } -//装備破壊 -int pc_break_equip(struct map_session_data *sd, unsigned short where) -{ - int i, j; - - nullpo_retr(-1, sd); - if (sd->unbreakable_equip & where) - return 0; - if (sd->unbreakable >= rand()%100) - return 0; - if (where == EQP_WEAPON && (sd->status.weapon == 0 || //Bare fists should not break :P - sd->status.weapon == 6 || sd->status.weapon == 7 || sd->status.weapon == 8 || // Axes and Maces can't be broken [DracoRPG] - sd->status.weapon == 10 || sd->status.weapon == 15 //Rods and Books can't be broken [Skotlex] - )) - return 0; - switch (where) { - case EQP_WEAPON: - i = SC_CP_WEAPON; - break; - case EQP_ARMOR: - i = SC_CP_ARMOR; - break; - case EQP_SHIELD: - i = SC_CP_SHIELD; - break; - case EQP_HELM: - i = SC_CP_HELM; - break; - default: - return 0; - } - if (sd->sc.count && sd->sc.data[i].timer != -1) - return 0; - - for (i = 0; i < 11; i++) { - if ((j = sd->equip_index[i]) > 0 && sd->status.inventory[j].attribute != 1 && - ((where == EQP_HELM && i == 6) || - (where == EQP_ARMOR && i == 7) || - (where == EQP_WEAPON && (i == 8 || i == 9) && sd->inventory_data[j]->type == 4) || - (where == EQP_SHIELD && i == 9 && sd->inventory_data[j]->type == 5))) - { - sd->status.inventory[j].attribute = 1; - pc_unequipitem(sd, j, 3); - clif_equiplist(sd); - return 1; - } - } - - return 1; -} - /*========================================== * session idに問題無し * char鯖から送られてきたステ?タスを設定 diff --git a/src/map/pc.h b/src/map/pc.h index 4701f781e..9c0fe20ab 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -47,12 +47,6 @@ int pc_reg_received(struct map_session_data *sd); int pc_isequip(struct map_session_data *sd,int n); int pc_equippoint(struct map_session_data *sd,int n); -int pc_break_equip(struct map_session_data *, unsigned short); -#define pc_breakweapon(sd) (pc_break_equip(sd, EQP_WEAPON)) -#define pc_breakarmor(sd) (pc_break_equip(sd, EQP_ARMOR)) -#define pc_breakshield(sd) (pc_break_equip(sd, EQP_SHIELD)) -#define pc_breakhelm(sd) (pc_break_equip(sd, EQP_HELM)) - int pc_checkskill(struct map_session_data *sd,int skill_id); int pc_checkallowskill(struct map_session_data *sd); int pc_checkequip(struct map_session_data *sd,int pos); @@ -194,7 +188,6 @@ struct map_session_data *pc_get_child(struct map_session_data *sd); int pc_set_gm_level(int account_id, int level); void pc_setstand(struct map_session_data *sd); -int pc_break_equip(struct map_session_data *sd, unsigned short where); int pc_candrop(struct map_session_data *sd,int item_id); struct pc_base_job{ diff --git a/src/map/skill.c b/src/map/skill.c index c8eda14ee..a36f17368 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1024,15 +1024,12 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int case AM_ACIDTERROR: status_change_start(bl,SC_BLEEDING,(skilllv*3),skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - if (dstsd && rand()%100 < skill_get_time(skillid,skilllv) * battle_config.equip_skill_break_rate / 100) { //fixed - if(pc_breakarmor(dstsd)) - clif_emotion(bl,23); - } + if (skill_break_equip(bl, EQP_ARMOR, 100*skill_get_time(skillid,skilllv), BCT_ENEMY)) + clif_emotion(bl,23); break; case AM_DEMONSTRATION: - if (dstsd && rand()%10000 < skilllv * battle_config.equip_skill_break_rate ) - pc_breakweapon(dstsd); + skill_break_equip(bl, EQP_WEAPON, 100*skilllv, BCT_ENEMY); break; case CR_SHIELDCHARGE: /* シ?ルドチャ?ジ */ @@ -1100,23 +1097,16 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int break; // Equipment breaking monster skills [Celest] case NPC_BREAKWEAPON: - if(dstsd && rand()%10000 < 10*skilllv*battle_config.equip_skill_break_rate) - pc_breakweapon(dstsd); + skill_break_equip(bl, EQP_WEAPON, 1000*skilllv, BCT_ENEMY); break; - case NPC_BREAKARMOR: - if(dstsd && rand()%10000 < 10*skilllv*battle_config.equip_skill_break_rate) - pc_breakarmor(dstsd); + skill_break_equip(bl, EQP_ARMOR, 1000*skilllv, BCT_ENEMY); break; - case NPC_BREAKHELM: - if(dstsd && rand()%10000 < 10*skilllv*battle_config.equip_skill_break_rate) - pc_breakhelm(dstsd); + skill_break_equip(bl, EQP_HELM, 1000*skilllv, BCT_ENEMY); break; - case NPC_BREAKSHIELD: - if(dstsd && rand()%10000 < 10*skilllv*battle_config.equip_skill_break_rate) - pc_breakshield(dstsd); + skill_break_equip(bl, EQP_SHIELD, 1000*skilllv, BCT_ENEMY); break; case CH_TIGERFIST: @@ -1185,13 +1175,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int break; case CR_ACIDDEMONSTRATION: - if (dstsd) { - if (rand()%10000 < skilllv * battle_config.equip_skill_break_rate) - pc_breakweapon(dstsd); - // separate chances? - if (rand()%10000 < skilllv * battle_config.equip_skill_break_rate) - pc_breakarmor(dstsd); - } + skill_break_equip(bl, EQP_WEAPON|EQP_SHIELD, 100*skilllv, BCT_ENEMY); break; case TK_DOWNKICK: @@ -1404,7 +1388,92 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * } return 0; } +/*========================================================================= + Breaks equipment. On-non players causes the corresponding strip effect. + - rate goes from 0 to 10000 (100.00%) + - flag is a BCT_ flag to indicate which type of adjustment should be used + (BCT_ENEMY/BCT_PARTY/BCT_SELF) are the valid values. +-------------------------------------------------------------------------*/ +int skill_break_equip(struct block_list *bl, unsigned short where, int rate, int flag) { + static int where_list[4] = {EQP_WEAPON, EQP_ARMOR, EQP_SHIELD, EQP_HELM}; + static int scatk[4] = {SC_STRIPWEAPON, SC_STRIPARMOR, SC_STRIPSHIELD, SC_STRIPHELM }; + static int scdef[4] = {SC_CP_WEAPON, SC_CP_ARMOR, SC_CP_SHIELD, SC_CP_HELM}; + struct status_change *sc = status_get_sc(bl); + int i,j; + TBL_PC *sd; + BL_CAST(BL_PC, bl, sd); + if (sc && !sc->count) + sc = NULL; + + if (sd) { + if (sd->unbreakable_equip) + where &= ~sd->unbreakable_equip; + if (sd->unbreakable) + rate -= rate*sd->unbreakable/100; + if (where&EQP_WEAPON) { + switch (sd->status.weapon) { + case 0: //Bare fists should not break :P + case 7: + case 8: // Axes and Maces can't be broken [DracoRPG] + case 10: + case 15: //Rods and Books can't be broken [Skotlex] + where &= ~EQP_WEAPON; + } + } + } + if (flag&BCT_ENEMY) { + if (battle_config.equip_skill_break_rate != 100) + rate = rate*battle_config.equip_skill_break_rate/100; + } else if (flag&(BCT_PARTY|BCT_SELF)) { + if (battle_config.equip_self_break_rate != 100) + rate = rate*battle_config.equip_self_break_rate/100; + } + + for (i = 0; i < 4; i++) { + if (where&where_list[i]) { + if (sc && sc->count && sc->data[scdef[i]].timer != -1) + where&=~where_list[i]; + else if (rand()%10000 > rate) + where&=~where_list[i]; + else if (!sd) //Cause Strip effect. + status_change_start(bl,scatk[i],100,0,0,0,0, + skill_get_time(StatusSkillChangeTable[scatk[i]],1),0); + } + } + if (!where) //Nothing to break. + return 0; + if (sd) { + for (i = 0; i < 11; i++) { + j = sd->equip_index[i]; + if (j <= 0 || sd->status.inventory[j].attribute == 1 || !sd->inventory_data[j]) + continue; + flag = 0; + switch(i) { + case 6: //Upper Head + flag = (where&EQP_HELM); + break; + case 7: //Body + flag = (where&EQP_ARMOR); + break; + case 8: //Left/Right hands + case 9: + flag = ( + (where&EQP_WEAPON && sd->inventory_data[j]->type == 4) || + (where&EQP_SHIELD && sd->inventory_data[j]->type == 5)); + break; + default: + continue; + } + if (flag) { + sd->status.inventory[j].attribute = 1; + pc_unequipitem(sd, j, 3); + } + } + clif_equiplist(sd); + } + return where; //Return list of pieces broken. +} /*========================================================================= Used to knock back players, monsters, traps, etc If count&0xf00000, the direction is send in the 6th byte. @@ -3455,10 +3524,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in skilllv,0,0,0,skill_get_time(skillid,skilllv),0); if(!i) { if (sd) clif_skill_fail(sd,skillid,0,0); - if(dstsd && battle_config.equip_self_break_rate) { - if(sd && sd != dstsd) clif_displaymessage(sd->fd,"You broke target's weapon"); - pc_breakweapon(dstsd); - } + if (skill_break_equip(bl, EQP_WEAPON, 10000, BCT_PARTY) && + sd && sd != dstsd) + clif_displaymessage(sd->fd,"You broke target's weapon"); + } clif_skill_nodamage(src,bl,skillid,skilllv,i); break; @@ -3498,7 +3567,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } clif_skill_nodamage(src,bl,skillid,skilllv, status_change_start(bl,type,100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0)); - } break; case PR_KYRIE: /* キリエエレイソン */ @@ -5284,7 +5352,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM }; battle_damage(src, bl, 1000, 0); clif_damage(src,bl,tick,0,0,1000,0,0,0); - if (dstsd && battle_config.equip_skill_break_rate) pc_break_equip(dstsd, where[rand() % 3]); + skill_break_equip(bl, where[rand()%3], 10000, BCT_ENEMY); } break; case 4: // atk halved diff --git a/src/map/skill.h b/src/map/skill.h index d18e2e59e..9c38744db 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -178,6 +178,7 @@ int skill_addtimerskill(struct block_list *src,unsigned int tick,int target,int int skill_additional_effect( struct block_list* src, struct block_list *bl,int skillid,int skilllv,int attack_type,unsigned int tick); int skill_counter_additional_effect( struct block_list* src, struct block_list *bl,int skillid,int skilllv,int attack_type,unsigned int tick); int skill_blown( struct block_list *src, struct block_list *target,int count); +int skill_break_equip(struct block_list *bl, unsigned short where, int rate, int flag); // ユニットスキル struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,int skilllv,int x,int y,int flag); struct skill_unit *skill_initunit(struct skill_unit_group *group,int idx,int x,int y); -- cgit v1.2.3-70-g09d2