diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 38 | ||||
-rw-r--r-- | src/map/pc.c | 51 | ||||
-rw-r--r-- | src/map/pc.h | 7 | ||||
-rw-r--r-- | src/map/skill.c | 128 | ||||
-rw-r--r-- | src/map/skill.h | 1 |
5 files changed, 113 insertions, 112 deletions
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);
|