瀏覽代碼

- Added function skill_strip to handle stripping code. The RG strip skills and GS_DISARM use it now.
- Modified the strip-related status changes so they handle removing the equipped item instead of leaving it up to the skill-code. They return 0 when nothing could be stripped.
- Cleaned some the MD_DETECTOR code.


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9499 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex 18 年之前
父節點
當前提交
b8a2a5f905
共有 7 個文件被更改,包括 105 次插入134 次删除
  1. 3 0
      Changelog-Trunk.txt
  2. 0 5
      db/skill_cast_db.txt
  3. 0 9
      src/map/clif.c
  4. 1 1
      src/map/script.c
  5. 44 103
      src/map/skill.c
  6. 1 0
      src/map/skill.h
  7. 56 16
      src/map/status.c

+ 3 - 0
Changelog-Trunk.txt

@@ -3,6 +3,9 @@ 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.
 
+2006/12/14
+	* Cleaned up the strip code (GS_DISARM, rogue skills).
+	* Cleaned some the MD_DETECTOR code.
 2006/12/13
 	* Additional damage bonuses (True Sight, EDP, Assassin Link, Crusader Link,
 	  Card skill damage bonuses) are now applied independently of each other,

+ 0 - 5
db/skill_cast_db.txt

@@ -375,11 +375,6 @@
 236,2000,0,0,120000:240000:360000:480000:600000,0
 //-- AM_CP_HELM
 237,2000,0,0,120000:240000:360000:480000:600000,0
-//==========================================
-//-- AM_CALLHOMUNCULUS
-243,0,0,0,0,0
-//-- AM_REST
-244,0,0,0,0,0
 //-- AM_RESURRECTHOMUN
 247,2000,0,0,0,0
 //==========================================

+ 0 - 9
src/map/clif.c

@@ -6869,8 +6869,6 @@ int clif_guild_basicinfo(struct map_session_data *sd)
 		strncpy((char*)WFIFOP(fd,94),msg_txt(299),20);
 
 	WFIFOSET(fd,packet_len_table[WFIFOW(fd,0)]);
-	// Found the appropriate packet field, testing for a trial period. [FlavioJS]
-	//clif_guild_emblem(sd,g);	// Guild emblem vanish fix [Valaris]
 	return 0;
 }
 
@@ -11823,13 +11821,6 @@ int clif_parse(int fd) {
 	}
 
 	sd = (TBL_PC *)session[fd]->session_data;
