Просмотр исходного кода

* Removed the dependency on winsock.h for definitions, it's all winsock2.h now.
* Minor documentation/re-coding in chat.c.
* More work on ticket #41.

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

FlavioJS 18 лет назад
Родитель
Сommit
bc088a5ad8

+ 3 - 0
Changelog-Trunk.txt

@@ -4,6 +4,9 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2007/05/06
+	* Removed the dependency on winsock.h for definitions, it's all winsock2.h now.
+	* Minor documentation/re-coding in chat.c.
+	* More work on ticket #41. [FLavioJS]
 	* Fixed Red Pouch overriding nobranch mapflag [Playtester]
 	* Attempt to fix Kyrie Eleison not castable on enemy players [Playtester]
 	- please test, I can't double client to test it in pvp

+ 6 - 3
src/char_sql/inter.h

@@ -4,6 +4,10 @@
 #ifndef _INTER_SQL_H_
 #define _INTER_SQL_H_
 
+#ifndef _CBASETYPES_H_
+#include "../common/cbasetypes.h"
+#endif
+
 int inter_init_sql(const char *file);
 void inter_final(void);
 int inter_parse_frommap(int fd);
@@ -21,9 +25,8 @@ int inter_log(char *fmt,...);
 extern unsigned int party_share_level;
 extern char inter_log_filename[1024];
 
-#ifdef __WIN32
-//Windows.h need to be included before mysql.h
-#include <windows.h>
+#ifdef WIN32
+#include <winsock2.h>
 #endif
 //add include for DBMS(mysql)
 #include <mysql.h>

+ 4 - 0
src/common/cbasetypes.h

@@ -307,4 +307,8 @@ typedef char bool;
 #define TOLOWER(c) (tolower((unsigned char)(c)))
 #define TOUPPER(c) (toupper((unsigned char)(c)))
 
+//////////////////////////////////////////////////////////////////////////
+// length of a static array
+#define ARRAYLENGTH(A) ( sizeof(A)/sizeof((A)[0]) )
+
 #endif /* _CBASETYPES_H_ */

+ 5 - 3
src/common/lock.c

@@ -1,6 +1,10 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 
+#include "../common/cbasetypes.h"
+#include "../common/showmsg.h"
+#include "lock.h"
+
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
@@ -11,10 +15,8 @@
 #define F_OK   0x0
 #define R_OK   0x4
 #endif
-#include "lock.h"
-#include "showmsg.h"
 
-#ifndef _WIN32
+#ifndef WIN32
 	#define exists(filename) (!access(filename, F_OK))
 #else
 // could be speed up maybe?

+ 3 - 1
src/common/plugin.h

@@ -4,7 +4,9 @@
 #ifndef	_PLUGIN_H_
 #define _PLUGIN_H_
 
-#include "cbasetypes.h"
+#ifndef _CBASETYPES_H_
+#include "../common/cbasetypes.h"
+#endif
 
 ////// Plugin functions ///////////////
 

+ 5 - 0
src/common/plugins.h

@@ -4,12 +4,17 @@
 #ifndef	_PLUGINS_H_
 #define _PLUGINS_H_
 
+#ifndef _CBASETYPES_H_
+#include "../common/cbasetypes.h"
+#endif
+
 #include "../common/plugin.h"
 
 ////// Dynamic Link Library functions ///////////////
 
 #ifdef WIN32
 
+	#define WIN32_LEAN_AND_MEAN
 	#include <windows.h>
 	#define DLL_OPEN(x)		LoadLibrary(x)
 	#define DLL_SYM(x,y,z)	(FARPROC)(x) = GetProcAddress(y,z)

+ 5 - 4
src/common/showmsg.c

@@ -1,16 +1,17 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 
+#include "../common/cbasetypes.h"
+#include "../common/utils.h"
+#include "showmsg.h"
+
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
 #include <time.h>
 #include <stdlib.h> // atexit
-#include "cbasetypes.h"
-#include "showmsg.h"
-#include "utils.h"
 
-#ifdef _WIN32
+#ifdef WIN32
 	#define WIN32_LEAN_AND_MEAN
 	#include <windows.h>
 

+ 13 - 12
src/common/socket.c

@@ -1,14 +1,22 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 
+#include "../common/cbasetypes.h"
+#include "../common/mmo.h"
+#include "../common/timer.h"
+#include "../common/malloc.h"
+#include "../common/showmsg.h"
+#include "../common/strlib.h"
+#include "socket.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
 
-#ifdef __WIN32
-	#define WIN32_LEAN_AND_MEAN
-	#include <windows.h>
+#ifdef WIN32
+	//#define WIN32_LEAN_AND_MEAN
+	//#include <windows.h>
 	#include <winsock2.h>
 	#include <io.h>
 #else
@@ -29,7 +37,7 @@
 #endif
 
 // portability layer 
-#ifdef _WIN32
+#ifdef WIN32
 	typedef int socklen_t;
 
 	#define s_errno WSAGetLastError()
@@ -52,13 +60,6 @@
 	#define S_ECONNABORTED ECONNABORTED
 #endif
 
-#include "../common/socket.h"
-#include "../common/mmo.h"
-#include "../common/timer.h"
-#include "../common/malloc.h"
-#include "../common/showmsg.h"
-#include "../common/strlib.h"
-
 fd_set readfds;
 int fd_max;
 time_t last_tick;
@@ -561,7 +562,7 @@ int do_sendrecv(int next)
 		fd_max = ret;
 	}
 
