瀏覽代碼

-Some script/atcommand function work. thx to Euphy
--Update of script documentation
--Readd "instance_announce" (Broadcasts to all maps inside an instance)
--Add "is_clientver" (Checks if a player's client version meets a required version or date.)
--Add "getserverdef" (Retrieves server definitions.)
--Overload of @item to allow @item <id1:name2:name3:..> <amount> (for lazy people =)

lighta 11 年之前
父節點
當前提交
ba6b57bdf3
共有 9 個文件被更改,包括 202 次插入54 次删除
  1. 11 0
      db/const.txt
  2. 1 1
      db/mob_skill_db2.txt
  3. 1 1
      db/pre-re/mob_skill_db.txt
  4. 1 1
      db/re/mob_skill_db.txt
  5. 52 16
      doc/script_commands.txt
  6. 1 1
      sql-files/mob_skill_db.sql
  7. 1 1
      sql-files/mob_skill_db_re.sql
  8. 39 33
      src/map/atcommand.c
  9. 95 0
      src/map/script.c

+ 11 - 0
db/const.txt

@@ -3284,3 +3284,14 @@ IT_PETARMOR	8
 IT_AMMO	10
 IT_DELAYCONSUME	11
 IT_CASH	18
+
+VAR_PACKETVER	0
+VAR_MAX_LEVEL	1
+VAR_MAX_STORAGE	2
+VAR_MAX_INVENTORY	3
+VAR_MAX_ZENY	4
+VAR_MAX_PARTY	5
+VAR_MAX_GUILD	6
+VAR_MAX_GUILDLEVEL	7
+VAR_MAX_GUILD_STORAGE	8
+VAR_MAX_BG_MEMBERS	9

+ 1 - 1
db/mob_skill_db2.txt

@@ -51,7 +51,7 @@
 // Note: if a negative MobID is provided, the skill will be treated as 'global':
 //	-1: added for all boss types.
 //	-2: added for all normal types.
-//	-4: added for all mobs.
+//	-3: added for all mobs.
 
 // rAthena Dev Team
 //1900,Valaris@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,

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

@@ -52,7 +52,7 @@
 // Note: if a negative MobID is provided, the skill will be treated as 'global':
 //	-1: added for all boss types.
 //	-2: added for all normal types.
-//	-4: added for all mobs.
+//	-3: added for all mobs.
 
 1001,Scorpion@NPC_FIREATTACK,attack,186,1,2000,0,5000,yes,target,always,0,,,,,,,
 1001,Scorpion@NPC_POISON,attack,176,3,500,800,5000,no,target,always,0,,,,,,,

+ 1 - 1
db/re/mob_skill_db.txt

@@ -52,7 +52,7 @@
 // Note: if a negative MobID is provided, the skill will be treated as 'global':
 //	-1: added for all boss types.
 //	-2: added for all normal types.
-//	-4: added for all mobs.
+//	-3: added for all mobs.
 
 1001,Scorpion@NPC_FIREATTACK,attack,186,1,2000,0,5000,yes,target,always,0,,,,,,,
 1001,Scorpion@NPC_POISON,attack,176,3,500,800,5000,no,target,always,0,,,,,,,

+ 52 - 16
doc/script_commands.txt

@@ -2756,16 +2756,12 @@ invoking player belongs.
 
 *gettimetick(<tick type>)
 
-This function will return the system time in UNIX epoch time (if tick type is 2) 
-or the time since the start of the current day in seconds if tick type is 1.
-Passing 0 will make it return the server's tick, which is a measurement in
-milliseconds used by the server's timer system. The server's tick is an
-unsigned int which loops every ~50 days.
-
-Just in case you don't know, UNIX epoch time is the number of seconds elapsed 
-since 1st of January 1970, and is useful to see, for example, for how long the 
-character has been online with OnPCLoginEvent and OnPCLogoutEvent, which could allow 
-you to make an 'online time counted for conviction only' jail script.
+This function will return a tick depending on <tick type>:
+ 0: The server's tick, a measurement in milliseconds used by the server's timer
+    system. This tick is an unsigned int which loops every ~50 days.
+ 1: The time, in seconds, since the start of the current day.
+ 2: The system time in UNIX epoch time, or the number of seconds elapsed since
+    January 1st, 1970. Useful for reliably measuring time intervals.
 
 ---------------------------------------
 
@@ -3047,7 +3043,7 @@ mob database and return the info set by TYPE argument.
 It will return -1 if there is no such monster (or the type value is invalid),
 or "null" if you requested the monster's name.
 
-Valid types are listed in const.txt:
+Valid types are listed in 'db/const.txt':
 	MOB_NAME	0
 	MOB_LV	1
 	MOB_MAXHP	2
@@ -3072,7 +3068,7 @@ Valid types are listed in const.txt:
 	MOB_MODE	21
 	MOB_MVPEXP	22
 
-For more details, see the sample in doc/sample/getmonsterinfo.txt.
+For more details, see the sample in 'doc/sample/getmonsterinfo.txt'.
 
 ---------------------------------------
 
@@ -3179,7 +3175,7 @@ account ID.
 *isloggedin(<account id>{,<char id>})
 
 This function returns 1 if the specified account is logged in and 0 if they 
-aren't. You can also pass the char_id to check for both account and char id.
+aren't. You can also pass the char id to check for both account and char id.
 
 ---------------------------------------
 
@@ -3455,9 +3451,10 @@ more:
 
 *checkre(<type>)
 
-Checks if a renewal feature is enabled or not in renewal.h, and returns 1 if enabled and 0 for disabled.
-The renewal feature to check is determined by type.
+Checks if a renewal feature is enabled or not in renewal.h, and returns 1 if
+enabled and 0 for disabled.
 
+The renewal feature to check is determined by type.
  0 - RENEWAL (game renewal server mode)
  1 - RENEWAL_CAST (renewal cast time)
  2 - RENEWAL_DROP (renewal drop rate algorithms)
@@ -3466,6 +3463,34 @@ The renewal feature to check is determined by type.
  5 - RENEWAL_EDP (renewal enchant deadly poison algorithm)
  6 - RENEWAL_ASPD (renewal ASPD)
 
+---------------------------------------
+
+*is_clientver(<type>,<value>{,<char id>})
+
+Checks a character's client version against a specified value. If no char id is
+given, the command will run for the invoking character. The function will return
+1 if the player's version is greater than or equal to the value, and 0 otherwise.
+
+Available types are:
+ 0 - version number (packet_db_ver)
+ 1 - client date (YYYYMMDD)
+
+---------------------------------------
+
+*getserverdef(<type>)
+
+Returns a server definition. Valid types are listed in 'db/const.txt':
+	VAR_PACKETVER	0
+	VAR_MAX_LEVEL	1
+	VAR_MAX_STORAGE	2
+	VAR_MAX_INVENTORY	3
+	VAR_MAX_ZENY	4
+	VAR_MAX_PARTY	5
+	VAR_MAX_GUILD	6
+	VAR_MAX_GUILDLEVEL	7
+	VAR_MAX_GUILD_STORAGE	8
+	VAR_MAX_BG_MEMBERS	9
+
 ---------------------------------------
 \\
 3,1.- Item-related commands
@@ -3661,7 +3686,7 @@ close;
 
 ---------------------------------------
 
-*warpchar "<map name>",<x>,<y>,<char_id>;
+*warpchar "<map name>",<x>,<y>,<char id>;
 
 Warps another player to specified map and coordinate given the char id, which you can get with
 getcharid(0,<player_name>). Obviously this is useless if you want to warp the same player that
@@ -7272,6 +7297,17 @@ come to a halt.
 
 ---------------------------------------
 
+*instance_announce <instance id>,"<text>",<flag>{,<fontColor>{,<fontType>{,<fontSize>{,<fontAlign>{,<fontY>}}}}};
+
+Broadcasts a message to all players in the instance <instance id> currently
+residing on an instance map. If -1 is specified for <instance id>, the instance
+the script is attached to is used. If the script is not attached to an instance,
+the instance of the currently attached player's party is used.
+
+For details on the other parameters, see 'announce'.
+
+---------------------------------------
+
 *instance_check_party(<party id>{,<amount>{,<min>{,<max>}}})
 
 This function checks if a party meets certain requirements, returning 1 if all

+ 1 - 1
sql-files/mob_skill_db.sql

@@ -79,7 +79,7 @@ CREATE TABLE IF NOT EXISTS `mob_skill_db` (
 # Note: if a negative MobID is provided, the skill will be treated as 'global':
 #	-1: added for all boss types.
 #	-2: added for all normal types.
-#	-4: added for all mobs.
+#	-3: added for all mobs.
 
 REPLACE INTO `mob_skill_db` VALUES (1001,'Scorpion@NPC_FIREATTACK','attack',186,1,2000,0,5000,'yes','target','always','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL);
 REPLACE INTO `mob_skill_db` VALUES (1001,'Scorpion@NPC_POISON','attack',176,3,500,800,5000,'no','target','always','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL);

+ 1 - 1
sql-files/mob_skill_db_re.sql

@@ -79,7 +79,7 @@ CREATE TABLE IF NOT EXISTS `mob_skill_db` (
 # Note: if a negative MobID is provided, the skill will be treated as 'global':
 #	-1: added for all boss types.
 #	-2: added for all normal types.
-#	-4: added for all mobs.
+#	-3: added for all mobs.
 
 REPLACE INTO `mob_skill_db` VALUES (1001,'Scorpion@NPC_FIREATTACK','attack',186,1,2000,0,5000,'yes','target','always','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL);
 REPLACE INTO `mob_skill_db` VALUES (1001,'Scorpion@NPC_POISON','attack',176,3,500,800,5000,'no','target','always','0',NULL,NULL,NULL,NULL,NULL,NULL,NULL);

+ 39 - 33
src/map/atcommand.c

@@ -1117,18 +1117,19 @@ ACMD_FUNC(heal)
 }
 
 /*==========================================
- * @item command (usage: @item <name/id_of_item> <quantity>) (modified by [Yor] for pet_egg)
+ * @item command (usage: @item <itemdid1:itemid2:itemname:..> <quantity>) (modified by [Yor] for pet_egg)
  * @itembound command (usage: @itembound <name/id_of_item> <quantity> <bound_type>)
  *------------------------------------------*/
 ACMD_FUNC(item)
 {
 	char item_name[100];
-	int number = 0, item_id, flag = 0, bound = 0;
+	int number = 0, flag = 0, bound = 0;
 	struct item item_tmp;
-	struct item_data *item_data;
-	int get_count, i;
-	nullpo_retr(-1, sd);
+	struct item_data *item_data[10];
+	int get_count, i, j=0;
+	char *itemlist;
 
+	nullpo_retr(-1, sd);
 	memset(item_name, '\0', sizeof(item_name));
 
 	if (!strcmpi(command+1,"itembound") && (!message || !*message || (
@@ -1144,15 +1145,15 @@ ACMD_FUNC(item)
 		clif_displaymessage(fd, msg_txt(sd,983)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity>).
 		return -1;
 	}
-
-	if (number <= 0)
-		number = 1;
-
-	if ((item_data = itemdb_searchname(item_name)) == NULL &&
-	    (item_data = itemdb_exists(atoi(item_name))) == NULL)
-	{
-		clif_displaymessage(fd, msg_txt(sd,19)); // Invalid item ID or name.
-		return -1;
+	itemlist = strtok(item_name, ":");
+	while (itemlist != NULL && j<10) {
+		if ((item_data[j] = itemdb_searchname(itemlist)) == NULL &&
+		    (item_data[j] = itemdb_exists(atoi(itemlist))) == NULL){
+			clif_displaymessage(fd, msg_txt(sd,19)); // Invalid item ID or name.
+			return -1;
+		}
+		itemlist = strtok(NULL, ":"); //next itemline
+		j++;
 	}
 
 	if( bound < 0 || bound > 4 ) {
@@ -1160,22 +1161,27 @@ ACMD_FUNC(item)
 		return -1;
 	}
 
-	item_id = item_data->nameid;
+	if (number <= 0)
+		number = 1;
 	get_count = number;
-	//Check if it's stackable.
-	if (!itemdb_isstackable2(item_data))
-		get_count = 1;
 
-	for (i = 0; i < number; i += get_count) {
-		// if not pet egg
-		if (!pet_create_egg(sd, item_id)) {
-			memset(&item_tmp, 0, sizeof(item_tmp));
-			item_tmp.nameid = item_id;
-			item_tmp.identify = 1;
-			item_tmp.bound = bound;
+	for(j--; j>=0; j--){ //produce items in list
+		int16 item_id = item_data[j]->nameid;
+		//Check if it's stackable.
+		if (!itemdb_isstackable2(item_data[j]))
+			get_count = 1;
 
-			if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
-				clif_additem(sd, 0, 0, flag);
+		for (i = 0; i < number; i += get_count) {
+			// if not pet egg
+			if (!pet_create_egg(sd, item_id)) {
+				memset(&item_tmp, 0, sizeof(item_tmp));
+				item_tmp.nameid = item_id;
+				item_tmp.identify = 1;
+				item_tmp.bound = bound;
+
+				if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
+					clif_additem(sd, 0, 0, flag);
+			}
 		}
 	}
 
@@ -3856,7 +3862,7 @@ ACMD_FUNC(mapinfo) {
 	if (map[m_id].flag.gvg)
 		strcat(atcmd_output, " GvG ON |");
 	if (map[m_id].flag.gvg_dungeon)
-		strcat(atcmd_output, " GvG Dungeon |"); 
+		strcat(atcmd_output, " GvG Dungeon |");
 	if (map[m_id].flag.gvg_castle)
 		strcat(atcmd_output, " GvG Castle |");
 	if (map[m_id].flag.gvg_noparty)
@@ -3875,7 +3881,7 @@ ACMD_FUNC(mapinfo) {
 	if (map[m_id].flag.noreturn)
 		strcat(atcmd_output, " NoReturn |");
 	if (map[m_id].flag.nogo)
-		strcat(atcmd_output, " NoGo |"); // 
+		strcat(atcmd_output, " NoGo |"); //
 	if (map[m_id].flag.nomemo)
 		strcat(atcmd_output, "  NoMemo |");
 	clif_displaymessage(fd, atcmd_output);
@@ -3923,9 +3929,9 @@ ACMD_FUNC(mapinfo) {
 	if (map[m_id].flag.notrade)
 		strcat(atcmd_output, " NoTrade |");
 	if (map[m_id].flag.novending)
-		strcat(atcmd_output, " NoVending |"); 
+		strcat(atcmd_output, " NoVending |");
 	if (map[m_id].flag.nodrop)
-		strcat(atcmd_output, " NoDrop |"); 
+		strcat(atcmd_output, " NoDrop |");
 	if (map[m_id].flag.noskill)
 		strcat(atcmd_output, " NoSkill |");
 	if (map[m_id].flag.noicewall)
@@ -3933,7 +3939,7 @@ ACMD_FUNC(mapinfo) {
 	if (map[m_id].flag.allowks)
 		strcat(atcmd_output, " AllowKS |");
 	if (map[m_id].flag.reset)
-		strcat(atcmd_output, " Reset |"); 
+		strcat(atcmd_output, " Reset |");
 	clif_displaymessage(fd, atcmd_output);
 
 	strcpy(atcmd_output,msg_txt(sd,1051)); // Other Flags2:
@@ -7676,7 +7682,7 @@ ACMD_FUNC(mapflag) {
 		return 1;
 	}
 	for (i = 0; flag_name[i]; i++) flag_name[i] = (char)tolower(flag_name[i]); //lowercase
-	
+
 	setflag(town);				setflag(autotrade);			setflag(allowks);				setflag(nomemo);
 	setflag(noteleport);		setflag(noreturn);			setflag(monster_noteleport);	setflag(nosave);
 	setflag(nobranch);			setflag(noexppenalty);		setflag(pvp);					setflag(pvp_noparty);

+ 95 - 0
src/map/script.c

@@ -16743,6 +16743,38 @@ BUILDIN_FUNC(instance_warpall)
 	return 0;
 }
 
+/*==========================================
+ * Broadcasts to all maps inside an instance
+ *
+ * instance_announce <instance id>,"<text>",<flag>{,<fontColor>{,<fontType>{,<fontSize>{,<fontAlign>{,<fontY>}}}}};
+ * Using -1 for <instance id> will auto-detect the id.
+ *------------------------------------------*/
+BUILDIN_FUNC(instance_announce) {
+	int         instance_id = script_getnum(st,2);
+	const char *mes         = script_getstr(st,3);
+	int         flag        = script_getnum(st,4);
+	const char *fontColor   = script_hasdata(st,5) ? script_getstr(st,5) : NULL;
+	int         fontType    = script_hasdata(st,6) ? script_getnum(st,6) : 0x190; // default fontType (FW_NORMAL)
+	int         fontSize    = script_hasdata(st,7) ? script_getnum(st,7) : 12;    // default fontSize
+	int         fontAlign   = script_hasdata(st,8) ? script_getnum(st,8) : 0;     // default fontAlign
+	int         fontY       = script_hasdata(st,9) ? script_getnum(st,9) : 0;     // default fontY
+
+	int i;
+
+	if( instance_id == -1 ) {
+		instance_id = script_instancegetid(st);
+	}
+
+	if( !instance_id && &instance_data[instance_id] != NULL)
+		return true;
+
+	for( i = 0; i < instance_data[instance_id].cnt_map; i++ )
+		map_foreachinmap(buildin_announce_sub, instance_data[instance_id].map[i].m, BL_PC,
+						 mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
+
+	return true;
+}
+
 /*==========================================
  * instance_check_party [malufett]
  * Values:
@@ -17893,6 +17925,65 @@ BUILDIN_FUNC(party_destroy)
 	return 0;
 }
 
+/*==========================================
+* Checks if a player's client version meets a required version or date.
+* @type :
+*  0 - check by version number
+*  1 - check by date
+* @return true/false
+ *------------------------------------------*/
+BUILDIN_FUNC(is_clientver){
+	TBL_PC *sd = NULL;
+	int type = script_getnum(st,2);
+	int data = script_getnum(st,3);
+	int ret = 0;
+
+	if (script_hasdata(st,4))
+		sd = map_charid2sd(script_getnum(st,4));
+	else
+		sd = script_rid2sd(st);
+	if (sd == NULL) {
+		script_pushint(st,0);
+		return 0;
+	}
+
+	switch(type){
+		case 0:
+			ret = (sd->packet_ver >= data)?1:0;
+			break;
+		case 1:
+			ret = (sd->packet_ver >= date2version(data))?1:0;
+			break;
+	}
+	script_pushint(st,ret);
+	return 0;
+}
+
+/*==========================================
+* Retrieves server definitions.
+* (see @type in const.txt)
+ *------------------------------------------*/
+BUILDIN_FUNC(getserverdef){
+	int type = script_getnum(st,2);
+	switch(type){
+		case 0: script_pushint(st,PACKETVER); break;
+		case 1: script_pushint(st,MAX_LEVEL); break;
+		case 2: script_pushint(st,MAX_STORAGE); break;
+		case 3: script_pushint(st,MAX_INVENTORY); break;
+		case 4: script_pushint(st,MAX_ZENY); break;
+		case 5: script_pushint(st,MAX_PARTY); break;
+		case 6: script_pushint(st,MAX_GUILD); break;
+		case 7: script_pushint(st,MAX_GUILDLEVEL); break;
+		case 8: script_pushint(st,MAX_GUILD_STORAGE); break;
+		case 9: script_pushint(st,MAX_BG_MEMBERS); break;
+		default:
+			ShowWarning("buildin_getserverdef: unknown type %d.\n", type);
+			script_pushint(st,0);
+			break;
+	}
+	return 0;
+}
+
 // declarations that were supposed to be exported from npc_chat.c
 #ifdef PCRE_SUPPORT
 BUILDIN_FUNC(defpattern);
@@ -18314,6 +18405,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(instance_npcname,"s?"),
 	BUILDIN_DEF(instance_mapname,"s?"),
 	BUILDIN_DEF(instance_warpall,"sii?"),
+	BUILDIN_DEF(instance_announce,"isi?????"),
 	BUILDIN_DEF(instance_check_party,"i???"),
 	/**
 	 * 3rd-related
@@ -18367,5 +18459,8 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(party_changeleader,"ii"),
 	BUILDIN_DEF(party_changeoption,"iii"),
 	BUILDIN_DEF(party_destroy,"i"),
+	
+	BUILDIN_DEF(is_clientver,"ii?"),
+	BUILDIN_DEF(getserverdef,"i"),
 	{NULL,NULL,NULL},
 };