Selaa lähdekoodia

Implemented Blocking Play feature
* Adds the SC_BLOCKING_PLAY status that keeps players from moving, using/picking/dropping items, using skills, chatting, and swapping equipment while changing maps.
* Disables the ability for players to pre-cast skills when changing maps to avoid cast times.
Thanks to @mrjnumber1!

aleos89 6 vuotta sitten
vanhempi
commit
3b1824fef5

+ 5 - 0
conf/battle/misc.conf

@@ -180,3 +180,8 @@ mail_delay: 1000
 
 // Hides items from the player's favorite tab from being sold to a NPC. (Note 1)
 hide_fav_sell: no
+
+// Block the player from moving, using/picking/dropping items, using skills, chatting, and swapping equipment while changing maps.
+// Disables the ability for players to pre-cast skills when changing maps to avoid cast times.
+// Duration is in milliseconds. Set to 0 to disable.
+blocking_play_delay: 20000

+ 8 - 4
doc/status_change.txt

@@ -2687,10 +2687,6 @@ SC_GVG_BLIND	(EFST_GVG_BLIND)
 	val1: Amount of HP that are instantly consumed
 	val2: Amount of SP that are instantly consumed
 
-SC_EXTREMITYFIST2	()
-	desc:
-	val1:
-
 SC_LHZ_DUN_N1	(EFST_LHZ_DUN_N1)
 	desc: Increases damage against Swordman, Thief and reduces damage taken from Acolyte, Merchant monsters of Biolab 5 (except MVPs).
 	val1: +% Damage
@@ -2710,3 +2706,11 @@ SC_LHZ_DUN_N4	(EFST_LHZ_DUN_N4)
 	desc: Increases and reduces damage against MVPs of Biolab 5.
 	val1: +% Damage
 	val2: +% Defense
+
+SC_BLOCKING_PLAY	(EFST_BLOCKING_PLAY)
+	desc: Keeps players from moving, using/picking/dropping items, using skills, chatting, and swapping equipment while changing maps.
+	val1: N/A
+
+SC_EXTREMITYFIST2	()
+	desc:
+	val1:

+ 1 - 0
src/map/battle.cpp

@@ -8509,6 +8509,7 @@ static const struct _battle_data {
 	{ "feature.attendance",                 &battle_config.feature_attendance,              1,      0,      1,              },
 	{ "feature.privateairship",             &battle_config.feature_privateairship,          1,      0,      1,              },
 	{ "rental_transaction",                 &battle_config.rental_transaction,              1,      0,      1,              },
+	{ "blocking_play_delay",                &battle_config.blocking_play_delay,             20000,  0,      INT_MAX,        },
 
 #include "../custom/battle_config_init.inc"
 };

+ 1 - 0
src/map/battle.hpp

@@ -649,6 +649,7 @@ struct Battle_Config
 	int feature_attendance;
 	int feature_privateairship;
 	int rental_transaction;
+	int blocking_play_delay;
 
 #include "../custom/battle_config_struct.inc"
 };

+ 3 - 4
src/map/clif.cpp

@@ -18590,11 +18590,10 @@ void clif_parse_reqworldinfo(int fd,struct map_session_data *sd) {
 		clif_ackworldinfo(sd);
 }
 
-/// unknown usage (CZ_BLOCKING_PLAY_CANCEL)
-/// 0447
+/// Enable playing abilities of a player if map is done loading.
+/// 0447 (CZ_BLOCKING_PLAY_CANCEL)
 void clif_parse_blocking_playcancel(int fd,struct map_session_data *sd) {
-	//if(sd)
-	;
+	status_change_end(&sd->bl, SC_BLOCKING_PLAY, INVALID_TIMER);
 }
 
 /// req world info (CZ_CLIENT_VERSION)

+ 8 - 3
src/map/pc.cpp

@@ -5513,6 +5513,10 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
 		}
 
 		sd->state.pmap = sd->bl.m;
+
+		if (battle_config.blocking_play_delay)
+			sc_start(&sd->bl, &sd->bl, SC_BLOCKING_PLAY, 100, 0, 0);
+
 		if (sd->sc.count) { // Cancel some map related stuff.
 			if (sd->sc.data[SC_JAILED])
 				return SETPOS_MAPINDEX; //You may not get out!
@@ -9837,7 +9841,8 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos)
 		return false;
 	}
 	if( sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAYNIGHTFEVER] ||