-#ifdef _WIN32
+#ifdef WIN32
 	// on windows, enumerating all members of the fd_set is way faster if we access the internals
 	for(i=0;i<(int)rfd.fd_count;i++)
 	{

+ 5 - 4
src/common/socket.h

@@ -4,10 +4,12 @@
 #ifndef	_SOCKET_H_
 #define _SOCKET_H_
 
+#ifndef _CBASETYPES_H_
+#include "../common/cbasetypes.h"
+#endif
+
 #ifdef WIN32
-	#define WIN32_LEAN_AND_MEAN
-	#include <windows.h>
-	#include <winsock.h>
+	#include <winsock2.h>
 	typedef long in_addr_t;
 #else
 	#include <sys/types.h>
@@ -15,7 +17,6 @@
 	#include <netinet/in.h>
 #endif
 
-#include "../common/cbasetypes.h"
 #include <time.h>
 
 

+ 9 - 8
src/common/timer.c

@@ -3,11 +3,17 @@
 
 #include <sys/types.h>
 
-#ifdef __WIN32
-#define __USE_W32_SOCKETS
+#include "../common/cbasetypes.h"
+#include "../common/malloc.h"
+#include "../common/showmsg.h"
+#include "timer.h"
+
+#ifdef WIN32
+//#define __USE_W32_SOCKETS
 // Well, this won't last another 30++ years (where conversion will truncate).
 //#define _USE_32BIT_TIME_T	// use 32 bit time variables on 64bit windows
-#include <windows.h>
+//#include <windows.h>
+#include <winsock2.h>
 #else
 #include <sys/socket.h>
 #include <sys/time.h>
@@ -18,11 +24,6 @@
 #include <string.h>
 #include <time.h>
 
-#include "../common/cbasetypes.h"
-#include "../common/malloc.h"
-#include "../common/showmsg.h"
-#include "timer.h"
-
 // タイマー間隔の最小値。モンスターの大量召還時、多数のクライアント接続時に
 // サーバーが反応しなくなる場合は、TIMER_MIN_INTERVAL を増やしてください。
 

+ 8 - 3
src/common/timer.h

@@ -4,10 +4,15 @@
 #ifndef	_TIMER_H_
 #define	_TIMER_H_
 
-#ifdef __WIN32
+#ifndef _CBASETYPES_H_
+#include "../common/cbasetypes.h"
+#endif
+
+#ifdef WIN32
 /* We need winsock lib to have timeval struct - windows is weirdo */
-#define __USE_W32_SOCKETS
-#include <windows.h>
+//#define __USE_W32_SOCKETS
+//#include <windows.h>
+#include <winsock2.h>
 #endif
 
 #define BASE_TICK 5

+ 3 - 0
src/login_sql/login.c

@@ -22,6 +22,9 @@
 #include "login.h"
 
 //add include for DBMS(mysql)
+#ifdef WIN32
+#include <winsock2.h>
+#endif
 #include <mysql.h>
 
 struct Login_Config {

+ 72 - 84
src/map/chat.c

@@ -1,18 +1,19 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 
-#include <stdio.h>
-#include <string.h>
-
+#include "../common/cbasetypes.h"
 #include "../common/nullpo.h"
 #include "../common/malloc.h"
 #include "battle.h"
-#include "chat.h"
 #include "map.h"
 #include "clif.h"
 #include "pc.h"
 #include "npc.h"
 #include "atcommand.h"
+#include "chat.h"
+
+#include <stdio.h>
+#include <string.h>
 
 int chat_triggerevent(struct chat_data *cd);
 
@@ -107,57 +108,58 @@ int chat_joinchat(struct map_session_data* sd, int chatid, char* pass)
 	return 0;
 }
 
-/*==========================================
- * チャットルームから抜ける
- *------------------------------------------
- */
-int chat_leavechat(struct map_session_data *sd)
+/// Removes the user from the chat room.
+int chat_leavechat(struct map_session_data* sd)
 {
-	struct chat_data *cd;
-	int i,leavechar;
+	struct chat_data* cd;
+	int i;
+	int leavechar;
 
 	nullpo_retr(1, sd);
 
-	cd=(struct chat_data*)map_id2bl(sd->chatID);
-	if(cd==NULL) {
-		sd->chatID = 0;
+	cd = (struct chat_data*)map_id2bl(sd->chatID);
+	if( cd == NULL )
+	{
+		pc_setchatid(sd, 0);
 		return 1;
 	}
 
-	for(i = 0,leavechar=-1;i < cd->users;i++){
+	for( i = 0, leavechar = -1; i < cd->users; i++ )
+	{
 		if(cd->usersd[i] == sd){
 			leavechar=i;
 			break;
 		}
 	}
-	if(leavechar<0)
-  	{	//Not found in the chatroom?
-		sd->chatID = 0;
+	if( leavechar < 0 )
+	{// Not found in the chatroom?
+		pc_setchatid(sd, 0);
 		return -1;
 	}
 
-	if(leavechar==0 && cd->users>1 && (*cd->owner)->type==BL_PC){
-		// 所有者だった&他に人が居る&PCのチャット
-		clif_changechatowner(cd,cd->usersd[1]);
-		clif_clearchat(cd,0);
+	if( leavechar == 0 && cd->users > 1 && (*cd->owner)->type == BL_PC )
+	{// Change ownership to the next user
+		clif_changechatowner(cd, cd->usersd[1]);
+		clif_clearchat(cd, 0);
 	}
 
 	// 抜けるPCにも送るのでusersを減らす前に実行
-	clif_leavechat(cd,sd);
+	clif_leavechat(cd, sd);
 
 	cd->users--;
-	pc_setchatid(sd,0);
+	pc_setchatid(sd, 0);
 
-	if(cd->users == 0 && (*cd->owner)->type==BL_PC){
-		//Delete empty chatroom
-		clif_clearchat(cd,0);
+	if( cd->users == 0 && (*cd->owner)->type==BL_PC )
+	{// Delete empty chatroom
+		clif_clearchat(cd, 0);
 		map_delobject(cd->bl.id);
 		return 1;
 	}
-	for(i=leavechar;i < cd->users;i++)
-		cd->usersd[i] = cd->usersd[i+1];
+	for( i = leavechar; i < cd->users; i++ )
+		cd->usersd[i] = cd->usersd[i + 1];
 
-	if(leavechar==0 && (*cd->owner)->type==BL_PC){
+	if( leavechar == 0 && (*cd->owner)->type==BL_PC )
+	{
 		//Adjust Chat location after owner has been changed.
 		map_delblock( &cd->bl );
 		cd->bl.x=cd->usersd[0]->bl.x;
@@ -272,11 +274,8 @@ int chat_kickchat(struct map_session_data *sd,char *kickusername)
 	return -1;
 }
 
-/*==========================================
- * npcチャットルーム作成
- *------------------------------------------
- */
-int chat_createnpcchat(struct npc_data *nd,int limit,int pub,int trigger,const char* title,int titlelen,const char *ev)
+/// Creates a chat room for the npc.
+int chat_createnpcchat(struct npc_data* nd,int limit,int pub,int trigger,const char* title,int titlelen,const char *ev)
 {
 	struct chat_data *cd;
 
@@ -285,45 +284,40 @@ int chat_createnpcchat(struct npc_data *nd,int limit,int pub,int trigger,const c
 	cd = (struct chat_data *) aMalloc(sizeof(struct chat_data));
 
 	cd->limit = cd->trigger = limit;
-	if(trigger>0)
+	if( trigger > 0 )
 		cd->trigger = trigger;
 	cd->pub = pub;
 	cd->users = 0;
-	memcpy(cd->pass,"",1);
-	if(titlelen>=sizeof(cd->title)-1) titlelen=sizeof(cd->title)-1;
-	memcpy(cd->title,title,titlelen);
-	cd->title[titlelen]=0;
-
-	cd->bl.m = nd->bl.m;
-	cd->bl.x = nd->bl.x;
-	cd->bl.y = nd->bl.y;
+	cd->pass[0] = '\0';
+	if( titlelen > sizeof(cd->title) - 1 )
+		titlelen = sizeof(cd->title) - 1;
+	memcpy(cd->title, title, titlelen);
+	cd->title[titlelen] = '\0';
+
+	cd->bl.m    = nd->bl.m;
+	cd->bl.x    = nd->bl.x;
+	cd->bl.y    = nd->bl.y;
 	cd->bl.type = BL_CHAT;
-	cd->bl.prev= cd->bl.next = NULL;
-	cd->owner_ = (struct block_list *)nd;
-	cd->owner = &cd->owner_;
-	if (strlen(ev) > 49)
-	{	//npc_event is a char[50]	[Skotlex]
-		memcpy(cd->npc_event,ev,49);
-		cd->npc_event[49] = '\0';
-	} else
-		memcpy(cd->npc_event,ev,strlen(ev)+1); //Include the \0
-
+	cd->bl.prev = cd->bl.next = NULL;
+	cd->owner_  = (struct block_list *)nd;
+	cd->owner   = &cd->owner_;
+	strncpy(cd->npc_event, ev, ARRAYLENGTH(cd->npc_event));
+	cd->npc_event[ARRAYLENGTH(cd->npc_event)-1] = '\0';
 	cd->bl.id = map_addobject(&cd->bl);	
-	if(cd->bl.id==0){
+	if( cd->bl.id == 0)
+	{
 		aFree(cd);
 		return 0;
 	}
-	nd->chat_id=cd->bl.id;
+	nd->chat_id = cd->bl.id;
 
-	clif_dispchat(cd,0);
+	clif_dispchat(cd, 0);
 
 	return 0;
 }
-/*==========================================
- * npcチャットルーム削除
- *------------------------------------------
- */
-int chat_deletenpcchat(struct npc_data *nd)
+
+/// Removes the chatroom from the npc.
+int chat_deletenpcchat(struct npc_data* nd)
 {
 	struct chat_data *cd;
 
@@ -331,9 +325,9 @@ int chat_deletenpcchat(struct npc_data *nd)
 	nullpo_retr(0, cd=(struct chat_data*)map_id2bl(nd->chat_id));
 	
 	chat_npckickall(cd);
-	clif_clearchat(cd,0);
+	clif_clearchat(cd, 0);
 	map_delobject(cd->bl.id);	// freeまでしてくれる
-	nd->chat_id=0;
+	nd->chat_id = 0;
 	
 	return 0;
 }
@@ -346,44 +340,38 @@ int chat_triggerevent(struct chat_data *cd)
 {
 	nullpo_retr(0, cd);
 
-	if(cd->users>=cd->trigger && cd->npc_event[0])
+	if( cd->users >= cd->trigger && cd->npc_event[0] )
 		npc_event_do(cd->npc_event);
 	return 0;
 }
 
-/*==========================================
- * イベントの有効化
- *------------------------------------------
- */
-int chat_enableevent(struct chat_data *cd)
+/// Enables the event of the chat room.
+/// At most, 127 users are needed to trigger the event.
+int chat_enableevent(struct chat_data* cd)
 {
 	nullpo_retr(0, cd);
 
-	cd->trigger&=0x7f;
+	cd->trigger &= 0x7f;
 	chat_triggerevent(cd);
 	return 0;
 }
-/*==========================================
- * イベントの無効化
- *------------------------------------------
- */
-int chat_disableevent(struct chat_data *cd)
+
+/// Disables the event of the chat room
+int chat_disableevent(struct chat_data* cd)
 {
 	nullpo_retr(0, cd);
 
-	cd->trigger|=0x80;
+	cd->trigger |= 0x80;
 	return 0;
 }
-/*==========================================
- * チャットルームから全員蹴り出す
- *------------------------------------------
- */
-int chat_npckickall(struct chat_data *cd)
+
+/// Kicks all the users for the chat room.
+int chat_npckickall(struct chat_data* cd)
 {
 	nullpo_retr(0, cd);
 
-	while(cd->users>0){
+	while( cd->users > 0 )
 		chat_leavechat(cd->usersd[cd->users-1]);
-	}
+
 	return 0;
 }

+ 11 - 5
src/map/map.h

@@ -4,7 +4,9 @@
 #ifndef _MAP_H_
 #define _MAP_H_
 
-#include <stdarg.h>
+#ifndef _CBASETYPES_H_
+#include "../common/cbasetypes.h"
+#endif
 #include "../common/mmo.h"
 #include "../common/mapindex.h"
 #include "../common/db.h"
@@ -12,6 +14,8 @@
 #include "itemdb.h" // MAX_ITEMGROUP
 #include "status.h" // SC_MAX
 
+#include <stdarg.h>
+
 //Uncomment to enable the Cell Stack Limit mod.
 //It's only config is the battle_config cell_stack_limit.
 //Only chars affected are those defined in BL_CHAR (mobs and players currently)
@@ -387,8 +391,10 @@ struct status_change_entry {
 struct status_change {
 	struct status_change_entry data[SC_MAX];
 	short count;
-	unsigned short opt1,opt2;
-	unsigned int opt3, option; //Note that older packet versions use short here.
+	unsigned short opt1;// body state
+	unsigned short opt2;// health state
+	unsigned int opt3;
+	unsigned int option;// effect state
 };
 
 struct vending {
@@ -1394,8 +1400,8 @@ extern char *map_server_dns;
 
 #ifndef TXT_ONLY
 
-#ifdef _WIN32
-#include <windows.h> // SOCKET
+#ifdef WIN32
+#include <winsock2.h>
 #endif
 #include <mysql.h>
 

+ 287 - 180
src/map/script.c

@@ -4026,12 +4026,12 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(skillpointcount,""),
 	BUILDIN_DEF(changebase,"i"),
 	BUILDIN_DEF(changesex,""),
-	BUILDIN_DEF(waitingroom,"si*"),
-	BUILDIN_DEF(delwaitingroom,"*"),
-	BUILDIN_DEF2(waitingroomkickall,"kickwaitingroomall","*"),
-	BUILDIN_DEF(enablewaitingroomevent,"*"),
-	BUILDIN_DEF(disablewaitingroomevent,"*"),
-	BUILDIN_DEF(getwaitingroomstate,"i*"),
+	BUILDIN_DEF(waitingroom,"si??"),
+	BUILDIN_DEF(delwaitingroom,"?"),
+	BUILDIN_DEF2(waitingroomkickall,"kickwaitingroomall","?"),
+	BUILDIN_DEF(enablewaitingroomevent,"?"),
+	BUILDIN_DEF(disablewaitingroomevent,"?"),
+	BUILDIN_DEF(getwaitingroomstate,"i?"),
 	BUILDIN_DEF(warpwaitingpc,"sii?"),
 	BUILDIN_DEF(attachrid,"i"),
 	BUILDIN_DEF(detachrid,""),
@@ -6797,11 +6797,12 @@ BUILDIN_FUNC(statusup2)
 }
 
 /// See 'doc/item_bonus.txt'
-/// bonus <bonus type>,<val1>
-/// bonus2 <bonus type>,<val1>,<val2>
-/// bonus3 <bonus type>,<val1>,<val2>,<val3>
-/// bonus4 <bonus type>,<val1>,<val2>,<val3>,<val4>
-/// bonus5 <bonus type>,<val1>,<val2>,<val3>,<val4>,<val5>
+///
+/// bonus <bonus type>,<val1>;
+/// bonus2 <bonus type>,<val1>,<val2>;
+/// bonus3 <bonus type>,<val1>,<val2>,<val3>;
+/// bonus4 <bonus type>,<val1>,<val2>,<val3>,<val4>;
+/// bonus5 <bonus type>,<val1>,<val2>,<val3>,<val4>,<val5>;
 BUILDIN_FUNC(bonus)
 {
 	int type;
@@ -6856,8 +6857,13 @@ BUILDIN_FUNC(bonus)
 }
 
 /// Changes the level of a player skill.
-/// skill <skill id>,<level>{,<flag>}
-/// @see pc_skill() for flag
+/// <flag> defaults to 1
+/// <flag>=0 : set the level of the skill
+/// <flag>=1 : set the temporary level of the skill
+/// <flag>=2 : add to the level of the skill
+///
+/// skill <skill id>,<level>,<flag>
+/// skill <skill id>,<level>
 BUILDIN_FUNC(skill)
 {
 	int id;
@@ -6879,8 +6885,12 @@ BUILDIN_FUNC(skill)
 }
 
 /// Changes the level of a player skill.
-/// addtoskill <skill id>,<level>{,<flag>}
-/// @see pc_skill() for flag
+/// like skill, but <flag> defaults to 2
+///
+/// addtoskill <skill id>,<amount>,<flag>
+/// addtoskill <skill id>,<amount>
+///
+/// @see skill
 BUILDIN_FUNC(addtoskill)
 {
 	int id;
@@ -6901,8 +6911,9 @@ BUILDIN_FUNC(addtoskill)
 	return 0;
 }
 
-/// Increases the level of the guild skill.
-/// guildskill <skill id>,<level>
+/// Increases the level of a guild skill.
+///
+/// guildskill <skill id>,<amount>;
 BUILDIN_FUNC(guildskill)
 {
 	int id;
@@ -6923,6 +6934,7 @@ BUILDIN_FUNC(guildskill)
 }
 
 /// Returns the level of the player skill.
+///
 /// getskilllv(<skill id>) -> <level>
 BUILDIN_FUNC(getskilllv)
 {
@@ -6940,6 +6952,7 @@ BUILDIN_FUNC(getskilllv)
 }
 
 /// Returns the level of the guild skill.
+///
 /// getgdskilllv(<guild id>,<skill id>) -> <level>
 BUILDIN_FUNC(getgdskilllv)
 {
@@ -6959,7 +6972,10 @@ BUILDIN_FUNC(getgdskilllv)
 }
 
 /// Returns the 'basic_skill_check' setting.
-/// basicskillcheck() -> <setting>
+/// This config determines if the server check the skill level of NV_BASIC 
+/// before alowing the basic actions.
+///
+/// basicskillcheck() -> <bool>
 BUILDIN_FUNC(basicskillcheck)
 {
 	script_pushint(st, battle_config.basic_skill_check);
@@ -6967,6 +6983,7 @@ BUILDIN_FUNC(basicskillcheck)
 }
 
 /// Returns the GM level of the player.
+///
 /// getgmlevel() -> <level>
 BUILDIN_FUNC(getgmlevel)
 {
@@ -6982,6 +6999,7 @@ BUILDIN_FUNC(getgmlevel)
 }
 
 /// Terminates the execution of this script instance.
+///
 /// end
 BUILDIN_FUNC(end)
 {
@@ -6989,7 +7007,8 @@ BUILDIN_FUNC(end)
 	return 0;
 }
 
-/// Checks if the player has that option.
+/// Checks if the player has that effect state (option).
+///
 /// checkoption(<option>) -> <bool>
 BUILDIN_FUNC(checkoption)
 {
@@ -7009,7 +7028,8 @@ BUILDIN_FUNC(checkoption)
 	return 0;
 }
 
-/// Checks if the player is in that opt1 state.
+/// Checks if the player is in that body state (opt1).
+///
 /// checkoption1(<opt1>) -> <bool>
 BUILDIN_FUNC(checkoption1)
 {
@@ -7029,7 +7049,8 @@ BUILDIN_FUNC(checkoption1)
 	return 0;
 }
 
-/// Checks if the player has that opt2.
+/// Checks if the player has that health state (opt2).
+///
 /// checkoption2(<opt2>) -> <bool>
 BUILDIN_FUNC(checkoption2)
 {
@@ -7049,8 +7070,13 @@ BUILDIN_FUNC(checkoption2)
 	return 0;
 }
 
-/// Changes the option of the player.
-/// setoption <option number>{,<flag>}
+/// Changes the effect state (option) of the player.
+/// <flag> defaults to 1
+/// <flag>=0 : removes the option
+/// <flag>=other : adds the option
+///
+/// setoption <option>,<flag>;
+/// setoption <option>;
 BUILDIN_FUNC(setoption)
 {
 	int option;
@@ -7079,7 +7105,9 @@ BUILDIN_FUNC(setoption)
 }
 
 /// Returns if the player has a cart.
+///
 /// checkcart() -> <bool>
+///
 /// @author Valaris
 BUILDIN_FUNC(checkcart)
 {
@@ -7098,7 +7126,16 @@ BUILDIN_FUNC(checkcart)
 }
 
 /// Sets the cart of the player.
-/// setcart {<type>}
+/// <type> defaults to 1
+/// <type>=0 : removes the cart
+/// <type>=1 : Normal cart
+/// <type>=2 : Wooden cart
+/// <type>=3 : Covered cart with flowers and ferns
+/// <type>=4 : Wooden cart with a Panda doll on the back
+/// <type>=5 : Normal cart with bigger wheels, a roof and a banner on the back
+///
+/// setcart <type>;
+/// setcart;
 BUILDIN_FUNC(setcart)
 {
 	int type = 1;
@@ -7116,7 +7153,9 @@ BUILDIN_FUNC(setcart)
 }
 
 /// Returns if the player has a falcon.
+///
 /// checkfalcon() -> <bool>
+///
 /// @author Valaris
 BUILDIN_FUNC(checkfalcon)
 {
@@ -7135,7 +7174,10 @@ BUILDIN_FUNC(checkfalcon)
 }
 
 /// Sets if the player has a falcon or not.
-/// setfalcon {<flag>}
+/// <flag> defaults to 1
+///
+/// setfalcon <flag>;
+/// setfalcon;
 BUILDIN_FUNC(setfalcon)
 {
 	int flag = 1;
@@ -7154,7 +7196,9 @@ BUILDIN_FUNC(setfalcon)
 }
 
 /// Returns if the player is riding.
+///
 /// checkriding() -> <bool>
+///
 /// @author Valaris
 BUILDIN_FUNC(checkriding)
 {
@@ -7173,7 +7217,10 @@ BUILDIN_FUNC(checkriding)
 }
 
 /// Sets if the player is riding.
-/// setriding {<flag>}
+/// <flag> defaults to 1
+///
+/// setriding <flag>;
+/// setriding;
 BUILDIN_FUNC(setriding)
 {
 	int flag = 1;
@@ -7191,6 +7238,7 @@ BUILDIN_FUNC(setriding)
 }
 
 /// Sets the save point of the player.
+///
 /// save "<map name>",<x>,<y>
 /// savepoint "<map name>",<x>,<y>
 BUILDIN_FUNC(savepoint)
@@ -8186,30 +8234,6 @@ BUILDIN_FUNC(disablenpc)
 	return 0;
 }
 
-BUILDIN_FUNC(enablearena)	// Added by RoVeRT
-{
-	struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
-	struct chat_data *cd;
-
-
-	if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL)
-		return 0;
-
-	npc_enable(nd->name,1);
-	nd->arenaflag=1;
-
-	if(cd->users>=cd->trigger && cd->npc_event[0])
-		npc_timer_event(cd->npc_event);
-
-	return 0;
-}
-BUILDIN_FUNC(disablearena)	// Added by RoVeRT
-{
-	struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
-	nd->arenaflag=0;
-
-	return 0;
-}
 /*==========================================
  * 隠れているNPCの表示
  *------------------------------------------
@@ -8586,40 +8610,6 @@ BUILDIN_FUNC(changesex)
 	return 0;
 }
 
-/*==========================================
- * npcチャット作成
- *------------------------------------------
- */
-BUILDIN_FUNC(waitingroom)
-{
-	const char *name,*ev="";
-	int limit, trigger = 0,pub=1;
-	name=script_getstr(st,2);
-	limit= script_getnum(st,3);
-	if(limit==0)
-		pub=3;
-
-	if( script_hasdata(st,5) ){
-		struct script_data* data=script_getdata(st,5);
-		get_val(st,data);
-		if( data_isstring(data) ){
-			// eathena仕様
-			trigger=script_getnum(st,4);
-			ev=script_getstr(st,5);
-		}else{
-			// 新Athena仕様(旧Athena仕様と互換性あり)
-			ev=script_getstr(st,4);
-			trigger=script_getnum(st,5);
-		}
-	}else{
-		// 旧Athena仕様
-		if( script_hasdata(st,4) )
-			ev=script_getstr(st,4);
-	}
-	chat_createnpcchat( (struct npc_data *)map_id2bl(st->oid),
-		limit,pub,trigger,name,(int)strlen(name)+1,ev);
-	return 0;
-}
 /*==========================================
  * Works like 'announce' but outputs in the common chat window
  *------------------------------------------
@@ -8643,164 +8633,281 @@ BUILDIN_FUNC(globalmes)
 
 	return 0;
 }
-/*==========================================
- * npcチャット削除
- *------------------------------------------
- */
+
+/////////////////////////////////////////////////////////////////////
+// NPC waiting room (chat room)
+//
+
+/// Creates a waiting room (chat room) for this npc.
+///
+/// waitingroom "<title>",<limit>,<trigger>,"<event>";
+/// waitingroom "<title>",<limit>,"<event>",<trigger>;
+/// waitingroom "<title>",<limit>,"<event>";
+/// waitingroom "<title>",<limit>;
+BUILDIN_FUNC(waitingroom)
+{
+	struct npc_data* nd;
+	const char* title;
+	const char* ev = "";
+	int limit;
+	int trigger = 0;
+	int pub = 1;
+
+	title = script_getstr(st, 2);
+	limit = script_getnum(st, 3);
+	if( limit == 0 )
+		pub = 3;
+
+	if( script_hasdata(st,5) )
+	{
+		struct script_data* data = script_getdata(st, 5);
+		get_val(st, data);
+		if( data_isstring(data) )
+		{// ,"<event>",<trigger>
+			trigger = script_getnum(st, 4);
+			ev = script_getstr(st, 5);
+		}
+		else
+		{// ,<trigger>,"<event>"
+			ev = script_getstr(st, 4);
+			trigger=script_getnum(st,5);
+		}
+	}
+	else if( script_hasdata(st,4) )
+	{// ,"<event>"
+		ev = script_getstr(st, 4);
+	}
+	if( (nd=(struct npc_data *)map_id2bl(st->oid)) != NULL )
+		chat_createnpcchat(nd, limit, pub, trigger, title, (int)strlen(title), ev);
+	return 0;
+}
+
+/// Removes the waiting room of the current or target npc.
+///
+/// delwaitingroom "<npc_name>";
+/// delwaitingroom;
 BUILDIN_FUNC(delwaitingroom)
 {
-	struct npc_data *nd;
+	struct npc_data* nd;
 	if( script_hasdata(st,2) )
-		nd=npc_name2id(script_getstr(st,2));
+		nd = npc_name2id(script_getstr(st, 2));
 	else
-		nd=(struct npc_data *)map_id2bl(st->oid);
-	chat_deletenpcchat(nd);
+		nd = (struct npc_data *)map_id2bl(st->oid);
+	if( nd != NULL )
+		chat_deletenpcchat(nd);
 	return 0;
 }
-/*==========================================
- * npcチャット全員蹴り出す
- *------------------------------------------
- */
+
+/// Kicks all the players from the waiting room of the current or target npc.
+///
+/// kickwaitingroomall "<npc_name>";
+/// kickwaitingroomall;
 BUILDIN_FUNC(waitingroomkickall)
 {
-	struct npc_data *nd;
-	struct chat_data *cd;
+	struct npc_data* nd;
+	struct chat_data* cd;
 
 	if( script_hasdata(st,2) )
-		nd=npc_name2id(script_getstr(st,2));
+		nd = npc_name2id(script_getstr(st,2));
 	else
-		nd=(struct npc_data *)map_id2bl(st->oid);
+		nd = (struct npc_data *)map_id2bl(st->oid);
 
-	if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL )
-		return 0;
-	chat_npckickall(cd);
+	if( nd != NULL && (cd=(struct chat_data *)map_id2bl(nd->chat_id)) != NULL )
+		chat_npckickall(cd);
 	return 0;
 }
 
-/*==========================================
- * npcチャットイベント有効化
- *------------------------------------------
- */
+/// Enables the waiting room event of the current or target npc.
+///
+/// enablewaitingroomevent "<npc_name>";
+/// enablewaitingroomevent;
 BUILDIN_FUNC(enablewaitingroomevent)
 {
-	struct npc_data *nd;
-	struct chat_data *cd;
+	struct npc_data* nd;
+	struct chat_data* cd;
 
 	if( script_hasdata(st,2) )
-		nd=npc_name2id(script_getstr(st,2));
+		nd = npc_name2id(script_getstr(st, 2));
 	else
-		nd=(struct npc_data *)map_id2bl(st->oid);
+		nd = (struct npc_data *)map_id2bl(st->oid);
 
-	if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL )
-		return 0;
-	chat_enableevent(cd);
+	if( nd != NULL && (cd=(struct chat_data *)map_id2bl(nd->chat_id)) != NULL )
+		chat_enableevent(cd);
 	return 0;
 }
 
-/*==========================================
- * npcチャットイベント無効化
- *------------------------------------------
- */
+/// Disables the waiting room event of the current or target npc.
+///
+/// disablewaitingroomevent "<npc_name>";
+/// disablewaitingroomevent;
 BUILDIN_FUNC(disablewaitingroomevent)
 {
 	struct npc_data *nd;
 	struct chat_data *cd;
 
 	if( script_hasdata(st,2) )
-		nd=npc_name2id(script_getstr(st,2));
+		nd = npc_name2id(script_getstr(st, 2));
 	else
-		nd=(struct npc_data *)map_id2bl(st->oid);
+		nd = (struct npc_data *)map_id2bl(st->oid);
 
-	if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL )
-		return 0;
-	chat_disableevent(cd);
+	if( nd != NULL && (cd=(struct chat_data *)map_id2bl(nd->chat_id)) != NULL )
+		chat_disableevent(cd);
 	return 0;
 }
-/*==========================================
- * npcチャット状態所得
- *------------------------------------------
- */
+
+/// Returns info on the waiting room of the current or target npc.
+/// Returns -1 if the type unknown
+/// <type>=0 : current number of users
+/// <type>=1 : maximum number of users allowed
+/// <type>=2 : the number of users that trigger the event
+/// <type>=3 : if the trigger is disabled
+/// <type>=4 : the title of the waiting room
+/// <type>=5 : the password of the waiting room
+/// <type>=16 : the name of the waiting room event
+/// <type>=32 : if the waiting room is full
+/// <type>=33 : if there are enough users to trigger the event
+///
+/// getwaitingroomstate(<type>,"<npc_name>") -> <info>
+/// getwaitingroomstate(<type>) -> <info>
 BUILDIN_FUNC(getwaitingroomstate)
 {
 	struct npc_data *nd;
 	struct chat_data *cd;
-	int val=0,type;
-	type=script_getnum(st,2);
+	int val=0;
+	int type;
+
+	type = script_getnum(st,2);
 	if( script_hasdata(st,3) )
-		nd=npc_name2id(script_getstr(st,3));
+		nd = npc_name2id(script_getstr(st, 3));
 	else
-		nd=(struct npc_data *)map_id2bl(st->oid);
+		nd = (struct npc_data *)map_id2bl(st->oid);
 
-	if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL ){
-		script_pushint(st,-1);
+	if( nd == NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id)) == NULL )
+	{
+		script_pushint(st, -1);
 		return 0;
 	}
 
-	switch(type){
-	case 0: val=cd->users; break;
-	case 1: val=cd->limit; break;
-	case 2: val=cd->trigger&0x7f; break;
-	case 3: val=((cd->trigger&0x80)>0); break;
-	case 32: val=(cd->users >= cd->limit); break;
-	case 33: val=(cd->users >= cd->trigger); break;
+	switch(type)
+	{
+	case 0:  script_pushint(st, cd->users); break;
+	case 1:  script_pushint(st, cd->limit); break;
+	case 2:  script_pushint(st, cd->trigger&0x7f); break;
+	case 3:  script_pushint(st, ((cd->trigger&0x80)!=0)); break;
+	case 4:  script_pushconststr(st, cd->title); break;
+	case 5:  script_pushconststr(st, cd->pass); break;
+	case 16: script_pushconststr(st, cd->npc_event);break;
+	case 32: script_pushint(st, (cd->users >= cd->limit)); break;
+	case 33: script_pushint(st, (cd->users >= cd->trigger)); break;
+	default: script_pushint(st, -1); break;
+	}
+	return 0;
+}
+
+/// Warps the trigger or target amount of players to the target map and position.
+/// Players are automatically removed from the waiting room.
+/// Those waiting the longest will get warped first.
+/// The target map can be "Random" for a random position in the current map,
+/// and "SavePoint" for the savepoint map+position.
+/// The map flag noteleport of the current map is only considered when teleporting to the savepoint.
+///
+/// The id's of the teleported players are put into the array $@warpwaitingpc[]
+/// The total number of teleported players is put into $@warpwaitingpcnum
+///
+/// warpwaitingpc "<map name>",<x>,<y>,<number of players>;
+/// warpwaitingpc "<map name>",<x>,<y>;
+BUILDIN_FUNC(warpwaitingpc)
+{
+	int x;
+	int y;
+	int i;
+	int n;
+	const char* map_name;
+	struct npc_data* nd;
+	struct chat_data* cd;
+	TBL_PC* sd;
 
-	case 4:
-		script_pushconststr(st,cd->title);
-		return 0;
-	case 5:
-		script_pushconststr(st,cd->pass);
-		return 0;
-	case 16:
-		script_pushconststr(st,cd->npc_event);
+	nd = (struct npc_data *)map_id2bl(st->oid);
+	if( nd == NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id)) == NULL )
 		return 0;
+
+	map_name = script_getstr(st,2);
+	x = script_getnum(st,3);
+	y = script_getnum(st,4);
+	n = cd->trigger&0x7f;
+
+	if( script_hasdata(st,5) )
+		n = script_getnum(st,5);
+
+	for( i = 0; i < n && cd->users > 0; i++ )
+	{
+		sd = cd->usersd[0];
+		if( sd != NULL )
+		{
+			ShowDebug("script:warpwaitingpc: no user in chat room position 0 (cd->users=%d,%d/%d)\n", cd->users, i, n);
+			mapreg_setreg(add_str("$@warpwaitingpc")+(i<<24), 0);
+			continue;// Broken npc chat room?
+		}
+
+		mapreg_setreg(add_str("$@warpwaitingpc")+(i<<24), sd->bl.id);
+
+		if( strcmp(map_name,"Random") == 0 )
+			pc_randomwarp(sd,3);
+		else if( strcmp(map_name,"SavePoint") == 0 )
+		{
+			if( map[sd->bl.m].flag.noteleport )
+				return 0;// can't teleport on this map
+
+			pc_setpos(sd,sd->status.save_point.map,
+				sd->status.save_point.x, sd->status.save_point.y, 3);
+		}
+		else
+			pc_setpos(sd, mapindex_name2id(map_name), x, y, 0);
 	}
-	script_pushint(st,val);
+	mapreg_setreg(add_str("$@warpwaitingpcnum"), i);
 	return 0;
 }
 
-/*==========================================
- * チャットメンバー(規定人数)ワープ
- *------------------------------------------
- */
-BUILDIN_FUNC(warpwaitingpc)
+/////////////////////////////////////////////////////////////////////
+// ...
+//
+
+/// TODO what is this suposed to do?
+///
+/// @author RoVeRT
+BUILDIN_FUNC(enablearena)
 {
-	int x,y,i,n;
-	const char *str;
 	struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
 	struct chat_data *cd;
-	TBL_PC *sd;
 
-	if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL )
+
+	if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL)
 		return 0;
 
-	n=cd->trigger&0x7f;
-	str=script_getstr(st,2);
-	x=script_getnum(st,3);
-	y=script_getnum(st,4);
+	npc_enable(nd->name, 1);
+	nd->arenaflag = 1;
 
-	if( script_hasdata(st,5) )
-		n=script_getnum(st,5);
+	if( cd->users >= cd->trigger && cd->npc_event[0] )
+		npc_timer_event(cd->npc_event);
 
-	for(i=0;i<n;i++){
-		sd=cd->usersd[0];
-		if (!sd) continue; //Broken npc chat room?
-		
-		mapreg_setreg(add_str("$@warpwaitingpc")+(i<<24),sd->bl.id);
+	return 0;
+}
 
-		if(strcmp(str,"Random")==0)
-			pc_randomwarp(sd,3);
-		else if(strcmp(str,"SavePoint")==0){
-			if(map[sd->bl.m].flag.noteleport)	// テレポ禁止
-				return 0;
+/// TODO what is this suposed to do?
+///
+/// @author RoVeRT
+BUILDIN_FUNC(disablearena)
+{
+	struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
+	nd->arenaflag=0;
 
-			pc_setpos(sd,sd->status.save_point.map,
-				sd->status.save_point.x,sd->status.save_point.y,3);
-		}else
-			pc_setpos(sd,mapindex_name2id(str),x,y,0);
-	}
-	mapreg_setreg(add_str("$@warpwaitingpcnum"),n);
 	return 0;
 }
+
+/////////////////////////////////////////////////////////////////////
+// ...
+//
+
 /*==========================================
  * RIDのアタッチ
  *------------------------------------------