소스 검색

Fixed bugreport:5356 Shadow Shaser's Shadow Form. Skill now redirects damage properly and is removed upon either caster or target leaving skill range

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@15755 54d463be-8e91-2dee-dedb-b68131a5f0ec
shennetsind 13 년 전
부모
커밋
bca0f1abae
3개의 변경된 파일42개의 추가작업 그리고 22개의 파일을 삭제
  1. 21 19
      src/map/battle.c
  2. 17 0
      src/map/map.c
  3. 4 3
      src/map/status.c

+ 21 - 19
src/map/battle.c

@@ -647,6 +647,26 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
 		if( sc->data[SC__DEADLYINFECT] && damage > 0 && rand()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
 			status_change_spread(bl, src); // Deadly infect attacked side
 
+		if( sc && sc->data[SC__SHADOWFORM] ) {
+			struct block_list *s_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2);
+			if( !s_bl ) { // If the shadow form target is not present remove the sc.
+				status_change_end(bl, SC__SHADOWFORM, -1);
+			} else if( status_isdead(s_bl) || !battle_check_target(src,s_bl,BCT_ENEMY)) { // If the shadow form target is dead or not your enemy remove the sc in both.
+				status_change_end(bl, SC__SHADOWFORM, -1);
+				if( s_bl->type == BL_PC )
+					((TBL_PC*)s_bl)->shadowform_id = 0;
+			} else {
+				if( (--sc->data[SC__SHADOWFORM]->val3) < 0 ) { // If you have exceded max hits supported, remove the sc in both.
+					status_change_end(bl, SC__SHADOWFORM, -1);
+					if( s_bl->type == BL_PC )
+						((TBL_PC*)s_bl)->shadowform_id = 0;
+				} else {
+					status_damage(src, s_bl, damage, 0, clif_damage(s_bl, s_bl, gettick(), 500, 500, damage, -1, 0, 0), 0);
+					return ATK_NONE;
+				}
+			}
+		}
+
 	}
 
 	//SC effects from caster side.
@@ -736,25 +756,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
 				pc_overheat(sd,element == ELE_FIRE ? 1 : -1);
 		}
 	}
-	if( sc && sc->data[SC__SHADOWFORM] ) {
-		struct block_list *s_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2);
-		if( !s_bl ) { // If the shadow form target is not present remove the sc.
-			status_change_end(bl, SC__SHADOWFORM, -1);
-		} else if( status_isdead(s_bl) || !battle_check_target(src,s_bl,BCT_ENEMY)) { // If the shadow form target is dead or not your enemy remove the sc in both.
-			status_change_end(bl, SC__SHADOWFORM, -1);
-			if( s_bl->type == BL_PC )
-				((TBL_PC*)s_bl)->shadowform_id = 0;
-		} else {
-			if( (--sc->data[SC__SHADOWFORM]->val3) < 0 ) { // If you have exceded max hits supported, remove the sc in both.
-				status_change_end(bl, SC__SHADOWFORM, -1);
-				if( s_bl->type == BL_PC )
-					((TBL_PC*)s_bl)->shadowform_id = 0;
-			} else {
-				status_damage(src, s_bl, damage, 0, clif_damage(s_bl, s_bl, gettick(), 500, 500, damage, -1, 0, 0), 0);
-				return ATK_NONE;
-			}
-		}
-	}
+
 	return damage;
 }
 

+ 17 - 0
src/map/map.c

@@ -413,8 +413,19 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
 #endif
 
 	if (bl->type&BL_CHAR) {
+
 		skill_unit_move(bl,tick,3);
 		sc = status_get_sc(bl);
+
+		if( bl->type == BL_PC && ((TBL_PC*)bl)->shadowform_id ) {//Shadow Form Target Moving
+			struct block_list *d_bl;
+			if( (d_bl = map_id2bl(((TBL_PC*)bl)->shadowform_id)) == NULL || bl->m != d_bl->m || !check_distance_bl(bl,d_bl,skill_get_range(SC_SHADOWFORM,1)) ) {
+				if( d_bl )
+					status_change_end(d_bl,SC__SHADOWFORM,INVALID_TIMER);
+				((TBL_PC*)bl)->shadowform_id = 0;
+			}
+		}
+
 		if (sc && sc->count) {
 			if (sc->data[SC_DANCING])
 				skill_unit_move_unit_group(skill_id2group(sc->data[SC_DANCING]->val2), bl->m, x1-x0, y1-y0);
@@ -430,6 +441,12 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
 					skill_unit_move_unit_group(skill_id2group(sc->data[SC_NEUTRALBARRIER_MASTER]->val2), bl->m, x1-x0, y1-y0);
 				else if (sc->data[SC_STEALTHFIELD_MASTER])
 					skill_unit_move_unit_group(skill_id2group(sc->data[SC_STEALTHFIELD_MASTER]->val2), bl->m, x1-x0, y1-y0);
+				
+				if( sc->data[SC__SHADOWFORM] ) {//Shadow Form Caster Moving
+					struct block_list *d_bl;
+					if( (d_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2)) == NULL || bl->m != d_bl->m || !check_distance_bl(bl,d_bl,skill_get_range(SC_SHADOWFORM,1)) )
+						status_change_end(bl,SC__SHADOWFORM,INVALID_TIMER);	
+				}
 			}
 			/* Guild Aura Moving */
 			if( bl->type == BL_PC && ((TBL_PC*)bl)->state.gmaster_flag ) {

+ 4 - 3
src/map/status.c

@@ -1552,13 +1552,14 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
 	switch( target->type ) {
 		case BL_PC: {
 				struct map_session_data *sd = (TBL_PC*) target;
-				bool is_boss = (status->mode&MD_BOSS), is_detector = (status->mode&MD_DETECTOR);
+				bool is_boss = (status->mode&MD_BOSS);
+				bool is_detect = ((status->mode&MD_DETECTOR)?true:false);//god-knows-why gcc doesn't shut up until this happens
 				if (pc_isinvisible(sd))
 					return 0;
 				if (tsc->option&hide_flag && !is_boss &&
-					(sd->special_state.perfect_hiding || !is_detector) )
+					(sd->special_state.perfect_hiding || !is_detect) )
 					return 0;
-				if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detector) && !skill_num )
+				if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && !skill_num )
 					return 0;
 				if( tsc->data[SC_CLOAKINGEXCEED] && !is_boss )
 					return 0;