-		sd->sc.data[SC_KYOUGAKU] || (sd->sc.data[SC_PYROCLASTIC] && sd->inventory_data[n]->type == IT_WEAPON)) ) {
+		sd->sc.data[SC_KYOUGAKU] || (sd->sc.data[SC_PYROCLASTIC] && sd->inventory_data[n]->type == IT_WEAPON)) ||
+		sd->sc.data[SC_BLOCKING_PLAY]) {
 		clif_equipitemack(sd,n,0,ITEM_EQUIP_ACK_FAIL); //Fail
 		return false;
 	}
@@ -10107,8 +10112,8 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
 		sd->sc.data[SC_SATURDAYNIGHTFEVER] ||
 		sd->sc.data[SC__BLOODYLUST] ||
 		sd->sc.data[SC_KYOUGAKU] ||
-		(sd->sc.data[SC_PYROCLASTIC] &&
-		sd->inventory_data[n]->type == IT_WEAPON)))	// can't switch weapon
+		(sd->sc.data[SC_PYROCLASTIC] && sd->inventory_data[n]->type == IT_WEAPON) ||
+		sd->sc.data[SC_BLOCKING_PLAY]))	// can't switch weapon
 	{
 		clif_unequipitemack(sd,n,0,0);
 		return false;

+ 1 - 0
src/map/script_constants.hpp

@@ -1520,6 +1520,7 @@
 	export_constant(SC_LHZ_DUN_N3);
 	export_constant(SC_LHZ_DUN_N4);
 	export_constant(SC_ANCILLA);
+	export_constant(SC_BLOCKING_PLAY);
 #ifdef RENEWAL
 	export_constant(SC_EXTREMITYFIST2);
 #endif

+ 3 - 0
src/map/skill.cpp

@@ -1924,6 +1924,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
 					case SC_WEDDING:		case SC_XMAS:			case SC_SUMMER:
 					case SC_DRESSUP:		case SC_HANBOK:			case SC_OKTOBERFEST:
 					case SC_LHZ_DUN_N1:		case SC_LHZ_DUN_N2:			case SC_LHZ_DUN_N3:			case SC_LHZ_DUN_N4:
+					case SC_BLOCKING_PLAY:
 						continue;
 					case SC_WHISTLE:		case SC_ASSNCROS:		case SC_POEMBRAGI:
 					case SC_APPLEIDUN:		case SC_HUMMING:		case SC_DONTFORGETME:
@@ -7998,6 +7999,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 					case SC_WEDDING:		case SC_XMAS:			case SC_SUMMER:
 					case SC_DRESSUP:		case SC_HANBOK:			case SC_OKTOBERFEST:
 					case SC_LHZ_DUN_N1:		case SC_LHZ_DUN_N2:			case SC_LHZ_DUN_N3:			case SC_LHZ_DUN_N4:
+					case SC_BLOCKING_PLAY:
 						continue;
 					case SC_WHISTLE:
 					case SC_ASSNCROS:
@@ -9452,6 +9454,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 					case SC_WEDDING:		case SC_XMAS:			case SC_SUMMER:
 					case SC_DRESSUP:		case SC_HANBOK:			case SC_OKTOBERFEST:
 					case SC_LHZ_DUN_N1:		case SC_LHZ_DUN_N2:			case SC_LHZ_DUN_N3:			case SC_LHZ_DUN_N4:
+					case SC_BLOCKING_PLAY:
 					continue;
 				case SC_ASSUMPTIO:
 					if( bl->type == BL_MOB )

+ 17 - 0
src/map/status.cpp

@@ -1176,6 +1176,8 @@ void initChangeTables(void)
 
 	StatusIconChangeTable[SC_ANCILLA] = EFST_ANCILLA;
 
+	StatusIconChangeTable[SC_BLOCKING_PLAY] = EFST_BLOCKING_PLAY;
+
 	/* Other SC which are not necessarily associated to skills */
 	StatusChangeFlagTable[SC_ASPDPOTION0] |= SCB_ASPD;
 	StatusChangeFlagTable[SC_ASPDPOTION1] |= SCB_ASPD;
@@ -1343,6 +1345,8 @@ void initChangeTables(void)
 	StatusChangeFlagTable[SC_EDP] |= SCB_WATK;
 #endif
 
+	StatusChangeFlagTable[SC_BLOCKING_PLAY] |= SCB_NONE;
+
 	/* StatusDisplayType Table [Ind] */
 	StatusDisplayType[SC_ALL_RIDING]	  = BL_PC;
 	StatusDisplayType[SC_PUSH_CART]		  = BL_PC;
@@ -1436,6 +1440,7 @@ void initChangeTables(void)
 	StatusChangeStateTable[SC_VACUUM_EXTREME]		|= SCS_NOMOVE;
 	StatusChangeStateTable[SC_SUHIDE]				|= SCS_NOMOVE;
 	StatusChangeStateTable[SC_SV_ROOTTWIST]			|= SCS_NOMOVE;
+	StatusChangeStateTable[SC_BLOCKING_PLAY]		|= SCS_NOMOVE;
 
 	/* StatusChangeState (SCS_) NOPICKUPITEMS */
 	StatusChangeStateTable[SC_HIDING]				|= SCS_NOPICKITEM;
@@ -1446,11 +1451,13 @@ void initChangeTables(void)
 	StatusChangeStateTable[SC__FEINTBOMB]			|= SCS_NOPICKITEM;
 	StatusChangeStateTable[SC_NOCHAT]				|= SCS_NOPICKITEM|SCS_NOPICKITEMCOND;
 	StatusChangeStateTable[SC_SUHIDE]				|= SCS_NOPICKITEM;
+	StatusChangeStateTable[SC_BLOCKING_PLAY]		|= SCS_NOPICKITEM;
 
 	/* StatusChangeState (SCS_) NODROPITEMS */
 	StatusChangeStateTable[SC_AUTOCOUNTER]			|= SCS_NODROPITEM;
 	StatusChangeStateTable[SC_BLADESTOP]			|= SCS_NODROPITEM;
 	StatusChangeStateTable[SC_NOCHAT]				|= SCS_NODROPITEM|SCS_NODROPITEMCOND;
+	StatusChangeStateTable[SC_BLOCKING_PLAY]		|= SCS_NODROPITEM;
 
 	/* StatusChangeState (SCS_) NOCAST (skills) */
 	StatusChangeStateTable[SC_SILENCE]				|= SCS_NOCAST;
@@ -1469,12 +1476,14 @@ void initChangeTables(void)
 	StatusChangeStateTable[SC_SATURDAYNIGHTFEVER]	|= SCS_NOCAST;
 	StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET]	|= SCS_NOCAST;
 	StatusChangeStateTable[SC_KINGS_GRACE]			|= SCS_NOCAST;
