소스 검색

Added party script commands and documentation (thank Euphy)
- party_create "<party name>"{,<char id>{,<item share: 0-no. 1-yes>{,<item share type: 0-favorite. 1-shared>}}};
- party_addmember <party id>,<char id>;
- party_delmember {<char id>};
- party_changeleader <party id>,<char id>;
- party_changeoption <party id>,<option>,<flag>;
- party_destroy <party id>;
Added script command for checking player's language
- checklang()
Mapflag related
- Add nocommand mapflag documentation
- Added notomb at @mapinfo message
- some changes at @mapflag
Attempt to fix error on 'skill_produce_mix' while deleting materials


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17414 54d463be-8e91-2dee-dedb-b68131a5f0ec

cydh 12 년 전
부모
커밋
12523667f7

+ 6 - 5
conf/msg_conf/map_msg.conf

@@ -935,12 +935,13 @@
 1097: GuildLock |
 1097: GuildLock |
 1098: Loadevent |
 1098: Loadevent |
 1100: Chmautojoin |
 1100: Chmautojoin |
-1101: nousecart |
-1102: noitemconsumption |
-1103: nosumstarmiracle |
-1104: nomineeffect |
-1105: nolockon |
+1101: NoUseCart |
+1102: NoItemConsumption |
+1103: NoSumStarMiracle |
+1104: NoMineEffect |
+1105: NoLockOn |
 1106: Restricted (zone %d)
 1106: Restricted (zone %d)
+1107: NoTomb |
 
 
 // @mount
 // @mount
 1119: You have mounted your Dragon.
 1119: You have mounted your Dragon.

+ 6 - 5
conf/msg_conf/map_msg_chn.conf

@@ -917,12 +917,13 @@
 1098: Loadevent |
 1098: Loadevent |
 1099: Src4instance |
 1099: Src4instance |
 1100: Chmautojoin |
 1100: Chmautojoin |
-1101: nousecart |
-1102: noitemconsumption |
-1103: nosumstarmiracle |
-1104: nomineeffect |
-1105: nolockon |
+1101: NoUseCart |
+1102: NoItemConsumption |
+1103: NoSumStarMiracle |
+1104: NoMineEffect |
+1105: NoLockOn |
 1106: Restricted (zone %d)
 1106: Restricted (zone %d)
+1107: NoTomb |
 
 
 // @mount
 // @mount
 1119: You have mounted your Dragon.
 1119: You have mounted your Dragon.

+ 6 - 5
conf/msg_conf/map_msg_frn.conf

@@ -923,12 +923,13 @@
 1098: Loadevent |
 1098: Loadevent |
 1099: Src4instance |
 1099: Src4instance |
 1100: Chmautojoin |
 1100: Chmautojoin |
-1101: nousecart |
-1102: noitemconsumption |
-1103: nosumstarmiracle |
-1104: nomineeffect |
-1105: nolockon |
+1101: NoUseCart |
+1102: NoItemConsumption |
+1103: NoSumStarMiracle |
+1104: NoMineEffect |
+1105: NoLockOn |
 1106: Restricted (zone %d)
 1106: Restricted (zone %d)
+1107: NoTomb |
 
 
 // @mount
 // @mount
 1119: Dragon monté.
 1119: Dragon monté.

+ 9 - 6
conf/msg_conf/map_msg_idn.conf

@@ -398,7 +398,9 @@
 380: Penggunaan item gagal. [%s] sedang cooling down. Tunggu %d detik.
 380: Penggunaan item gagal. [%s] sedang cooling down. Tunggu %d detik.
 381: Penggunaan skill gagal. [%s] membutuhkan %dx %s.
 381: Penggunaan skill gagal. [%s] membutuhkan %dx %s.
 382: Kamu terlalu dekat dengan batu atau emperium untuk menggunakan skill ini.
 382: Kamu terlalu dekat dengan batu atau emperium untuk menggunakan skill ini.
-//383-389 kosong
+383: Kamu tidak dapat membuat save point di instance
+384: Kamu tidak dapat membuat memo di isntance
+//385-389 kosong
 //NoAsk
 //NoAsk
 390: Penolakan otomatis diaktifkan.
 390: Penolakan otomatis diaktifkan.
 391: Penolakan otomatis ditidakaktifkan.
 391: Penolakan otomatis ditidakaktifkan.
@@ -932,12 +934,13 @@
 1097: GuildLock | 
 1097: GuildLock | 
 1098: Loadevent |
 1098: Loadevent |
 1100: Chmautojoin |
 1100: Chmautojoin |
-1101: nousecart |
-1102: noitemconsumption |
-1103: nosumstarmiracle |
-1104: nomineeffect |
-1105: nolockon |
+1101: NoUseCart |
+1102: NoItemConsumption |
+1103: NoSumStarMiracle |
+1104: NoMineEffect |
+1105: NoLockOn |
 1106: Restricted (zone %d)
 1106: Restricted (zone %d)
+1107: NoTomb |
 
 
 // @mount
 // @mount
 1119: Kamu sudah menaiki seekor naga.
 1119: Kamu sudah menaiki seekor naga.

+ 6 - 5
conf/msg_conf/map_msg_por.conf

@@ -916,12 +916,13 @@
 1098: Loadevent |
 1098: Loadevent |
 1099: Src4instance |
 1099: Src4instance |
 1100: Chmautojoin |
 1100: Chmautojoin |
-1101: nousecart |
-1102: noitemconsumption |
-1103: nosumstarmiracle |
-1104: nomineeffect |
-1105: nolockon |
+1101: NoUseCart |
+1102: NoItemConsumption |
+1103: NoSumStarMiracle |
+1104: NoMineEffect |
+1105: NoLockOn |
 1106: Restricted (zone %d)
 1106: Restricted (zone %d)
+1107: NoTomb |
 
 
 // @mount
 // @mount
 1119: Você montou um Dragão.
 1119: Você montou um Dragão.

+ 6 - 5
conf/msg_conf/map_msg_rus.conf

@@ -924,12 +924,13 @@
 1098: Loadevent |
 1098: Loadevent |
 1099: Src4instance |
 1099: Src4instance |
 1100: Chmautojoin |
 1100: Chmautojoin |
-1101: nousecart |
-1102: noitemconsumption |
-1103: nosumstarmiracle |
-1104: nomineeffect |
-1105: nolockon |
+1101: NoUseCart |
+1102: NoItemConsumption |
+1103: NoSumStarMiracle |
+1104: NoMineEffect |
+1105: NoLockOn |
 1106: Restricted (zone %d)
 1106: Restricted (zone %d)
+1107: NoTomb |
 
 
 // @mount
 // @mount
 1119: Âû îñåäëàëè Äðàêîíà.
 1119: Âû îñåäëàëè Äðàêîíà.

+ 6 - 5
conf/msg_conf/map_msg_spn.conf

@@ -923,12 +923,13 @@
 1098: Loadevent |
 1098: Loadevent |
 1099: Src4instance |
 1099: Src4instance |
 1100: Chmautojoin |
 1100: Chmautojoin |
-1101: nousecart |
-1102: noitemconsumption |
-1103: nosumstarmiracle |
-1104: nomineeffect |
-1105: nolockon |
+1101: NoUseCart |
+1102: NoItemConsumption |
+1103: NoSumStarMiracle |
+1104: NoMineEffect |
+1105: NoLockOn |
 1106: Restricted (zone %d)
 1106: Restricted (zone %d)
+1107: NoTomb |
 
 
 // @mount
 // @mount
 1119: Te has montado en tu dragón.
 1119: Te has montado en tu dragón.

+ 6 - 5
conf/msg_conf/map_msg_tha.conf

@@ -930,12 +930,13 @@
 1098: Loadevent |
 1098: Loadevent |
 1099: Src4instance |
 1099: Src4instance |
 1100: Chmautojoin |
 1100: Chmautojoin |
-1101: nousecart |
-1102: noitemconsumption |
-1103: nosumstarmiracle |
-1104: nomineeffect |
-1105: nolockon |
+1101: NoUseCart |
+1102: NoItemConsumption |
+1103: NoSumStarMiracle |
+1104: NoMineEffect |
+1105: NoLockOn |
 1106: Restricted (zone %d)
 1106: Restricted (zone %d)
+1107: NoTomb |
 
 
 // @mount
 // @mount
 1119: ¤Ø³ä´é¢Õè Dragon àÃÕºÃéÍÂ.
 1119: ¤Ø³ä´é¢Õè Dragon àÃÕºÃéÍÂ.

+ 7 - 0
doc/mapflags.txt

@@ -217,6 +217,13 @@ Disables locking on a map.
 
 
 ---------------------------------------
 ---------------------------------------
 
 
+*nocommand	<group level>
+
+Disables everyone to use command on a map. If group level is specified, only disables
+player who has group level below it.
+
+---------------------------------------
+
 =====================
 =====================
 | 2. Battle-related |
 | 2. Battle-related |
 =====================
 =====================

+ 245 - 143
doc/script_commands.txt

@@ -997,6 +997,7 @@ From here on, we will have the commands sorted as follow:
 10.- Pet commands.
 10.- Pet commands.
 11.- Homunculus commands.
 11.- Homunculus commands.
 12.- Mercenary commands.
 12.- Mercenary commands.
+13.- Party commands.
 
 
 =====================
 =====================
 |1.- Basic commands.|
 |1.- Basic commands.|
@@ -2267,148 +2268,6 @@ which is a quick way to see if they are married:
 
 
 ---------------------------------------
 ---------------------------------------
 
 
-*getpartyname(<party id>)
-
-This function will return the name of a party that has the specified ID number. 
-If there is no such party ID, "null" will be returned.
-
-Lets say the ID of a party was saved as a global variable:
-
-    // This would return the name of the party from the ID stored in a variable
-    mes "You're in the '"+getpartyname($@var)+"' party, I know!";
-
----------------------------------------
-
-*getpartymember <party id>{,<type>};
-
-This command will find all members of a specified party and returns their names 
-(or character id or account id depending on the value of "type") into an array
-of temporary global variables. There's actually quite a few commands like this
-which will fill a special variable with data upon execution and not do anything
-else.
-
-Upon executing this,
-
-$@partymembername$[] is a global temporary string array which contains all the 
-                     names of these party members
-                     (only set when type is 0 or not specified)
-
-$@partymembercid[]   is a global temporary number array which contains the 
-                     character id of these party members.
-                     (only set when type is 1)
-
-$@partymemberaid[]   is a global temporary number array which contains the 
-                     account id of these party members.
-                     (only set when type is 2)
-
-$@partymembercount   is the number of party members that were found.
-
-The party members will (apparently) be found regardless of whether they are 
-online or offline. Note that the names come in no particular order.
-
-Be sure to use $@partymembercount to go through this array, and not 
-'getarraysize', because it is not cleared between runs of 'getpartymember'. If 
-someone with 7 party members invokes this script, the array would have 7 
-elements. But if another person calls up the NPC, and he has a party of 5, the 
-server will not clear the array for you, overwriting the values instead. So in 
-addition to returning the 5 member names, the 6th and 7th elements from the last 
-call remain, and you will get 5+2 members, of which the last 2 don't belong to 
-the new guy's party. $@partymembercount will always contain the correct number, 
-(5) unlike 'getarraysize()' which will return 7 in this case.
-
-Example 1: list party member names
-
-	// get the party member names
-	getpartymember getcharid(1),0;
-	
-	// It's a good idea to copy the global temporary $@partymember***** 
-	// variables to your own scope variables because if you have pauses in this 
-	// script (sleep, sleep2, next, close2, input, menu, select, or prompt), 
-	// another player could click this NPC, trigger 'getpartymember', and 
-	// overwrite the $@partymember***** variables.
-	set .@count, $@partymembercount;
-	copyarray .@name$[0], $@partymembername$[0], $@partymembercount;
-	
-	// list the party member names
-	for (set .@i,0; .@i < .@count; set .@i, .@i+1) {
-		mes (.@i +1) + ". ^0000FF" + .@name$[.@i] + "^000000";
-	}
-	close;
-
-
-Example 2: check party count (with a 'next' pause), before warping to event
-
-	set .register_num, 5; // How many party members are required?
-	
-	// get the charID and accountID of character's party members
-	getpartymember getcharid(1), 1;
-	getpartymember getcharid(1), 2;
-	
-	if ( $@partymembercount != .register_num ) {
-		mes "Please form a party of "+ .register_num +" to continue";
-		close;
-	}
-	
-	// loop through both and use 'isloggedin' to count online party members
-	for ( set .@i, 0; .@i < $@partymembercount; set .@i, .@i +1 )
-		if ( isloggedin( $@partymemberaid[.@i], $@partymembercid[.@i] ) )
-			set .@count_online, .@count_online +1 ;
-	// We search accountID & charID because a single party can have multiple 
-	// characters from the same account. Without searching through the charID, 
-	// if a player has 2 characters from the same account inside the party but 
-	// only 1 char online, it would count their online char twice.
-	
-	if ( .@count_online != .register_num ) {
-		mes "All your party members must be online to continue";
-		close;
-	}
-	
-	// copy the array to prevent players cheating the system
-	copyarray .@partymembercid, $@partymembercid, .register_num;
-	
-	mes "Are you ready ?";
-	next; // careful here
-	select "Yes";
-	
-	// When a script hits a next, menu, sleep or input that pauses the script, 
-	// players can invite or /leave and make changes in their party. To prevent 
-	// this, we call getpartymember again and compare with the original values.
-	
-	getpartymember getcharid(1), 1;
-	if ( $@partymembercount != .register_num ) {
-		mes "You've made changes to your party !";
-		close;
-	}
-	for ( set .@i, 0; .@i < $@partymembercount; set .@i, .@i +1 ) {
-		if ( .@partymembercid[.@i] != $@partymembercid[.@i] ) {
-			mes "You've made changes to your party !";
-			close;
-		}
-	}
-	
-	// Finally, it's safe to start the event!
-	warpparty "event_map", 0,0, getcharid(1);
-
----------------------------------------
-
-*getpartyleader(<party id>{,<type>})
-
-This function returns some information about the given party-id's leader.
-When type is omitted, the default information retrieved is the leader's name.
-Possible types are:
-
-	1: Leader account id
-	2: Leader character id
-	3: Leader's class
-	4: Leader's current map name
-	5: Leader's current level as stored on the party structure (may not be
-	   current level if leader leveled up recently).
-
-If retrieval fails (leader not found or party does not exist), this function
-returns "null" instead of the character name, and -1 for the other types.
-
----------------------------------------
-
 *getlook(<type>)
 *getlook(<type>)
 
 
 This function will return the number for the current character look value 
 This function will return the number for the current character look value 
@@ -2443,7 +2302,24 @@ Examples:
 
 
 // Outputs IP address of character "Silver".
 // Outputs IP address of character "Silver".
 	mes "Silver's IP: " + getcharip("Silver");
 	mes "Silver's IP: " + getcharip("Silver");
- 
+
+---------------------------------------
+
+*checklang
+
+Returns the language number from player, and -1 if upon error
+
+	0 - English (ENG)
+	1 - Russkiy (RUS)
+	2 - Espanol (SPN)
+	3 - Deutsch (GRM)
+	4 - Hanyu (CHN)
+	5 - Bahasa Malaysia (MAL)
+	6 - Bahasa Indonesia (IDN)
+	7 - Francais (FRN)
+	8 - Portugues Brasileiro (POR)
+	9 - Thai (THA)
+
 ---------------------------------------
 ---------------------------------------
 \\
 \\
 2,2 Item-related commands
 2,2 Item-related commands
@@ -7918,5 +7794,231 @@ for name and 0 for all other types.
 
 
 ---------------------------------------
 ---------------------------------------
 
 
+======================
+|13.- Party commands.|
+======================
+---------------------------------------
+
+*getpartyname(<party id>)
+
+This function will return the name of a party that has the specified ID number. 
+If there is no such party ID, "null" will be returned.
+
+Lets say the ID of a party was saved as a global variable:
+
+    // This would return the name of the party from the ID stored in a variable
+    mes "You're in the '"+getpartyname($@var)+"' party, I know!";
+
+---------------------------------------
+
+*getpartymember <party id>{,<type>};
+
+This command will find all members of a specified party and returns their names 
+(or character id or account id depending on the value of "type") into an array
+of temporary global variables. There's actually quite a few commands like this
+which will fill a special variable with data upon execution and not do anything
+else.
+
+Upon executing this,
+
+$@partymembername$[] is a global temporary string array which contains all the 
+                     names of these party members
+                     (only set when type is 0 or not specified)
+
+$@partymembercid[]   is a global temporary number array which contains the 
+                     character id of these party members.
+                     (only set when type is 1)
+
+$@partymemberaid[]   is a global temporary number array which contains the 
+                     account id of these party members.
+                     (only set when type is 2)
+
+$@partymembercount   is the number of party members that were found.
+
+The party members will (apparently) be found regardless of whether they are 
+online or offline. Note that the names come in no particular order.
+
+Be sure to use $@partymembercount to go through this array, and not 
+'getarraysize', because it is not cleared between runs of 'getpartymember'. If 
+someone with 7 party members invokes this script, the array would have 7 
+elements. But if another person calls up the NPC, and he has a party of 5, the 
+server will not clear the array for you, overwriting the values instead. So in 
+addition to returning the 5 member names, the 6th and 7th elements from the last 
+call remain, and you will get 5+2 members, of which the last 2 don't belong to 
+the new guy's party. $@partymembercount will always contain the correct number, 
+(5) unlike 'getarraysize()' which will return 7 in this case.
+
+Example 1: list party member names
+
+	// get the party member names
+	getpartymember getcharid(1),0;
+	
+	// It's a good idea to copy the global temporary $@partymember***** 
+	// variables to your own scope variables because if you have pauses in this 
+	// script (sleep, sleep2, next, close2, input, menu, select, or prompt), 
+	// another player could click this NPC, trigger 'getpartymember', and 
+	// overwrite the $@partymember***** variables.
+	set .@count, $@partymembercount;
+	copyarray .@name$[0], $@partymembername$[0], $@partymembercount;
+	
+	// list the party member names
+	for (set .@i,0; .@i < .@count; set .@i, .@i+1) {
+		mes (.@i +1) + ". ^0000FF" + .@name$[.@i] + "^000000";
+	}
+	close;
+
+
+Example 2: check party count (with a 'next' pause), before warping to event
+
+	set .register_num, 5; // How many party members are required?
+	
+	// get the charID and accountID of character's party members
+	getpartymember getcharid(1), 1;
+	getpartymember getcharid(1), 2;
+	
+	if ( $@partymembercount != .register_num ) {
+		mes "Please form a party of "+ .register_num +" to continue";
+		close;
+	}
+	
+	// loop through both and use 'isloggedin' to count online party members
+	for ( set .@i, 0; .@i < $@partymembercount; set .@i, .@i +1 )
+		if ( isloggedin( $@partymemberaid[.@i], $@partymembercid[.@i] ) )
+			set .@count_online, .@count_online +1 ;
+	// We search accountID & charID because a single party can have multiple 
+	// characters from the same account. Without searching through the charID, 
+	// if a player has 2 characters from the same account inside the party but 
+	// only 1 char online, it would count their online char twice.
+	
+	if ( .@count_online != .register_num ) {
+		mes "All your party members must be online to continue";
+		close;
+	}
+	
+	// copy the array to prevent players cheating the system
+	copyarray .@partymembercid, $@partymembercid, .register_num;
+	
+	mes "Are you ready ?";
+	next; // careful here
+	select "Yes";
+	
+	// When a script hits a next, menu, sleep or input that pauses the script, 
+	// players can invite or /leave and make changes in their party. To prevent 
+	// this, we call getpartymember again and compare with the original values.
+	
+	getpartymember getcharid(1), 1;
+	if ( $@partymembercount != .register_num ) {
+		mes "You've made changes to your party !";
+		close;
+	}
+	for ( set .@i, 0; .@i < $@partymembercount; set .@i, .@i +1 ) {
+		if ( .@partymembercid[.@i] != $@partymembercid[.@i] ) {
+			mes "You've made changes to your party !";
+			close;
+		}
+	}
+	
+	// Finally, it's safe to start the event!
+	warpparty "event_map", 0,0, getcharid(1);
+
+---------------------------------------
+
+*getpartyleader(<party id>{,<type>})
+
+This function returns some information about the given party-id's leader.
+When type is omitted, the default information retrieved is the leader's name.
+Possible types are:
+
+	1: Leader account id
+	2: Leader character id
+	3: Leader's class
+	4: Leader's current map name
+	5: Leader's current level as stored on the party structure (may not be
+	   current level if leader leveled up recently).
+
+If retrieval fails (leader not found or party does not exist), this function
+returns "null" instead of the character name, and -1 for the other types.
+
+---------------------------------------
+
+*party_create("<party name>"{,<character id>{,<item share>,<item share type>}});
+
+Organizes a party with the attached or specified character as leader. If
+successful, the command returns 1 and sets the global temporary variable
+"$@party_create_id" to the ID of the party created.
+
+Additionally, item sharing options can be provided:
+ - Item Share: 0-Each Take (default), 1-Party Share
+ - Item Share Type: 0-Each Take (default), 1-Even Share
+
+These values are returned upon failure:
+ 0: Unknown error.
+-1: Player not found.
+-2: Player already has a party.
+-3: Party name exists.
+
+---------------------------------------
+
+*party_destroy(<party id>);
+
+Disbands a party. The command returns 1 upon success and 0 upon failure.
+
+---------------------------------------
+
+*party_addmember(<party id>,<character id>);
+
+Adds a player to an existing party.
+
+The command returns 1 upon success, and these values upon failure:
+ 0: Unknown error.
+-1: Player not found.
+-2: Player already has a party.
+-3: Party not found.
+-4: Party is full.
+
+---------------------------------------
+
+*party_delmember({<character id>});
+
+Removes a player from his/her party. If no player is specified, the command
+will run for the invoking player. If that player is the only party member
+remaining, the party will be disbanded.
+
+The command returns 1 upon success, and these values upon failure:
+ 0: Unknown error.
+-1: Player not found.
+-2: Player is not in the party.
+
+---------------------------------------
+
+*party_changeleader(<party id>,<character id>);
+
+Transfers leadership of a party to the specified character. The original
+party leader doesn't need be online.
+
+The command returns 1 upon success, and these values upon failure:
+ 0: Unknown error.
+-1: Party not found.
+-2: Player not found.
+-3: Player is not in the party.
+-4: Player is already party leader
+
+---------------------------------------
+
+*party_changeoption(<party id>,<option>,<flag>);
+
+Changes a party option.
+
+Valid options are:
+ 0 - Exp Share (flags: 0-Each Take, 1-Even Share)
+ 1 - Item Share (flags: 0-Each Take, 1-Party Share)
+ 2 - Item Share Type (flags: 0-Each Take, 1-Even Share)
+
+The command returns 1 upon success, and these values upon failure:
+ 0: Invalid option.
+-1: Party not found.
+
+---------------------------------------
+
 Whew.
 Whew.
 That's about all of them.
 That's about all of them.

+ 40 - 36
src/map/atcommand.c

@@ -3956,15 +3956,17 @@ ACMD_FUNC(mapinfo) {
 	if (map[m_id].flag.chmautojoin)
 	if (map[m_id].flag.chmautojoin)
 		strcat(atcmd_output, msg_txt(sd,1100)); // Chmautojoin |
 		strcat(atcmd_output, msg_txt(sd,1100)); // Chmautojoin |
 	if (map[m_id].flag.nousecart)
 	if (map[m_id].flag.nousecart)
-		strcat(atcmd_output, msg_txt(sd,1101)); // nousecart |
+		strcat(atcmd_output, msg_txt(sd,1101)); // NoUsecart |
 	if (map[m_id].flag.noitemconsumption)
 	if (map[m_id].flag.noitemconsumption)
-		strcat(atcmd_output, msg_txt(sd,1102)); // noitemconsumption |
+		strcat(atcmd_output, msg_txt(sd,1102)); // NoItemConsumption |
 	if (map[m_id].flag.nosumstarmiracle)
 	if (map[m_id].flag.nosumstarmiracle)
-		strcat(atcmd_output, msg_txt(sd,1103)); // nosumstarmiracle |
+		strcat(atcmd_output, msg_txt(sd,1103)); // NoSumStarMiracle |
 	if (map[m_id].flag.nomineeffect)
 	if (map[m_id].flag.nomineeffect)
-		strcat(atcmd_output, msg_txt(sd,1104)); // nomineeffect |
+		strcat(atcmd_output, msg_txt(sd,1104)); // NoMineEffect |
 	if (map[m_id].flag.nolockon)
 	if (map[m_id].flag.nolockon)
-		strcat(atcmd_output, msg_txt(sd,1105)); // nolockon |
+		strcat(atcmd_output, msg_txt(sd,1105)); // NoLockOn |
+	if (map[m_id].flag.notomb)
+		strcat(atcmd_output, msg_txt(sd,1107)); // NoTomb |
 	clif_displaymessage(fd, atcmd_output);
 	clif_displaymessage(fd, atcmd_output);
 
 
 	switch (list) {
 	switch (list) {
@@ -5719,7 +5721,7 @@ ACMD_FUNC(changeleader)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if (party_changeleader(sd, map_nick2sd((char *) message)))
+	if (party_changeleader(sd, map_nick2sd((char *) message),NULL))
 		return 0;
 		return 0;
 	return -1;
 	return -1;
 }
 }
@@ -7647,39 +7649,41 @@ ACMD_FUNC(mapflag) {
 	if (!message || !*message || (sscanf(message, "%99s %hd", flag_name, &flag) < 1)) {
 	if (!message || !*message || (sscanf(message, "%99s %hd", flag_name, &flag) < 1)) {
 		clif_displaymessage(sd->fd,msg_txt(sd,1311)); // Enabled Mapflags in this map:
 		clif_displaymessage(sd->fd,msg_txt(sd,1311)); // Enabled Mapflags in this map:
 		clif_displaymessage(sd->fd,"----------------------------------");
 		clif_displaymessage(sd->fd,"----------------------------------");
-		checkflag(town);
-		checkflag(autotrade);			checkflag(allowks);				checkflag(nomemo);		checkflag(noteleport);
-		checkflag(noreturn);			checkflag(monster_noteleport);	checkflag(nosave);		checkflag(nobranch);
-		checkflag(noexppenalty);		checkflag(pvp);					checkflag(pvp_noparty);	checkflag(pvp_noguild);
-		checkflag(pvp_nightmaredrop);	checkflag(pvp_nocalcrank);		checkflag(gvg_castle);	checkflag(gvg);
-		checkflag(gvg_dungeon);			checkflag(gvg_noparty);			checkflag(battleground);checkflag(nozenypenalty);
-		checkflag(notrade);				checkflag(noskill);				checkflag(nowarp);		checkflag(nowarpto);
-		checkflag(noicewall);			checkflag(snow);				checkflag(clouds);		checkflag(clouds2);
-		checkflag(fog);					checkflag(fireworks);			checkflag(sakura);		checkflag(leaves);
-		checkflag(nogo);				checkflag(nobaseexp);
-		checkflag(nojobexp);			checkflag(nomobloot);			checkflag(nomvploot);	checkflag(nightenabled);
-		checkflag(restricted);			checkflag(nodrop);				checkflag(novending);	checkflag(loadevent);
-		checkflag(nochat);				checkflag(partylock);			checkflag(guildlock);	checkflag(notomb);
+		checkflag(town);				checkflag(autotrade);			checkflag(allowks);				checkflag(nomemo);
+		checkflag(noteleport);			checkflag(noreturn);			checkflag(monster_noteleport);	checkflag(nosave);
+		checkflag(nobranch);			checkflag(noexppenalty);		checkflag(pvp);					checkflag(pvp_noparty);
+		checkflag(pvp_noguild);			checkflag(pvp_nightmaredrop);	checkflag(pvp_nocalcrank);		checkflag(gvg_castle);
+		checkflag(gvg);					checkflag(gvg_dungeon);			checkflag(gvg_noparty);			checkflag(battleground);
+		checkflag(nozenypenalty);		checkflag(notrade);				checkflag(noskill);				checkflag(nowarp);
+		checkflag(nowarpto);			checkflag(noicewall);			checkflag(snow);				checkflag(clouds);
+		checkflag(clouds2);				checkflag(fog);					checkflag(fireworks);			checkflag(sakura);
+		checkflag(leaves);				checkflag(nogo);				checkflag(nobaseexp);			checkflag(nojobexp);
+		checkflag(nomobloot);			checkflag(nomvploot);			checkflag(nightenabled);		checkflag(restricted);
+		checkflag(nodrop);				checkflag(novending);			checkflag(loadevent);			checkflag(nochat);
+		checkflag(partylock);			checkflag(guildlock);			checkflag(reset);				checkflag(chmautojoin);
+		checkflag(nousecart);			checkflag(noitemconsumption);	checkflag(nosumstarmiracle);	checkflag(nomineeffect);
+		checkflag(nolockon);			checkflag(notomb);
 		clif_displaymessage(sd->fd," ");
 		clif_displaymessage(sd->fd," ");
 		clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
 		clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
 		clif_displaymessage(sd->fd,msg_txt(sd,1313)); // Type "@mapflag available" to list the available mapflags.
 		clif_displaymessage(sd->fd,msg_txt(sd,1313)); // Type "@mapflag available" to list the available mapflags.
 		return 1;
 		return 1;
 	}
 	}
 	for (i = 0; flag_name[i]; i++) flag_name[i] = (char)tolower(flag_name[i]); //lowercase
 	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);		setflag(pvp_noguild);
-	setflag(pvp_nightmaredrop);	setflag(pvp_nocalcrank);	setflag(gvg_castle);		setflag(gvg);
-	setflag(gvg_dungeon);		setflag(gvg_noparty);		setflag(battleground);		setflag(nozenypenalty);
-	setflag(notrade);			setflag(noskill);			setflag(nowarp);			setflag(nowarpto);
-	setflag(noicewall);			setflag(snow);				setflag(clouds);			setflag(clouds2);
-	setflag(fog);				setflag(fireworks);			setflag(sakura);			setflag(leaves);
-	setflag(nogo);				setflag(nobaseexp);
-	setflag(nojobexp);			setflag(nomobloot);			setflag(nomvploot);			setflag(nightenabled);
-	setflag(restricted);		setflag(nodrop);			setflag(novending);			setflag(loadevent);
-	setflag(nochat);			setflag(partylock);			setflag(guildlock);			setflag(notomb);
+	
+	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);
+	setflag(pvp_noguild);		setflag(pvp_nightmaredrop);	setflag(pvp_nocalcrank);		setflag(gvg_castle);
+	setflag(gvg);				setflag(gvg_dungeon);		setflag(gvg_noparty);			setflag(battleground);
+	setflag(nozenypenalty);		setflag(notrade);			setflag(noskill);				setflag(nowarp);
+	setflag(nowarpto);			setflag(noicewall);			setflag(snow);					setflag(clouds);
+	setflag(clouds2);			setflag(fog);				setflag(fireworks);				setflag(sakura);
+	setflag(leaves);			setflag(nogo);				setflag(nobaseexp);				setflag(nojobexp);
+	setflag(nomobloot);			setflag(nomvploot);			setflag(nightenabled);			setflag(restricted);
+	setflag(nodrop);			setflag(novending);			setflag(loadevent);				setflag(nochat);
+	setflag(partylock);			setflag(guildlock);			setflag(reset);					setflag(chmautojoin);
+	setflag(nousecart);			setflag(noitemconsumption);	setflag(nosumstarmiracle);		setflag(nomineeffect);
+	setflag(nolockon);			setflag(notomb);
 
 
 	clif_displaymessage(sd->fd,msg_txt(sd,1314)); // Invalid flag name or flag.
 	clif_displaymessage(sd->fd,msg_txt(sd,1314)); // Invalid flag name or flag.
 	clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
 	clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
@@ -7689,9 +7693,9 @@ ACMD_FUNC(mapflag) {
 	clif_displaymessage(sd->fd,"nobranch, noexppenalty, pvp, pvp_noparty, pvp_noguild, pvp_nightmaredrop,");
 	clif_displaymessage(sd->fd,"nobranch, noexppenalty, pvp, pvp_noparty, pvp_noguild, pvp_nightmaredrop,");
 	clif_displaymessage(sd->fd,"pvp_nocalcrank, gvg_castle, gvg, gvg_dungeon, gvg_noparty, battleground,");
 	clif_displaymessage(sd->fd,"pvp_nocalcrank, gvg_castle, gvg, gvg_dungeon, gvg_noparty, battleground,");
 	clif_displaymessage(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
 	clif_displaymessage(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
-	clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot,");
-	clif_displaymessage(sd->fd,"nomvploot, nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock,");
-	clif_displaymessage(sd->fd,"guildlock, notomb");
+	clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot, nomvploot,");
+	clif_displaymessage(sd->fd,"nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock, guildlock,");
+	clif_displaymessage(sd->fd,"reset, chmautojoin, nousecart, noitemconsumption, nosumstarmiracle, nolockon, notomb");
 
 
 #undef checkflag
 #undef checkflag
 #undef setflag
 #undef setflag

+ 1 - 1
src/map/clif.c

@@ -11767,7 +11767,7 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd){
 /// Changes Party Leader (CZ_CHANGE_GROUP_MASTER).
 /// Changes Party Leader (CZ_CHANGE_GROUP_MASTER).
 /// 07da <account id>.L
 /// 07da <account id>.L
 void clif_parse_PartyChangeLeader(int fd, struct map_session_data* sd){
 void clif_parse_PartyChangeLeader(int fd, struct map_session_data* sd){
-	party_changeleader(sd, map_id2sd(RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])));
+	party_changeleader(sd, map_id2sd(RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])),NULL);
 }
 }
 
 
 
 

+ 82 - 41
src/map/party.c

@@ -23,6 +23,7 @@
 #include "skill.h"
 #include "skill.h"
 #include "status.h"
 #include "status.h"
 #include "itemdb.h"
 #include "itemdb.h"
+#include "mapreg.h"
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
@@ -34,6 +35,7 @@ static DBMap* party_booking_db; // int char_id -> struct party_booking_ad_info*
 static unsigned long party_booking_nextid = 1;
 static unsigned long party_booking_nextid = 1;
 
 
 int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
 int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
+int party_create_byscript;
 
 
 /*==========================================
 /*==========================================
  * Fills the given party_member structure according to the sd provided.
  * Fills the given party_member structure according to the sd provided.
@@ -160,7 +162,7 @@ int party_create(struct map_session_data *sd,char *name,int item,int item2)
 	if( sd->status.party_id > 0 || sd->party_joining || sd->party_creating )
 	if( sd->status.party_id > 0 || sd->party_joining || sd->party_creating )
 	{// already associated with a party
 	{// already associated with a party
 		clif_party_created(sd,2);
 		clif_party_created(sd,2);
-		return 0;
+		return -2;
 	}
 	}
 
 
 	sd->party_creating = true;
 	sd->party_creating = true;
@@ -168,10 +170,9 @@ int party_create(struct map_session_data *sd,char *name,int item,int item2)
 	party_fill_member(&leader, sd, 1);
 	party_fill_member(&leader, sd, 1);
 
 
 	intif_create_party(&leader,name,item,item2);
 	intif_create_party(&leader,name,item,item2);
-	return 0;
+	return 1;
 }
 }
 
 
-
 void party_created(int account_id,int char_id,int fail,int party_id,char *name)
 void party_created(int account_id,int char_id,int fail,int party_id,char *name)
 {
 {
 	struct map_session_data *sd;
 	struct map_session_data *sd;
@@ -189,11 +190,14 @@ void party_created(int account_id,int char_id,int fail,int party_id,char *name)
 	if( !fail ) {
 	if( !fail ) {
 		sd->status.party_id = party_id;
 		sd->status.party_id = party_id;
 		clif_party_created(sd,0); //Success message
 		clif_party_created(sd,0); //Success message
-		//We don't do any further work here because the char-server sends a party info packet right after creating the party.
-	} else {
-		clif_party_created(sd,1); // "party name already exists"
+		//We don't do any further work here because the char-server sends a party info packet right after creating the party
+		if(party_create_byscript) {	//returns party id in $@party_create_id if party is created by script
+			mapreg_setreg(add_str("$@party_create_id"),party_id);
+			party_create_byscript = 0;
+		}
 	}
 	}
-
+	else
+		clif_party_created(sd,1); // "party name already exists"
 }
 }
 
 
 int party_request_info(int party_id, int char_id)
 int party_request_info(int party_id, int char_id)
@@ -393,7 +397,7 @@ int party_invite(struct map_session_data *sd,struct map_session_data *tsd)
 	return 1;
 	return 1;
 }
 }
 
 
-void party_reply_invite(struct map_session_data *sd,int party_id,int flag)
+int party_reply_invite(struct map_session_data *sd,int party_id,int flag)
 {
 {
 	struct map_session_data* tsd;
 	struct map_session_data* tsd;
 	struct party_member member;
 	struct party_member member;
@@ -402,7 +406,7 @@ void party_reply_invite(struct map_session_data *sd,int party_id,int flag)
 	{// forged
 	{// forged
 		sd->party_invite = 0;
 		sd->party_invite = 0;
 		sd->party_invite_account = 0;
 		sd->party_invite_account = 0;
-		return;
+		return 0;
 	}
 	}
 	tsd = map_id2sd(sd->party_invite_account);
 	tsd = map_id2sd(sd->party_invite_account);
 
 
@@ -411,6 +415,7 @@ void party_reply_invite(struct map_session_data *sd,int party_id,int flag)
 		sd->party_joining = true;
 		sd->party_joining = true;
 		party_fill_member(&member, sd, 0);
 		party_fill_member(&member, sd, 0);
 		intif_party_addmember(sd->party_invite, &member);
 		intif_party_addmember(sd->party_invite, &member);
+		return 1;
 	}
 	}
 	else
 	else
 	{// rejected or failure
 	{// rejected or failure
@@ -418,7 +423,9 @@ void party_reply_invite(struct map_session_data *sd,int party_id,int flag)
 		sd->party_invite_account = 0;
 		sd->party_invite_account = 0;
 		if( tsd != NULL )
 		if( tsd != NULL )
 			clif_party_inviteack(tsd,sd->status.name,1);
 			clif_party_inviteack(tsd,sd->status.name,1);
+		return 0;
 	}
 	}
+	return 0;
 }
 }
 
 
 //Invoked when a player joins:
 //Invoked when a player joins:
@@ -616,19 +623,47 @@ int party_broken(int party_id)
 	}
 	}
 
 
 	idb_remove(party_db,party_id);
 	idb_remove(party_db,party_id);
-	return 0;
+	return 1;
 }
 }
 
 
 int party_changeoption(struct map_session_data *sd,int exp,int item)
 int party_changeoption(struct map_session_data *sd,int exp,int item)
 {
 {
 	nullpo_ret(sd);
 	nullpo_ret(sd);
 
 
-	if( sd->status.party_id==0)
-		return 0;
+	if( sd->status.party_id == 0 )
+		return -3;
 	intif_party_changeoption(sd->status.party_id,sd->status.account_id,exp,item);
 	intif_party_changeoption(sd->status.party_id,sd->status.account_id,exp,item);
 	return 0;
 	return 0;
 }
 }
 
 
+//options: 0-exp, 1-item share, 2-pickup distribution
+int party_setoption(struct party_data *party, int option, int flag)
+{
+	int i;
+	ARR_FIND(0,MAX_PARTY,i,party->party.member[i].leader);
+	if(i >= MAX_PARTY)
+		return 0;
+	switch(option) {
+		case 0:
+			intif_party_changeoption(party->party.party_id,party->party.member[i].account_id,flag,party->party.item);
+			break;
+		case 1:
+			if(flag) flag = party->party.item|1;
+			else flag = party->party.item&~1;
+			intif_party_changeoption(party->party.party_id,party->party.member[i].account_id,party->party.exp,flag);
+			break;
+		case 2:
+			if(flag) flag = party->party.item|2;
+			else flag = party->party.item&~2;
+			intif_party_changeoption(party->party.party_id,party->party.member[i].account_id,party->party.exp,flag);
+			break;
+		default:
+			return 0;
+			break;
+	}
+	return 1;
+}
+
 int party_optionchanged(int party_id,int account_id,int exp,int item,int flag)
 int party_optionchanged(int party_id,int account_id,int exp,int item,int flag)
 {
 {
 	struct party_data *p;
 	struct party_data *p;
@@ -647,55 +682,61 @@ int party_optionchanged(int party_id,int account_id,int exp,int item,int flag)
 	return 0;
 	return 0;
 }
 }
 
 
-bool party_changeleader(struct map_session_data *sd, struct map_session_data *tsd)
+int party_changeleader(struct map_session_data *sd, struct map_session_data *tsd, struct party_data *p)
 {
 {
-	struct party_data *p;
 	int mi, tmi;
 	int mi, tmi;
 
 
-	if (!sd || !sd->status.party_id)
-		return false;
+	if ( !p ) {
 
 
-	if (!tsd || tsd->status.party_id != sd->status.party_id) {
-		clif_displaymessage(sd->fd, msg_txt(sd,283));
-		return false;
-	}
+		if (!sd || !sd->status.party_id)
+			return -1;
 
 
-	if( map[sd->bl.m].flag.partylock )
-	{
-		clif_displaymessage(sd->fd, msg_txt(sd,287));
-		return false;
-	}
+		if (!tsd || tsd->status.party_id != sd->status.party_id) {
+			clif_displaymessage(sd->fd, msg_txt(sd,283));
+			return -3;
+		}
 
 
-	if ((p = party_search(sd->status.party_id)) == NULL)
-		return false;
+		if ( map[sd->bl.m].flag.partylock )
+		{
+			clif_displaymessage(sd->fd, msg_txt(sd,287));
+			return 0;
+		}
 
 
-	ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd );
-	if (mi == MAX_PARTY)
-		return false; //Shouldn't happen
+		if ((p = party_search(sd->status.party_id)) == NULL )
+			return -1;
 
 
-	if (!p->party.member[mi].leader)
-	{	//Need to be a party leader.
-		clif_displaymessage(sd->fd, msg_txt(sd,282));
-		return false;
-	}
+		ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd );
+		if (mi == MAX_PARTY)
+			return 0; //Shouldn't happen
 
 
-	ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd);
-	if (tmi == MAX_PARTY)
-		return false; //Shouldn't happen
+		if (!p->party.member[mi].leader)
+		{	//Need to be a party leader.
+			clif_displaymessage(sd->fd, msg_txt(sd,282));
+			return 0;
+		}
+
+		ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd);
+		if (tmi == MAX_PARTY)
+			return 0; //Shouldn't happen
+	}
+	else {
+		ARR_FIND(0,MAX_PARTY,mi,p->party.member[mi].leader);
+		ARR_FIND(0,MAX_PARTY,tmi,p->data[tmi].sd ==  tsd);
+	}
 
 
 	//Change leadership.
 	//Change leadership.
 	p->party.member[mi].leader = 0;
 	p->party.member[mi].leader = 0;
-	if (p->data[mi].sd->fd)
+	if (p->data[mi].sd && p->data[mi].sd->fd)
 		clif_displaymessage(p->data[mi].sd->fd, msg_txt(sd,284));
 		clif_displaymessage(p->data[mi].sd->fd, msg_txt(sd,284));
 
 
 	p->party.member[tmi].leader = 1;
 	p->party.member[tmi].leader = 1;
-	if (p->data[tmi].sd->fd)
+	if (p->data[tmi].sd && p->data[tmi].sd->fd)
 		clif_displaymessage(p->data[tmi].sd->fd, msg_txt(sd,285));
 		clif_displaymessage(p->data[tmi].sd->fd, msg_txt(sd,285));
 
 
 	//Update info.
 	//Update info.
 	intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id);
 	intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id);
 	clif_party_info(p,NULL);
 	clif_party_info(p,NULL);
-	return true;
+	return 1;
 }
 }
 
 
 /// Invoked (from char-server) when a party member
 /// Invoked (from char-server) when a party member

+ 6 - 2
src/map/party.h

@@ -47,6 +47,8 @@ struct party_booking_ad_info {
 	struct party_booking_detail p_detail;
 	struct party_booking_detail p_detail;
 };
 };
 
 
+extern int party_create_byscript;
+
 void do_init_party(void);
 void do_init_party(void);
 void do_final_party(void);
 void do_final_party(void);
 struct party_data* party_search(int party_id);
 struct party_data* party_search(int party_id);
@@ -63,14 +65,16 @@ int party_member_added(int party_id,int account_id,int char_id,int flag);
 int party_leave(struct map_session_data *sd);
 int party_leave(struct map_session_data *sd);
 int party_removemember(struct map_session_data *sd,int account_id,char *name);
 int party_removemember(struct map_session_data *sd,int account_id,char *name);
 int party_member_withdraw(int party_id,int account_id,int char_id);
 int party_member_withdraw(int party_id,int account_id,int char_id);
-void party_reply_invite(struct map_session_data *sd,int party_id,int flag);
+int party_reply_invite(struct map_session_data *sd,int party_id,int flag);
+#define party_add_member(party_id,sd) party_reply_invite(sd,party_id,1)
 int party_recv_noinfo(int party_id, int char_id);
 int party_recv_noinfo(int party_id, int char_id);
 int party_recv_info(struct party* sp, int char_id);
 int party_recv_info(struct party* sp, int char_id);
 int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv);
 int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv);
 int party_broken(int party_id);
 int party_broken(int party_id);
 int party_optionchanged(int party_id,int account_id,int exp,int item,int flag);
 int party_optionchanged(int party_id,int account_id,int exp,int item,int flag);
 int party_changeoption(struct map_session_data *sd,int exp,int item);
 int party_changeoption(struct map_session_data *sd,int exp,int item);
-bool party_changeleader(struct map_session_data *sd, struct map_session_data *t_sd);
+int party_setoption(struct party_data *party, int option, int flag);
+int party_changeleader(struct map_session_data *sd, struct map_session_data *t_sd, struct party_data *p);
 void party_send_movemap(struct map_session_data *sd);
 void party_send_movemap(struct map_session_data *sd);
 void party_send_levelup(struct map_session_data *sd);
 void party_send_levelup(struct map_session_data *sd);
 int party_send_logout(struct map_session_data *sd);
 int party_send_logout(struct map_session_data *sd);

+ 2 - 1
src/map/pc.c

@@ -9879,7 +9879,7 @@ static bool pc_readdb_job_exp(char* fields[], int columns, int current)
  *------------------------------------------*/
  *------------------------------------------*/
 int pc_readdb(void)
 int pc_readdb(void)
 {
 {
-	int i,j,k, entries;
+	int i,k, entries;
 	FILE *fp;
 	FILE *fp;
 	char line[24000];
 	char line[24000];
 
 
@@ -9894,6 +9894,7 @@ int pc_readdb(void)
 #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
 #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
 	sv_readdb(db_path, "re/level_penalty.txt", ',', 4, 4, -1, &pc_readdb_levelpenalty);
 	sv_readdb(db_path, "re/level_penalty.txt", ',', 4, 4, -1, &pc_readdb_levelpenalty);
 	for( k=1; k < 3; k++ ){ // fill in the blanks
 	for( k=1; k < 3; k++ ){ // fill in the blanks
+		int j;
 		for( j = 0; j < RC_MAX; j++ ){
 		for( j = 0; j < RC_MAX; j++ ){
 			int tmp = 0;
 			int tmp = 0;
 			for( i = 0; i < MAX_LEVEL*2; i++ ){
 			for( i = 0; i < MAX_LEVEL*2; i++ ){

+ 230 - 0
src/map/script.c

@@ -17573,6 +17573,227 @@ BUILDIN_FUNC(countbound)
 	return 0;
 	return 0;
 }
 }
 
 
+/*==========================================
+ * party_create "<party name>"{,<char id>{,<item share: 0-no. 1-yes>{,<item share type: 0-favorite. 1-shared>}}};
+ * Return values:
+ *	-3	- party name is exist
+ *	-2	- player is in party already
+ *	-1	- player is not found
+ *	0	- unknown error
+ *	1	- success, will return party id $@party_create_id
+ *------------------------------------------*/
+BUILDIN_FUNC(party_create)
+{
+	char party_name[NAME_LENGTH];
+	int item1 = 0, item2 = 0;
+	TBL_PC *sd;
+
+	if( (!script_hasdata(st,3) && !(sd = script_rid2sd(st))) || (script_hasdata(st,3) && !(sd = map_charid2sd(script_getnum(st,3)))) ) {
+		script_pushint(st,-1);
+		return 0;
+	}
+
+	if( sd->status.party_id ) {
+		script_pushint(st,-2);
+		return 0;
+	}
+
+	safestrncpy(party_name,script_getstr(st,2),NAME_LENGTH);
+	trim(party_name);
+	if( party_searchname(party_name) ) {
+		script_pushint(st,-3);
+		return 0;
+	}
+	if( script_getnum(st,4) )
+		item1 = 1;
+	if( script_getnum(st,5) )
+		item2 = 1;
+
+	party_create_byscript = 1;
+	script_pushint(st,party_create(sd,party_name,item1,item2));
+	return 0;
+}
+
+/*==========================================
+ * party_addmember <party id>,<char id>;
+ * Adds player to specified party
+ * Return values:
+ *	-4	- party is full
+ *	-3	- party is not found
+ *	-2	- player is in party already
+ *	-1	- player is not found
+ *	0	- unknown error
+ *	1	- success
+ *------------------------------------------*/
+BUILDIN_FUNC(party_addmember)
+{
+	int party_id = script_getnum(st,2);
+	TBL_PC *sd;
+	struct party_data *party;
+
+	if( !(sd = map_charid2sd(script_getnum(st,3))) ) {
+		script_pushint(st,-1);
+		return 0;
+	}
+
+	if( sd->status.party_id ) {
+		script_pushint(st,-2);
+		return 0;
+	}
+
+	if( !(party = party_search(party_id)) ) {
+		script_pushint(st,-3);
+		return 0;
+	}
+
+	if( party->party.count >= MAX_PARTY ) {
+		script_pushint(st,-4);
+		return 0;
+	}
+	sd->party_invite = party_id;
+	script_pushint(st,party_add_member(party_id,sd));
+	return 0;
+}
+
+/*==========================================
+ * party_delmember {<char id>};
+ * Removes player from his/her party
+ * Return values:
+ *	-2	- player is not in party
+ *	-1	- player is not found
+ *	0	- unknown error
+ *	1	- success
+ *------------------------------------------*/
+BUILDIN_FUNC(party_delmember)
+{
+	TBL_PC *sd;
+
+	if( (!script_hasdata(st,2) && !(sd = script_rid2sd(st))) || (script_hasdata(st,2) && !(sd = map_charid2sd(script_getnum(st,2)))) ) {
+		script_pushint(st,-1);
+		return 0;
+	}	
+	if( !sd->status.party_id ) {
+		script_pushint(st,-2);
+		return 0;
+	}
+	script_pushint(st,party_leave(sd));
+	return 0;
+}
+
+/*==========================================
+ * party_changeleader <party id>,<char id>;
+ * Can change party leader even the leader is not online
+ * Return values:
+ *	-4	- selected player is party leader already
+ *	-3	- player is not in this party
+ *	-2	- player is not found
+ *	-1	- party is not found
+ *	0	- unknown error
+ *	1	- success
+ *------------------------------------------*/
+BUILDIN_FUNC(party_changeleader)
+{
+	int i, party_id = script_getnum(st,2);
+	TBL_PC *sd = NULL;
+	TBL_PC *tsd = NULL;
+	struct party_data *party = NULL;
+
+	if( !(party = party_search(party_id)) ) {
+		script_pushint(st,-1);
+		return 0;
+	}
+
+	if( !(tsd = map_charid2sd(script_getnum(st,3))) ) {
+		script_pushint(st,-2);
+		return 0;
+	}
+
+	if( tsd->status.party_id != party_id ) {
+		script_pushint(st,-3);
+		return 0;
+	}
+
+	ARR_FIND(0,MAX_PARTY,i,party->party.member[i].leader);
+	if( i >= MAX_PARTY ) {	//this is should impossible!
+		script_pushint(st,0);
+		return 0;
+	}
+	if( party->data[i].sd == tsd ) {
+		script_pushint(st,-4);
+		return 0;
+	}
+
+	script_pushint(st,party_changeleader(sd,tsd,party));
+	return 0;
+}
+
+/*==========================================
+ * party_changeoption <party id>,<option>,<flag>;
+ * Return values:
+ *	-1	- party is not found
+ *	0	- invalid option
+ *	1	- success
+ *------------------------------------------*/
+BUILDIN_FUNC(party_changeoption)
+{
+	struct party_data *party;
+
+	if( !(party = party_search(script_getnum(st,2))) ) {
+		script_pushint(st,-1);
+		return 0;
+	}
+	script_pushint(st,party_setoption(party,script_getnum(st,3),script_getnum(st,4)));
+	return 0;
+}
+
+/*==========================================
+ * party_destroy <party id>;
+ * Destroys party with party id. If char id is specified, destroys player's party
+ * Return values:
+ *	0	- failed
+ *	1	- success
+ *------------------------------------------*/
+BUILDIN_FUNC(party_destroy)
+{
+	int i;
+	struct party_data *party;
+
+	if( !(party = party_search(script_getnum(st,2))) ) {
+		script_pushint(st,0);
+		return 0;
+	}
+
+	ARR_FIND(0,MAX_PARTY,i,party->party.member[i].leader);
+	if( i >= MAX_PARTY || !party->data[i].sd ) { //leader not online
+		int j;
+		for( j = 0; j < MAX_PARTY; j++ ) {
+			TBL_PC *sd = party->data[j].sd;
+			if(sd)
+				party_member_withdraw(party->party.party_id,sd->status.account_id,sd->status.char_id);
+			else if( party->party.member[j].char_id )
+				intif_party_leave(party->party.party_id,party->party.member[j].account_id,party->party.member[j].char_id);
+		}
+		party_broken(party->party.party_id);
+		script_pushint(st,1);
+	}
+	else	//leader leave = party broken
+		script_pushint(st,party_leave(party->data[i].sd));
+	return 0;
+}
+ 
+BUILDIN_FUNC(checklang)
+{
+	TBL_PC* sd = NULL;
+
+	if( (sd = script_rid2sd(st)) == NULL ) {
+		script_pushint(st,-1);
+		return 0;
+	}
+
+	script_pushint(st,sd->langtype);
+	return 0;
+}
+
 // declarations that were supposed to be exported from npc_chat.c
 // declarations that were supposed to be exported from npc_chat.c
 #ifdef PCRE_SUPPORT
 #ifdef PCRE_SUPPORT
 BUILDIN_FUNC(defpattern);
 BUILDIN_FUNC(defpattern);
@@ -18019,6 +18240,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(delequip,"i"),
 	BUILDIN_DEF(delequip,"i"),
 	BUILDIN_DEF(sit,"?"),
 	BUILDIN_DEF(sit,"?"),
 	BUILDIN_DEF(stand,"?"),
 	BUILDIN_DEF(stand,"?"),
+	BUILDIN_DEF(checklang,""),
 	/**
 	/**
 	 * @commands (script based)
 	 * @commands (script based)
 	 **/
 	 **/
@@ -18038,5 +18260,13 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF2(getitem,"getitembound","vii?"),
 	BUILDIN_DEF2(getitem,"getitembound","vii?"),
 	BUILDIN_DEF2(getitem2,"getitembound2","viiiiiiiii?"),
 	BUILDIN_DEF2(getitem2,"getitembound2","viiiiiiiii?"),
 	BUILDIN_DEF(countbound, "?"),
 	BUILDIN_DEF(countbound, "?"),
+
+	// Party related
+	BUILDIN_DEF(party_create,"s???"),
+	BUILDIN_DEF(party_addmember,"ii"),
+	BUILDIN_DEF(party_delmember,"?"),
+	BUILDIN_DEF(party_changeleader,"ii"),
+	BUILDIN_DEF(party_changeoption,"iii"),
+	BUILDIN_DEF(party_destroy,"i"),
 	{NULL,NULL,NULL},
 	{NULL,NULL,NULL},
 };
 };

+ 3 - 1
src/map/skill.c

@@ -16458,8 +16458,10 @@ int skill_produce_mix (struct map_session_data *sd, uint16 skill_id, int nameid,
 				y = sd->status.inventory[j].amount;
 				y = sd->status.inventory[j].amount;
 				if(y>x)y=x;
 				if(y>x)y=x;
 				pc_delitem(sd,j,y,0,0,LOG_TYPE_PRODUCE);
 				pc_delitem(sd,j,y,0,0,LOG_TYPE_PRODUCE);
-			} else
+			} else {
 				ShowError("skill_produce_mix: material item error\n");
 				ShowError("skill_produce_mix: material item error\n");
+				return 0;
+			}
 
 
 			x-=y;
 			x-=y;
 		}while( j>=0 && x>0 );
 		}while( j>=0 && x>0 );