-
-	if (sd && sd->fd != fd)
-	{	//FIXME: Temporal debug until a certain mysterious crash is fixed.
-		ShowError("Player's connection value is incorrect! %d != %d\n", sd->fd, fd);
-		sd->fd = fd;
-	}
-
 	if (session[fd]->eof) {
 		if (sd) {
 			if (sd->state.autotrade) {

+ 1 - 1
src/map/script.c

@@ -7815,7 +7815,7 @@ int buildin_homunculus_evolution(struct script_state *st)
 	struct map_session_data *sd;
 	sd=script_rid2sd(st);
 	if ( sd->hd && sd->hd->homunculusDB->evo_class && sd->hd->homunculus.intimacy > 91000 ) {
-		return merc_hom_evolution(sd->hd) ;
+		return !merc_hom_evolution(sd->hd) ;
 	}
 	clif_emotion(&sd->hd->bl, 4) ;	//swt
 	return 0;

+ 44 - 103
src/map/skill.c

@@ -1356,22 +1356,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 		rate = 3*skilllv;
 		if (sstatus->dex > tstatus->dex)
 			rate += (sstatus->dex - tstatus->dex)/5;
-		
-		if (rand()%100 >= rate)
-			break;
-
-		if (dstsd) {
-			if (dstsd->equip_index[EQI_HAND_R]<0 ||
-				!dstsd->inventory_data[dstsd->equip_index[EQI_HAND_R]] ||
-				!(dstsd->unstripable_equip&EQP_WEAPON) ||
-		  		(tsc && tsc->data[SC_CP_WEAPON].timer != -1)
-			)	//Fail
-				break;
-			pc_unequipitem(dstsd,dstsd->equip_index[EQI_HAND_R],3);
-		} else if (tstatus->mode&MD_BOSS ||
-			(tsc && tsc->data[SC_CP_WEAPON].timer != -1))
-			break;
-		sc_start(bl,SC_STRIPWEAPON,100,skilllv,skill_get_time(skillid,skilllv));
+		skill_strip_equip(bl, EQP_WEAPON, rate, skilllv, skill_get_time(skillid,skilllv));
 		break;
 	}
 
@@ -1721,6 +1706,36 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in
 
 	return where; //Return list of pieces broken.
 }
+
+int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int lv, int time)
+{
+	struct status_change *sc;
+	const int pos[4]    = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HELM};
+	const int sc_atk[4] = {SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM};
+	const int sc_def[4] = {SC_CP_WEAPON, SC_CP_SHIELD, SC_CP_ARMOR, SC_CP_HELM};
+	int i;
+
+	if (rand()%100 >= rate)
+		return 0;
+
+	sc = status_get_sc(bl);
+	if (!sc)
+		return 0;
+
+	for (i = 0; i < sizeof(pos)/sizeof(pos[0]); i++) {
+		if (where&pos[i] && sc->data[sc_def[i]].timer != -1)
+			where&=~pos[i]; 
+	}
+	if (!where) return 0;
+
+	for (i = 0; i < sizeof(pos)/sizeof(pos[0]); i++) {
+		if (where&pos[i] && !sc_start(bl, sc_atk[i], 100, lv, time))
+			where&=~pos[i];
+	}
+	return where?1:0;
+}
+
+
 /*=========================================================================
  Used to knock back players, monsters, traps, etc
  If count&0xf00000, the direction is send in the 6th byte.
@@ -4429,106 +4444,32 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 	case RG_STRIPSHIELD:
 	case RG_STRIPARMOR:
 	case RG_STRIPHELM:
-	case ST_FULLSTRIP:			// Rewritten most of the code [DracoRPG]
-		{
-		int strip_fix, equip = 0;
-		int sclist[4] = {0,0,0,0};
-
+	case ST_FULLSTRIP:
+		i = 5+2*skilllv;
+		if (sstatus->dex > tstatus->dex)
+			i += (sstatus->dex - tstatus->dex)/5;
 		switch (skillid) {
 		case RG_STRIPWEAPON:
-		   equip = EQP_WEAPON;
+			type = EQP_WEAPON;
 			break;
 		case RG_STRIPSHIELD:
-		   equip = EQP_SHIELD;
+			type = EQP_SHIELD;
 			break;
 		case RG_STRIPARMOR:
-		   equip = EQP_ARMOR;
+			type = EQP_ARMOR;
 			break;
 		case RG_STRIPHELM:
-		   equip = EQP_HELM;
+			type = EQP_HELM;
 			break;
 		case ST_FULLSTRIP:
-		   equip = EQP_WEAPON|EQP_SHIELD|EQP_ARMOR|EQP_HELM;
-			break;
-		}
-
-		strip_fix = sstatus->dex - tstatus->dex;
-		if(strip_fix < 0)
-			strip_fix=0;
-		if (rand()%100 >= 5+2*skilllv+strip_fix/5)
-		{
-			if (sd)
-				clif_skill_fail(sd,skillid,0,0);
+			type = EQP_WEAPON|EQP_SHIELD|EQP_ARMOR|EQP_HELM;
 			break;
 		}
-		if (dstsd) {
-			for (i=0;i<EQI_MAX;i++) {
-				if (dstsd->equip_index[i]<0 || !dstsd->inventory_data[dstsd->equip_index[i]])
-					continue;
-				switch (i) {
-				case EQI_HAND_L: //Shield / left-hand weapon
-					if(dstsd->inventory_data[dstsd->equip_index[i]]->type == IT_ARMOR)
-					{ //Shield
-						if (equip&EQP_SHIELD &&
-							!(dstsd->unstripable_equip&EQP_SHIELD) &&
-						  	!(tsc && tsc->data[SC_CP_SHIELD].timer != -1)
-						){
-							sclist[1] = SC_STRIPSHIELD; // Okay, we found a shield to strip - It is really a shield, not a two-handed weapon or a left-hand weapon
-							pc_unequipitem(dstsd,dstsd->equip_index[i],3);
-						}
-						continue;
-					}
-					//Continue to weapon
-				case EQI_HAND_R:
-					if (equip&EQP_WEAPON &&
-						!(dstsd->unstripable_equip&EQP_WEAPON) &&
-				  		!(tsc && tsc->data[SC_CP_WEAPON].timer != -1)
-					) {
-						sclist[0] = SC_STRIPWEAPON; // Okay, we found a weapon to strip - It can be a right-hand, left-hand or two-handed weapon
-						pc_unequipitem(dstsd,dstsd->equip_index[i],3);
-					}
-					break;
-				case EQI_ARMOR: //Armor
-					if (equip &EQP_ARMOR && 
-						!(dstsd->unstripable_equip &EQP_ARMOR) &&
-					  	!(tsc && tsc->data[SC_CP_ARMOR].timer != -1)
-					) {
-						sclist[2] = SC_STRIPARMOR; // Okay, we found an armor to strip
-						pc_unequipitem(dstsd,dstsd->equip_index[i],3);
-					}
-					break;
-				case EQI_HEAD_TOP: //Helm  
-					if (equip &EQP_HELM &&
-						!(dstsd->unstripable_equip &EQP_HELM) &&
-						!(tsc && tsc->data[SC_CP_HELM].timer != -1)
-					 ) {
-						sclist[3] = SC_STRIPHELM; // Okay, we found a helm to strip
-						pc_unequipitem(dstsd,dstsd->equip_index[i],3);
-					}
-					break;
-				}
-			}
-		} else if (!(tstatus->mode&MD_BOSS)) {
-			if (equip&EQP_WEAPON && !(tsc && tsc->data[SC_CP_WEAPON].timer != -1))
-				sclist[0] = SC_STRIPWEAPON;
-			if (equip&EQP_SHIELD && !(tsc && tsc->data[SC_CP_SHIELD].timer != -1))
-				sclist[1] = SC_STRIPSHIELD;
-			if (equip&EQP_ARMOR && !(tsc && tsc->data[SC_CP_ARMOR].timer != -1))
-				sclist[2] = SC_STRIPARMOR;
-			if (equip&EQP_HELM && !(tsc && tsc->data[SC_CP_HELM].timer != -1))
-				sclist[3] = SC_STRIPHELM;
-		}
-		equip = 0; //Reuse equip to hold how many stats are invoked.
-		for (i=0;i<4;i++) {
-			if (sclist[i]) // Start the SC only if an equipment was stripped from this location
-			equip+=sc_start(bl,sclist[i],100,skilllv,skill_get_time(skillid,skilllv)+strip_fix/2);
-		}
-		if (equip)
-			clif_skill_nodamage(src,bl,skillid,skilllv,1);
-		else if (sd) //Nothing stripped.
-			clif_skill_fail(sd,skillid,0,0);
+		if (!clif_skill_nodamage(src,bl,skillid,skilllv,
+				skill_strip_equip(bl, type, i, skilllv, skill_get_time(skillid,skilllv)))
+			&& sd)
+			clif_skill_fail(sd,skillid,0,0); //Nothing stripped.
 		break;
-		}
 
 	/* PotionPitcher */
 	case AM_BERSERKPITCHER:

+ 1 - 0
src/map/skill.h

@@ -194,6 +194,7 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s
 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);
+int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int lv, int time);
 // ƒ†ƒ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, int val1, int val2);

+ 56 - 16
src/map/status.c

@@ -1106,8 +1106,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
 			return 0;
 	default:
 		//Check for chase-walk/hiding/cloaking opponents.
-		if (tsc && tsc->option&hide_flag && !(status->mode&MD_BOSS) && 
-			!(status->mode&MD_DETECTOR))
+		if (tsc && tsc->option&hide_flag && !(status->mode&(MD_BOSS|MD_DETECTOR)))
 			return 0;
 	}
 	return 1;
@@ -1136,19 +1135,17 @@ int status_check_visibility(struct block_list *src, struct block_list *target)
 	switch (target->type)
 	{	//Check for chase-walk/hiding/cloaking opponents.
 	case BL_PC:
-		{
-			if(tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) &&
-				!(status->mode&MD_BOSS) &&
-				(
-				 	((TBL_PC*)target)->special_state.perfect_hiding ||
-				  	!(status->mode&MD_DETECTOR)
-				))
-				return 0;
-		}
+		if(tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) &&
+			!(status->mode&MD_BOSS) &&
+			(
+				((TBL_PC*)target)->special_state.perfect_hiding ||
+				!(status->mode&MD_DETECTOR)
+			))
+			return 0;
 		break;
 	default:
 		if (tsc && tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) &&
-			!(status->mode&MD_BOSS) && !(status->mode&MD_DETECTOR))
+			!(status->mode&(MD_BOSS|MD_DETECTOR)))
 				return 0;
 	}
 
@@ -4646,6 +4643,10 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
 			case SC_COMA:
 			case SC_GRAVITATION:
 			case SC_SUITON:
+			case SC_STRIPWEAPON:
+			case SC_STRIPSHIELD:
+			case SC_STRIPARMOR:
+			case SC_STRIPHELM:
 				return 0;
 		}
 	}
@@ -4927,19 +4928,58 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
 			}
 			break;
 		case SC_STRIPWEAPON:
-			if (bl->type != BL_PC) //Watk reduction
+			if (sd) {
+				int i;
+				if(sd->unstripable_equip&EQP_WEAPON)
+					return 0;
+				i = sd->equip_index[EQI_HAND_L];
+				if (i>=0 && sd->inventory_data[i] &&
+					sd->inventory_data[i]->type == IT_WEAPON)
+					pc_unequipitem(sd,i,3); //L-hand weapon
+
+				i = sd->equip_index[EQI_HAND_R];
+				if (i<0 || !sd->inventory_data[i] ||
+					sd->inventory_data[i]->type != IT_WEAPON)
+					return 0;
+				pc_unequipitem(sd,i,3);
+			} else //Watk reduction
 				val2 = 5*val1;
 			break;
 		case SC_STRIPSHIELD:
-			if (bl->type != BL_PC) //Def reduction
+			if (sd) {
+				int i;
+				if(sd->unstripable_equip&EQP_SHIELD)
+					return 0;
+				i = sd->equip_index[EQI_HAND_L];
+				if (i<0 || !sd->inventory_data[i] ||
+					sd->inventory_data[i]->type != IT_ARMOR)
+					return 0;
+				pc_unequipitem(sd,i,3);
+			} else //Def reduction
 				val2 = 3*val1;
 			break;
 		case SC_STRIPARMOR:
-			if (bl->type != BL_PC) //Vit reduction
+			if (sd) {
+				int i;
+				if(sd->unstripable_equip&EQP_ARMOR)
+					return 0;
+				i = sd->equip_index[EQI_ARMOR];
+				if (i<0 || !sd->inventory_data[i])
+					return 0;
+				pc_unequipitem(sd,i,3);
+			} else //Vit reduction
 				val2 = 8*val1;
 			break;
 		case SC_STRIPHELM:
-			if (bl->type != BL_PC) //Int reduction
+			if (sd) {
+				int i;
+				if(sd->unstripable_equip&EQP_HELM)
+					return 0;
+				i = sd->equip_index[EQI_HEAD_TOP];
+				if (i<0 || !sd->inventory_data[i])
+					return 0;
+				pc_unequipitem(sd,i,3);
+			} else //Int reduction
 				val2 = 8*val1;
 			break;
 		case SC_AUTOSPELL: