Преглед на файлове

- 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 години
родител
ревизия
7f4bc7d9e0
променени са 7 файла, в които са добавени 119 реда и са изтрити 112 реда
  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
 
 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]
 	- 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

+ 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.
 - Send the guild/party mini-dots on map-login.
 - 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_);
 	}
 
-	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;

+ 0 - 51
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鯖から送られてきたステ?タスを設定

+ 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_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{

+ 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:
 		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

+ 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_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);
 // ƒ†ƒ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 *skill_initunit(struct skill_unit_group *group,int idx,int x,int y);