Browse Source

- 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://svn.code.sf.net/p/rathena/svn/trunk@5374 54d463be-8e91-2dee-dedb-b68131a5f0ec
skotlex 19 years ago
parent
commit
7f4bc7d9e0
7 changed files with 119 additions and 112 deletions
  1. 5 0
      Changelog-Trunk.txt
  2. 1 0
      Dev/todo-for-stable.txt
  3. 14 24
      src/map/battle.c
  4. 0 51
      src/map/pc.c
  5. 0 7
      src/map/pc.h
  6. 98 30
      src/map/skill.c
  7. 1 0
      src/map/skill.h

+ 5 - 0
Changelog-Trunk.txt

@@ -5,6 +5,11 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.  EV
 GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
 GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
 
 
 2006/02/22
 2006/02/22
+	* Changed the way equipment breaking works. Function pc_break_equip was
+	  removed and now skill_break_equip is used. Basicly, it's the same as
+	  before, except that when you 'break' a piece of equipment of a
+	  non-player, the corresponding strip(weapon/armor/shield/helm) status
+	  effect is induced (duration: strip skill lv 1) [Skotlex]
 	* Cleaned up the Dev folder. [Skotlex]
 	* Cleaned up the Dev folder. [Skotlex]
 	- Take note of the file todo-for-stable, which holds all modifications in
 	- Take note of the file todo-for-stable, which holds all modifications in
 	  trunk that have not yet made it into stable. Be sure to update the file
 	  trunk that have not yet made it into stable. Be sure to update the file

+ 1 - 0
Dev/todo-for-stable.txt

@@ -32,3 +32,4 @@ stable. Remove it from the list once merged.
 - Revert the map-sql handling of the gm-list retrieval.
 - Revert the map-sql handling of the gm-list retrieval.
 - Send the guild/party mini-dots on map-login.
 - Send the guild/party mini-dots on map-login.
 - Updated the path-finding routines from jA
 - Updated the path-finding routines from jA
+- Replace pc_break_equip for skill_break_equip

+ 14 - 24
src/map/battle.c

@@ -2258,9 +2258,9 @@ static struct Damage battle_calc_weapon_attack(
 			mob_class_change(((struct mob_data *)target),class_);
 			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;
 			int breakrate = battle_config.equip_natural_break_rate;
 			if (sc) {
 			if (sc) {
 				if(sc->data[SC_OVERTHRUST].timer!=-1)
 				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)
 				if(sc->data[SC_MAXOVERTHRUST].timer!=-1)
 					breakrate += 10;
 					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 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) {
 				if (sc->data[SC_MELTDOWN].timer!=-1) {
 				if (sc->data[SC_MELTDOWN].timer!=-1) {
 					breakrate[0] += 100*sc->data[SC_MELTDOWN].val1;
 					breakrate[0] += 100*sc->data[SC_MELTDOWN].val1;
 					breakrate[1] += 70*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;
 	return wd;

+ 0 - 51
src/map/pc.c

@@ -642,57 +642,6 @@ int pc_isequip(struct map_session_data *sd,int n)
 	return 1;
 	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に問題無し
  * session idに問題無し
  * char鯖から送られてきたステ?タスを設定
  * char鯖から送られてきたステ?タスを設定

+ 0 - 7
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_isequip(struct map_session_data *sd,int n);
 int pc_equippoint(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_checkskill(struct map_session_data *sd,int skill_id);
 int pc_checkallowskill(struct map_session_data *sd);
 int pc_checkallowskill(struct map_session_data *sd);
 int pc_checkequip(struct map_session_data *sd,int pos);
 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);
 int pc_set_gm_level(int account_id, int level);
 void pc_setstand(struct map_session_data *sd);
 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);
 int pc_candrop(struct map_session_data *sd,int item_id);
 
 
 struct pc_base_job{
 struct pc_base_job{

+ 98 - 30
src/map/skill.c

@@ -1024,15 +1024,12 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 
 
 	case AM_ACIDTERROR:
 	case AM_ACIDTERROR:
 		status_change_start(bl,SC_BLEEDING,(skilllv*3),skilllv,0,0,0,skill_get_time2(skillid,skilllv),0);
 		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;
 		break;
 
 
 	case AM_DEMONSTRATION:
 	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;
 		break;
 		
 		
 	case CR_SHIELDCHARGE:		/* シ?ルドチャ?ジ */
 	case CR_SHIELDCHARGE:		/* シ?ルドチャ?ジ */
@@ -1100,23 +1097,16 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 		break;
 		break;
 	// Equipment breaking monster skills [Celest]
 	// Equipment breaking monster skills [Celest]
 	case NPC_BREAKWEAPON:
 	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;
 		break;
-
 	case NPC_BREAKARMOR:
 	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;
 		break;
-
 	case NPC_BREAKHELM:
 	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;
 		break;
-
 	case NPC_BREAKSHIELD:
 	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;
 		break;
 
 
 	case CH_TIGERFIST:
 	case CH_TIGERFIST:
@@ -1185,13 +1175,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 		break;
 		break;
 
 
 	case CR_ACIDDEMONSTRATION:
 	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;
 		break;
 
 
 	case TK_DOWNKICK:
 	case TK_DOWNKICK:
@@ -1404,7 +1388,92 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
 	}
 	}
 	return 0;
 	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
  Used to knock back players, monsters, traps, etc
  If count&0xf00000, the direction is send in the 6th byte.
  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);
 				skilllv,0,0,0,skill_get_time(skillid,skilllv),0);
 		if(!i) {
 		if(!i) {
 			if (sd) clif_skill_fail(sd,skillid,0,0);
 			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);
 		clif_skill_nodamage(src,bl,skillid,skilllv,i);
 		break;
 		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,
 		clif_skill_nodamage(src,bl,skillid,skilllv,
 			status_change_start(bl,type,100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0));
 			status_change_start(bl,type,100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0));
-		}
 		break;
 		break;
 
 
 	case PR_KYRIE:			/* キリエエレイソン */
 	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 };
 						int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM };
 						battle_damage(src, bl, 1000, 0);
 						battle_damage(src, bl, 1000, 0);
 						clif_damage(src,bl,tick,0,0,1000,0,0,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;
 					break;
 				case 4:	// atk halved
 				case 4:	// atk halved

+ 1 - 0
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_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_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_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);
 // ƒ†ƒjƒbƒgƒXƒLƒ‹
 // ƒ†ƒjƒbƒgƒXƒLƒ‹
 struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,int skilllv,int x,int y,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);
 struct skill_unit *skill_initunit(struct skill_unit_group *group,int idx,int x,int y);