+	StatusChangeStateTable[SC_BLOCKING_PLAY]		|= SCS_NOCAST;
 
 	/* StatusChangeState (SCS_) NOCHAT (skills) */
 	StatusChangeStateTable[SC_BERSERK]				|= SCS_NOCHAT;
 	StatusChangeStateTable[SC_SATURDAYNIGHTFEVER]	|= SCS_NOCHAT;
 	StatusChangeStateTable[SC_DEEPSLEEP]			|= SCS_NOCHAT;
 	StatusChangeStateTable[SC_NOCHAT]				|= SCS_NOCHAT|SCS_NOCHATCOND;
+	StatusChangeStateTable[SC_BLOCKING_PLAY]		|= SCS_NOCHAT;
 }
 
 static void initDummyData(void)
@@ -9427,6 +9436,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			case SC_REUSE_LIMIT_ASPD_POTION:
 			case SC_DORAM_BUF_01:
 			case SC_DORAM_BUF_02:
+			case SC_BLOCKING_PLAY:
 				return 0;
 			case SC_PUSH_CART:
 			case SC_COMBO:
@@ -9765,6 +9775,10 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			}
 			break;
 
+		case SC_BLOCKING_PLAY:
+			tick = battle_config.blocking_play_delay;
+			break;
+
 		case SC_STONE:
 			val3 = max(val3, 100); // Incubation time
 			val4 = max(tick-val3, 100); // Petrify time
@@ -11946,6 +11960,7 @@ int status_change_clear(struct block_list* bl, int type)
 			case SC_LHZ_DUN_N2:
 			case SC_LHZ_DUN_N3:
 			case SC_LHZ_DUN_N4:
+			case SC_BLOCKING_PLAY:
 			// Costumes
 			case SC_MOONSTAR:
 			case SC_SUPER_STAR:
@@ -11980,6 +11995,7 @@ int status_change_clear(struct block_list* bl, int type)
 			case SC_PUSH_CART:
 			case SC_ALL_RIDING:
 			case SC_STYLE_CHANGE:
+			case SC_BLOCKING_PLAY:
 			// Costumes
 			case SC_MOONSTAR:
 			case SC_SUPER_STAR:
@@ -13976,6 +13992,7 @@ void status_change_clear_buffs(struct block_list* bl, uint8 type)
 			case SC_LHZ_DUN_N2:
 			case SC_LHZ_DUN_N3:
 			case SC_LHZ_DUN_N4:
+			case SC_BLOCKING_PLAY:
 			// Clans
 			case SC_CLAN_INFO:
 			case SC_SWORDCLAN: