浏览代码

Combo skill updates
- Cleaned up skill_combo so it's easier to understand and update
- Monk updates (bugreport:9364, bugreport:4534)
* Default combo delay is now (1000 - 4*AGI - 2*DEX) milliseconds, it will be used when none is specified in the skill_cast_db.txt
* Fixed DEX increasing combo delay rather than decreasing it
* Fixed "Triple Attack" not giving any "can act" delay so you were able to use a skill right when it triggered
* Fixed combo delays of all combo skills (turns out they all use the default in both pre-re and re!)
* Fixed "Palm Strike" in renewal having cast time rather than cast delay
* Monk Spirit now reduces the SP cost of all Monk/Champion combo skills to 2 SP
- Taekwon updates (bugreport:9364)
* Stances will no longer give you walk delay when they trigger
* You can still use the Kick after moving as long as it's still within the combo delay
- Hunter updates (bugreport:9082)
* Beast Strafing is now a target skill, you can target any brute or insect monster with it regardless of your previous target
* You no longer need to target a brute or insect monster with Double Strafe for the combo to trigger
* If the combo triggers you no longer get walk and attack delay (that means you can still use DS continuously)
* You can still use Beast Strafe after moving as long as it's still within the combo delay

Playtester 10 年之前
父节点
当前提交
b89b669325
共有 8 个文件被更改,包括 69 次插入55 次删除
  1. 2 9
      db/pre-re/skill_cast_db.txt
  2. 1 1
      db/pre-re/skill_db.txt
  3. 2 3
      db/re/skill_cast_db.txt
  4. 1 1
      db/re/skill_db.txt
  5. 2 0
      src/map/battle.c
  6. 44 27
      src/map/skill.c
  7. 16 13
      src/map/status.c
  8. 1 1
      src/map/unit.c

+ 2 - 9
db/pre-re/skill_cast_db.txt

@@ -396,8 +396,6 @@
 261,1000,0,0,600000,0,0
 //-- MO_ABSORBSPIRITS
 262,2000,0,0,0,0,0
-//-- MO_TRIPLEATTACK
-263,0,1000,0,0,0,0
 //-- MO_INVESTIGATE
 266,1000,500,0,0,0,0
 //-- MO_FINGEROFFENSIVE
@@ -410,12 +408,9 @@
 270,0,0,0,180000,0,0
 //-- MO_EXTREMITYFIST
 271,4000:3500:3000:2500:2000,3000:2500:2000:1500:1000,0,0,300000,0
-//-- MO_CHAINCOMBO
-272,0,1000,0,0,0,0
-//-- MO_COMBOFINISH
-273,0,700,0,0,0,0
 //==========================================
 
+
 //===== Sage ===============================
 //-- SA_MAGICROD
 276,0,0,0,400:600:800:1000:1200,0,0
@@ -581,9 +576,7 @@
 //-- CH_PALMSTRIKE
 370,0,300,0,0,0,0
 //-- CH_TIGERFIST
-371,0,700,0,0,2000:4000:6000:8000:10000,0
-//-- CH_CHAINCRUSH
-372,0,800:800:800:800:800:1000:1000:1000:1000:1000,0,0,0,0
+371,0,0,0,0,2000:4000:6000:8000:10000,0
 //==========================================
 
 

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

@@ -714,7 +714,7 @@
 496,0,6,4,0,0x1,0,1,0,no,0,0x8,0,none,0,0x0,		AM_TWILIGHT1,Twilight Alchemy 1
 497,0,6,4,0,0x1,0,1,0,no,0,0x8,0,none,0,0x0,		AM_TWILIGHT2,Twilight Alchemy 2
 498,0,6,4,0,0x1,0,1,0,no,0,0x8,0,none,0,0x0,		AM_TWILIGHT3,Twilight Alchemy 3
-499,-9,8,4,-1,0,0,1,2,no,0,0x208,0,weapon,0,0x80,	HT_POWER,Beast Strafing
+499,-9,8,1,-1,0,0,1,2,no,0,0x8,0,weapon,0,0x80,	HT_POWER,Beast Strafing
 
 //****
 // Gunslinger

+ 2 - 3
db/re/skill_cast_db.txt

@@ -393,8 +393,6 @@
 261,500,0,0,600000,0,0,500
 //-- MO_ABSORBSPIRITS
 262,1000,0,0,0,0,0,1000
