Ver código fonte

Pneuma / ArrowShower / Ranges, Charge Attack, Waterball / Jupitel fixes
* Pneuma / Arrow Shower / Ranges (fixes #915)
-- Pneuma now also protects against knockback from ranged skills
-- Arrow Shower cast by monsters is now always a melee skill and cannot be blocked by Pneuma, but can always be blocked by Safety Wall
-- When monsters cast a skill that has no specific rule, it will be considered melee when the target is within a 7x7 area around the monster, rather than a 11x11 area
* Charge Attack (fixes #417)
-- Damage: 0-3 cells 100%, 4-6 cells 200%, 7-9 cells 300%, 10-12 cells 400%, 13 cells 500%
-- Cast time pre-Renewal: 0-3 cells 500ms, 4-6 cells 1000ms, 7+ cells 1500ms
-- Cast time renewal: 500ms (250ms fixed)
-- The caster will now move to the cell next to the target rather than right on it
-- When the attack misses, there won't be knockback (but the caster will still move)
* Waterball/Jupitel (follow up to 6ebcb67, fixes #907)
-- Waterball/Jupitel now can hit through shootable walls
-- Waterball cells now can overlap

Playtester 9 anos atrás
pai
commit
4fd4c1d5bf
4 arquivos alterados com 21 adições e 25 exclusões
  1. 1 1
      db/pre-re/skill_cast_db.txt
  2. 8 12
      src/map/battle.c
  3. 5 6
      src/map/skill.c
  4. 7 6
      src/map/unit.c

+ 1 - 1
db/pre-re/skill_cast_db.txt

@@ -1027,7 +1027,7 @@
 
 //===== 2nd Jobs Quest Skills ==============
 //-- KN_CHARGEATK
-1001,300,300,0,0,0,0
+1001,500,0,0,0,0,0
 //-- CR_SHRINK
 1002,0,0,0,300000,0,0
 

+ 8 - 12
src/map/battle.c

@@ -965,7 +965,6 @@ bool battle_check_sc(struct block_list *src, struct block_list *target, struct s
 
 	if( sc->data[SC_PNEUMA] && (d->flag&(BF_MAGIC|BF_LONG)) == BF_LONG ) {
 		d->dmg_lv = ATK_BLOCK;
-		skill_blown(src,target,skill_get_blewcount(skill_id,skill_lv),-1,0);
 		return false;
 	}
 	return true;
@@ -1982,11 +1981,15 @@ static int battle_range_type(struct block_list *src, struct block_list *target,
 	if( skill_get_inf2( skill_id ) & INF2_TRAP )
 		return BF_SHORT;
 
+	// When monsters use Arrow Shower, it is always short range
+	if (src->type == BL_MOB && skill_id == AC_SHOWER)
+		return BF_SHORT;
+
 	//Skill Range Criteria
 	if (battle_config.skillrange_by_distance &&
 		(src->type&battle_config.skillrange_by_distance)
 	) { //based on distance between src/target [Skotlex]
-		if (check_distance_bl(src, target, 5))
+		if (check_distance_bl(src, target, 3))
 			return BF_SHORT;
 		return BF_LONG;
 	}
@@ -3668,17 +3671,10 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
 			break;
 #endif
 		case KN_CHARGEATK: { // +100% every 3 cells of distance but hard-limited to 500%
-				unsigned int k = wd.miscflag / 3;
-
-				if (k < 2)
+				unsigned int k = (wd.miscflag-1)/3;
+				if (k < 0)
 					k = 0;
-				else if (k > 1 && k < 3)
-					k = 1;
-				else if (k > 2 && k < 4)
-					k = 2;
-				else if (k > 3 && k < 5)
-					k = 3;
-				else
+				else if (k > 4)
 					k = 4;
 				skillratio += 100 * k;
 			}

+ 5 - 6
src/map/skill.c

@@ -3910,7 +3910,7 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
 				}	// Fall through
 				case WZ_JUPITEL:
 					// Official behaviour is to hit as long as there is a line of sight, regardless of distance
-					if (skl->type > 0 && !status_isdead(target) && path_search_long(NULL,src->m,src->x,src->y,target->x,target->y,CELL_CHKNOREACH)) {
+					if (skl->type > 0 && !status_isdead(target) && path_search_long(NULL,src->m,src->x,src->y,target->x,target->y,CELL_CHKWALL)) {
 						// Apply canact delay here to prevent hacks (unlimited casting)
 						ud->canact_tick = tick + skill_delayfix(src, skl->skill_id, skl->skill_lv);
 						skill_attack(BF_MAGIC, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag);
@@ -4423,13 +4423,12 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 
 		// teleport to target (if not on WoE grounds)
 		if (!map_flag_gvg(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 0, 1))
-			clif_blown(src);
+			skill_blown(src, src, 1, (dir+4)%8, 0); //Target position is actually one cell next to the target
 
 		// cause damage and knockback if the path to target was a straight one
 		if (path) {
-			dist = cap_value(dist, 0, 9);
-			skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, dist);
-			skill_blown(src, bl, dist, dir, 0);
+			if(skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, dist))
+				skill_blown(src, bl, dist, dir, 0);
 			//HACK: since knockback officially defaults to the left, the client also turns to the left... therefore,
 			// make the caster look in the direction of the target
 			unit_setdir(src, (dir+4)%8);
@@ -17032,7 +17031,7 @@ static int skill_cell_overlap(struct block_list *bl, va_list ap)
 					skill_delunit(unit);
 					return 1;
 			}
-			//Fall through
+			break;
 		case WZ_ICEWALL:
 		case HP_BASILICA:
 		case HW_GRAVITATION:

+ 7 - 6
src/map/unit.c

@@ -1765,15 +1765,16 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
 			if( sc && sc->data[SC_BASILICA] )
 				casttime = -1; // No Casting time on basilica cancel
 		break;
-		case KN_CHARGEATK: {
-			unsigned int k = (distance_bl(src,target)-1)/3; // +100% every 3 cells of distance
-
-			if( k > 2 )
-				k = 2; // ...but hard-limited to 300%.
-
+#ifndef RENEWAL_CAST
+		case KN_CHARGEATK:
+		{
+			unsigned int k = (distance_bl(src,target)-1)/3; //Range 0-3: 500ms, Range 4-6: 1000ms, Range 7+: 1500ms
+			if(k > 2)
+				k = 2;
 			casttime += casttime * k;
 		}
 		break;
+#endif
 		case GD_EMERGENCYCALL: // Emergency Call double cast when the user has learned Leap [Daegaladh]
 			if( sd && pc_checkskill(sd,TK_HIGHJUMP) )
 				casttime *= 2;