-//-- MO_TRIPLEATTACK
-263,0,0,0,0,0,0,0
 //-- MO_INVESTIGATE
 266,500,500,0,0,0,0,500
 //-- MO_FINGEROFFENSIVE
@@ -409,6 +407,7 @@
 271,2000:1750:1500:1250:1000:500:1000:1000:1000:1000,3000:2500:2000:1500:1000,0,10000,300000,0,2000:1750:1500:1250:1000:500:1000:1000:1000:1000
 //==========================================
 
+
 //===== Sage ===============================
 //-- SA_MAGICROD
 276,0,1000,0,400:600:800:1000:1200,0,0,0
@@ -567,7 +566,7 @@
 
 //===== Champion ===========================
 //-- CH_PALMSTRIKE
-370,300,0,0,0,0,0,0
+370,0,300,0,0,0,0,0
 //-- CH_TIGERFIST
 371,0,0,0,0,2000:4000:6000:8000:10000,0,0
 //==========================================

+ 1 - 1
db/re/skill_db.txt

@@ -714,7 +714,7 @@
 496,0,6,4,0,0x1,0,1,0,no,0,0x8,0,none,0,0x0,		AM_TWILIGHT1,Twilight Alchemy 1
 497,0,6,4,0,0x1,0,1,0,no,0,0x8,0,none,0,0x0,		AM_TWILIGHT2,Twilight Alchemy 2
 498,0,6,4,0,0x1,0,1,0,no,0,0x8,0,none,0,0x0,		AM_TWILIGHT3,Twilight Alchemy 3
-499,-9,8,4,-1,0,0,1,2,no,0,0x208,0,weapon,0,0x80,	HT_POWER,Beast Strafing
+499,-9,8,1,-1,0,0,1,2,no,0,0x8,0,weapon,0,0x80,	HT_POWER,Beast Strafing
 
 //****
 // Gunslinger

+ 2 - 0
src/map/battle.c

@@ -6730,6 +6730,8 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
 			status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
 		}
 		if (rnd()%100 < triple_rate) {
+			//Need to apply canact_tick here because it doesn't go through skill_castend_id
+			sd->ud.canact_tick = tick + skill_delayfix(src, MO_TRIPLEATTACK, skillv);
 			if( skill_attack(BF_WEAPON,src,src,target,MO_TRIPLEATTACK,skillv,tick,0) )
 				return ATK_DEF;
 			return ATK_MISS;

+ 44 - 27
src/map/skill.c

@@ -935,22 +935,30 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
 					// Chance to trigger Taekwon kicks [Dralnu]
 					if(sc && !sc->data[SC_COMBO]) {
 						if(sc->data[SC_READYSTORM] &&
-							sc_start(src,src,SC_COMBO, 15, TK_STORMKICK,
-								(2000 - 4*sstatus->agi - 2*sstatus->dex))); //Stance triggered
+							sc_start4(src,src,SC_COMBO, 15, TK_STORMKICK,
+								bl->id, 2, 0,
+								(2000 - 4*sstatus->agi - 2*sstatus->dex)))
+							; //Stance triggered
 						else if(sc->data[SC_READYDOWN] &&
-							sc_start(src,src,SC_COMBO, 15, TK_DOWNKICK,
-								(2000 - 4*sstatus->agi - 2*sstatus->dex))); //Stance triggered
+							sc_start4(src,src,SC_COMBO, 15, TK_DOWNKICK,
+								bl->id, 2, 0,
+								(2000 - 4*sstatus->agi - 2*sstatus->dex)))
+							; //Stance triggered
 						else if(sc->data[SC_READYTURN] &&
-							sc_start(src,src,SC_COMBO, 15, TK_TURNKICK,
-								(2000 - 4*sstatus->agi - 2*sstatus->dex))); //Stance triggered
+							sc_start4(src,src,SC_COMBO, 15, TK_TURNKICK,
+								bl->id, 2, 0,
+								(2000 - 4*sstatus->agi - 2*sstatus->dex)))
+							; //Stance triggered
 						else if (sc->data[SC_READYCOUNTER]) { //additional chance from SG_FRIEND [Komurka]
 							rate = 20;
 							if (sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == TK_COUNTER) {
 								rate += rate*sc->data[SC_SKILLRATE_UP]->val2/100;
 								status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
 							}
-							sc_start2(src,src, SC_COMBO, rate, TK_COUNTER, bl->id,
-								(2000 - 4*sstatus->agi - 2*sstatus->dex));
+							sc_start4(src,src, SC_COMBO, rate, TK_COUNTER,
+								bl->id, 2, 0,
+								(2000 - 4*sstatus->agi - 2*sstatus->dex))
+							; //Stance triggered
 						}
 					}
 					if(sc && sc->data[SC_PYROCLASTIC] && ((rnd()%100)<=sc->data[SC_PYROCLASTIC]->val3) )
@@ -2529,7 +2537,9 @@ void skill_combo_toogle_inf(struct block_list* bl, uint16 skill_id, int inf){
 }
 
 void skill_combo(struct block_list* src,struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int tick){
-	int duration = 0, delay=0; //Used to signal if this skill can be combo'ed later on.
+	int duration = 0; //Set to duration the user can use a combo skill or 1 for aftercast delay of pre-skill
+	int nodelay = 0; //Set to 1 for no walk/attack delay, set to 2 for no walk delay
+	int target_id = bl->id; //Set to 0 if combo skill should not autotarget
 	struct status_change_entry *sce;
 	TBL_PC *sd = BL_CAST(BL_PC,src);
 	TBL_HOM *hd = BL_CAST(BL_HOM,src);
@@ -2565,30 +2575,31 @@ void skill_combo(struct block_list* src,struct block_list *dsrc, struct block_li
 		switch(skill_id) {
 		case MO_TRIPLEATTACK:
 			if (pc_checkskill(sd, MO_CHAINCOMBO) > 0 || pc_checkskill(sd, SR_DRAGONCOMBO) > 0)
-				duration=1;
+				duration = 1;
 			break;
 		case MO_CHAINCOMBO:
 			if(pc_checkskill(sd, MO_COMBOFINISH) > 0 && sd->spiritball > 0)
-				duration=1;
+				duration = 1;
 			break;
 		case MO_COMBOFINISH:
 			if (sd->status.party_id>0) //bonus from SG_FRIEND [Komurka]
 				party_skill_check(sd, sd->status.party_id, MO_COMBOFINISH, skill_lv);
 			if (pc_checkskill(sd, CH_TIGERFIST) > 0 && sd->spiritball > 0)
-				duration=1;
+				duration = 1;
 		case CH_TIGERFIST:
 			if (!duration && pc_checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1)
-				duration=1;
+				duration = 1;
 		case CH_CHAINCRUSH:
 			if (!duration && pc_checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball > 0 && sd->sc.data[SC_EXPLOSIONSPIRITS])
-				duration=1;
+				duration = 1;
 			break;
-		case AC_DOUBLE: {
-			unsigned char race = status_get_race(bl);
-			if( (race == RC_BRUTE || race == RC_INSECT) && pc_checkskill(sd, HT_POWER))
+		case AC_DOUBLE:
+			if( pc_checkskill(sd, HT_POWER)) {
 				duration = 2000;
+				nodelay = 1; //Neither gives walk nor attack delay
+				target_id = 0; //Does not need to be used on previous target
+			}
 			break;
-		}
 		case SR_DRAGONCOMBO:
 			if( pc_checkskill(sd, SR_FALLENEMPIRE) > 0 )
 				duration = 1;
@@ -2606,20 +2617,20 @@ void skill_combo(struct block_list* src,struct block_list *dsrc, struct block_li
 		case MH_SONIC_CRAW:
 		case MH_SILVERVEIN_RUSH:
 			if(hd->homunculus.spiritball > 0) duration = 2000;
-				delay=1;
+				nodelay = 1;
 			break;
 		case MH_EQC:
 		case MH_MIDNIGHT_FRENZY:
 			if(hd->homunculus.spiritball >= 2) duration = 2000;
-				delay=1;
+				nodelay = 1;
 			break;
 		}
 	}
 
 	if (duration) { //Possible to chain
-		if(sd && duration==1) duration = DIFF_TICK(sd->ud.canact_tick, tick); //auto calc duration
-		duration = max(1,duration);
-		sc_start4(src,src,SC_COMBO,100,skill_id,bl->id,delay,0,duration);
+		if(sd && duration==1) duration = DIFF_TICK(sd->ud.canact_tick, tick); //Auto calc duration
+		duration = max(status_get_amotion(src),duration); //Never less than aMotion
+		sc_start4(src,src,SC_COMBO,100,skill_id,target_id,nodelay,0,duration);
 		clif_combo_delay(src, duration);
 	}
 }
@@ -4109,7 +4120,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 	case WS_CARTTERMINATION:	// Cart Termination
 	case AS_VENOMKNIFE:
 	case HT_PHANTASMIC:
-	case HT_POWER:
 	case TK_DOWNKICK:
 	case TK_COUNTER:
 	case GS_CHAINACTION:
@@ -4335,6 +4345,11 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 		}
 		break;
 
+	case HT_POWER:
+		if( tstatus->race == RC_BRUTE || tstatus->race == RC_INSECT )
+			skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
+		break;
+
 	//Splash attack skills.
 	case AS_GRIMTOOTH:
 	case MC_CARTREVOLUTION:
@@ -15271,13 +15286,12 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
 				req.sp -= req.sp*3*kaina_lv/100;
 		}
 			break;
-		case MO_TRIPLEATTACK:
 		case MO_CHAINCOMBO:
 		case MO_COMBOFINISH:
 		case CH_TIGERFIST:
 		case CH_CHAINCRUSH:
 			if(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_MONK)
-				req.sp -= req.sp*25/100; //FIXME: Need real data. this is a custom value.
+				req.sp = 2; //Monk Spirit makes monk/champion combo skills cost 2 SP regardless of original cost
 			break;
 		case MO_BODYRELOCATION:
 			if( sc && sc->data[SC_EXPLOSIONSPIRITS] )
@@ -15585,7 +15599,10 @@ int skill_delayfix (struct block_list *bl, uint16 skill_id, uint16 skill_lv)
 	case CH_CHAINCRUSH:
 	case SR_DRAGONCOMBO:
 	case SR_FALLENEMPIRE:
-		time -= 4*status_get_agi(bl) - 2*status_get_dex(bl);
+		//If delay not specified, it will be 1000 - 4*agi - 2*dex
+		if (time == 0)
+			time = 1000;
+		time -= (4*status_get_agi(bl) + 2*status_get_dex(bl));
 		break;
 	case HP_BASILICA:
 		if( sc && !sc->data[SC_BASILICA] )

+ 16 - 13
src/map/status.c

@@ -8920,22 +8920,25 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			}
 			break;
 
-		case SC_COMBO: {
-				// val1: Skill ID
-				// val2: When given, target (for autotargetting skills)
-				// val3: When set, this combo time should NOT delay attack/movement
-				// val3: TK: Last used kick
-				// val4: TK: Combo time
-				struct unit_data *ud = unit_bl2ud(bl);
-				if (ud && !val3) {
-					tick += 300 * battle_config.combo_delay_rate/100;
-					ud->attackabletime = gettick()+tick;
+		case SC_COMBO:
+		{
+			// val1: Skill ID
+			// val2: When given, target (for autotargetting skills)
+			// val3: When set, this combo time should NOT delay attack/movement
+			// val3: If set to 2 this combo will delay ONLY attack
+			// val3: TK: Last used kick
+			// val4: TK: Combo time
+			struct unit_data *ud = unit_bl2ud(bl);
+			if ( ud && (!val3 || val3 == 2) ) {
+				tick += 300 * battle_config.combo_delay_rate/100;
+				ud->attackabletime = gettick()+tick;
+				if( !val3 )
 					unit_set_walkdelay(bl, gettick(), tick, 1);
-				}
-				val3 = 0;
-				val4 = tick;
 			}
+			val3 = 0;
+			val4 = tick;
 			break;
+		}
 		case SC_EARTHSCROLL:
 			val2 = 11-val1; // Chance to consume: 11-skill_lv%
 			break;

+ 1 - 1
src/map/unit.c

@@ -1403,7 +1403,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
 		(sd?skill_check_condition_castbegin(sd,skill_id,skill_lv):0) )) {
 		if (sc->data[SC_COMBO]->val2)
 			target_id = sc->data[SC_COMBO]->val2;
-		else
+		else if (target_id == src->id || ud->target > 0)
 			target_id = ud->target;
 
 		if( skill_get_inf(skill_id)&INF_SELF_SKILL && skill_get_nk(skill_id)&NK_NO_DAMAGE )// exploit fix