summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/Makefile.in4
-rw-r--r--src/char/char.c25
-rw-r--r--src/char/char.h4
-rw-r--r--src/char/int_guild.c2
-rw-r--r--src/common/HPM.c4
-rw-r--r--src/common/HPM.h2
-rw-r--r--src/common/Makefile.in2
-rw-r--r--src/common/db.c2
-rw-r--r--src/common/db.h4
-rw-r--r--src/common/ers.h14
-rw-r--r--src/common/memmgr.c22
-rw-r--r--src/common/memmgr.h2
-rw-r--r--src/common/mmo.h25
-rw-r--r--src/common/mutex.h4
-rw-r--r--src/common/showmsg.c2
-rw-r--r--src/common/socket.c14
-rw-r--r--src/common/socket.h5
-rw-r--r--src/common/sql.h4
-rw-r--r--src/common/sysinfo.c2
-rw-r--r--src/common/utils.c43
-rw-r--r--src/common/utils.h3
-rw-r--r--src/config/const.h6
-rw-r--r--src/login/Makefile.in2
-rw-r--r--src/login/ipban_sql.c32
-rw-r--r--src/login/login.c190
-rw-r--r--src/login/login.h5
-rw-r--r--src/map/Makefile.in4
-rw-r--r--src/map/atcommand.c23
-rw-r--r--src/map/battle.c5
-rw-r--r--src/map/chrif.c6
-rw-r--r--src/map/clif.c134
-rw-r--r--src/map/clif.h13
-rw-r--r--src/map/guild.c2
-rw-r--r--src/map/homunculus.h15
-rw-r--r--src/map/itemdb.c43
-rw-r--r--src/map/itemdb.h4
-rw-r--r--src/map/map.c2
-rw-r--r--src/map/map.h4
-rw-r--r--src/map/mob.c665
-rw-r--r--src/map/mob.h16
-rw-r--r--src/map/npc.c34
-rw-r--r--src/map/npc.h22
-rw-r--r--src/map/npc_chat.c4
-rw-r--r--src/map/packets.h12
-rw-r--r--src/map/packets_struct.h6
-rw-r--r--src/map/pc.c117
-rw-r--r--src/map/pc.h2
-rw-r--r--src/map/pet.c2
-rw-r--r--src/map/pet.h2
-rw-r--r--src/map/script.c396
-rw-r--r--src/map/script.h7
-rw-r--r--src/map/skill.c17
-rw-r--r--src/map/status.c112
-rw-r--r--src/map/status.h14
-rw-r--r--src/map/unit.c18
-rw-r--r--src/map/vending.c12
-rw-r--r--src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc8
-rw-r--r--src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc2
-rw-r--r--src/plugins/HPMHooking/HPMHooking_login.Hooks.inc53
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc24
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc6
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc250
-rw-r--r--src/plugins/Makefile.in4
-rw-r--r--src/plugins/constdb2doc.c197
-rw-r--r--src/plugins/db2sql.c557
-rw-r--r--src/plugins/dbghelpplug.c6
-rw-r--r--src/test/Makefile.in4
67 files changed, 2234 insertions, 1014 deletions
diff --git a/src/char/Makefile.in b/src/char/Makefile.in
index bc2c0e980..8d9094f18 100644
--- a/src/char/Makefile.in
+++ b/src/char/Makefile.in
@@ -110,13 +110,13 @@ char-server: ../../char-server@EXEEXT@
../../char-server@EXEEXT@: $(CHAR_SERVER_SQL_DEPENDS) Makefile
@echo " LD $(notdir $@)"
@$(CC) @STATIC@ @LDFLAGS@ -o ../../char-server@EXEEXT@ $(CHAR_OBJ) $(COMMON_D)/obj_sql/common_sql.a \
- $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
+ $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@
# char object files
obj_sql/%.o: %.c $(CHAR_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj_sql
@echo " CC $<"
- @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @PCRE_CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+ @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
# missing object files
$(COMMON_D)/obj_all/common.a:
diff --git a/src/char/char.c b/src/char/char.c
index 09f74034c..d05d13d4b 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -2637,11 +2637,11 @@ int char_parse_fromlogin(int fd) {
}
}
- while(RFIFOREST(fd) >= 2) {
+ while (RFIFOREST(fd) >= 2) {
uint16 command = RFIFOW(fd,0);
if (VECTOR_LENGTH(HPM->packets[hpParse_FromLogin]) > 0) {
- int result = HPM->parse_packets(fd,hpParse_FromLogin);
+ int result = HPM->parse_packets(fd,command,hpParse_FromLogin);
if (result == 1)
continue;
if (result == 2)
@@ -3926,16 +3926,17 @@ int char_parse_frommap(int fd)
return 0;
}
- while(RFIFOREST(fd) >= 2) {
+ while (RFIFOREST(fd) >= 2) {
+ int packet_id = RFIFOW(fd,0);
if (VECTOR_LENGTH(HPM->packets[hpParse_FromMap]) > 0) {
- int result = HPM->parse_packets(fd,hpParse_FromMap);
+ int result = HPM->parse_packets(fd,packet_id,hpParse_FromMap);
if (result == 1)
continue;
if (result == 2)
return 0;
}
- switch(RFIFOW(fd,0)) {
+ switch (packet_id) {
case 0x2b0a:
if( RFIFOREST(fd) < RFIFOW(fd, 2) )
return 0;
@@ -5106,21 +5107,21 @@ int char_parse_char(int fd)
return 0;
}
- while( RFIFOREST(fd) >= 2 ) {
- //For use in packets that depend on an sd being present [Skotlex]
- #define FIFOSD_CHECK(rest) do { if(RFIFOREST(fd) < (rest)) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,(rest)); return 0; } } while (0)
+ while (RFIFOREST(fd) >= 2) {
+ cmd = RFIFOW(fd,0);
+
+//For use in packets that depend on an sd being present [Skotlex]
+#define FIFOSD_CHECK(rest) do { if(RFIFOREST(fd) < (rest)) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,(rest)); return 0; } } while (0)
if (VECTOR_LENGTH(HPM->packets[hpParse_Char]) > 0) {
- int result = HPM->parse_packets(fd,hpParse_Char);
+ int result = HPM->parse_packets(fd,cmd,hpParse_Char);
if (result == 1)
continue;
if (result == 2)
return 0;
}
- cmd = RFIFOW(fd,0);
-
- switch( cmd ) {
+ switch (cmd) {
// request to connect
// 0065 <account id>.L <login id1>.L <login id2>.L <???>.W <sex>.B
case 0x65:
diff --git a/src/char/char.h b/src/char/char.h
index 3d25ec465..ff46e4353 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -317,8 +317,8 @@ extern char char_reg_num_db[32];
extern int guild_exp_rate;
extern int log_inter;
-void char_load_defaults();
-void char_defaults();
+void char_load_defaults(void);
+void char_defaults(void);
#endif // HERCULES_CORE
HPShared struct char_interface *chr;
diff --git a/src/char/int_guild.c b/src/char/int_guild.c
index 03a1d368d..60efeac94 100644
--- a/src/char/int_guild.c
+++ b/src/char/int_guild.c
@@ -1201,7 +1201,7 @@ int mapif_parse_CreateGuild(int fd,int account_id,char *name,struct guild_member
g->member[0].modified = GS_MEMBER_MODIFIED;
// Set default positions
- g->position[0].mode = GPERM_BOTH;
+ g->position[0].mode = GPERM_ALL;
strcpy(g->position[0].name,"GuildMaster");
strcpy(g->position[MAX_GUILDPOSITION-1].name,"Newbie");
g->position[0].modified = g->position[MAX_GUILDPOSITION-1].modified = GS_POSITION_MODIFIED;
diff --git a/src/common/HPM.c b/src/common/HPM.c
index 62ef54499..d9c3262d7 100644
--- a/src/common/HPM.c
+++ b/src/common/HPM.c
@@ -718,13 +718,13 @@ CPCMD(plugins)
* @retval 1 OK
* @retval 2 incomplete packet
*/
-unsigned char hplugins_parse_packets(int fd, enum HPluginPacketHookingPoints point)
+unsigned char hplugins_parse_packets(int fd, int packet_id, enum HPluginPacketHookingPoints point)
{
struct HPluginPacket *packet = NULL;
int i;
int16 length;
- ARR_FIND(0, VECTOR_LENGTH(HPM->packets[point]), i, VECTOR_INDEX(HPM->packets[point], i).cmd == RFIFOW(fd,0));
+ ARR_FIND(0, VECTOR_LENGTH(HPM->packets[point]), i, VECTOR_INDEX(HPM->packets[point], i).cmd == packet_id);
if (i == VECTOR_LENGTH(HPM->packets[point]))
return 0;
diff --git a/src/common/HPM.h b/src/common/HPM.h
index 215161a86..109549aad 100644
--- a/src/common/HPM.h
+++ b/src/common/HPM.h
@@ -157,7 +157,7 @@ struct HPM_interface {
void (*share) (void *value, const char *name);
void (*config_read) (void);
char *(*pid2name) (unsigned int pid);
- unsigned char (*parse_packets) (int fd, enum HPluginPacketHookingPoints point);
+ unsigned char (*parse_packets) (int fd, int packet_id, enum HPluginPacketHookingPoints point);
void (*load_sub) (struct hplugin *plugin);
bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID);
/* for custom config parsing */
diff --git a/src/common/Makefile.in b/src/common/Makefile.in
index df3ecaf2d..9d4b2d044 100644
--- a/src/common/Makefile.in
+++ b/src/common/Makefile.in
@@ -135,7 +135,7 @@ obj_all/sysinfo.o: sysinfo.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_
obj_all/%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | $(SYSINFO_INC) obj_all
@echo " CC $<"
- @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @PCRE_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+ @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
obj_all/mini%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | $(SYSINFO_INC) obj_all
@echo " CC $<"
diff --git a/src/common/db.c b/src/common/db.c
index 361e212cb..ca9a70f7c 100644
--- a/src/common/db.c
+++ b/src/common/db.c
@@ -353,7 +353,7 @@ static struct db_stats {
};
#define DB_COUNTSTAT(token) do { if ((stats.token) != UINT32_MAX) ++(stats.token); } while(0)
#else /* !defined(DB_ENABLE_STATS) */
-#define DB_COUNTSTAT(token)
+#define DB_COUNTSTAT(token) (void)0
#endif /* !defined(DB_ENABLE_STATS) */
/* [Ind/Hercules] */
diff --git a/src/common/db.h b/src/common/db.h
index 205288f13..b73970947 100644
--- a/src/common/db.h
+++ b/src/common/db.h
@@ -1717,7 +1717,7 @@ HPShared struct db_interface *DB;
* @return negative if v1 is top, positive if v2 is top, 0 if equal.
*/
#define BHEAP_MINTOPCMP(v1, v2) \
- ( v1 == v2 ? 0 : v1 < v2 ? -1 : 1 )
+ ( (v1) == (v2) ? 0 : (v1) < (v2) ? -1 : 1 )
/**
* Generic comparator for a max-heap (maximum value at top).
@@ -1732,6 +1732,6 @@ HPShared struct db_interface *DB;
* @return negative if v1 is top, positive if v2 is top, 0 if equal.
*/
#define BHEAP_MAXTOPCMP(v1, v2) \
- ( v1 == v2 ? 0 : v1 > v2 ? -1 : 1 )
+ ( (v1) == (v2) ? 0 : (v1) > (v2) ? -1 : 1 )
#endif /* COMMON_DB_H */
diff --git a/src/common/ers.h b/src/common/ers.h
index 938882edd..1689345dc 100644
--- a/src/common/ers.h
+++ b/src/common/ers.h
@@ -148,15 +148,15 @@ typedef struct eri {
#ifdef DISABLE_ERS
// Use memory manager to allocate/free and disable other interface functions
-# define ers_alloc(obj,type) (type *)aMalloc(sizeof(type))
-# define ers_free(obj,entry) aFree(entry)
-# define ers_entry_size(obj) (size_t)0
-# define ers_destroy(obj)
-# define ers_chunk_size(obj,size)
+# define ers_alloc(obj,type) ((void)(obj), (type *)aMalloc(sizeof(type)))
+# define ers_free(obj,entry) ((void)(obj), aFree(entry))
+# define ers_entry_size(obj) ((void)(obj), (size_t)0)
+# define ers_destroy(obj) ((void)(obj), (void)0)
+# define ers_chunk_size(obj,size) ((void)(obj), (void)(size), (size_t)0)
// Disable the public functions
# define ers_new(size,name,options) NULL
-# define ers_report()
-# define ers_final()
+# define ers_report() (void)0
+# define ers_final() (void)0
#else /* not DISABLE_ERS */
// These defines should be used to allow the code to keep working whenever
// the system is disabled
diff --git a/src/common/memmgr.c b/src/common/memmgr.c
index 97991ceaa..93c23ff18 100644
--- a/src/common/memmgr.c
+++ b/src/common/memmgr.c
@@ -45,7 +45,7 @@ struct malloc_interface *iMalloc;
# define REALLOC(p,n,file,line,func) mwRealloc((p),(n),(file),(line))
# define STRDUP(p,file,line,func) mwStrdup((p),(file),(line))
# define FREE(p,file,line,func) mwFree((p),(file),(line))
-# define MEMORY_USAGE() (size_t)0
+# define MEMORY_USAGE() ((size_t)0)
# define MEMORY_VERIFY(ptr) mwIsSafeAddr((ptr), 1)
# define MEMORY_CHECK() CHECK()
@@ -67,21 +67,21 @@ struct malloc_interface *iMalloc;
# include <gc.h>
# ifdef GC_ADD_CALLER
-# define RETURN_ADDR 0,
+# define MALLOC(n,file,line,func) GC_debug_malloc((n), 0, (file), (line))
+# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), 0, (file), (line))
+# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), 0, (file), (line))
+# define STRDUP(p,file,line,func) GC_debug_strdup((p), 0, (file), (line))
# else
-# define RETURN_ADDR
+# define MALLOC(n,file,line,func) GC_debug_malloc((n), (file), (line))
+# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), (file), (line))
+# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), (file), (line))
+# define STRDUP(p,file,line,func) GC_debug_strdup((p), (file), (line))
# endif
-# define MALLOC(n,file,line,func) GC_debug_malloc((n), RETURN_ADDR (file),(line))
-# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line))
-# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), RETURN_ADDR (file),(line))
-# define STRDUP(p,file,line,func) GC_debug_strdup((p), RETURN_ADDR (file),(line))
# define FREE(p,file,line,func) GC_debug_free(p)
# define MEMORY_USAGE() GC_get_heap_size()
# define MEMORY_VERIFY(ptr) (GC_base(ptr) != NULL)
# define MEMORY_CHECK() GC_gcollect()
-# undef RETURN_ADDR
-
#else
# define MALLOC(n,file,line,func) malloc(n)
@@ -89,9 +89,9 @@ struct malloc_interface *iMalloc;
# define REALLOC(p,n,file,line,func) realloc((p),(n))
# define STRDUP(p,file,line,func) strdup(p)
# define FREE(p,file,line,func) free(p)
-# define MEMORY_USAGE() (size_t)0
+# define MEMORY_USAGE() ((size_t)0)
# define MEMORY_VERIFY(ptr) true
-# define MEMORY_CHECK()
+# define MEMORY_CHECK() (void)0
#endif
diff --git a/src/common/memmgr.h b/src/common/memmgr.h
index 4b06ae56e..5975f55c4 100644
--- a/src/common/memmgr.h
+++ b/src/common/memmgr.h
@@ -60,7 +60,7 @@
#ifdef __GNUC__ // GCC has variable length arrays
#define CREATE_BUFFER(name, type, size) type name[size]
-#define DELETE_BUFFER(name)
+#define DELETE_BUFFER(name) (void)0
#else // others don't, so we emulate them
diff --git a/src/common/mmo.h b/src/common/mmo.h
index eb1d7cc8e..981c1b30b 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -98,13 +98,19 @@
#endif // 20090603
#endif // 20070227
-/* Feb 1st 2012 */
-#if PACKETVER >= 20120201
-# define NEW_CARTS
-# define MAX_CARTS 9
+#if PACKETVER >= 20150805 /* Cart Decoration */
+ #define CART_DECORATION
+ #define MAX_CARTDECORATION_CARTS 3 // Currently there are 3 Carts available in kRO. [Frost]
#else
-# define MAX_CARTS 5
+ #define MAX_CARTDECORATION_CARTS 0
#endif
+#if PACKETVER >= 20120201 /* New Geneticist Carts */
+ #define NEW_CARTS
+ #define MAX_BASE_CARTS 9
+#else
+ #define MAX_BASE_CARTS 5
+#endif
+#define MAX_CARTS (MAX_BASE_CARTS + MAX_CARTDECORATION_CARTS)
#define MAX_INVENTORY 100
//Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well.
@@ -207,6 +213,11 @@
#define JOBL_BABY 0x2000 //8192
#define JOBL_THIRD 0x4000 //16384
+//Packet DB
+#define MIN_PACKET_DB 0x0064 //what's the point of minimum packet id ? [hemagx]
+#define MAX_PACKET_DB 0x0F00
+#define MAX_PACKET_POS 20
+
#define SCRIPT_VARNAME_LENGTH 32 ///< Maximum length of a script variable
struct hplugin_data_store;
@@ -262,6 +273,7 @@ struct item {
//Equip position constants
enum equip_pos {
+ EQP_NONE = 0x000000,
EQP_HEAD_LOW = 0x000001,
EQP_HEAD_MID = 0x000200, //512
EQP_HEAD_TOP = 0x000100, //256
@@ -742,7 +754,8 @@ enum { //Change Member Infos
enum guild_permission { // Guild permissions
GPERM_INVITE = 0x01,
GPERM_EXPEL = 0x10,
- GPERM_BOTH = GPERM_INVITE|GPERM_EXPEL,
+ GPERM_ALL = GPERM_INVITE|GPERM_EXPEL,
+ GPERM_MASK = GPERM_ALL,
};
enum {
diff --git a/src/common/mutex.h b/src/common/mutex.h
index 5127d9f4b..e49791493 100644
--- a/src/common/mutex.h
+++ b/src/common/mutex.h
@@ -32,7 +32,7 @@ typedef struct racond racond; // Condition Var
*
* @return not NULL
*/
-ramutex *ramutex_create();
+ramutex *ramutex_create(void);
/**
* Destroys a Mutex
@@ -70,7 +70,7 @@ void ramutex_unlock(ramutex *m);
*
* @return not NULL
*/
-racond *racond_create();
+racond *racond_create(void);
/**
* Destroy a Condition variable
diff --git a/src/common/showmsg.c b/src/common/showmsg.c
index e60b9f536..956222a7d 100644
--- a/src/common/showmsg.c
+++ b/src/common/showmsg.c
@@ -478,7 +478,7 @@ int FPRINTF(HANDLE handle, const char *fmt, ...) {
return ret;
}
-#define FFLUSH(handle)
+#define FFLUSH(handle) (void)(handle)
#define STDOUT GetStdHandle(STD_OUTPUT_HANDLE)
#define STDERR GetStdHandle(STD_ERROR_HANDLE)
diff --git a/src/common/socket.c b/src/common/socket.c
index f67c3d074..740c07bdc 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -76,11 +76,11 @@ struct socket_interface *sockt;
struct socket_data **session;
#ifdef SEND_SHORTLIST
- // Add a fd to the shortlist so that it'll be recognized as a fd that needs
- // sending done on it.
- void send_shortlist_add_fd(int fd);
- // Do pending network sends (and eof handling) from the shortlist.
- void send_shortlist_do_sends();
+// Add a fd to the shortlist so that it'll be recognized as a fd that needs
+// sending done on it.
+void send_shortlist_add_fd(int fd);
+// Do pending network sends (and eof handling) from the shortlist.
+void send_shortlist_do_sends(void);
#endif
/////////////////////////////////////////////////////////////////////
@@ -1103,7 +1103,7 @@ static int connect_check_clear(int tid, int64 tick, int id, intptr_t data) {
clear++;
}
list++;
- }
+ }
dbi_destroy(iter);
if( access_debug ){
@@ -1570,7 +1570,7 @@ void send_shortlist_add_fd(int fd)
}
// Do pending network sends and eof handling from the shortlist.
-void send_shortlist_do_sends()
+void send_shortlist_do_sends(void)
{
int i;
diff --git a/src/common/socket.h b/src/common/socket.h
index b33fd2acf..8936c7772 100644
--- a/src/common/socket.h
+++ b/src/common/socket.h
@@ -77,6 +77,11 @@ struct hplugin_data_store;
/* [Ind/Hercules] */
#define RFIFO2PTR(fd) (void*)(sockt->session[fd]->rdata + sockt->session[fd]->rdata_pos)
+#define RP2PTR(fd) RFIFO2PTR(fd)
+
+/* [Hemagx/Hercules] */
+#define WFIFO2PTR(fd) (void*)(sockt->session[fd]->wdata + sockt->session[fd]->wdata_pos)
+#define WP2PTR(fd) WFIFO2PTR(fd)
// buffer I/O macros
#define RBUFP(p,pos) (((uint8*)(p)) + (pos))
diff --git a/src/common/sql.h b/src/common/sql.h
index 33643407d..e949a8280 100644
--- a/src/common/sql.h
+++ b/src/common/sql.h
@@ -272,13 +272,13 @@ void Sql_HerculesUpdateSkip(Sql* self,const char *filename);
HPShared struct sql_interface *SQL;
#if defined(SQL_REMOVE_SHOWDEBUG)
-#define Sql_ShowDebug(self) (void)0
+#define Sql_ShowDebug(self) (void)(self)
#else
#define Sql_ShowDebug(self) (SQL->ShowDebug_((self), __FILE__, __LINE__))
#endif
#if defined(SQL_REMOVE_SHOWDEBUG)
-#define SqlStmt_ShowDebug(self) (void)0
+#define SqlStmt_ShowDebug(self) (void)(self)
#else
/// Shows debug information (with statement).
#define SqlStmt_ShowDebug(self) (SQL->StmtShowDebug_((self), __FILE__, __LINE__))
diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c
index dbedfa2db..7cc4cd16a 100644
--- a/src/common/sysinfo.c
+++ b/src/common/sysinfo.c
@@ -65,7 +65,7 @@ struct sysinfo_interface *sysinfo;
#define VCSTYPE_UNKNOWN 0
#define VCSTYPE_GIT 1
#define VCSTYPE_SVN 2
-#define VCSTYPE_NONE -1
+#define VCSTYPE_NONE (-1)
#ifdef WIN32
/**
diff --git a/src/common/utils.c b/src/common/utils.c
index dcf0a749a..73df3aae1 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -25,6 +25,7 @@
#include "common/cbasetypes.h"
#include "common/core.h"
#include "common/mmo.h"
+#include "common/nullpo.h"
#include "common/showmsg.h"
#include "common/socket.h"
#include "common/strlib.h"
@@ -352,6 +353,48 @@ unsigned int get_percentage(const unsigned int A, const unsigned int B)
return (unsigned int)floor(result);
}
+/**
+ * Applies a percentual rate modifier.
+ *
+ * @param value The base value.
+ * @param rate The rate modifier to apply.
+ * @param stdrate The rate modifier's divider (rate == stdrate => 100%).
+ * @return The modified value.
+ */
+int64 apply_percentrate64(int64 value, int rate, int stdrate)
+{
+ Assert_ret(stdrate > 0);
+ Assert_ret(rate >= 0);
+ if (rate == stdrate)
+ return value;
+ if (rate == 0)
+ return 0;
+ if (INT64_MAX / rate < value) {
+ // Give up some precision to prevent overflows
+ return value / stdrate * rate;
+ }
+ return value * rate / stdrate;
+}
+
+/**
+ * Applies a percentual rate modifier.
+ *
+ * @param value The base value.
+ * @param rate The rate modifier to apply. Must be <= maxrate.
+ * @param maxrate The rate modifier's divider (maxrate = 100%).
+ * @return The modified value.
+ */
+int apply_percentrate(int value, int rate, int maxrate)
+{
+ Assert_ret(maxrate > 0);
+ Assert_ret(rate >= 0);
+ if (rate == maxrate)
+ return value;
+ if (rate == 0)
+ return 0;
+ return (int)(value * (int64)rate / maxrate);
+}
+
//-----------------------------------------------------
// custom timestamp formatting (from eApp)
//-----------------------------------------------------
diff --git a/src/common/utils.h b/src/common/utils.h
index da2a29317..3f181ef12 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -42,6 +42,9 @@ bool exists(const char* filename);
/// calculates the value of A / B, in percent (rounded down)
unsigned int get_percentage(const unsigned int A, const unsigned int B);
+int64 apply_percentrate64(int64 value, int rate, int maxrate);
+int apply_percentrate(int value, int rate, int maxrate);
+
const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format);
//////////////////////////////////////////////////////////////////////////
diff --git a/src/config/const.h b/src/config/const.h
index 75bf35dd9..655f0f949 100644
--- a/src/config/const.h
+++ b/src/config/const.h
@@ -101,9 +101,9 @@
md.damage = md.damage * 150 / 100 + md.damage * status->get_lv(src) / 100; \
} while(0)
#else
- #define RE_LVL_DMOD(val)
- #define RE_LVL_MDMOD(val)
- #define RE_LVL_TMDMOD()
+ #define RE_LVL_DMOD(val) (void)(val)
+ #define RE_LVL_MDMOD(val) (void)(val)
+ #define RE_LVL_TMDMOD() (void)0
#endif
// Renewal variable cast time reduction
diff --git a/src/login/Makefile.in b/src/login/Makefile.in
index 022831fb5..6560e6497 100644
--- a/src/login/Makefile.in
+++ b/src/login/Makefile.in
@@ -106,7 +106,7 @@ login-server: ../../login-server@EXEEXT@
../../login-server@EXEEXT@: $(LOGIN_SERVER_SQL_DEPENDS) Makefile
@echo " LD $(notdir $@)"
@$(CC) @STATIC@ @LDFLAGS@ -o ../../login-server@EXEEXT@ $(LOGIN_OBJ) $(COMMON_D)/obj_sql/common_sql.a \
- $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
+ $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@
# login object files
diff --git a/src/login/ipban_sql.c b/src/login/ipban_sql.c
index 090886e93..9d059ccd2 100644
--- a/src/login/ipban_sql.c
+++ b/src/login/ipban_sql.c
@@ -68,7 +68,7 @@ void ipban_init(void)
ipban_inited = true;
- if( !login_config.ipban )
+ if (!login->config->ipban)
return;// ipban disabled
if( ipban_db_hostname[0] != '\0' )
@@ -101,10 +101,10 @@ void ipban_init(void)
if( codepage[0] != '\0' && SQL_ERROR == SQL->SetEncoding(sql_handle, codepage) )
Sql_ShowDebug(sql_handle);
- if( login_config.ipban_cleanup_interval > 0 )
+ if (login->config->ipban_cleanup_interval > 0)
{ // set up periodic cleanup of connection history and active bans
timer->add_func_list(ipban_cleanup, "ipban_cleanup");
- cleanup_timer_id = timer->add_interval(timer->gettick()+10, ipban_cleanup, 0, 0, login_config.ipban_cleanup_interval*1000);
+ cleanup_timer_id = timer->add_interval(timer->gettick()+10, ipban_cleanup, 0, 0, login->config->ipban_cleanup_interval*1000);
} else // make sure it gets cleaned up on login-server start regardless of interval-based cleanups
ipban_cleanup(0,0,0,0);
}
@@ -112,10 +112,10 @@ void ipban_init(void)
// finalize
void ipban_final(void)
{
- if( !login_config.ipban )
+ if (!login->config->ipban)
return;// ipban disabled
- if( login_config.ipban_cleanup_interval > 0 )
+ if (login->config->ipban_cleanup_interval > 0)
// release data
timer->delete(cleanup_timer_id, ipban_cleanup);
@@ -196,19 +196,19 @@ bool ipban_config_read(const char* key, const char* value)
{
key += strlen(signature);
if( strcmpi(key, "enable") == 0 )
- login_config.ipban = (bool)config_switch(value);
+ login->config->ipban = (bool)config_switch(value);
else
if( strcmpi(key, "dynamic_pass_failure_ban") == 0 )
- login_config.dynamic_pass_failure_ban = (bool)config_switch(value);
+ login->config->dynamic_pass_failure_ban = (bool)config_switch(value);
else
if( strcmpi(key, "dynamic_pass_failure_ban_interval") == 0 )
- login_config.dynamic_pass_failure_ban_interval = atoi(value);
+ login->config->dynamic_pass_failure_ban_interval = atoi(value);
else
if( strcmpi(key, "dynamic_pass_failure_ban_limit") == 0 )
- login_config.dynamic_pass_failure_ban_limit = atoi(value);
+ login->config->dynamic_pass_failure_ban_limit = atoi(value);
else
if( strcmpi(key, "dynamic_pass_failure_ban_duration") == 0 )
- login_config.dynamic_pass_failure_ban_duration = atoi(value);
+ login->config->dynamic_pass_failure_ban_duration = atoi(value);
else
return false;// not found
return true;
@@ -224,7 +224,7 @@ bool ipban_check(uint32 ip)
char* data = NULL;
int matches;
- if( !login_config.ipban )
+ if (!login->config->ipban)
return false;// ipban disabled
if( SQL_ERROR == SQL->Query(sql_handle, "SELECT count(*) FROM `%s` WHERE `rtime` > NOW() AND (`list` = '%u.*.*.*' OR `list` = '%u.%u.*.*' OR `list` = '%u.%u.%u.*' OR `list` = '%u.%u.%u.%u')",
@@ -250,17 +250,17 @@ void ipban_log(uint32 ip)
{
unsigned long failures;
- if( !login_config.ipban )
+ if (!login->config->ipban)
return;// ipban disabled
- failures = loginlog_failedattempts(ip, login_config.dynamic_pass_failure_ban_interval);// how many times failed account? in one ip.
+ failures = loginlog_failedattempts(ip, login->config->dynamic_pass_failure_ban_interval);// how many times failed account? in one ip.
// if over the limit, add a temporary ban entry
- if( failures >= login_config.dynamic_pass_failure_ban_limit )
+ if (failures >= login->config->dynamic_pass_failure_ban_limit)
{
uint8* p = (uint8*)&ip;
if (SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s`(`list`,`btime`,`rtime`,`reason`) VALUES ('%u.%u.%u.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban')",
- ipban_table, p[3], p[2], p[1], login_config.dynamic_pass_failure_ban_duration))
+ ipban_table, p[3], p[2], p[1], login->config->dynamic_pass_failure_ban_duration))
{
Sql_ShowDebug(sql_handle);
}
@@ -269,7 +269,7 @@ void ipban_log(uint32 ip)
// remove expired bans
int ipban_cleanup(int tid, int64 tick, int id, intptr_t data) {
- if( !login_config.ipban )
+ if (!login->config->ipban)
return 0;// ipban disabled
if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `rtime` <= NOW()", ipban_table) )
diff --git a/src/login/login.c b/src/login/login.c
index e478d0252..d4768df86 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -46,7 +46,7 @@
struct login_interface login_s;
struct login_interface *login;
-struct Login_Config login_config;
+struct Login_Config login_config_;
struct mmo_char_server server[MAX_SERVERS]; // char server data
struct Account_engine account_engine[] = {
@@ -559,7 +559,7 @@ void login_fromchar_parse_ban(int fd, int id, const char *const ip)
ShowNotice("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", server[id].name, account_id, ip);
} else {
char tmpstr[24];
- timestamp2string(tmpstr, sizeof(tmpstr), timestamp, login_config.date_format);
+ timestamp2string(tmpstr, sizeof(tmpstr), timestamp, login->config->date_format);
ShowNotice("Char-server '%s': Ban request (account: %d, new final date of banishment: %ld (%s), ip: %s).\n",
server[id].name, account_id, (long)timestamp, tmpstr, ip);
@@ -808,18 +808,18 @@ int login_parse_fromchar(int fd)
ipl = server[id].ip;
sockt->ip2str(ipl, ip);
- while( RFIFOREST(fd) >= 2 ) {
+ while (RFIFOREST(fd) >= 2) {
uint16 command = RFIFOW(fd,0);
if (VECTOR_LENGTH(HPM->packets[hpParse_FromChar]) > 0) {
- int result = HPM->parse_packets(fd,hpParse_FromChar);
+ int result = HPM->parse_packets(fd,command,hpParse_FromChar);
if (result == 1)
continue;
if (result == 2)
return 0;
}
- switch( command ) {
+ switch (command) {
case 0x2712: // request from char-server to authenticate an account
if( RFIFOREST(fd) < 23 )
@@ -995,12 +995,12 @@ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, con
//Account Registration Flood Protection by [Kevin]
if( new_reg_tick == 0 )
new_reg_tick = timer->gettick();
- if( DIFF_TICK(tick, new_reg_tick) < 0 && num_regs >= login_config.allowed_regs ) {
+ if (DIFF_TICK(tick, new_reg_tick) < 0 && num_regs >= login->config->allowed_regs) {
ShowNotice("Account registration denied (registration limit exceeded)\n");
return 3;
}
- if( login_config.new_acc_length_limit && ( strlen(userid) < 4 || strlen(pass) < 4 ) )
+ if (login->config->new_acc_length_limit && (strlen(userid) < 4 || strlen(pass) < 4))
return 1;
// check for invalid inputs
@@ -1019,7 +1019,7 @@ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, con
safestrncpy(acc.pass, pass, sizeof(acc.pass));
acc.sex = sex;
safestrncpy(acc.email, "a@a.com", sizeof(acc.email));
- acc.expiration_time = ( login_config.start_limited_time != -1 ) ? time(NULL) + login_config.start_limited_time : 0;
+ acc.expiration_time = (login->config->start_limited_time != -1) ? time(NULL) + login->config->start_limited_time : 0;
safestrncpy(acc.lastlogin, "0000-00-00 00:00:00", sizeof(acc.lastlogin));
safestrncpy(acc.last_ip, last_ip, sizeof(acc.last_ip));
safestrncpy(acc.birthdate, "0000-00-00", sizeof(acc.birthdate));
@@ -1034,7 +1034,7 @@ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, con
if( DIFF_TICK(tick, new_reg_tick) > 0 ) {// Update the registration check.
num_regs = 0;
- new_reg_tick = tick + login_config.time_allowed*1000;
+ new_reg_tick = tick + login->config->time_allowed*1000;
}
++num_regs;
@@ -1054,7 +1054,7 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) {
sockt->ip2str(sockt->session[sd->fd]->client_addr, ip);
// DNS Blacklist check
- if( login_config.use_dnsbl ) {
+ if (login->config->use_dnsbl) {
char r_ip[16];
char ip_dnsbl[256];
char* dnsbl_serv;
@@ -1062,7 +1062,7 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) {
sprintf(r_ip, "%u.%u.%u.%u", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
- for( dnsbl_serv = strtok(login_config.dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,",") ) {
+ for (dnsbl_serv = strtok(login->config->dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,",")) {
sprintf(ip_dnsbl, "%s.%s", r_ip, trim(dnsbl_serv));
if (sockt->host2ip(ip_dnsbl)) {
ShowInfo("DNSBL: (%s) Blacklisted. User Kicked.\n", r_ip);
@@ -1073,13 +1073,13 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) {
}
//Client Version check
- if( login_config.check_client_version && sd->version != login_config.client_version_to_connect )
+ if (login->config->check_client_version && sd->version != login->config->client_version_to_connect)
return 5;
len = strnlen(sd->userid, NAME_LENGTH);
// Account creation with _M/_F
- if( login_config.new_account_flag ) {
+ if (login->config->new_account_flag) {
if (len > 2 && sd->passwd[0] != '\0' && // valid user and password lengths
sd->passwdenc == PWENC_NONE && // unencoded password
sd->userid[len-2] == '_' && memchr("FfMm", sd->userid[len-1], 4)) // _M/_F suffix
@@ -1113,7 +1113,7 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) {
if( acc.unban_time != 0 && acc.unban_time > time(NULL) ) {
char tmpstr[24];
- timestamp2string(tmpstr, sizeof(tmpstr), acc.unban_time, login_config.date_format);
+ timestamp2string(tmpstr, sizeof(tmpstr), acc.unban_time, login->config->date_format);
ShowNotice("Connection refused (account: %s, pass: %s, banned until %s, ip: %s)\n", sd->userid, sd->passwd, tmpstr, ip);
return 6; // 6 = Your are Prohibited to log in until %s
}
@@ -1123,11 +1123,11 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) {
return acc.state - 1;
}
- if( login_config.client_hash_check && !isServer ) {
+ if (login->config->client_hash_check && !isServer) {
struct client_hash_node *node = NULL;
bool match = false;
- for( node = login_config.client_hash_nodes; node; node = node->next ) {
+ for (node = login->config->client_hash_nodes; node; node = node->next) {
if( acc.group_id < node->group_id )
continue;
if( *node->hash == '\0' // Allowed to login without hash
@@ -1216,12 +1216,12 @@ void login_auth_ok(struct login_session_data* sd)
return;
}
- if( login_config.group_id_to_connect >= 0 && sd->group_id != login_config.group_id_to_connect ) {
- ShowStatus("Connection refused: the required group id for connection is %d (account: %s, group: %d).\n", login_config.group_id_to_connect, sd->userid, sd->group_id);
+ if (login->config->group_id_to_connect >= 0 && sd->group_id != login->config->group_id_to_connect) {
+ ShowStatus("Connection refused: the required group id for connection is %d (account: %s, group: %d).\n", login->config->group_id_to_connect, sd->userid, sd->group_id);
login->connection_problem(fd, 1); // 01 = server closed
return;
- } else if( login_config.min_group_id_to_connect >= 0 && login_config.group_id_to_connect == -1 && sd->group_id < login_config.min_group_id_to_connect ) {
- ShowStatus("Connection refused: the minimum group id required for connection is %d (account: %s, group: %d).\n", login_config.min_group_id_to_connect, sd->userid, sd->group_id);
+ } else if (login->config->min_group_id_to_connect >= 0 && login->config->group_id_to_connect == -1 && sd->group_id < login->config->min_group_id_to_connect) {
+ ShowStatus("Connection refused: the minimum group id required for connection is %d (account: %s, group: %d).\n", login->config->min_group_id_to_connect, sd->userid, sd->group_id);
login->connection_problem(fd, 1); // 01 = server closed
return;
}
@@ -1331,8 +1331,7 @@ void login_auth_failed(struct login_session_data* sd, int result)
fd = sd->fd;
ip = sockt->session[fd]->client_addr;
- if (login_config.log_login)
- {
+ if (login->config->log_login) {
const char* error;
switch( result ) {
case 0: error = "Unregistered ID."; break; // 0 = Unregistered ID
@@ -1363,7 +1362,7 @@ void login_auth_failed(struct login_session_data* sd, int result)
login_log(ip, sd->userid, result, error); // FIXME: result can be 100, conflicting with the value 100 we use for successful login...
}
- if (result == 1 && login_config.dynamic_pass_failure_ban && !sockt->trusted_ip_check(ip))
+ if (result == 1 && login->config->dynamic_pass_failure_ban && !sockt->trusted_ip_check(ip))
ipban_log(ip); // log failed password attempt
#if PACKETVER >= 20120000 /* not sure when this started */
@@ -1375,7 +1374,7 @@ void login_auth_failed(struct login_session_data* sd, int result)
else { // 6 = Your are Prohibited to log in until %s
struct mmo_account acc;
time_t unban_time = ( accounts->load_str(accounts, &acc, sd->userid) ) ? acc.unban_time : 0;
- timestamp2string((char*)WFIFOP(fd,6), 20, unban_time, login_config.date_format);
+ timestamp2string((char*)WFIFOP(fd,6), 20, unban_time, login->config->date_format);
}
WFIFOSET(fd,26);
#else
@@ -1387,7 +1386,7 @@ void login_auth_failed(struct login_session_data* sd, int result)
else { // 6 = Your are Prohibited to log in until %s
struct mmo_account acc;
time_t unban_time = ( accounts->load_str(accounts, &acc, sd->userid) ) ? acc.unban_time : 0;
- timestamp2string((char*)WFIFOP(fd,3), 20, unban_time, login_config.date_format);
+ timestamp2string((char*)WFIFOP(fd,3), 20, unban_time, login->config->date_format);
}
WFIFOSET(fd,23);
#endif
@@ -1471,7 +1470,7 @@ bool login_parse_client_login(int fd, struct login_session_data* sd, const char
{
ShowStatus("Request for connection of %s (ip: %s).\n", sd->userid, ip);
safestrncpy(sd->passwd, password, PASSWD_LEN);
- if( login_config.use_md5_passwds )
+ if (login->config->use_md5_passwds)
MD5_String(sd->passwd, sd->passwd);
sd->passwdenc = PWENC_NONE;
}
@@ -1482,7 +1481,7 @@ bool login_parse_client_login(int fd, struct login_session_data* sd, const char
sd->passwdenc = PASSWORDENC;
}
- if (sd->passwdenc != PWENC_NONE && login_config.use_md5_passwds) {
+ if (sd->passwdenc != PWENC_NONE && login->config->use_md5_passwds) {
login->auth_failed(sd, 3); // send "rejected from server"
return true;
}
@@ -1538,10 +1537,10 @@ void login_parse_request_connection(int fd, struct login_session_data* sd, const
safestrncpy(sd->userid, (char*)RFIFOP(fd,2), NAME_LENGTH);
safestrncpy(sd->passwd, (char*)RFIFOP(fd,26), NAME_LENGTH);
- if( login_config.use_md5_passwds )
+ if (login->config->use_md5_passwds)
MD5_String(sd->passwd, sd->passwd);
sd->passwdenc = PWENC_NONE;
- sd->version = login_config.client_version_to_connect; // hack to skip version check
+ sd->version = login->config->client_version_to_connect; // hack to skip version check
server_ip = ntohl(RFIFOL(fd,54));
server_port = ntohs(RFIFOW(fd,58));
safestrncpy(server_name, (char*)RFIFOP(fd,60), 20);
@@ -1606,8 +1605,7 @@ int login_parse_login(int fd)
if( sd == NULL )
{
// Perform ip-ban check
- if (login_config.ipban && !sockt->trusted_ip_check(ipl) && ipban_check(ipl))
- {
+ if (login->config->ipban && !sockt->trusted_ip_check(ipl) && ipban_check(ipl)) {
ShowStatus("Connection refused: IP isn't authorized (deny/allow, ip: %s).\n", ip);
login_log(ipl, "unknown", -3, "ip banned");
login->login_error(fd, 3); // 3 = Rejected from Server
@@ -1621,18 +1619,18 @@ int login_parse_login(int fd)
sd->fd = fd;
}
- while( RFIFOREST(fd) >= 2 ) {
+ while (RFIFOREST(fd) >= 2) {
uint16 command = RFIFOW(fd,0);
if (VECTOR_LENGTH(HPM->packets[hpParse_Login]) > 0) {
- int result = HPM->parse_packets(fd,hpParse_Login);
+ int result = HPM->parse_packets(fd,command,hpParse_Login);
if (result == 1)
continue;
if (result == 2)
return 0;
}
- switch( command ) {
+ switch (command) {
case 0x0200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
if (RFIFOREST(fd) < 26)
@@ -1701,40 +1699,40 @@ int login_parse_login(int fd)
}
-void login_set_defaults()
+void login_config_set_defaults(void)
{
- login_config.login_ip = INADDR_ANY;
- login_config.login_port = 6900;
- login_config.ipban_cleanup_interval = 60;
- login_config.ip_sync_interval = 0;
- login_config.log_login = true;
- safestrncpy(login_config.date_format, "%Y-%m-%d %H:%M:%S", sizeof(login_config.date_format));
- login_config.new_account_flag = true;
- login_config.new_acc_length_limit = true;
- login_config.use_md5_passwds = false;
- login_config.group_id_to_connect = -1;
- login_config.min_group_id_to_connect = -1;
- login_config.check_client_version = false;
- login_config.client_version_to_connect = 20;
- login_config.allowed_regs = 1;
- login_config.time_allowed = 10;
-
- login_config.ipban = true;
- login_config.dynamic_pass_failure_ban = true;
- login_config.dynamic_pass_failure_ban_interval = 5;
- login_config.dynamic_pass_failure_ban_limit = 7;
- login_config.dynamic_pass_failure_ban_duration = 5;
- login_config.use_dnsbl = false;
- safestrncpy(login_config.dnsbl_servs, "", sizeof(login_config.dnsbl_servs));
-
- login_config.client_hash_check = 0;
- login_config.client_hash_nodes = NULL;
+ login->config->login_ip = INADDR_ANY;
+ login->config->login_port = 6900;
+ login->config->ipban_cleanup_interval = 60;
+ login->config->ip_sync_interval = 0;
+ login->config->log_login = true;
+ safestrncpy(login->config->date_format, "%Y-%m-%d %H:%M:%S", sizeof(login->config->date_format));
+ login->config->new_account_flag = true;
+ login->config->new_acc_length_limit = true;
+ login->config->use_md5_passwds = false;
+ login->config->group_id_to_connect = -1;
+ login->config->min_group_id_to_connect = -1;
+ login->config->check_client_version = false;
+ login->config->client_version_to_connect = 20;
+ login->config->allowed_regs = 1;
+ login->config->time_allowed = 10;
+
+ login->config->ipban = true;
+ login->config->dynamic_pass_failure_ban = true;
+ login->config->dynamic_pass_failure_ban_interval = 5;
+ login->config->dynamic_pass_failure_ban_limit = 7;
+ login->config->dynamic_pass_failure_ban_duration = 5;
+ login->config->use_dnsbl = false;
+ safestrncpy(login->config->dnsbl_servs, "", sizeof(login->config->dnsbl_servs));
+
+ login->config->client_hash_check = 0;
+ login->config->client_hash_nodes = NULL;
}
//-----------------------------------
// Reading main configuration file
//-----------------------------------
-int login_config_read(const char* cfgName)
+int login_config_read(const char *cfgName)
{
char line[1024], w1[1024], w2[1024];
FILE* fp;
@@ -1761,50 +1759,50 @@ int login_config_read(const char* cfgName)
ShowInfo("Console Silent Setting: %d\n", atoi(w2));
}
else if( !strcmpi(w1, "bind_ip") ) {
- login_config.login_ip = sockt->host2ip(w2);
- if( login_config.login_ip ) {
+ login->config->login_ip = sockt->host2ip(w2);
+ if (login->config->login_ip) {
char ip_str[16];
- ShowStatus("Login server binding IP address : %s -> %s\n", w2, sockt->ip2str(login_config.login_ip, ip_str));
+ ShowStatus("Login server binding IP address : %s -> %s\n", w2, sockt->ip2str(login->config->login_ip, ip_str));
}
}
else if( !strcmpi(w1, "login_port") ) {
- login_config.login_port = (uint16)atoi(w2);
+ login->config->login_port = (uint16)atoi(w2);
}
else if(!strcmpi(w1, "log_login"))
- login_config.log_login = (bool)config_switch(w2);
+ login->config->log_login = (bool)config_switch(w2);
else if(!strcmpi(w1, "new_account"))
- login_config.new_account_flag = (bool)config_switch(w2);
+ login->config->new_account_flag = (bool)config_switch(w2);
else if(!strcmpi(w1, "new_acc_length_limit"))
- login_config.new_acc_length_limit = (bool)config_switch(w2);
+ login->config->new_acc_length_limit = (bool)config_switch(w2);
else if(!strcmpi(w1, "start_limited_time"))
- login_config.start_limited_time = atoi(w2);
+ login->config->start_limited_time = atoi(w2);
else if(!strcmpi(w1, "check_client_version"))
- login_config.check_client_version = (bool)config_switch(w2);
+ login->config->check_client_version = (bool)config_switch(w2);
else if(!strcmpi(w1, "client_version_to_connect"))
- login_config.client_version_to_connect = (unsigned int)strtoul(w2, NULL, 10);
+ login->config->client_version_to_connect = (unsigned int)strtoul(w2, NULL, 10);
else if(!strcmpi(w1, "use_MD5_passwords"))
- login_config.use_md5_passwds = (bool)config_switch(w2);
+ login->config->use_md5_passwds = (bool)config_switch(w2);
else if(!strcmpi(w1, "group_id_to_connect"))
- login_config.group_id_to_connect = atoi(w2);
+ login->config->group_id_to_connect = atoi(w2);
else if(!strcmpi(w1, "min_group_id_to_connect"))
- login_config.min_group_id_to_connect = atoi(w2);
+ login->config->min_group_id_to_connect = atoi(w2);
else if(!strcmpi(w1, "date_format"))
- safestrncpy(login_config.date_format, w2, sizeof(login_config.date_format));
+ safestrncpy(login->config->date_format, w2, sizeof(login->config->date_format));
else if(!strcmpi(w1, "allowed_regs")) //account flood protection system
- login_config.allowed_regs = atoi(w2);
+ login->config->allowed_regs = atoi(w2);
else if(!strcmpi(w1, "time_allowed"))
- login_config.time_allowed = atoi(w2);
+ login->config->time_allowed = atoi(w2);
else if(!strcmpi(w1, "use_dnsbl"))
- login_config.use_dnsbl = (bool)config_switch(w2);
+ login->config->use_dnsbl = (bool)config_switch(w2);
else if(!strcmpi(w1, "dnsbl_servers"))
- safestrncpy(login_config.dnsbl_servs, w2, sizeof(login_config.dnsbl_servs));
+ safestrncpy(login->config->dnsbl_servs, w2, sizeof(login->config->dnsbl_servs));
else if(!strcmpi(w1, "ipban_cleanup_interval"))
- login_config.ipban_cleanup_interval = (unsigned int)atoi(w2);
+ login->config->ipban_cleanup_interval = (unsigned int)atoi(w2);
else if(!strcmpi(w1, "ip_sync_interval"))
- login_config.ip_sync_interval = (unsigned int)1000*60*atoi(w2); //w2 comes in minutes.
+ login->config->ip_sync_interval = (unsigned int)1000*60*atoi(w2); //w2 comes in minutes.
else if(!strcmpi(w1, "client_hash_check"))
- login_config.client_hash_check = config_switch(w2);
+ login->config->client_hash_check = config_switch(w2);
else if(!strcmpi(w1, "client_hash")) {
int group = 0;
char md5[33];
@@ -1831,9 +1829,9 @@ int login_config_read(const char* cfgName)
}
nnode->group_id = group;
- nnode->next = login_config.client_hash_nodes;
+ nnode->next = login->config->client_hash_nodes;
- login_config.client_hash_nodes = nnode;
+ login->config->client_hash_nodes = nnode;
}
}
else if(!strcmpi(w1, "import"))
@@ -1858,7 +1856,7 @@ int login_config_read(const char* cfgName)
//--------------------------------------
int do_final(void) {
int i;
- struct client_hash_node *hn = login_config.client_hash_nodes;
+ struct client_hash_node *hn = login->config->client_hash_nodes;
ShowStatus("Terminating...\n");
@@ -1872,7 +1870,7 @@ int do_final(void) {
login_log(0, "login server", 100, "login server shutdown");
- if( login_config.log_login )
+ if (login->config->log_login)
loginlog_final();
ipban_final();
@@ -1986,7 +1984,7 @@ int do_init(int argc, char** argv)
login_defaults();
// read login-server configuration
- login_set_defaults();
+ login->config_set_defaults();
login->LOGIN_CONF_NAME = aStrdup("conf/login-server.conf");
login->NET_CONF_NAME = aStrdup("conf/network.conf");
@@ -2004,7 +2002,7 @@ int do_init(int argc, char** argv)
chrif_server_init(i);
// initialize logging
- if( login_config.log_login )
+ if (login->config->log_login)
loginlog_init();
// initialize static and dynamic ipban system
@@ -2025,9 +2023,9 @@ int do_init(int argc, char** argv)
timer->add_interval(timer->gettick() + 600*1000, login->online_data_cleanup, 0, 0, 600*1000);
// add timer to detect ip address change and perform update
- if (login_config.ip_sync_interval) {
+ if (login->config->ip_sync_interval) {
timer->add_func_list(login->sync_ip_addresses, "login->sync_ip_addresses");
- timer->add_interval(timer->gettick() + login_config.ip_sync_interval, login->sync_ip_addresses, 0, 0, login_config.ip_sync_interval);
+ timer->add_interval(timer->gettick() + login->config->ip_sync_interval, login->sync_ip_addresses, 0, 0, login->config->ip_sync_interval);
}
// Account database init
@@ -2039,8 +2037,8 @@ int do_init(int argc, char** argv)
HPM->event(HPET_INIT);
// server port open & binding
- if ((login->fd = sockt->make_listen_bind(login_config.login_ip,login_config.login_port)) == -1) {
- ShowFatalError("Failed to bind to port '"CL_WHITE"%d"CL_RESET"'\n",login_config.login_port);
+ if ((login->fd = sockt->make_listen_bind(login->config->login_ip,login->config->login_port)) == -1) {
+ ShowFatalError("Failed to bind to port '"CL_WHITE"%d"CL_RESET"'\n",login->config->login_port);
exit(EXIT_FAILURE);
}
@@ -2053,7 +2051,7 @@ int do_init(int argc, char** argv)
console->display_gplnotice();
#endif // CONSOLE_INPUT
- ShowStatus("The login-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %u).\n\n", login_config.login_port);
+ ShowStatus("The login-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %u).\n\n", login->config->login_port);
login_log(0, "login server", 100, "login server started");
HPM->event(HPET_READY);
@@ -2064,7 +2062,7 @@ int do_init(int argc, char** argv)
void login_defaults(void) {
login = &login_s;
- login->lc = &login_config;
+ login->config = &login_config_;
login->accounts = accounts;
login->mmo_auth = login_mmo_auth;
@@ -2124,6 +2122,8 @@ void login_defaults(void) {
login->login_error = login_login_error;
login->send_coding_key = login_send_coding_key;
+ login->config_set_defaults = login_config_set_defaults;
+ login->config_read = login_config_read;
login->LOGIN_CONF_NAME = NULL;
login->NET_CONF_NAME = NULL;
}
diff --git a/src/login/login.h b/src/login/login.h
index 8036d04ad..f79f75cb3 100644
--- a/src/login/login.h
+++ b/src/login/login.h
@@ -152,7 +152,7 @@ struct login_interface {
DBMap* auth_db;
DBMap* online_db;
int fd;
- struct Login_Config *lc;
+ struct Login_Config *config;
struct AccountDB* accounts;
int (*mmo_auth) (struct login_session_data* sd, bool isServer);
@@ -209,13 +209,14 @@ struct login_interface {
void (*char_server_connection_status) (int fd, struct login_session_data* sd, uint8 status);
void (*parse_request_connection) (int fd, struct login_session_data* sd, const char *ip, uint32 ipl);
int (*parse_login) (int fd);
+ void (*config_set_defaults) (void);
+ int (*config_read) (const char *cfgName);
char *LOGIN_CONF_NAME;
char *NET_CONF_NAME; ///< Network configuration filename
};
#ifdef HERCULES_CORE
extern struct mmo_char_server server[MAX_SERVERS];
-extern struct Login_Config login_config;
void login_defaults(void);
#endif // HERCULES_CORE
diff --git a/src/map/Makefile.in b/src/map/Makefile.in
index 60d87522e..b5a3d4461 100644
--- a/src/map/Makefile.in
+++ b/src/map/Makefile.in
@@ -116,13 +116,13 @@ map-server: ../../map-server@EXEEXT@
../../map-server@EXEEXT@: $(MAP_SERVER_SQL_DEPENDS) Makefile
@echo " LD $(notdir $@)"
@$(CC) @STATIC@ @LDFLAGS@ -o ../../map-server@EXEEXT@ $(MAP_OBJ) $(COMMON_D)/obj_sql/common_sql.a \
- $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
+ $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@
# map object files
obj_sql/%.o: %.c $(MAP_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj_sql
@echo " CC $<"
- @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @PCRE_CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+ @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
# missing object files
$(COMMON_D)/obj_all/common.a:
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 9d03dd057..bc539837d 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -260,24 +260,28 @@ ACMD(send)
if (type >= MIN_PACKET_DB && type <= MAX_PACKET_DB) {
int off = 2;
+ if (clif->packet(type) == NULL) {
+ // unknown packet - ERROR
+ safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,905), type); // Unknown packet: 0x%x
+ clif->message(fd, atcmd_output);
+ return false;
+ }
+
if (len) {
// show packet length
safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,904), type, clif->packet(type)->len); // Packet 0x%x length: %d
clif->message(fd, atcmd_output);
return true;
}
-
+
len = clif->packet(type)->len;
- if (len == 0) {
- // unknown packet - ERROR
- safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,905), type); // Unknown packet: 0x%x
- clif->message(fd, atcmd_output);
- return false;
- } else if (len == -1) {
+
+ if (len == -1) {
// dynamic packet
len = SHRT_MAX-4; // maximum length
off = 4;
}
+
WFIFOHEAD(sd->fd, len);
WFIFOW(sd->fd,0)=TOW(type);
@@ -3917,7 +3921,7 @@ ACMD(mapinfo)
strcat(atcmd_output, msg_fd(fd,1096)); // PartyLock |
if (map->list[m_id].flag.guildlock)
strcat(atcmd_output, msg_fd(fd,1097)); // GuildLock |
- if (map->list[m_id].flag.noviewid)
+ if (map->list[m_id].flag.noviewid != EQP_NONE)
strcat(atcmd_output, msg_fd(fd,1079)); // NoViewID |
clif->message(fd, atcmd_output);
@@ -8414,6 +8418,7 @@ ACMD(charcommands)
atcommand->commands_sub(sd, fd, COMMAND_CHARCOMMAND);
return true;
}
+
/* for new mounts */
ACMD(cashmount)
{
@@ -8425,7 +8430,7 @@ ACMD(cashmount)
clif->message(sd->fd,msg_fd(fd,1362)); // NOTICE: If you crash with mount your LUA is outdated.
if (!sd->sc.data[SC_ALL_RIDING]) {
clif->message(sd->fd,msg_fd(fd,1363)); // You have mounted.
- sc_start(NULL,&sd->bl,SC_ALL_RIDING,100,0,-1);
+ sc_start(NULL,&sd->bl,SC_ALL_RIDING,100,25,-1);
} else {
clif->message(sd->fd,msg_fd(fd,1364)); // You have released your mount.
status_change_end(&sd->bl, SC_ALL_RIDING, INVALID_TIMER);
diff --git a/src/map/battle.c b/src/map/battle.c
index 3b3ea2047..44adef051 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -4118,7 +4118,8 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
#else
short totaldef = tstatus->def2 + (short)status->get_def(target);
#endif
- if ( sd ) wd.damage += sd->bonus.arrow_atk;
+ if (sd != NULL)
+ wd.damage += sd->bonus.arrow_atk;
md.damage = (int)(3 * (1 + wd.damage) * (5 + skill_lv) / 5.0f);
md.damage -= totaldef;
@@ -4583,7 +4584,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
skill_id == NJ_KIRIKAGE))
{
short cri = sstatus->cri;
- if (sd) {
+ if (sd != NULL) {
// if show_katar_crit_bonus is enabled, it already done the calculation in status.c
if (!battle_config.show_katar_crit_bonus && sd->status.weapon == W_KATAR) {
cri <<= 1;
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 1f7fbe96e..258d550d4 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -1394,16 +1394,16 @@ int chrif_parse(int fd) {
}
while (RFIFOREST(fd) >= 2) {
+ cmd = RFIFOW(fd,0);
+
if (VECTOR_LENGTH(HPM->packets[hpChrif_Parse]) > 0) {
- int result = HPM->parse_packets(fd,hpChrif_Parse);
+ int result = HPM->parse_packets(fd,cmd,hpChrif_Parse);
if (result == 1)
continue;
if (result == 2)
return 0;
}
- cmd = RFIFOW(fd,0);
-
if (cmd < 0x2af8 || cmd >= 0x2af8 + ARRAYLENGTH(chrif->packet_len_table) || chrif->packet_len_table[cmd-0x2af8] == 0) {
int result = intif->parse(fd); // Passed on to the intif
diff --git a/src/map/clif.c b/src/map/clif.c
index 827f57c45..3b2f255ef 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1010,7 +1010,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
#endif
#if PACKETVER >= 20131223
p.AID = bl->id;
- p.GID = (sd) ? sd->status.char_id : 0; // CCODE
+ p.GID = (sd) ? sd->status.char_id : 0; // CCODE
#else
p.GID = bl->id;
#endif
@@ -1151,7 +1151,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
#endif
#if PACKETVER >= 20131223
p.AID = bl->id;
- p.GID = (sd) ? sd->status.char_id : 0; // CCODE
+ p.GID = (sd) ? sd->status.char_id : 0; // CCODE
#else
p.GID = bl->id;
#endif
@@ -1246,7 +1246,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
#endif
#if PACKETVER >= 20131223
p.AID = bl->id;
- p.GID = (tsd) ? tsd->status.char_id : 0; // CCODE
+ p.GID = (tsd) ? tsd->status.char_id : 0; // CCODE
#else
p.GID = bl->id;
#endif
@@ -2333,9 +2333,9 @@ void clif_add_random_options(unsigned char* buf, struct item* item)
int i;
nullpo_retv(buf);
for (i = 0; i < 5; i++){
- WBUFW(buf,i*5+0) = 0; // OptIndex
- WBUFW(buf,i*5+2) = 0; // Value
- WBUFB(buf,i*5+4) = 0; // Param1
+ WBUFW(buf,i*5+0) = 0; // OptIndex
+ WBUFW(buf,i*5+2) = 0; // Value
+ WBUFB(buf,i*5+4) = 0; // Param1
}
}
@@ -4330,7 +4330,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int
p.leftDamage = damage2;
}
#if PACKETVER >= 20131223
- p.is_sp_damaged = 0; // [ToDo] IsSPDamage - Displays blue digits.
+ p.is_sp_damaged = 0; // TODO: IsSPDamage - Displays blue digits.
#endif
if(disguised(dst)) {
@@ -5078,7 +5078,7 @@ int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick
// type 6 (ACTION_SKILL) skills. So we have to do a small
// hack to set all type 6 to be sent as type 8 ACTION_ATTACK_MULTIPLE
#if PACKETVER < 20131223
- WBUFB(buf, 32) = type;
+ WBUFB(buf, 32) = type;
#else
WBUFB(buf, 32) = (type == BDT_SKILL) ? BDT_MULTIHIT : type;
#endif
@@ -9859,10 +9859,8 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
// Chat logging type 'O' / Global Chat
logs->chat(LOG_CHAT_GLOBAL, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, message);
-#ifdef PCRE_SUPPORT
// trigger listening npcs
map->foreachinrange(npc_chat->sub, &sd->bl, AREA_SIZE, BL_NPC, text, textlen, &sd->bl);
-#endif
}
void clif_parse_MapMove(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
@@ -10398,7 +10396,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd) __attribute__((non
/// 00a9 <index>.W <position>.W
/// 0998 <index>.W <position>.L
void clif_parse_EquipItem(int fd,struct map_session_data *sd) {
- struct packet_equip_item *p = P2PTR(fd);
+ struct packet_equip_item *p = RP2PTR(fd);
if(pc_isdead(sd)) {
clif->clearunit_area(&sd->bl,CLR_DEAD);
@@ -10874,6 +10872,25 @@ void clif_parse_ChangeCart(int fd,struct map_session_data *sd)
pc->setcart(sd,type);
}
+/// Request to select cart's visual look for new cart design (CZ_SELECTCART).
+/// 0980 <identity>.L <type>.B
+void clif_parse_SelectCart(int fd, struct map_session_data *sd)
+{
+#if PACKETVER >= 20150805 // RagexeRE
+ int type;
+
+ if (!sd || !pc->checkskill(sd, MC_CARTDECORATE) || RFIFOL(fd, 2) != sd->status.account_id)
+ return;
+
+ type = (int)RFIFOB(fd, 6);
+
+ if (type <= MAX_BASE_CARTS || type > MAX_CARTS)
+ return;
+
+ pc->setcart(sd, type);
+#endif
+}
+
void clif_parse_StatusUp(int fd,struct map_session_data *sd) __attribute__((nonnull (2)));
/// Request to increase status (CZ_STATUS_CHANGE).
/// 00bb <status id>.W <amount>.B
@@ -11465,6 +11482,22 @@ void clif_parse_ItemIdentify(int fd,struct map_session_data *sd)
clif_menuskill_clear(sd);
}
+/// Identifying item with right-click (CZ_REQ_ONECLICK_ITEMIDENTIFY).
+/// 0A35 <index>.W
+void clif_parse_OneClick_ItemIdentify(int fd, struct map_session_data *sd)
+{
+ int cmd = RFIFOW(fd,0);
+ short idx = RFIFOW(fd, packet_db[cmd].pos[0]) - 2;
+ int n;
+
+ if (idx < 0 || idx >= MAX_INVENTORY || sd->inventory_data[idx] == NULL || sd->status.inventory[idx].nameid <= 0)
+ return;
+
+ if ((n = pc->have_magnifier(sd) ) != INDEX_NOT_FOUND &&
+ pc->delitem(sd, n, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER) == 0)
+ skill->identify(sd, idx);
+}
+
void clif_parse_SelectArrow(int fd,struct map_session_data *sd) __attribute__((nonnull (2)));
/// Answer to arrow crafting item selection dialog (CZ_REQ_MAKINGARROW).
/// 01ae <name id>.W
@@ -13344,7 +13377,7 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) __attribute
/// 013f <item/mob name>.24B
/// 09ce <item/mob name>.100B [Ind/Yommy<3]
void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) {
- struct packet_gm_monster_item *p = P2PTR(fd);
+ struct packet_gm_monster_item *p = RP2PTR(fd);
int i, count;
char *item_monster_name;
struct item_data *item_array[10];
@@ -17547,18 +17580,18 @@ void clif_maptypeproperty2(struct block_list *bl,enum send_target t) {
p.PacketType = maptypeproperty2Type;
p.type = 0x28;
- p.flag.party = map->list[bl->m].flag.pvp ? 1 : 0; //PARTY
- p.flag.guild = (map->list[bl->m].flag.battleground || map_flag_gvg(bl->m)) ? 1 : 0; // GUILD
- p.flag.siege = (map->list[bl->m].flag.battleground || map_flag_gvg2(bl->m)) ? 1: 0; // SIEGE
- p.flag.mineffect = map_flag_gvg(bl->m) ? 1 : ( (sd && sd->state.lesseffect) ? 1 : 0); // USE_SIMPLE_EFFECT - Forcing /mineffect in castles during WoE (probably redundant? I'm not sure)
+ p.flag.party = map->list[bl->m].flag.pvp ? 1 : 0; //PARTY
+ p.flag.guild = (map->list[bl->m].flag.battleground || map_flag_gvg(bl->m)) ? 1 : 0; // GUILD
+ p.flag.siege = (map->list[bl->m].flag.battleground || map_flag_gvg2(bl->m)) ? 1: 0; // SIEGE
+ p.flag.mineffect = map_flag_gvg(bl->m) ? 1 : ( (sd && sd->state.lesseffect) ? 1 : 0); // USE_SIMPLE_EFFECT - Forcing /mineffect in castles during WoE (probably redundant? I'm not sure)
p.flag.nolockon = 0; // DISABLE_LOCKON - TODO
- p.flag.countpk = map->list[bl->m].flag.pvp ? 1 : 0; // COUNT_PK
- p.flag.nopartyformation = map->list[bl->m].flag.partylock ? 1 : 0; // NO_PARTY_FORMATION
- p.flag.bg = map->list[bl->m].flag.battleground ? 1 : 0; // BATTLEFIELD
+ p.flag.countpk = map->list[bl->m].flag.pvp ? 1 : 0; // COUNT_PK
+ p.flag.nopartyformation = map->list[bl->m].flag.partylock ? 1 : 0; // NO_PARTY_FORMATION
+ p.flag.bg = map->list[bl->m].flag.battleground ? 1 : 0; // BATTLEFIELD
p.flag.nocostume = (map->list[bl->m].flag.noviewid & EQP_COSTUME) ? 1 : 0; // DISABLE_COSTUMEITEM - Disables Costume Sprite
p.flag.usecart = 1; // USECART - TODO
p.flag.summonstarmiracle = 0; // SUNMOONSTAR_MIRACLE - TODO
- p.flag.SpareBits = 0; // UNUSED
+ p.flag.SpareBits = 0; // UNUSED
clif->send(&p,sizeof(p),bl,t);
#endif
@@ -17659,7 +17692,7 @@ void clif_bgqueue_notice_delete(struct map_session_data *sd, enum BATTLEGROUNDS_
void clif_parse_bgqueue_register(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
void clif_parse_bgqueue_register(int fd, struct map_session_data *sd) {
- struct packet_bgqueue_register *p = P2PTR(fd);
+ struct packet_bgqueue_register *p = RP2PTR(fd);
struct bg_arena *arena = NULL;
if( !bg->queue_on ) return; /* temp, until feature is complete */
@@ -17697,7 +17730,7 @@ void clif_bgqueue_update_info(struct map_session_data *sd, unsigned char arena_i
void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) {
- struct packet_bgqueue_checkstate *p = P2PTR(fd);
+ struct packet_bgqueue_checkstate *p = RP2PTR(fd);
nullpo_retv(sd);
if ( sd->bg_queue.arena && sd->bg_queue.type ) {
@@ -17708,7 +17741,7 @@ void clif_parse_bgqueue_checkstate(int fd, struct map_session_data *sd) {
void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) {
- struct packet_bgqueue_revoke_req *p = P2PTR(fd);
+ struct packet_bgqueue_revoke_req *p = RP2PTR(fd);
if( sd->bg_queue.arena )
bg->queue_pc_cleanup(sd);
@@ -17718,7 +17751,7 @@ void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) {
void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) {
- struct packet_bgqueue_battlebegin_ack *p = P2PTR(fd);
+ struct packet_bgqueue_battlebegin_ack *p = RP2PTR(fd);
struct bg_arena *arena;
if( !bg->queue_on ) return; /* temp, until feature is complete */
@@ -17857,7 +17890,7 @@ void clif_cart_additem_ack(struct map_session_data *sd, int flag) {
void clif_parse_BankDeposit(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
/* Bank System [Yommy/Hercules] */
void clif_parse_BankDeposit(int fd, struct map_session_data* sd) {
- struct packet_banking_deposit_req *p = P2PTR(fd);
+ struct packet_banking_deposit_req *p = RP2PTR(fd);
int money;
if (!battle_config.feature_banking) {
@@ -17872,7 +17905,7 @@ void clif_parse_BankDeposit(int fd, struct map_session_data* sd) {
void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) __attribute__((nonnull (2)));
void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) {
- struct packet_banking_withdraw_req *p = P2PTR(fd);
+ struct packet_banking_withdraw_req *p = RP2PTR(fd);
int money;
if (!battle_config.feature_banking) {
@@ -18149,7 +18182,7 @@ void clif_npc_market_purchase_ack(struct map_session_data *sd, struct packet_npc
void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) {
#if PACKETVER >= 20131223
- struct packet_npc_market_purchase *p = P2PTR(fd);
+ struct packet_npc_market_purchase *p = RP2PTR(fd);
clif->npc_market_purchase_ack(sd,p,npc->market_buylist(sd,(p->PacketLength - 4) / sizeof(p->list[0]),p));
#endif
@@ -18607,6 +18640,28 @@ void clif_dressroom_open(struct map_session_data *sd, int view)
WFIFOSET(fd,packet_len(0xa02));
}
+/// Request to select cart's visual look for new cart design (ZC_SELECTCART).
+/// 097f <Length>.W <identity>.L <type>.B
+void clif_selectcart(struct map_session_data *sd)
+{
+#if PACKETVER >= 20150805
+ int i = 0, fd;
+
+ fd = sd->fd;
+
+ WFIFOHEAD(fd, 8 + MAX_CARTDECORATION_CARTS);
+ WFIFOW(fd, 0) = 0x97f;
+ WFIFOW(fd, 2) = 8 + MAX_CARTDECORATION_CARTS;
+ WFIFOL(fd, 4) = sd->status.account_id;
+
+ for (i = 0; i < MAX_CARTDECORATION_CARTS; i++) {
+ WFIFOB(fd, 8 + i) = MAX_BASE_CARTS + 1 + i;
+ }
+
+ WFIFOSET(fd, 8 + MAX_CARTDECORATION_CARTS);
+#endif
+}
+
/* */
unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
if( sd ) {
@@ -18688,21 +18743,21 @@ int clif_parse(int fd) {
if (RFIFOREST(fd) < 2)
return 0;
+ if (sd)
+ parse_cmd_func = sd->parse_cmd_func;
+ else
+ parse_cmd_func = clif->parse_cmd;
+
+ cmd = parse_cmd_func(fd,sd);
+
if (VECTOR_LENGTH(HPM->packets[hpClif_Parse]) > 0) {
- int result = HPM->parse_packets(fd,hpClif_Parse);
+ int result = HPM->parse_packets(fd,cmd,hpClif_Parse);
if (result == 1)
continue;
if (result == 2)
return 0;
}
- if( sd )
- parse_cmd_func = sd->parse_cmd_func;
- else
- parse_cmd_func = clif->parse_cmd;
-
- cmd = parse_cmd_func(fd,sd);
-
// filter out invalid / unsupported packets
if (cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0) {
ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x (0x%04x), %"PRIuS" bytes received), disconnecting session #%d.\n",
@@ -18814,6 +18869,11 @@ static void __attribute__ ((unused)) packetdb_addpacket(short cmd, int len, ...)
return;
}
+ if (cmd < MIN_PACKET_DB) {
+ ShowError("Packet Error: packet 0x%x is lower than the minimum allowed (0x%x), skipping...\n", cmd, MIN_PACKET_DB);
+ return;
+ }
+
packet_db[cmd].len = len;
va_start(va,len);
@@ -19419,6 +19479,8 @@ void clif_defaults(void) {
clif->cancelmergeitem = clif_cancelmergeitem;
clif->comparemergeitem = clif_comparemergeitem;
clif->ackmergeitems = clif_ackmergeitems;
+ /* Cart Deco */
+ clif->selectcart = clif_selectcart;
/*------------------------
*- Parse Incoming Packet
@@ -19467,6 +19529,7 @@ void clif_defaults(void) {
clif->pGetItemFromCart = clif_parse_GetItemFromCart;
clif->pRemoveOption = clif_parse_RemoveOption;
clif->pChangeCart = clif_parse_ChangeCart;
+ clif->pSelectCart = clif_parse_SelectCart;
clif->pStatusUp = clif_parse_StatusUp;
clif->pSkillUp = clif_parse_SkillUp;
clif->pUseSkillToId = clif_parse_UseSkillToId;
@@ -19663,4 +19726,5 @@ void clif_defaults(void) {
clif->add_random_options = clif_add_random_options;
clif->pHotkeyRowShift = clif_parse_HotkeyRowShift;
clif->dressroom_open = clif_dressroom_open;
+ clif->pOneClick_ItemIdentify = clif_parse_OneClick_ItemIdentify;
}
diff --git a/src/map/clif.h b/src/map/clif.h
index 5a6b01d31..d68a09393 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -58,12 +58,11 @@ struct view_data;
* Defines
**/
#define packet_len(cmd) packet_db[cmd].len
-#define P2PTR(fd) RFIFO2PTR(fd)
#define clif_menuskill_clear(sd) ((sd)->menuskill_id = (sd)->menuskill_val = (sd)->menuskill_val2 = 0)
#define clif_disp_onlyself(sd,mes,len) clif->disp_message( &(sd)->bl, (mes), (len), SELF )
#define MAX_ROULETTE_LEVEL 7 /** client-defined value **/
#define MAX_ROULETTE_COLUMNS 9 /** client-defined value **/
-#define RGB2BGR(c) ((c & 0x0000FF) << 16 | (c & 0x00FF00) | (c & 0xFF0000) >> 16)
+#define RGB2BGR(c) (((c) & 0x0000FF) << 16 | ((c) & 0x00FF00) | ((c) & 0xFF0000) >> 16)
#define COLOR_RED 0xff0000U
#define COLOR_GREEN 0x00ff00U
@@ -73,12 +72,6 @@ struct view_data;
/**
* Enumerations
**/
-enum {// packet DB
- MIN_PACKET_DB = 0x0064,
- MAX_PACKET_DB = 0x0F00,
- MAX_PACKET_POS = 20,
-};
-
typedef enum send_target {
ALL_CLIENT,
ALL_SAMEMAP,
@@ -1338,6 +1331,10 @@ struct clif_interface {
void (*add_random_options) (unsigned char* buf, struct item* item);
void (*pHotkeyRowShift) (int fd, struct map_session_data *sd);
void (*dressroom_open) (struct map_session_data *sd, int view);
+ void (*pOneClick_ItemIdentify) (int fd,struct map_session_data *sd);
+ /* Cart Deco */
+ void(*selectcart) (struct map_session_data *sd);
+ void(*pSelectCart) (int fd, struct map_session_data *sd);
};
#ifdef HERCULES_CORE
diff --git a/src/map/guild.c b/src/map/guild.c
index cba05638f..f4f0c0528 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -1117,7 +1117,7 @@ int guild_change_position(int guild_id,int idx,int mode,int exp_mode,const char
nullpo_ret(name);
exp_mode = cap_value(exp_mode, 0, battle_config.guild_exp_limit);
- p.mode=mode&GPERM_BOTH; // Invite and Expel
+ p.mode=mode&GPERM_MASK;
p.exp_mode=exp_mode;
safestrncpy(p.name,name,NAME_LENGTH);
return intif->guild_position(guild_id,idx,&p);
diff --git a/src/map/homunculus.h b/src/map/homunculus.h
index 1712c98a9..c2ce042ec 100644
--- a/src/map/homunculus.h
+++ b/src/map/homunculus.h
@@ -63,14 +63,15 @@ enum homun_id {
#define homun_alive(x) ((x) && (x)->homunculus.vaporize == HOM_ST_ACTIVE && (x)->battle_status.hp > 0)
#ifdef RENEWAL
-#define HOMUN_LEVEL_STATWEIGHT_VALUE 0
-#define APPLY_HOMUN_LEVEL_STATWEIGHT()( \
- hom->str_value = hom->agi_value = \
- hom->vit_value = hom->int_value = \
- hom->dex_value = hom->luk_value = hom->level / 10 - HOMUN_LEVEL_STATWEIGHT_VALUE \
- )
+#define HOMUN_LEVEL_STATWEIGHT_VALUE 0
+#define APPLY_HOMUN_LEVEL_STATWEIGHT() \
+ do { \
+ hom->str_value = hom->agi_value = \
+ hom->vit_value = hom->int_value = \
+ hom->dex_value = hom->luk_value = hom->level / 10 - HOMUN_LEVEL_STATWEIGHT_VALUE; \
+ } while (false)
#else
-#define APPLY_HOMUN_LEVEL_STATWEIGHT()
+#define APPLY_HOMUN_LEVEL_STATWEIGHT() (void)0
#endif
struct h_stats {
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 048efd636..bd552dd16 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -1188,7 +1188,7 @@ void itemdb_read_chains(void) {
int c = 0;
config_setting_t *entry = NULL;
- script->set_constant2(name,i-1,0);
+ script->set_constant2(name, i-1, false, false);
itemdb->chains[count].qty = (unsigned short)libconfig->setting_length(itc);
CREATE(itemdb->chains[count].items, struct item_chain_entry, libconfig->setting_length(itc));
@@ -1254,7 +1254,8 @@ int itemdb_combo_split_atoi (char *str, int *val) {
/**
* <combo{:combo{:combo:{..}}}>,<{ script }>
**/
-void itemdb_read_combos() {
+void itemdb_read_combos(void)
+{
uint32 lines = 0, count = 0;
char line[1024];
char filepath[256];
@@ -1384,17 +1385,17 @@ int itemdb_gendercheck(struct item_data *id)
* This function is called after preparing the item entry data, and it takes
* care of inserting it and cleaning up any remainders of the previous one.
*
- * @param *entry Pointer to the new item_data entry. Ownership is NOT taken,
- * but the content is modified to reflect the validation.
- * @param n Ordinal number of the entry, to be displayed in case of
- * validation errors.
- * @param *source Source of the entry (table or file name), to be displayed in
- * case of validation errors.
+ * @param entry Pointer to the new item_data entry. Ownership is NOT taken,
+ * but the content is modified to reflect the validation.
+ * @param n Ordinal number of the entry, to be displayed in case of
+ * validation errors.
+ * @param source Source of the entry (file name), to be displayed in case of
+ * validation errors.
* @return Nameid of the validated entry, or 0 in case of failure.
*
- * Note: This is safe to call if the new entry is a copy of the old one (i.e.
- * item_db2 inheritance), as it will make sure not to free any scripts still in
- * use in the new entry.
+ * Note: This is safe to call if the new entry is a shallow copy of the old one
+ * (i.e. item_db2 inheritance), as it will make sure not to free any scripts
+ * still in use by the new entry.
*/
int itemdb_validate_entry(struct item_data *entry, int n, const char *source) {
struct item_data *item;
@@ -1543,13 +1544,13 @@ void itemdb_readdb_additional_fields(int itemid, config_setting_t *it, int n, co
* Processes one itemdb entry from the libconfig backend, loading and inserting
* it into the item database.
*
- * @param *it Libconfig setting entry. It is expected to be valid and it
- * won't be freed (it is care of the caller to do so if
- * necessary)
- * @param n Ordinal number of the entry, to be displayed in case of
- * validation errors.
- * @param *source Source of the entry (file name), to be displayed in case of
- * validation errors.
+ * @param it Libconfig setting entry. It is expected to be valid and it
+ * won't be freed (it is care of the caller to do so if
+ * necessary)
+ * @param n Ordinal number of the entry, to be displayed in case of
+ * validation errors.
+ * @param source Source of the entry (file name), to be displayed in case of
+ * validation errors.
* @return Nameid of the validated entry, or 0 in case of failure.
*/
int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source) {
@@ -1626,7 +1627,7 @@ int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source)
} else {
// Use old entry as default
struct item_data *old_entry = itemdb->load(id.nameid);
- memcpy(&id, old_entry, sizeof(struct item_data));
+ memcpy(&id, old_entry, sizeof(id));
}
}
@@ -1873,7 +1874,7 @@ bool itemdb_lookup_const(const config_setting_t *it, const char *name, int *valu
* Reads from a libconfig-formatted itemdb file and inserts the found entries into the
* item database, overwriting duplicate ones (i.e. item_db2 overriding item_db.)
*
- * @param *filename File name, relative to the database path.
+ * @param filename File name, relative to the database path.
* @return The number of found entries.
*/
int itemdb_readdb_libconfig(const char *filename) {
@@ -2148,7 +2149,7 @@ void itemdb_name_constants(void) {
script->parser_current_file = "Item Database (Likely an invalid or conflicting AegisName)";
#endif // ENABLE_CASE_CHECK
for( data = dbi_first(iter); dbi_exists(iter); data = dbi_next(iter) )
- script->set_constant2(data->name,data->nameid,0);
+ script->set_constant2(data->name, data->nameid, false, false);
#ifdef ENABLE_CASE_CHECK
script->parser_current_file = NULL;
#endif // ENABLE_CASE_CHECK
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index d751451c6..8a0ec389d 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -64,6 +64,7 @@ enum item_itemid {
ITEMID_BRANCH_OF_DEAD_TREE = 604,
ITEMID_ANODYNE = 605,
ITEMID_ALOEBERA = 606,
+ ITEMID_MAGNIFIER = 611,
ITEMID_POISON_BOTTLE = 678,
ITEMID_EMPTY_BOTTLE = 713,
ITEMID_EMPERIUM = 714,
@@ -136,6 +137,7 @@ enum item_itemid {
ITEMID_MAGIC_CASTLE = 12308,
ITEMID_BULGING_HEAD = 12309,
ITEMID_THICK_MANUAL50 = 12312,
+ ITEMID_NOVICE_MAGNIFIER = 12325,
ITEMID_ANCILLA = 12333,
ITEMID_REPAIR_A = 12392,
ITEMID_REPAIR_B = 12393,
@@ -626,7 +628,7 @@ struct itemdb_interface {
int (*isidentified) (int nameid);
int (*isidentified2) (struct item_data *data);
int (*combo_split_atoi) (char *str, int *val);
- void (*read_combos) ();
+ void (*read_combos) (void);
int (*gendercheck) (struct item_data *id);
int (*validate_entry) (struct item_data *entry, int n, const char *source);
void (*readdb_additional_fields) (int itemid, config_setting_t *it, int n, const char *source);
diff --git a/src/map/map.c b/src/map/map.c
index 1b922148b..3dad25fce 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -5774,9 +5774,7 @@ void map_load_defaults(void) {
pet_defaults();
path_defaults();
quest_defaults();
-#ifdef PCRE_SUPPORT
npc_chat_defaults();
-#endif
}
/**
* --run-once handler
diff --git a/src/map/map.h b/src/map/map.h
index 4c74d352c..ff7ca2d38 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -716,7 +716,7 @@ struct map_data {
unsigned noknockback : 1;
unsigned notomb : 1;
unsigned nocashshop : 1;
- unsigned noviewid : 22;
+ uint32 noviewid; ///< noviewid (bitmask - @see enum equip_pos)
} flag;
struct point save;
struct npc_data *npc[MAX_NPC_PER_MAP];
@@ -866,6 +866,7 @@ typedef struct elemental_data TBL_ELEM;
* object is passed to BL_UCAST. It's declared as static inline to let the
* compiler optimize out the function call overhead.
*/
+static inline struct block_list *BL_UCAST_(struct block_list *bl) __attribute__((unused));
static inline struct block_list *BL_UCAST_(struct block_list *bl)
{
return bl;
@@ -894,6 +895,7 @@ static inline struct block_list *BL_UCAST_(struct block_list *bl)
* object is passed to BL_UCAST. It's declared as static inline to let the
* compiler optimize out the function call overhead.
*/
+static inline const struct block_list *BL_UCCAST_(const struct block_list *bl) __attribute__((unused));
static inline const struct block_list *BL_UCCAST_(const struct block_list *bl)
{
return bl;
diff --git a/src/map/mob.c b/src/map/mob.c
index 37da81a15..bc78c6098 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -2064,7 +2064,7 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage) {
if (battle_config.show_mob_info&3)
clif->charnameack (0, &md->bl);
-
+
#if PACKETVER >= 20131223
// Resend ZC_NOTIFY_MOVEENTRY to Update the HP
if (battle_config.show_monster_hp_bar)
@@ -2482,15 +2482,15 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
if(mvp_sd && md->db->mexp > 0 && md->special_state.ai == AI_NONE) {
int log_mvp[2] = {0};
unsigned int mexp;
- double exp;
+ int64 exp;
//mapflag: noexp check [Lorky]
- if (map->list[m].flag.nobaseexp || type&2)
- exp =1;
- else {
+ if (map->list[m].flag.nobaseexp || type&2) {
+ exp = 1;
+ } else {
exp = md->db->mexp;
if (count > 1)
- exp += exp*(battle_config.exp_bonus_attacker*(count-1))/100.; //[Gengar]
+ exp += apply_percentrate64(exp, battle_config.exp_bonus_attacker * (count-1), 100); //[Gengar]
}
mexp = (unsigned int)cap_value(exp, 1, UINT_MAX);
@@ -3632,7 +3632,7 @@ int mob_makedummymobdb(int class_)
//Adjusts the drop rate of item according to the criteria given. [Skotlex]
unsigned int mob_drop_adjust(int baserate, int rate_adjust, unsigned short rate_min, unsigned short rate_max)
{
- double rate = baserate;
+ int64 rate = baserate;
if (battle_config.logarithmic_drops && rate_adjust > 0 && rate_adjust != 100 && baserate > 0) //Logarithmic drops equation by Ishizu-Chan
//Equation: Droprate(x,y) = x * (5 - log(x)) ^ (ln(y) / ln(5))
@@ -3640,7 +3640,7 @@ unsigned int mob_drop_adjust(int baserate, int rate_adjust, unsigned short rate_
rate = rate * pow((5.0 - log10(rate)), (log(rate_adjust/100.) / log(5.0))) + 0.5;
else
//Classical linear rate adjustment.
- rate = rate * rate_adjust/100;
+ rate = apply_percentrate64(rate, rate_adjust, 100);
return (unsigned int)cap_value(rate,rate_min,rate_max);
}
@@ -3678,30 +3678,45 @@ static inline int mob_parse_dbrow_cap_value(int class_, int min, int max, int va
return value;
}
-void mob_read_db_stats_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t)
+/**
+ * Processes the stats for a mob database entry.
+ *
+ * @param[in,out] entry The destination mob_db entry, already initialized
+ * (mob_id is expected to be already set).
+ * @param[in] t The libconfig entry.
+ */
+void mob_read_db_stats_sub(struct mob_db *entry, config_setting_t *t)
{
int i32;
if (mob->lookup_const(t, "Str", &i32) && i32 >= 0) {
- mstatus->str = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ entry->status.str = mob_parse_dbrow_cap_value(entry->mob_id, UINT16_MIN, UINT16_MAX, i32);
}
if (mob->lookup_const(t, "Agi", &i32) && i32 >= 0) {
- mstatus->agi = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ entry->status.agi = mob_parse_dbrow_cap_value(entry->mob_id, UINT16_MIN, UINT16_MAX, i32);
}
if (mob->lookup_const(t, "Vit", &i32) && i32 >= 0) {
- mstatus->vit = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ entry->status.vit = mob_parse_dbrow_cap_value(entry->mob_id, UINT16_MIN, UINT16_MAX, i32);
}
if (mob->lookup_const(t, "Int", &i32) && i32 >= 0) {
- mstatus->int_ = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ entry->status.int_ = mob_parse_dbrow_cap_value(entry->mob_id, UINT16_MIN, UINT16_MAX, i32);
}
if (mob->lookup_const(t, "Dex", &i32) && i32 >= 0) {
- mstatus->dex = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ entry->status.dex = mob_parse_dbrow_cap_value(entry->mob_id, UINT16_MIN, UINT16_MAX, i32);
}
if (mob->lookup_const(t, "Luk", &i32) && i32 >= 0) {
- mstatus->luk = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ entry->status.luk = mob_parse_dbrow_cap_value(entry->mob_id, UINT16_MIN, UINT16_MAX, i32);
}
}
-int mob_read_db_mode_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t)
+/**
+ * Processes the mode for a mob_db entry.
+ *
+ * @param[in] entry The destination mob_db entry, already initialized.
+ * @param[in] t The libconfig entry.
+ *
+ * @return The parsed mode.
+ */
+int mob_read_db_mode_sub(struct mob_db *entry, config_setting_t *t)
{
int mode = 0;
config_setting_t *t2;
@@ -3740,7 +3755,14 @@ int mob_read_db_mode_sub(struct mob_db *entry, struct status_data *mstatus, int
return mode;
}
-void mob_read_db_mvpdrops_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t)
+/**
+ * Processes the MVP drops for a mob_db entry.
+ *
+ * @param[in,out] entry The destination mob_db entry, already initialized
+ * (mob_id is expected to be already set).
+ * @param[in] t The libconfig entry.
+ */
+void mob_read_db_mvpdrops_sub(struct mob_db *entry, config_setting_t *t)
{
config_setting_t *drop;
int i = 0;
@@ -3752,28 +3774,26 @@ void mob_read_db_mvpdrops_sub(struct mob_db *entry, struct status_data *mstatus,
int rate_adjust = battle_config.item_rate_mvp;
struct item_data* id = itemdb->search_name(name);
int value = 0;
- if (!id)
- {
- ShowWarning("mob_read_db: mvp drop item %s not found in monster %d\n", name, class_);
- i ++;
+ if (!id) {
+ ShowWarning("mob_read_db: mvp drop item %s not found in monster %d\n", name, entry->mob_id);
+ i++;
continue;
}
if (mob->get_const(drop, &i32) && i32 >= 0) {
value = i32;
}
- if (value <= 0)
- {
- ShowWarning("mob_read_db: wrong drop chance %d for mvp drop item %s in monster %d\n", value, name, class_);
- i ++;
+ if (value <= 0) {
+ ShowWarning("mob_read_db: wrong drop chance %d for mvp drop item %s in monster %d\n", value, name, entry->mob_id);
+ i++;
continue;
}
entry->mvpitem[idx].nameid = id->nameid;
if (!entry->mvpitem[idx].nameid) {
entry->mvpitem[idx].p = 0; //No item....
- i ++;
+ i++;
continue;
}
- mob->item_dropratio_adjust(entry->mvpitem[idx].nameid, class_, &rate_adjust);
+ mob->item_dropratio_adjust(entry->mvpitem[idx].nameid, entry->mob_id, &rate_adjust);
entry->mvpitem[idx].p = mob->drop_adjust(value, rate_adjust, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
//calculate and store Max available drop chance of the MVP item
@@ -3787,11 +3807,18 @@ void mob_read_db_mvpdrops_sub(struct mob_db *entry, struct status_data *mstatus,
idx++;
}
if (idx == MAX_MVP_DROP && libconfig->setting_get_elem(t, i)) {
- ShowWarning("mob_read_db: Too many mvp drops in mob %d\n", class_);
+ ShowWarning("mob_read_db: Too many mvp drops in mob %d\n", entry->mob_id);
}
}
-void mob_read_db_drops_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t)
+/**
+ * Processes the drops for a mob_db entry.
+ *
+ * @param[in,out] entry The destination mob_db entry, already initialized
+ * (mob_id, status.mode are expected to be already set).
+ * @param[in] t The libconfig entry.
+ */
+void mob_read_db_drops_sub(struct mob_db *entry, config_setting_t *t)
{
config_setting_t *drop;
int i = 0;
@@ -3805,73 +3832,72 @@ void mob_read_db_drops_sub(struct mob_db *entry, struct status_data *mstatus, in
unsigned short ratemin, ratemax;
struct item_data* id = itemdb->search_name(name);
int value = 0;
- if (!id)
- {
- ShowWarning("mob_read_db: drop item %s not found in monster %d\n", name, class_);
- i ++;
+ if (!id) {
+ ShowWarning("mob_read_db: drop item %s not found in monster %d\n", name, entry->mob_id);
+ i++;
continue;
}
if (mob->get_const(drop, &i32) && i32 >= 0) {
value = i32;
}
- if (value <= 0)
- {
- ShowWarning("mob_read_db: wrong drop chance %d for drop item %s in monster %d\n", value, name, class_);
- i ++;
+ if (value <= 0) {
+ ShowWarning("mob_read_db: wrong drop chance %d for drop item %s in monster %d\n", value, name, entry->mob_id);
+ i++;
continue;
}
entry->dropitem[idx].nameid = id->nameid;
if (!entry->dropitem[idx].nameid) {
entry->dropitem[idx].p = 0; //No drop.
- i ++;
+ i++;
continue;
}
type = id->type;
- if ((class_ >= MOBID_TREASURE_BOX1 && class_ <= MOBID_TREASURE_BOX40) || (class_ >= MOBID_TREASURE_BOX41 && class_ <= MOBID_TREASURE_BOX49)) {
+ if ((entry->mob_id >= MOBID_TREASURE_BOX1 && entry->mob_id <= MOBID_TREASURE_BOX40)
+ || (entry->mob_id >= MOBID_TREASURE_BOX41 && entry->mob_id <= MOBID_TREASURE_BOX49)) {
//Treasure box drop rates [Skotlex]
rate_adjust = battle_config.item_rate_treasure;
ratemin = battle_config.item_drop_treasure_min;
ratemax = battle_config.item_drop_treasure_max;
- }
- else switch (type)
- { // Added support to restrict normal drops of MVP's [Reddozen]
+ } else {
+ switch (type) { // Added support to restrict normal drops of MVP's [Reddozen]
case IT_HEALING:
- rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_heal_boss : battle_config.item_rate_heal;
+ rate_adjust = (entry->status.mode&MD_BOSS) ? battle_config.item_rate_heal_boss : battle_config.item_rate_heal;
ratemin = battle_config.item_drop_heal_min;
ratemax = battle_config.item_drop_heal_max;
break;
case IT_USABLE:
case IT_CASH:
- rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_use_boss : battle_config.item_rate_use;
+ rate_adjust = (entry->status.mode&MD_BOSS) ? battle_config.item_rate_use_boss : battle_config.item_rate_use;
ratemin = battle_config.item_drop_use_min;
ratemax = battle_config.item_drop_use_max;
break;
case IT_WEAPON:
case IT_ARMOR:
case IT_PETARMOR:
- rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_equip_boss : battle_config.item_rate_equip;
+ rate_adjust = (entry->status.mode&MD_BOSS) ? battle_config.item_rate_equip_boss : battle_config.item_rate_equip;
ratemin = battle_config.item_drop_equip_min;
ratemax = battle_config.item_drop_equip_max;
break;
case IT_CARD:
- rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_card_boss : battle_config.item_rate_card;
+ rate_adjust = (entry->status.mode&MD_BOSS) ? battle_config.item_rate_card_boss : battle_config.item_rate_card;
ratemin = battle_config.item_drop_card_min;
ratemax = battle_config.item_drop_card_max;
break;
default:
- rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_common_boss : battle_config.item_rate_common;
+ rate_adjust = (entry->status.mode&MD_BOSS) ? battle_config.item_rate_common_boss : battle_config.item_rate_common;
ratemin = battle_config.item_drop_common_min;
ratemax = battle_config.item_drop_common_max;
break;
+ }
}
- mob->item_dropratio_adjust(id->nameid, class_, &rate_adjust);
+ mob->item_dropratio_adjust(id->nameid, entry->mob_id, &rate_adjust);
entry->dropitem[idx].p = mob->drop_adjust(value, rate_adjust, ratemin, ratemax);
//calculate and store Max available drop chance of the item
if (entry->dropitem[idx].p
- && (class_ < MOBID_TREASURE_BOX1 || class_ > MOBID_TREASURE_BOX40)
- && (class_ < MOBID_TREASURE_BOX41 || class_ > MOBID_TREASURE_BOX49)) {
+ && (entry->mob_id < MOBID_TREASURE_BOX1 || entry->mob_id > MOBID_TREASURE_BOX40)
+ && (entry->mob_id < MOBID_TREASURE_BOX41 || entry->mob_id > MOBID_TREASURE_BOX49)) {
//Skip treasure chests.
if (id->maxchance == -1 || (id->maxchance < entry->dropitem[idx].p) ) {
id->maxchance = entry->dropitem[idx].p; //item has bigger drop chance or sold in shops
@@ -3880,361 +3906,454 @@ void mob_read_db_drops_sub(struct mob_db *entry, struct status_data *mstatus, in
if (id->mob[k].chance <= entry->dropitem[idx].p)
break;
}
- if (k == MAX_SEARCH)
- {
+ if (k == MAX_SEARCH) {
i++;
idx++;
continue;
}
- if (id->mob[k].id != class_ && k != MAX_SEARCH - 1)
+ if (id->mob[k].id != entry->mob_id && k != MAX_SEARCH - 1)
memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
id->mob[k].chance = entry->dropitem[idx].p;
- id->mob[k].id = class_;
+ id->mob[k].id = entry->mob_id;
}
i++;
idx++;
}
if (idx == MAX_MOB_DROP && libconfig->setting_get_elem(t, i)) {
- ShowWarning("mob_read_db: Too many drops in mob %d\n", class_);
+ ShowWarning("mob_read_db: Too many drops in mob %d\n", entry->mob_id);
}
}
-/*==========================================
- * processes one mobdb entry
- *------------------------------------------*/
-bool mob_read_db_sub(config_setting_t *mobt, int id, const char *source)
+/**
+ * Validates a mob DB entry and inserts it into the database.
+ * This function is called after preparing the mob entry data, and it takes
+ * care of inserting it and cleaning up any remainders of the previous one (in
+ * case it is overwriting an existing entry).
+ *
+ * @param entry Pointer to the new mob_db entry. Ownership is NOT taken, but
+ * the content is modified to reflect the validation.
+ * @param n Ordinal number of the entry, to be displayed in case of
+ * validation errors.
+ * @param source Source of the entry (file name), to be displayed in case of
+ * validation errors.
+ * @return Mob ID of the validated entry, or 0 in case of failure.
+ *
+ * Note: This is safe to call if the new entry is a shallow copy of the old one
+ * (i.e. mob_db2 inheritance), as it will make sure not to free any data still
+ * in use by the new entry.
+ */
+int mob_db_validate_entry(struct mob_db *entry, int n, const char *source)
{
- struct mob_db *entry = NULL, tmpEntry;
- config_setting_t *t = NULL;
- int i32 = 0, value = 0, class_ = 0;
- struct status_data *mstatus;
struct mob_data data;
- const char *str = NULL;
- double maxhp;
- double exp;
- bool inherit = false;
- bool range2Updated = false;
- bool range3Updated = false;
- bool dmotionUpdated = false;
- bool maxhpUpdated = false;
- bool maxspUpdated = false;
- entry = &tmpEntry;
- if (!libconfig->setting_lookup_int(mobt, "Id", &class_)) {
- ShowWarning("mob_read_db_sub: Missing id in \"%s\", entry #%d, skipping.\n", source, class_);
- return false;
+ if (entry->mob_id <= 1000 || entry->mob_id > MAX_MOB_DB) {
+ ShowError("mob_db_validate_entry: Invalid monster ID %d, must be in range %d-%d.\n", entry->mob_id, 1000, MAX_MOB_DB);
+ return 0;
+ }
+ if (pc->db_checkid(entry->mob_id)) {
+ ShowError("mob_read_db_sub: Invalid monster ID %d, reserved for player classes.\n", entry->mob_id);
+ return 0;
+ }
+ if (entry->mob_id >= MOB_CLONE_START && entry->mob_id < MOB_CLONE_END) {
+ ShowError("mob_read_db_sub: Invalid monster ID %d. Range %d-%d is reserved for player clones. Please increase MAX_MOB_DB (%d).\n",
+ entry->mob_id, MOB_CLONE_START, MOB_CLONE_END-1, MAX_MOB_DB);
+ return 0;
}
- if (class_ <= 1000 || class_ > MAX_MOB_DB) {
- ShowError("mob_read_db_sub: Invalid monster ID %d, must be in range %d-%d.\n", class_, 1000, MAX_MOB_DB);
- return false;
+ entry->lv = cap_value(entry->lv, 1, USHRT_MAX);
+
+ if (entry->status.max_sp < 1)
+ entry->status.max_sp = 1;
+ //Since mobs always respawn with full life...
+ entry->status.hp = entry->status.max_hp;
+ entry->status.sp = entry->status.max_sp;
+
+ /*
+ * Disabled for renewal since difference of 0 and 1 still has an impact in the formulas
+ * Just in case there is a mishandled division by zero please let us know. [malufett]
+ */
+#ifndef RENEWAL
+ //All status should be min 1 to prevent divisions by zero from some skills. [Skotlex]
+ if (entry->status.str < 1) entry->status.str = 1;
+ if (entry->status.agi < 1) entry->status.agi = 1;
+ if (entry->status.vit < 1) entry->status.vit = 1;
+ if (entry->status.int_< 1) entry->status.int_= 1;
+ if (entry->status.dex < 1) entry->status.dex = 1;
+ if (entry->status.luk < 1) entry->status.luk = 1;
+#endif
+
+ if (entry->range2 < 1)
+ entry->range2 = 1;
+
+#if 0 // This code was (accidentally) never enabled. It'll stay commented out until it's proven to be needed.
+ //Tests showed that chase range is effectively 2 cells larger than expected [Playtester]
+ if (entry->range3 > 0)
+ entry->range3 += 2;
+#endif // 0
+
+ if (entry->range3 < entry->range2)
+ entry->range3 = entry->range2;
+
+ entry->status.size = cap_value(entry->status.size, 0, 2);
+
+ entry->status.race = cap_value(entry->status.race, 0, RC_MAX - 1);
+
+ if (entry->status.def_ele >= ELE_MAX) {
+ ShowWarning("mob_read_db_sub: Invalid element type %d for monster ID %d (max=%d).\n", entry->status.def_ele, entry->mob_id, ELE_MAX-1);
+ entry->status.def_ele = ELE_NEUTRAL;
+ entry->status.ele_lv = 1;
}
- if (pc->db_checkid(class_)) {
- ShowError("mob_read_db_sub: Invalid monster ID %d, reserved for player classes.\n", class_);
- return false;
+ if (entry->status.ele_lv < 1 || entry->status.ele_lv > 4) {
+ ShowWarning("mob_read_db_sub: Invalid element level %d for monster ID %d, must be in range 1-4.\n", entry->status.ele_lv, entry->mob_id);
+ entry->status.ele_lv = 1;
}
- if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END) {
- ShowError("mob_read_db_sub: Invalid monster ID %d. Range %d-%d is reserved for player clones. Please increase MAX_MOB_DB (%d).\n", class_, MOB_CLONE_START, MOB_CLONE_END-1, MAX_MOB_DB);
- return false;
+ // If the attack animation is longer than the delay, the client crops the attack animation!
+ // On aegis there is no real visible effect of having a recharge-time less than amotion anyway.
+ if (entry->status.adelay < entry->status.amotion)
+ entry->status.adelay = entry->status.amotion;
+
+ // Fill in remaining status data by using a dummy monster.
+ data.bl.type = BL_MOB;
+ data.level = entry->lv;
+ memcpy(&data.status, &entry->status, sizeof(struct status_data));
+ status->calc_misc(&data.bl, &entry->status, entry->lv);
+
+ // Finally insert monster's data into the database.
+ if (mob->db_data[entry->mob_id] == NULL) {
+ mob->db_data[entry->mob_id] = (struct mob_db*)aMalloc(sizeof(struct mob_db));
+ } else {
+ //Copy over spawn data
+ memcpy(&entry->spawn, mob->db_data[entry->mob_id]->spawn, sizeof(entry->spawn));
}
+ memcpy(mob->db_data[entry->mob_id], entry, sizeof(struct mob_db));
+
+ return entry->mob_id;
+}
+
+/**
+ * Processes one mobdb entry from the libconfig file, loading and inserting it
+ * into the mob database.
+ *
+ * @param mobt Libconfig setting entry. It is expected to be valid and it
+ * won't be freed (it is care of the caller to do so if
+ * necessary).
+ * @param n Ordinal number of the entry, to be displayed in case of
+ * validation errors.
+ * @param source Source of the entry (file name), to be displayed in case of
+ * validation errors.
+ * @return Mob ID of the validated entry, or 0 in case of failure.
+ */
+int mob_read_db_sub(config_setting_t *mobt, int n, const char *source)
+{
+ struct mob_db md = { 0 };
+ config_setting_t *t = NULL;
+ const char *str = NULL;
+ int i32 = 0;
+ bool inherit = false;
+ bool maxhpUpdated = false;
+
+ nullpo_ret(mobt);
+ /*
+ * // Mandatory fields
+ * Id: ID
+ * SpriteName: "SPRITE_NAME"
+ * Name: "Mob name"
+ * JName: "Mob name"
+ * // Optional fields
+ * Lv: level
+ * Hp: health
+ * Sp: mana
+ * Exp: basic experience
+ * JExp: job experience
+ * AttackRange: attack range
+ * Attack: [attack1, attack2]
+ * Def: defence
+ * Mdef: magic defence
+ * Stats: {
+ * Str: strength
+ * Agi: agility
+ * Vit: vitality
+ * Int: intelligence
+ * Dex: dexterity
+ * Luk: luck
+ * }
+ * ViewRange: view range
+ * ChaseRange: chase range
+ * Size: size
+ * Race: race
+ * Element: (type, level)
+ * Mode: {
+ * CanMove: true/false
+ * Looter: true/false
+ * Aggressive: true/false
+ * Assist: true/false
+ * CastSensorIdle:true/false
+ * Boss: true/false
+ * Plant: true/false
+ * CanAttack: true/false
+ * Detector: true/false
+ * CastSensorChase: true/false
+ * ChangeChase: true/false
+ * Angry: true/false
+ * ChangeTargetMelee: true/false
+ * ChangeTargetChase: true/false
+ * TargetWeak: true/false
+ * }
+ * MoveSpeed: move speed
+ * AttackDelay: attack delay
+ * AttackMotion: attack motion
+ * DamageMotion: damage motion
+ * MvpExp: mvp experience
+ * MvpDrops: {
+ * AegisName: chance
+ * ...
+ * }
+ * Drops: {
+ * AegisName: chance
+ * ...
+ * }
+ */
+
+ if (!libconfig->setting_lookup_int(mobt, "Id", &i32)) {
+ ShowWarning("mob_read_db_sub: Missing id in \"%s\", entry #%d, skipping.\n", source, n);
+ return 0;
+ }
+ md.mob_id = i32;
+ md.vd.class_ = md.mob_id;
if ((t = libconfig->setting_get_member(mobt, "Inherit")) && (inherit = libconfig->setting_get_bool(t))) {
- if (!mob->db_data[class_]) {
- ShowWarning("mob_read_db_sub: Trying to inherit nonexistent mob %d, default values will be used instead.\n", class_);
+ if (!mob->db_data[md.mob_id]) {
+ ShowWarning("mob_read_db_sub: Trying to inherit nonexistent mob %d, default values will be used instead.\n", md.mob_id);
inherit = false;
} else {
// Use old entry as default
- struct mob_db *old_entry = mob->db_data[class_];
- memcpy(entry, old_entry, sizeof(struct mob_db));
- inherit = true;
+ struct mob_db *old_entry = mob->db_data[md.mob_id];
+ memcpy(&md, old_entry, sizeof(md));
}
}
- if (!inherit) {
- memset(&tmpEntry, 0, sizeof(tmpEntry));
- }
-
- mstatus = &entry->status;
-
- entry->vd.class_ = class_;
if (!libconfig->setting_lookup_string(mobt, "SpriteName", &str) || !*str ) {
if (!inherit) {
- ShowWarning("mob_read_db_sub: Missing SpriteName in mob %d of \"%s\", skipping.\n", class_, source);
- return false;
+ ShowWarning("mob_read_db_sub: Missing SpriteName in mob %d of \"%s\", skipping.\n", md.mob_id, source);
+ return 0;
}
} else {
- safestrncpy(entry->sprite, str, sizeof(entry->sprite));
+ safestrncpy(md.sprite, str, sizeof(md.sprite));
}
if (!libconfig->setting_lookup_string(mobt, "Name", &str) || !*str ) {
if (!inherit) {
- ShowWarning("mob_read_db_sub: Missing Name in mob %d of \"%s\", skipping.\n", class_, source);
- return false;
+ ShowWarning("mob_read_db_sub: Missing Name in mob %d of \"%s\", skipping.\n", md.mob_id, source);
+ return 0;
+ }
+ } else {
+ safestrncpy(md.name, str, sizeof(md.name));
+ }
+
+ if (!libconfig->setting_lookup_string(mobt, "JName", &str) || !*str ) {
+ if (!inherit) {
+ safestrncpy(md.jname, md.name, sizeof(md.jname));
}
} else {
- safestrncpy(entry->name, str, sizeof(entry->name));
- safestrncpy(entry->jname, str, sizeof(entry->jname));
+ safestrncpy(md.jname, str, sizeof(md.jname));
}
if (mob->lookup_const(mobt, "Lv", &i32) && i32 >= 0) {
- entry->lv = i32;
- entry->lv = cap_value(entry->lv, 1, USHRT_MAX);
+ md.lv = i32;
} else if (!inherit) {
- entry->lv = 1;
+ md.lv = 1;
}
if (mob->lookup_const(mobt, "Hp", &i32) && i32 >= 0) {
- mstatus->max_hp = i32;
- maxhpUpdated = true;
+ md.status.max_hp = i32;
+ maxhpUpdated = true; // battle_config modifiers to max_hp are applied below
} else if (!inherit) {
- mstatus->max_hp = 1;
- maxhpUpdated = true;
+ md.status.max_hp = 1;
+ maxhpUpdated = true; // battle_config modifiers to max_hp are applied below
}
if (mob->lookup_const(mobt, "Sp", &i32) && i32 >= 0) {
- mstatus->max_sp = i32;
- maxspUpdated = true;
+ md.status.max_sp = i32;
} else if (!inherit) {
- maxspUpdated = true;
+ md.status.max_sp = 1;
}
if (mob->lookup_const(mobt, "Exp", &i32) && i32 >= 0) {
- exp = (double)(i32) * (double)battle_config.base_exp_rate / 100.;
- entry->base_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+ int64 exp = apply_percentrate64(i32, battle_config.base_exp_rate, 100);
+ md.base_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
}
if (mob->lookup_const(mobt, "JExp", &i32) && i32 >= 0) {
- exp = (double)(i32) * (double)battle_config.job_exp_rate / 100.;
- entry->job_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+ int64 exp = apply_percentrate64(i32, battle_config.job_exp_rate, 100);
+ md.job_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
}
if (mob->lookup_const(mobt, "AttackRange", &i32) && i32 >= 0) {
- mstatus->rhw.range = i32;
+ md.status.rhw.range = i32;
} else {
- mstatus->rhw.range = 1;
+ md.status.rhw.range = 1;
}
if ((t = libconfig->setting_get_member(mobt, "Attack"))) {
if (config_setting_is_aggregate(t)) {
if (libconfig->setting_length(t) >= 2)
- mstatus->rhw.atk2 = libconfig->setting_get_int_elem(t, 1);
+ md.status.rhw.atk2 = libconfig->setting_get_int_elem(t, 1);
if (libconfig->setting_length(t) >= 1)
- mstatus->rhw.atk = libconfig->setting_get_int_elem(t, 0);
+ md.status.rhw.atk = libconfig->setting_get_int_elem(t, 0);
} else if (mob->lookup_const(mobt, "Attack", &i32) && i32 >= 0) {
- mstatus->rhw.atk = i32;
- mstatus->rhw.atk2 = i32;
+ md.status.rhw.atk = i32;
+ md.status.rhw.atk2 = i32;
}
}
if (mob->lookup_const(mobt, "Def", &i32) && i32 >= 0) {
- mstatus->def = mob_parse_dbrow_cap_value(class_, DEFTYPE_MIN, DEFTYPE_MAX, i32);
+ md.status.def = mob_parse_dbrow_cap_value(md.mob_id, DEFTYPE_MIN, DEFTYPE_MAX, i32);
}
if (mob->lookup_const(mobt, "Mdef", &i32) && i32 >= 0) {
- mstatus->mdef = mob_parse_dbrow_cap_value(class_, DEFTYPE_MIN, DEFTYPE_MAX, i32);
+ md.status.mdef = mob_parse_dbrow_cap_value(md.mob_id, DEFTYPE_MIN, DEFTYPE_MAX, i32);
}
if ((t = libconfig->setting_get_member(mobt, "Stats"))) {
if (config_setting_is_group(t)) {
- mob->read_db_stats_sub(entry, mstatus, class_, t);
+ mob->read_db_stats_sub(&md, t);
} else if (mob->lookup_const(mobt, "Stats", &i32) && i32 >= 0) {
- mstatus->str = mstatus->agi = mstatus->vit = mstatus->int_ = mstatus->dex = mstatus->luk =
- mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ md.status.str = md.status.agi = md.status.vit = md.status.int_ = md.status.dex = md.status.luk =
+ mob_parse_dbrow_cap_value(md.mob_id, UINT16_MIN, UINT16_MAX, i32);
}
}
- /*
- * Disabled for renewal since difference of 0 and 1 still has an impact in the formulas
- * Just in case there is a mishandled division by zero please let us know. [malufett]
- */
-#ifndef RENEWAL
- //All status should be min 1 to prevent divisions by zero from some skills. [Skotlex]
- if (mstatus->str < 1) mstatus->str = 1;
- if (mstatus->agi < 1) mstatus->agi = 1;
- if (mstatus->vit < 1) mstatus->vit = 1;
- if (mstatus->int_< 1) mstatus->int_= 1;
- if (mstatus->dex < 1) mstatus->dex = 1;
- if (mstatus->luk < 1) mstatus->luk = 1;
-#endif
-
- //Tests showed that chase range is effectively 2 cells larger than expected [Playtester]
- if (entry->range3 > 0)
- entry->range3 += 2;
-
if (mob->lookup_const(mobt, "ViewRange", &i32) && i32 >= 0) {
- entry->range2 = i32;
- range2Updated = true;
+ if (battle_config.view_range_rate != 100) {
+ md.range2 = i32 * battle_config.view_range_rate / 100;
+ } else {
+ md.range2 = i32;
+ }
} else if (!inherit) {
- entry->range2 = 1;
- range2Updated = true;
+ md.range2 = 1;
}
if (mob->lookup_const(mobt, "ChaseRange", &i32) && i32 >= 0) {
- entry->range3 = i32;
- range3Updated = true;
- } else if (!inherit) {
- entry->range3 = 1;
- range3Updated = true;
- }
- if (range2Updated) {
- if (battle_config.view_range_rate != 100) {
- entry->range2 = entry->range2 * battle_config.view_range_rate / 100;
- if (entry->range2 < 1)
- entry->range2 = 1;
- }
- }
- if (range3Updated) {
if (battle_config.chase_range_rate != 100) {
- entry->range3 = entry->range3 * battle_config.chase_range_rate / 100;
- if (entry->range3 < entry->range2)
- entry->range3 = entry->range2;
+ md.range3 = i32 * battle_config.chase_range_rate / 100;
+ } else {
+ md.range3 = i32;
}
+ } else if (!inherit) {
+ md.range3 = 1;
}
if (mob->lookup_const(mobt, "Size", &i32) && i32 >= 0) {
- mstatus->size = i32;
- mstatus->size = cap_value(mstatus->size, 0, 2);
+ md.status.size = i32;
} else if (!inherit) {
- mstatus->size = 0;
+ md.status.size = 0;
}
if (mob->lookup_const(mobt, "Race", &i32) && i32 >= 0) {
- mstatus->race = i32;
- mstatus->race = cap_value(mstatus->race, 0, RC_MAX - 1);
+ md.status.race = i32;
} else if (!inherit) {
- mstatus->race = 0;
+ md.status.race = 0;
}
if ((t = libconfig->setting_get_member(mobt, "Element")) && config_setting_is_list(t)) {
+ int value = 0;
if (mob->get_const(libconfig->setting_get_elem(t, 0), &i32) && mob->get_const(libconfig->setting_get_elem(t, 1), &value)) {
- mstatus->def_ele = i32;
- mstatus->ele_lv = value;
- }
- } else {
- if (!inherit) {
- ShowError("mob_read_db_sub: Missing element for monster ID %d.\n", class_);
- return false;
- }
- }
-
- if (mstatus->def_ele >= ELE_MAX) {
- if (!inherit) {
- ShowError("mob_read_db_sub: Invalid element type %d for monster ID %d (max=%d).\n", mstatus->def_ele, class_, ELE_MAX-1);
- return false;
- }
- }
- if (mstatus->ele_lv < 1 || mstatus->ele_lv > 4) {
- if (!inherit) {
- ShowError("mob_read_db_sub: Invalid element level %d for monster ID %d, must be in range 1-4.\n", mstatus->ele_lv, class_);
- return false;
+ md.status.def_ele = i32;
+ md.status.ele_lv = value;
+ } else if (!inherit) {
+ ShowWarning("mob_read_db_sub: Missing element for monster ID %d.\n", md.mob_id);
+ md.status.def_ele = ELE_NEUTRAL;
+ md.status.ele_lv = 1;
}
+ } else if (!inherit) {
+ ShowWarning("mob_read_db_sub: Missing element for monster ID %d.\n", md.mob_id);
+ md.status.def_ele = ELE_NEUTRAL;
+ md.status.ele_lv = 1;
}
if ((t = libconfig->setting_get_member(mobt, "Mode"))) {
if (config_setting_is_group(t)) {
- mstatus->mode = mob->read_db_mode_sub(entry, mstatus, class_, t);
+ md.status.mode = mob->read_db_mode_sub(&md, t);
} else if (mob->lookup_const(mobt, "Mode", &i32) && i32 >= 0) {
- mstatus->mode = i32;
+ md.status.mode = i32;
}
}
-
if (!battle_config.monster_active_enable)
- mstatus->mode &= ~MD_AGGRESSIVE;
+ md.status.mode &= ~MD_AGGRESSIVE;
if (mob->lookup_const(mobt, "MoveSpeed", &i32) && i32 >= 0) {
- mstatus->speed = i32;
+ md.status.speed = i32;
}
- mstatus->aspd_rate = 1000;
+ md.status.aspd_rate = 1000;
if (mob->lookup_const(mobt, "AttackDelay", &i32) && i32 >= 0) {
- mstatus->adelay = cap_value(i32, battle_config.monster_max_aspd*2, 4000);
+ md.status.adelay = cap_value(i32, battle_config.monster_max_aspd*2, 4000);
} else if (!inherit) {
- mstatus->adelay = 4000;
+ md.status.adelay = 4000;
}
if (mob->lookup_const(mobt, "AttackMotion", &i32) && i32 >= 0) {
- mstatus->amotion = cap_value(i32, battle_config.monster_max_aspd, 2000);
+ md.status.amotion = cap_value(i32, battle_config.monster_max_aspd, 2000);
} else if (!inherit) {
- mstatus->amotion = 2000;
+ md.status.amotion = 2000;
}
- //If the attack animation is longer than the delay, the client crops the attack animation!
- //On aegis there is no real visible effect of having a recharge-time less than amotion anyway.
- if (mstatus->adelay < mstatus->amotion)
- mstatus->adelay = mstatus->amotion;
-
if (mob->lookup_const(mobt, "DamageMotion", &i32) && i32 >= 0) {
- mstatus->dmotion = i32;
- dmotionUpdated = true;
- } else if (!inherit) {
- dmotionUpdated = true;
+ if (battle_config.monster_damage_delay_rate != 100)
+ md.status.dmotion = i32 * battle_config.monster_damage_delay_rate / 100;
+ else
+ md.status.dmotion = i32;
}
- if (dmotionUpdated && battle_config.monster_damage_delay_rate != 100)
- mstatus->dmotion = mstatus->dmotion * battle_config.monster_damage_delay_rate / 100;
-
- // Fill in remaining status data by using a dummy monster.
- data.bl.type = BL_MOB;
- data.level = entry->lv;
- memcpy(&data.status, mstatus, sizeof(struct status_data));
- status->calc_misc(&data.bl, mstatus, entry->lv);
-
// MVP EXP Bonus: MEXP
- // Some new MVP's MEXP multiple by high exp-rate cause overflow. [LuzZza]
if (mob->lookup_const(mobt, "MvpExp", &i32) && i32 >= 0) {
- exp = (double)i32 * (double)battle_config.mvp_exp_rate / 100.;
- entry->mexp = (unsigned int)cap_value(exp, 0, UINT_MAX);
- } else if (!inherit) {
- exp = 0;
+ // Some new MVP's MEXP multiple by high exp-rate cause overflow. [LuzZza]
+ int64 exp = apply_percentrate64(i32, battle_config.mvp_exp_rate, 100);
+ md.mexp = (unsigned int)cap_value(exp, 0, UINT_MAX);
}
if (maxhpUpdated) {
- //Now that we know if it is an mvp or not, apply battle_config modifiers [Skotlex]
- maxhp = (double)mstatus->max_hp;
- if (entry->mexp > 0) { //Mvp
- if (battle_config.mvp_hp_rate != 100)
- maxhp = maxhp * (double)battle_config.mvp_hp_rate / 100.;
+ // Now that we know if it is an mvp or not, apply battle_config modifiers [Skotlex]
+ int64 maxhp = md.status.max_hp;
+ if (md.mexp > 0) { //Mvp
+ maxhp = apply_percentrate64(maxhp, battle_config.mvp_hp_rate, 100);
} else { //Normal mob
- if (battle_config.monster_hp_rate != 100)
- maxhp = maxhp * (double)battle_config.monster_hp_rate / 100.;
+ maxhp = apply_percentrate64(maxhp, battle_config.monster_hp_rate, 100);
}
- mstatus->max_hp = (unsigned int)cap_value(maxhp, 1, UINT_MAX);
+ md.status.max_hp = (unsigned int)cap_value(maxhp, 1, UINT_MAX);
}
- if (maxspUpdated) {
- if(mstatus->max_sp < 1) mstatus->max_sp = 1;
- }
-
- //Since mobs always respawn with full life...
- mstatus->hp = mstatus->max_hp;
- mstatus->sp = mstatus->max_sp;
if ((t = libconfig->setting_get_member(mobt, "MvpDrops"))) {
if (config_setting_is_group(t)) {
- mob->read_db_mvpdrops_sub(entry, mstatus, class_, t);
+ mob->read_db_mvpdrops_sub(&md, t);
}
}
if ((t = libconfig->setting_get_member(mobt, "Drops"))) {
if (config_setting_is_group(t)) {
- mob->read_db_drops_sub(entry, mstatus, class_, t);
+ mob->read_db_drops_sub(&md, t);
}
}
- mob->read_db_additional_fields(entry, class_, mobt, id, source);
- // Finally insert monster's data into the database.
- if (mob->db_data[class_] == NULL)
- mob->db_data[class_] = (struct mob_db*)aMalloc(sizeof(struct mob_db));
- else
- //Copy over spawn data
- memcpy(&entry->spawn, mob->db_data[class_]->spawn, sizeof(entry->spawn));
+ mob->read_db_additional_fields(&md, mobt, n, source);
- memcpy(mob->db_data[class_], entry, sizeof(struct mob_db));
- return true;
+ return mob->db_validate_entry(&md, n, source);
}
-void mob_read_db_additional_fields(struct mob_db *entry, int class_, config_setting_t *it, int n, const char *source)
+/**
+ * Processes any (plugin-defined) additional fields for a mob_db entry.
+ *
+ * @param[in,out] entry The destination mob_db entry, already initialized
+ * (mob_id, status.mode are expected to be already set).
+ * @param[in] t The libconfig entry.
+ * @param[in] n Ordinal number of the entry, to be displayed in case
+ * of validation errors.
+ * @param[in] source Source of the entry (file name), to be displayed in
+ * case of validation errors.
+ */
+void mob_read_db_additional_fields(struct mob_db *entry, config_setting_t *t, int n, const char *source)
{
// do nothing. plugins can do own work
}
@@ -4282,13 +4401,23 @@ void mob_readdb(void) {
mob->name_constants();
}
+/**
+ * Reads from a libconfig-formatted mobdb file and inserts the found entries
+ * into the mob database, overwriting duplicate ones (i.e. mob_db2 overriding
+ * mob_db.)
+ *
+ * @param filename File name, relative to the database path.
+ * @param ignore_missing Whether to ignore errors caused by a missing db file.
+ * @return the number of found entries.
+ */
int mob_read_libconfig(const char *filename, bool ignore_missing)
{
+ bool duplicate[MAX_MOB_DB] = { 0 };
config_t mob_db_conf;
char filepath[256];
config_setting_t *mdb;
config_setting_t *t;
- int i = 0;
+ int i = 0, count = 0;
nullpo_ret(filename);
sprintf(filepath, "%s/%s", map->db_path, filename);
@@ -4298,15 +4427,28 @@ int mob_read_libconfig(const char *filename, bool ignore_missing)
if (libconfig->read_file(&mob_db_conf, filepath) || !(mdb = libconfig->setting_get_member(mob_db_conf.root, "mob_db"))) {
ShowError("can't read %s\n", filepath);
- return -1;
+ return 0;
}
while ((t = libconfig->setting_get_elem(mdb, i++))) {
- mob->read_db_sub(t, i - 1, filepath);
+ int mob_id = mob->read_db_sub(t, i - 1, filename);
+
+ if (mob_id <= 0 || mob_id >= MAX_MOB_DB)
+ continue;
+
+ count++;
+
+ if (duplicate[mob_id]) {
+ ShowWarning("mob_read_libconfig:%s: duplicate entry of ID #%d (%s/%s)\n",
+ filename, mob_id, mob->db_data[mob_id]->sprite, mob->db_data[mob_id]->jname);
+ } else {
+ duplicate[mob_id] = true;
+ }
}
libconfig->destroy(&mob_db_conf);
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, filepath);
- return 0;
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename);
+
+ return count;
}
void mob_name_constants(void) {
@@ -4316,7 +4458,7 @@ void mob_name_constants(void) {
#endif // ENABLE_CASE_CHECK
for (i = 0; i < MAX_MOB_DB; i++) {
if (mob->db_data[i] && !mob->is_clone(i))
- script->set_constant2(mob->db_data[i]->sprite, i, 0);
+ script->set_constant2(mob->db_data[i]->sprite, i, false, false);
}
#ifdef ENABLE_CASE_CHECK
script->parser_current_file = NULL;
@@ -4922,7 +5064,7 @@ void mob_reload(void) {
/**
* Clears spawn related information for a script reload.
*/
-void mob_clear_spawninfo()
+void mob_clear_spawninfo(void)
{
int i;
for (i = 0; i < MAX_MOB_DB; i++)
@@ -5127,6 +5269,7 @@ void mob_defaults(void) {
mob->item_dropratio_adjust = item_dropratio_adjust;
mob->lookup_const = mob_lookup_const;
mob->get_const = mob_get_const;
+ mob->db_validate_entry = mob_db_validate_entry;
mob->readdb = mob_readdb;
mob->read_libconfig = mob_read_libconfig;
mob->read_db_additional_fields = mob_read_db_additional_fields;
diff --git a/src/map/mob.h b/src/map/mob.h
index 5485b2a91..9a5239b11 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -141,6 +141,7 @@ struct spawn_info {
};
struct mob_db {
+ int mob_id;
char sprite[NAME_LENGTH],name[NAME_LENGTH],jname[NAME_LENGTH];
unsigned int base_exp,job_exp;
unsigned int mexp;
@@ -511,13 +512,14 @@ struct mob_interface {
void (*readdb) (void);
bool (*lookup_const) (const config_setting_t *it, const char *name, int *value);
bool (*get_const) (const config_setting_t *it, int *value);
+ int (*db_validate_entry) (struct mob_db *entry, int n, const char *source);
int (*read_libconfig) (const char *filename, bool ignore_missing);
- void (*read_db_additional_fields) (struct mob_db *entry, int class_, config_setting_t *it, int n, const char *source);
- bool (*read_db_sub) (config_setting_t *mobt, int id, const char *source);
- void (*read_db_drops_sub) (struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t);
- void (*read_db_mvpdrops_sub) (struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t);
- int (*read_db_mode_sub) (struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t);
- void (*read_db_stats_sub) (struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t);
+ void (*read_db_additional_fields) (struct mob_db *entry, config_setting_t *it, int n, const char *source);
+ int (*read_db_sub) (config_setting_t *mobt, int id, const char *source);
+ void (*read_db_drops_sub) (struct mob_db *entry, config_setting_t *t);
+ void (*read_db_mvpdrops_sub) (struct mob_db *entry, config_setting_t *t);
+ int (*read_db_mode_sub) (struct mob_db *entry, config_setting_t *t);
+ void (*read_db_stats_sub) (struct mob_db *entry, config_setting_t *t);
void (*name_constants) (void);
bool (*readdb_mobavail) (char *str[], int columns, int current);
int (*read_randommonster) (void);
@@ -528,7 +530,7 @@ struct mob_interface {
bool (*readdb_race2) (char *fields[], int columns, int current);
bool (*readdb_itemratio) (char *str[], int columns, int current);
void (*load) (bool minimal);
- void (*clear_spawninfo) ();
+ void (*clear_spawninfo) (void);
void (*destroy_mob_db) (int index);
};
diff --git a/src/map/npc.c b/src/map/npc.c
index 411e52c29..23b0b9555 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -1769,7 +1769,7 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
if( w + sd->weight > sd->max_weight )
return ERROR_TYPE_INVENTORY_WEIGHT;
- if( (double)shop[i].value * amount > INT_MAX ) {
+ if ((int64)shop[i].value * amount > INT_MAX) {
ShowWarning("npc_cashshop_buy: Item '%s' (%d) price overflow attempt!\n", item->name, nameid);
ShowDebug("(NPC:'%s' (%s,%d,%d), player:'%s' (%d/%d), value:%d, amount:%d)\n",
nd->exname, map->list[nd->bl.m].name, nd->bl.x, nd->bl.y,
@@ -1812,7 +1812,7 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) {
struct npc_data* nd;
struct npc_item_list *shop = NULL;
- double z;
+ int64 z;
int i,j,w,skill_t,new_, idx = skill->get_index(MC_DISCOUNT);
unsigned short shop_size = 0;
@@ -1883,21 +1883,21 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) {
value = pc->modifybuyvalue(sd,value);
- z += (double)value * amount;
+ z += (int64)value * amount;
w += itemdb_weight(nameid) * amount;
}
if( nd->master_nd != NULL ) //Script-based shops.
return npc->buylist_sub(sd,n,item_list,nd->master_nd);
- if( z > (double)sd->status.zeny )
+ if (z > sd->status.zeny)
return 1; // Not enough Zeny
if( w + sd->weight > sd->max_weight )
return 2; // Too heavy
if( pc->inventoryblank(sd) < new_ )
return 3; // Not enough space to store items
- pc->payzeny(sd,(int)z,LOG_TYPE_NPC, NULL);
+ pc->payzeny(sd, (int)z, LOG_TYPE_NPC, NULL);
for( i = 0; i < n; ++i ) {
int nameid = item_list[i*2+1];
@@ -1921,10 +1921,10 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) {
skill_t = sd->status.skill[idx].flag - SKILL_FLAG_REPLACED_LV_0;
if( skill_t > 0 ) {
- z = z * (double)skill_t * (double)battle_config.shop_exp/10000.;
- if( z < 1 )
+ z = apply_percentrate64(z, skill_t * battle_config.shop_exp, 10000);
+ if (z < 1)
z = 1;
- pc->gainexp(sd,NULL,0,(int)z, false);
+ pc->gainexp(sd, NULL, 0, (int)z, false);
}
}
@@ -1937,7 +1937,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) {
int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, struct packet_npc_market_purchase *p) {
struct npc_data* nd;
struct npc_item_list *shop = NULL;
- double z;
+ int64 z;
int i,j,w,new_;
unsigned short shop_size = 0;
@@ -1997,11 +1997,11 @@ int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, st
return 1;
}
- z += (double)value * amount;
+ z += (int64)value * amount;
w += itemdb_weight(nameid) * amount;
}
- if( z > (double)sd->status.zeny ) /* TODO find official response for this */
+ if (z > sd->status.zeny) /* TODO find official response for this */
return 1; // Not enough Zeny
if( w + sd->weight > sd->max_weight ) /* TODO find official response for this */
@@ -2098,7 +2098,7 @@ int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_li
/// @param item_list 'n' pairs <index,amount>
/// @return result code for clif->parse_NpcSellListSend
int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list) {
- double z;
+ int64 z;
int i,skill_t, skill_idx = skill->get_index(MC_OVERCHARGE);
struct npc_data *nd;
bool duplicates[MAX_INVENTORY] = { 0 };
@@ -2147,7 +2147,7 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
value = pc->modifysellvalue(sd, sd->inventory_data[idx]->value_sell);
- z += (double)value*amount;
+ z += (int64)value * amount;
}
if( nd->master_nd ) { // Script-controlled shops
@@ -2181,8 +2181,8 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
skill_t = sd->status.skill[skill_idx].flag - SKILL_FLAG_REPLACED_LV_0;
if( skill_t > 0 ) {
- z = z * (double)skill_t * (double)battle_config.shop_exp/10000.;
- if( z < 1 )
+ z = apply_percentrate64(z, skill_t * battle_config.shop_exp, 10000);
+ if (z < 1)
z = 1;
pc->gainexp(sd, NULL, 0, (int)z, false);
}
@@ -2276,9 +2276,7 @@ int npc_unload(struct npc_data* nd, bool single)
if (nd->chat_id) // remove npc chatroom object and kick users
chat->delete_npc_chat(nd);
-#ifdef PCRE_SUPPORT
npc_chat->finalize(nd); // deallocate npc PCRE data structures
-#endif
if (single && nd->path != NULL) {
npc->releasepathreference(nd->path);
@@ -2551,7 +2549,7 @@ void npc_parsename(struct npc_data* nd, const char* name, const char* start, con
// Support for using Constants in place of NPC View IDs.
int npc_parseview(const char* w4, const char* start, const char* buffer, const char* filepath) {
int val = FAKE_NPC, i = 0;
- char viewid[1024]; // Max size of name from const.txt, see script->read_constdb.
+ char viewid[1024]; // Max size of name from constants.conf, see script->read_constdb.
// Extract view ID / constant
while (w4[i] != '\0') {
diff --git a/src/map/npc.h b/src/map/npc.h
index 0b2729bcf..568ddfe87 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -309,53 +309,38 @@ void npc_defaults(void);
HPShared struct npc_interface *npc;
/* comes from npc_chat.c */
-#ifdef PCRE_SUPPORT
#include <pcre/include/pcre.h>
-#endif // PCRE_SUPPORT
/**
* Structure containing all info associated with a single pattern block
*/
struct pcrematch_entry {
-#ifdef PCRE_SUPPORT
struct pcrematch_entry* next;
char* pattern;
pcre* pcre_;
pcre_extra* pcre_extra_;
char* label;
-#else // not PCRE_SUPPORT
- UNAVAILABLE_STRUCT;
-#endif // PCRE_SUPPORT
};
/**
* A set of patterns that can be activated and deactived with a single command
*/
struct pcrematch_set {
-#ifdef PCRE_SUPPORT
struct pcrematch_set* prev;
struct pcrematch_set* next;
struct pcrematch_entry* head;
int setid;
-#else // not PCRE_SUPPORT
- UNAVAILABLE_STRUCT;
-#endif // PCRE_SUPPORT
};
/**
* Entire data structure hung off a NPC
*/
struct npc_parse {
-#ifdef PCRE_SUPPORT
struct pcrematch_set* active;
struct pcrematch_set* inactive;
-#else // not PCRE_SUPPORT
- UNAVAILABLE_STRUCT;
-#endif // PCRE_SUPPORT
};
struct npc_chat_interface {
-#ifdef PCRE_SUPPORT
int (*sub) (struct block_list* bl, va_list ap);
void (*finalize) (struct npc_data* nd);
void (*def_pattern) (struct npc_data* nd, int setid, const char* pattern, const char* label);
@@ -365,9 +350,6 @@ struct npc_chat_interface {
void (*activate_pcreset) (struct npc_data* nd, int setid);
struct pcrematch_set* (*lookup_pcreset) (struct npc_data* nd, int setid);
void (*finalize_pcrematch_entry) (struct pcrematch_entry* e);
-#else // not PCRE_SUPPORT
- UNAVAILABLE_STRUCT;
-#endif // PCRE_SUPPORT
};
/**
@@ -376,7 +358,6 @@ struct npc_chat_interface {
* should be moved into core/perhaps its own file once hpm is enhanced for login/char
**/
struct pcre_interface {
-#ifdef PCRE_SUPPORT
pcre *(*compile) (const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr);
pcre_extra *(*study) (const pcre *code, int options, const char **errptr);
int (*exec) (const pcre *code, const pcre_extra *extra, PCRE_SPTR subject, int length, int startoffset, int options, int *ovector, int ovecsize);
@@ -385,9 +366,6 @@ struct pcre_interface {
void (*free_substring) (const char *stringptr);
int (*copy_named_substring) (const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int buffersize);
int (*get_substring) (const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr);
-#else // not PCRE_SUPPORT
- UNAVAILABLE_STRUCT;
-#endif // PCRE_SUPPORT
};
/**
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c
index fef3ba99b..001baf3ea 100644
--- a/src/map/npc_chat.c
+++ b/src/map/npc_chat.c
@@ -20,8 +20,6 @@
*/
#define HERCULES_CORE
-#ifdef PCRE_SUPPORT
-
#include "npc.h" // struct npc_data
#include "map/mob.h" // struct mob_data
@@ -470,5 +468,3 @@ void npc_chat_defaults(void) {
libpcre->copy_named_substring = pcre_copy_named_substring;
libpcre->get_substring = pcre_get_substring;
}
-
-#endif //PCRE_SUPPORT
diff --git a/src/map/packets.h b/src/map/packets.h
index 9b9c7945f..0badd94f5 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -2910,9 +2910,15 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x08A8,26,clif->pFriendsListAdd,2);
packet(0x0817,5,clif->pHomMenu,2,4);
packet(0x0923,36,clif->pStoragePassword,0);
- packet(0x09e8,11,clif->pDull); // CZ_OPEN_MAILBOX
- packet(0x0a2e,6,clif->pDull); // TITLE
- packet(0x0a02,4); // ZC_DRESSROOM_OPEN
+ packet(0x09E8,11,clif->pDull); // CZ_OPEN_MAILBOX
+ packet(0x0A2E,6,clif->pDull); // TITLE
+ packet(0x0A02,4); // ZC_DRESSROOM_OPEN
+ packet(0x0A35,4,clif->pOneClick_ItemIdentify,2);
+#endif
+
+#if PACKETVER >= 20150805 // RagexeRE
+ packet(0x097f,-1); // ZC_SELECTCART
+ packet(0x0980,7,clif->pSelectCart); // CZ_SELECTCART
#endif
/* PacketKeys: http://herc.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 43ff0737f..cc8389a6b 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -1157,9 +1157,9 @@ struct packet_hotkey {
char Rotate;
#endif
struct {
- char isSkill; // 0: Item, 1:Skill
- unsigned int ID; // Item/Skill ID
- short count; // Item Quantity/Skill Level
+ char isSkill; // 0: Item, 1:Skill
+ unsigned int ID; // Item/Skill ID
+ short count; // Item Quantity/Skill Level
} hotkey[MAX_HOTKEYS];
#else // not HOTKEY_SAVING
UNAVAILABLE_STRUCT;
diff --git a/src/map/pc.c b/src/map/pc.c
index 2dfd9519b..8d1df71a9 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -4156,34 +4156,39 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
/*==========================================
* Update buying value by skills
*------------------------------------------*/
-int pc_modifybuyvalue(struct map_session_data *sd,int orig_value) {
- int skill_lv,val = orig_value,rate1 = 0,rate2 = 0;
- if((skill_lv=pc->checkskill(sd,MC_DISCOUNT))>0) // merchant discount
+int pc_modifybuyvalue(struct map_session_data *sd, int orig_value)
+{
+ int skill_lv, rate1 = 0, rate2 = 0;
+ if (orig_value <= 0)
+ return 0;
+ if ((skill_lv=pc->checkskill(sd,MC_DISCOUNT)) > 0) // merchant discount
rate1 = 5+skill_lv*2-((skill_lv==10)? 1:0);
- if((skill_lv=pc->checkskill(sd,RG_COMPULSION))>0) // rogue discount
+ if ((skill_lv=pc->checkskill(sd,RG_COMPULSION)) > 0) // rogue discount
rate2 = 5+skill_lv*4;
- if(rate1 < rate2) rate1 = rate2;
- if(rate1)
- val = (int)((double)orig_value*(double)(100-rate1)/100.);
- if(val < 0) val = 0;
- if(orig_value > 0 && val < 1) val = 1;
-
- return val;
+ if (rate1 < rate2)
+ rate1 = rate2;
+ if (rate1 != 0)
+ orig_value = apply_percentrate(orig_value, 100-rate1, 100);
+ if (orig_value < 1)
+ orig_value = 1;
+ return orig_value;
}
/*==========================================
* Update selling value by skills
*------------------------------------------*/
-int pc_modifysellvalue(struct map_session_data *sd,int orig_value) {
- int skill_lv,val = orig_value,rate = 0;
- if((skill_lv=pc->checkskill(sd,MC_OVERCHARGE))>0) //OverCharge
+int pc_modifysellvalue(struct map_session_data *sd, int orig_value)
+{
+ int skill_lv, rate = 0;
+ if (orig_value <= 0)
+ return 0;
+ if ((skill_lv=pc->checkskill(sd,MC_OVERCHARGE)) > 0) //OverCharge
rate = 5+skill_lv*2-((skill_lv==10)? 1:0);
- if(rate)
- val = (int)((double)orig_value*(double)(100+rate)/100.);
- if(val < 0) val = 0;
- if(orig_value > 0 && val < 1) val = 1;
-
- return val;
+ if (rate != 0)
+ orig_value = apply_percentrate(orig_value, 100+rate, 100);
+ if (orig_value < 1)
+ orig_value = 1;
+ return orig_value;
}
/*==========================================
@@ -5259,7 +5264,7 @@ int pc_show_steal(struct block_list *bl,va_list ap)
int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skill_lv)
{
int i,itemid,flag;
- double rate;
+ int rate;
struct status_data *sd_status, *md_status;
struct mob_data *md = BL_CAST(BL_MOB, bl);
struct item tmp_item;
@@ -5284,18 +5289,22 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil
}
// base skill success chance (percentual)
- rate = (sd_status->dex - md_status->dex)/2 + skill_lv*6 + 4;
- rate += sd->bonus.add_steal_rate;
+ rate = (sd_status->dex - md_status->dex)/2 + skill_lv*6 + 4 + sd->bonus.add_steal_rate;
if( rate < 1 )
return 0;
// Try dropping one item, in the order from first to last possible slot.
// Droprate is affected by the skill success rate.
- for( i = 0; i < MAX_STEAL_DROP; i++ )
- if (md->db->dropitem[i].nameid > 0 && (data = itemdb->exists(md->db->dropitem[i].nameid)) != NULL && rnd() % 10000 < md->db->dropitem[i].p * rate/100.)
+ for (i = 0; i < MAX_STEAL_DROP; i++) {
+ if (md->db->dropitem[i].nameid == 0)
+ continue;
+ if ((data = itemdb->exists(md->db->dropitem[i].nameid)) == NULL)
+ continue;
+ if (rnd() % 10000 < apply_percentrate(md->db->dropitem[i].p, rate, 100))
break;
- if( i == MAX_STEAL_DROP )
+ }
+ if (i == MAX_STEAL_DROP)
return 0;
itemid = md->db->dropitem[i].nameid;
@@ -6612,16 +6621,16 @@ void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned in
if (sd->sc.data[SC_OVERLAPEXPUP])
bonus += sd->sc.data[SC_OVERLAPEXPUP]->val1;
- *base_exp = (unsigned int) cap_value(*base_exp + (double)*base_exp * bonus/100., 1, UINT_MAX);
+ *base_exp = (unsigned int) cap_value(*base_exp + apply_percentrate64(*base_exp, bonus, 100), 1, UINT_MAX);
if (sd->sc.data[SC_CASH_PLUSONLYJOBEXP])
bonus += sd->sc.data[SC_CASH_PLUSONLYJOBEXP]->val1;
- *job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * bonus/100., 1, UINT_MAX);
+ *job_exp = (unsigned int) cap_value(*job_exp + apply_percentrate64(*job_exp, bonus, 100), 1, UINT_MAX);
- if( sd->status.mod_exp != 100 ) {
- *base_exp = (unsigned int) cap_value((double)*base_exp * sd->status.mod_exp/100., 1, UINT_MAX);
- *job_exp = (unsigned int) cap_value((double)*job_exp * sd->status.mod_exp/100., 1, UINT_MAX);
+ if (sd->status.mod_exp != 100) {
+ *base_exp = (unsigned int) cap_value(apply_percentrate64(*base_exp, sd->status.mod_exp, 100), 1, UINT_MAX);
+ *job_exp = (unsigned int) cap_value(apply_percentrate64(*job_exp, sd->status.mod_exp, 100), 1, UINT_MAX);
}
}
@@ -7713,18 +7722,18 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
&& !map->list[sd->bl.m].flag.noexppenalty && !map_flag_gvg2(sd->bl.m)
&& !sd->sc.data[SC_BABY] && !sd->sc.data[SC_CASH_DEATHPENALTY]
) {
- unsigned int base_penalty = 0;
if (battle_config.death_penalty_base > 0) {
+ unsigned int base_penalty = 0;
switch (battle_config.death_penalty_type) {
case 1:
- base_penalty = (unsigned int) ((double)pc->nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
+ base_penalty = (unsigned int) apply_percentrate64(pc->nextbaseexp(sd), battle_config.death_penalty_base, 10000);
break;
case 2:
- base_penalty = (unsigned int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
+ base_penalty = (unsigned int) apply_percentrate64(sd->status.base_exp, battle_config.death_penalty_base, 10000);
break;
}
- if(base_penalty) {
+ if (base_penalty != 0) {
if (battle_config.pk_mode && src && src->type==BL_PC)
base_penalty*=2;
if( sd->status.mod_death != 100 )
@@ -7735,31 +7744,31 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
}
if(battle_config.death_penalty_job > 0) {
- base_penalty = 0;
+ unsigned int job_penalty = 0;
switch (battle_config.death_penalty_type) {
case 1:
- base_penalty = (unsigned int) ((double)pc->nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
+ job_penalty = (unsigned int) apply_percentrate64(pc->nextjobexp(sd), battle_config.death_penalty_job, 10000);
break;
case 2:
- base_penalty = (unsigned int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
+ job_penalty = (unsigned int) apply_percentrate64(sd->status.job_exp, battle_config.death_penalty_job, 10000);
break;
}
- if(base_penalty) {
+ if (job_penalty != 0) {
if (battle_config.pk_mode && src && src->type==BL_PC)
- base_penalty*=2;
+ job_penalty*=2;
if( sd->status.mod_death != 100 )
- base_penalty = base_penalty * sd->status.mod_death / 100;
- sd->status.job_exp -= min(sd->status.job_exp, base_penalty);
+ job_penalty = job_penalty * sd->status.mod_death / 100;
+ sd->status.job_exp -= min(sd->status.job_exp, job_penalty);
clif->updatestatus(sd,SP_JOBEXP);
}
}
- if(battle_config.zeny_penalty > 0 && !map->list[sd->bl.m].flag.nozenypenalty) {
- base_penalty = (unsigned int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.);
- if(base_penalty)
- pc->payzeny(sd, base_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL);
+ if (battle_config.zeny_penalty > 0 && !map->list[sd->bl.m].flag.nozenypenalty) {
+ int zeny_penalty = apply_percentrate(sd->status.zeny, battle_config.zeny_penalty, 10000);
+ if (zeny_penalty != 0)
+ pc->payzeny(sd, zeny_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL);
}
}
@@ -11479,6 +11488,20 @@ bool pc_db_checkid(unsigned int class_)
|| (class_ >= JOB_REBELLION && class_ < JOB_MAX );
}
+/**
+ * checks if player have any kind of magnifier in inventory
+ * @param sd map_session_data of Player
+ * @return index of magnifer, INDEX_NOT_FOUND if it is not found
+ */
+int pc_have_magnifier(struct map_session_data *sd)
+{
+ int n;
+ n = pc->search_inventory(sd, ITEMID_MAGNIFIER);
+ if (n == INDEX_NOT_FOUND)
+ n = pc->search_inventory(sd, ITEMID_NOVICE_MAGNIFIER);
+ return n;
+}
+
void do_final_pc(void) {
db_destroy(pc->itemcd_db);
pc->at_db->destroy(pc->at_db,pc->autotrade_final);
@@ -11846,4 +11869,6 @@ void pc_defaults(void) {
pc->check_job_name = pc_check_job_name;
pc->update_idle_time = pc_update_idle_time;
+
+ pc->have_magnifier = pc_have_magnifier;
}
diff --git a/src/map/pc.h b/src/map/pc.h
index 23b46a631..06bc5e5ae 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -1088,6 +1088,8 @@ END_ZEROED_BLOCK; /* End */
int (*check_job_name) (const char *name);
void (*update_idle_time) (struct map_session_data* sd, enum e_battle_config_idletime type);
+
+ int (*have_magnifier) (struct map_session_data *sd);
};
#ifdef HERCULES_CORE
diff --git a/src/map/pet.c b/src/map/pet.c
index db8d0d1f1..c6f7e8cca 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -1178,7 +1178,7 @@ int pet_skill_support_timer(int tid, int64 tick, int id, intptr_t data) {
/**
* Loads (or reloads) the pet database.
*/
-int read_petdb()
+int read_petdb(void)
{
const char *filename[] = {
DBPATH"pet_db.txt",
diff --git a/src/map/pet.h b/src/map/pet.h
index 2442a381f..83e39a887 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -166,7 +166,7 @@ struct pet_interface {
int (*skill_bonus_timer) (int tid, int64 tick, int id, intptr_t data);
int (*recovery_timer) (int tid, int64 tick, int id, intptr_t data);
int (*skill_support_timer) (int tid, int64 tick, int id, intptr_t data);
- int (*read_db) ();
+ int (*read_db) (void);
};
#ifdef HERCULES_CORE
diff --git a/src/map/script.c b/src/map/script.c
index befb85304..f3c839555 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -159,10 +159,8 @@ const char* script_op2name(int op) {
RETURN_OP_NAME(C_SUB_POST);
RETURN_OP_NAME(C_ADD_PRE);
RETURN_OP_NAME(C_SUB_PRE);
-#ifdef PCRE_SUPPORT
RETURN_OP_NAME(C_RE_EQ);
RETURN_OP_NAME(C_RE_NE);
-#endif // PCRE_SUPPORT
default:
ShowDebug("script_op2name: unexpected op=%d\n", op);
@@ -1379,6 +1377,10 @@ const char* parse_simpleexpr(const char *p)
return pv;
}
+ if (script->str_data[l].type == C_INT && script->str_data[l].deprecated) {
+ disp_warning_message("This constant is deprecated and it will be removed in a future version. Please see the script documentation and constants.conf for an alternative.\n", p);
+ }
+
p=script->skip_word(p);
if( *p == '[' ) {
// array(name[i] => getelementofarray(name,i) )
@@ -1442,10 +1444,8 @@ const char* script_parse_subexpr(const char* p,int limit)
|| (op=C_XOR, opl=4, len=1,*p=='^') // ^
|| (op=C_EQ, opl=6, len=2,*p=='=' && p[1]=='=') // ==
|| (op=C_NE, opl=6, len=2,*p=='!' && p[1]=='=') // !=
-#ifdef PCRE_SUPPORT
|| (op=C_RE_EQ, opl=6, len=2,*p=='~' && p[1]=='=') // ~=
|| (op=C_RE_NE, opl=6, len=2,*p=='~' && p[1]=='!') // ~!
-#endif // PCRE_SUPPORT
|| (op=C_R_SHIFT,opl=8, len=2,*p=='>' && p[1]=='>') // >>
|| (op=C_GE, opl=7, len=2,*p=='>' && p[1]=='=') // >=
|| (op=C_GT, opl=7, len=1,*p=='>') // >
@@ -2231,25 +2231,31 @@ bool script_get_constant(const char* name, int* value)
return false;
}
value[0] = script->str_data[n].val;
+ if (script->str_data[n].deprecated) {
+ ShowWarning("The constant '%s' is deprecated and it will be removed in a future version. Please see the script documentation and constants.conf for an alternative.\n", name);
+ }
return true;
}
/// Creates new constant or parameter with given value.
-void script_set_constant(const char* name, int value, bool isparameter) {
+void script_set_constant(const char *name, int value, bool is_parameter, bool is_deprecated)
+{
int n = script->add_str(name);
if( script->str_data[n].type == C_NOP ) {// new
- script->str_data[n].type = isparameter ? C_PARAM : C_INT;
+ script->str_data[n].type = is_parameter ? C_PARAM : C_INT;
script->str_data[n].val = value;
+ script->str_data[n].deprecated = is_deprecated ? 1 : 0;
} else if( script->str_data[n].type == C_PARAM || script->str_data[n].type == C_INT ) {// existing parameter or constant
ShowError("script_set_constant: Attempted to overwrite existing %s '%s' (old value=%d, new value=%d).\n", ( script->str_data[n].type == C_PARAM ) ? "parameter" : "constant", name, script->str_data[n].val, value);
} else {// existing name
- ShowError("script_set_constant: Invalid name for %s '%s' (already defined as %s).\n", isparameter ? "parameter" : "constant", name, script->op2name(script->str_data[n].type));
+ ShowError("script_set_constant: Invalid name for %s '%s' (already defined as %s).\n", is_parameter ? "parameter" : "constant", name, script->op2name(script->str_data[n].type));
}
}
/* adds data to a existent constant in the database, inserted normally via parse */
-void script_set_constant2(const char *name, int value, bool isparameter) {
+void script_set_constant2(const char *name, int value, bool is_parameter, bool is_deprecated)
+{
int n = script->add_str(name);
if( script->str_data[n].type == C_PARAM ) {
@@ -2273,36 +2279,88 @@ void script_set_constant2(const char *name, int value, bool isparameter) {
script->str_data[n].label = -1;
}
- script->str_data[n].type = isparameter ? C_PARAM : C_INT;
+ script->str_data[n].type = is_parameter ? C_PARAM : C_INT;
script->str_data[n].val = value;
-
+ script->str_data[n].deprecated = is_deprecated ? 1 : 0;
}
-/*==========================================
- * Reading constant databases
- * const.txt
- *------------------------------------------*/
-void read_constdb(void) {
- FILE *fp;
- char line[1024],name[1024],val[1024];
- int type;
- sprintf(line, "%s/const.txt", map->db_path);
- fp=fopen(line, "r");
- if(fp==NULL) {
- ShowError("can't read %s\n", line);
- return ;
+/**
+ * Loads the constants database from constants.conf
+ */
+void read_constdb(void)
+{
+ config_t constants_conf;
+ char filepath[256];
+ config_setting_t *cdb;
+ config_setting_t *t;
+ int i = 0;
+
+ sprintf(filepath, "%s/constants.conf", map->db_path);
+
+ if (libconfig->read_file(&constants_conf, filepath) || !(cdb = libconfig->setting_get_member(constants_conf.root, "constants_db"))) {
+ ShowError("can't read %s\n", filepath);
+ return;
}
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
+
+ while ((t = libconfig->setting_get_elem(cdb, i++))) {
+ bool is_parameter = false;
+ bool is_deprecated = false;
+ int value = 0;
+ const char *name = config_setting_name(t);
+ const char *p = name;
+
+ while (*p != '\0') {
+ if (!ISALNUM(*p) && *p != '_')
+ break;
+ p++;
+ }
+ if (*p != '\0') {
+ ShowWarning("read_constdb: Invalid constant name %s. Skipping.\n", name);
continue;
- type = 0;
- if (sscanf(line, "%1023[A-Za-z0-9_],%1023[-0-9xXA-Fa-f],%d", name, val, &type) >=2
- || sscanf(line, "%1023[A-Za-z0-9_] %1023[-0-9xXA-Fa-f] %d", name, val, &type) >=2
- ) {
- script->set_constant(name, (int)strtol(val, NULL, 0), (bool)type);
}
+ if (strcmp(name, "comment__") == 0) {
+ const char *comment = libconfig->setting_get_string(t);
+ if (comment == NULL)
+ continue;
+ if (*comment == '\0')
+ comment = NULL;
+ script->constdb_comment(comment);
+ continue;
+ }
+ if (config_setting_is_aggregate(t)) {
+ int i32;
+ if (!libconfig->setting_lookup_int(t, "Value", &i32)) {
+ ShowWarning("read_constdb: Invalid entry for %s. Skipping.\n", name);
+ continue;
+ }
+ value = i32;
+ if (libconfig->setting_lookup_bool(t, "Parameter", &i32)) {
+ if (i32 != 0)
+ is_parameter = true;
+ }
+ if (libconfig->setting_lookup_bool(t, "Deprecated", &i32)) {
+ if (i32 != 0)
+ is_deprecated = true;
+ }
+ } else {
+ value = libconfig->setting_get_int(t);
+ }
+ script->set_constant(name, value, is_parameter, is_deprecated);
}
- fclose(fp);
+ script->constdb_comment(NULL);
+ libconfig->destroy(&constants_conf);
+}
+
+/**
+ * Sets the current constdb comment.
+ *
+ * This function does nothing (used by plugins only)
+ *
+ * @param comment The comment to set (NULL to unset)
+ */
+void script_constdb_comment(const char *comment)
+{
+ (void)comment;
}
// Standard UNIX tab size is 8
@@ -3699,7 +3757,6 @@ void op_2str(struct script_state* st, int op, const char* s1, const char* s2)
case C_GE: a = (strcmp(s1,s2) >= 0); break;
case C_LT: a = (strcmp(s1,s2) < 0); break;
case C_LE: a = (strcmp(s1,s2) <= 0); break;
-#ifdef PCRE_SUPPORT
case C_RE_EQ:
case C_RE_NE:
{
@@ -3764,7 +3821,6 @@ void op_2str(struct script_state* st, int op, const char* s1, const char* s2)
libpcre->free(extra_regex);
}
break;
-#endif // PCRE_SUPPORT
case C_ADD:
{
char* buf = (char *)aMalloc((strlen(s1)+strlen(s2)+1)*sizeof(char));
@@ -3789,7 +3845,7 @@ void op_2str(struct script_state* st, int op, const char* s1, const char* s2)
void op_2num(struct script_state* st, int op, int i1, int i2)
{
int ret;
- double ret_double;
+ int64 ret64;
switch( op ) {
case C_AND: ret = i1 & i2; break;
@@ -3821,25 +3877,21 @@ void op_2num(struct script_state* st, int op, int i1, int i2)
ret = i1 % i2;
break;
default:
- switch( op )
- {// operators that can overflow/underflow
- case C_ADD: ret = i1 + i2; ret_double = (double)i1 + (double)i2; break;
- case C_SUB: ret = i1 - i2; ret_double = (double)i1 - (double)i2; break;
- case C_MUL: ret = i1 * i2; ret_double = (double)i1 * (double)i2; break;
+ switch (op) { // operators that can overflow/underflow
+ case C_ADD: ret = i1 + i2; ret64 = (int64)i1 + i2; break;
+ case C_SUB: ret = i1 - i2; ret64 = (int64)i1 - i2; break;
+ case C_MUL: ret = i1 * i2; ret64 = (int64)i1 * i2; break;
default:
ShowError("script:op_2num: unexpected number operator %s i1=%d i2=%d\n", script->op2name(op), i1, i2);
script->reportsrc(st);
script_pushnil(st);
return;
}
- if( ret_double < (double)INT_MIN )
- {
+ if (ret64 < INT_MIN) {
ShowWarning("script:op_2num: underflow detected op=%s i1=%d i2=%d\n", script->op2name(op), i1, i2);
script->reportsrc(st);
ret = INT_MIN;
- }
- else if( ret_double > (double)INT_MAX )
- {
+ } else if (ret64 > INT_MAX) {
ShowWarning("script:op_2num: overflow detected op=%s i1=%d i2=%d\n", script->op2name(op), i1, i2);
script->reportsrc(st);
ret = INT_MAX;
@@ -4361,10 +4413,8 @@ void run_script_main(struct script_state *st) {
case C_LOR:
case C_R_SHIFT:
case C_L_SHIFT:
-#ifdef PCRE_SUPPORT
case C_RE_EQ:
case C_RE_NE:
-#endif // PCRE_SUPPORT
script->op_2(st, c);
break;
@@ -9648,20 +9698,18 @@ BUILDIN(makepet)
BUILDIN(getexp)
{
int base=0,job=0;
- double bonus;
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
return true;
- base=script_getnum(st,2);
- job =script_getnum(st,3);
- if(base<0 || job<0)
+ base = script_getnum(st,2);
+ job = script_getnum(st,3);
+ if (base < 0 || job < 0)
return true;
// bonus for npc-given exp
- bonus = battle_config.quest_exp_rate / 100.;
- base = (int) cap_value(base * bonus, 0, INT_MAX);
- job = (int) cap_value(job * bonus, 0, INT_MAX);
+ base = cap_value(apply_percentrate(base, battle_config.quest_exp_rate, 100), 0, INT_MAX);
+ job = cap_value(apply_percentrate(job, battle_config.quest_exp_rate, 100), 0, INT_MAX);
pc->gainexp(sd, &sd->bl, base, job, true);
@@ -11684,7 +11732,7 @@ BUILDIN(getmapflag)
case MF_RESET: script_pushint(st,map->list[m].flag.reset); break;
case MF_NOTOMB: script_pushint(st,map->list[m].flag.notomb); break;
case MF_NOCASHSHOP: script_pushint(st,map->list[m].flag.nocashshop); break;
- case MF_NOVIEWID: script_pushint(st,map->list[m].flag.noviewid); break;
+ case MF_NOVIEWID: script_pushint(st,map->list[m].flag.noviewid); break;
}
}
@@ -11808,7 +11856,7 @@ BUILDIN(setmapflag) {
case MF_RESET: map->list[m].flag.reset = 1; break;
case MF_NOTOMB: map->list[m].flag.notomb = 1; break;
case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 1; break;
- case MF_NOVIEWID: map->list[m].flag.noviewid = (val <= 0) ? 0 : val; break;
+ case MF_NOVIEWID: map->list[m].flag.noviewid = (val <= 0) ? EQP_NONE : val; break;
}
}
@@ -11895,7 +11943,7 @@ BUILDIN(removemapflag) {
case MF_RESET: map->list[m].flag.reset = 0; break;
case MF_NOTOMB: map->list[m].flag.notomb = 0; break;
case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 0; break;
- case MF_NOVIEWID: map->list[m].flag.noviewid = 0; break;
+ case MF_NOVIEWID: map->list[m].flag.noviewid = EQP_NONE; break;
}
}
@@ -18450,7 +18498,7 @@ BUILDIN(setcashmount)
if (sd->sc.data[SC_ALL_RIDING])
status_change_end(&sd->bl, SC_ALL_RIDING, INVALID_TIMER);
else
- sc_start(NULL,&sd->bl, SC_ALL_RIDING, 100, 0, -1);
+ sc_start(NULL,&sd->bl, SC_ALL_RIDING, 100, 25, -1);
script_pushint(st,1);//in both cases, return 1.
}
return true;
@@ -20067,7 +20115,6 @@ BUILDIN(_) {
}
// declarations that were supposed to be exported from npc_chat.c
-#ifdef PCRE_SUPPORT
BUILDIN(defpattern);
BUILDIN(activatepset);
BUILDIN(deactivatepset);
@@ -20080,7 +20127,6 @@ BUILDIN(pcre_match) {
script->op_2str(st, C_RE_EQ, input, regex);
return true;
}
-#endif
/**
* Adds a built-in script function.
@@ -20497,13 +20543,11 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getrefine,""), // returns the refined number of the current item, or an item with index specified [celest]
BUILDIN_DEF(night,""), // sets the server to night time
BUILDIN_DEF(day,""), // sets the server to day time
-#ifdef PCRE_SUPPORT
BUILDIN_DEF(defpattern,"iss"), // Define pattern to listen for [MouseJstr]
BUILDIN_DEF(activatepset,"i"), // Activate a pattern set [MouseJstr]
BUILDIN_DEF(deactivatepset,"i"), // Deactive a pattern set [MouseJstr]
BUILDIN_DEF(deletepset,"i"), // Delete a pattern set [MouseJstr]
BUILDIN_DEF(pcre_match,"ss"),
-#endif
BUILDIN_DEF(dispbottom,"s?"), //added from jA [Lupus]
BUILDIN_DEF(getusersname,""),
BUILDIN_DEF(recovery,""),
@@ -20778,119 +20822,164 @@ void script_label_add(int key, int pos) {
/**
* Sets source-end constants for scripts to play with
**/
-void script_hardcoded_constants(void) {
- /* server defines */
- script->set_constant("PACKETVER",PACKETVER,false);
- script->set_constant("MAX_LEVEL",MAX_LEVEL,false);
- script->set_constant("MAX_STORAGE",MAX_STORAGE,false);
- script->set_constant("MAX_GUILD_STORAGE",MAX_GUILD_STORAGE,false);
- script->set_constant("MAX_CART",MAX_INVENTORY,false);
- script->set_constant("MAX_INVENTORY",MAX_INVENTORY,false);
- script->set_constant("MAX_ZENY",MAX_ZENY,false);
- script->set_constant("MAX_BG_MEMBERS",MAX_BG_MEMBERS,false);
- script->set_constant("MAX_CHAT_USERS",MAX_CHAT_USERS,false);
- script->set_constant("MAX_REFINE",MAX_REFINE,false);
-
- /* status options */
- script->set_constant("Option_Nothing",OPTION_NOTHING,false);
- script->set_constant("Option_Sight",OPTION_SIGHT,false);
- script->set_constant("Option_Hide",OPTION_HIDE,false);
- script->set_constant("Option_Cloak",OPTION_CLOAK,false);
- script->set_constant("Option_Falcon",OPTION_FALCON,false);
- script->set_constant("Option_Riding",OPTION_RIDING,false);
- script->set_constant("Option_Invisible",OPTION_INVISIBLE,false);
- script->set_constant("Option_Orcish",OPTION_ORCISH,false);
- script->set_constant("Option_Wedding",OPTION_WEDDING,false);
- script->set_constant("Option_Chasewalk",OPTION_CHASEWALK,false);
- script->set_constant("Option_Flying",OPTION_FLYING,false);
- script->set_constant("Option_Xmas",OPTION_XMAS,false);
- script->set_constant("Option_Transform",OPTION_TRANSFORM,false);
- script->set_constant("Option_Summer",OPTION_SUMMER,false);
- script->set_constant("Option_Dragon1",OPTION_DRAGON1,false);
- script->set_constant("Option_Wug",OPTION_WUG,false);
- script->set_constant("Option_Wugrider",OPTION_WUGRIDER,false);
- script->set_constant("Option_Madogear",OPTION_MADOGEAR,false);
- script->set_constant("Option_Dragon2",OPTION_DRAGON2,false);
- script->set_constant("Option_Dragon3",OPTION_DRAGON3,false);
- script->set_constant("Option_Dragon4",OPTION_DRAGON4,false);
- script->set_constant("Option_Dragon5",OPTION_DRAGON5,false);
- script->set_constant("Option_Hanbok",OPTION_HANBOK,false);
- script->set_constant("Option_Oktoberfest",OPTION_OKTOBERFEST,false);
-
- /* status option compounds */
- script->set_constant("Option_Dragon",OPTION_DRAGON,false);
- script->set_constant("Option_Costume",OPTION_COSTUME,false);
-
- /* send_target */
- script->set_constant("ALL_CLIENT",ALL_CLIENT,false);
- script->set_constant("ALL_SAMEMAP",ALL_SAMEMAP,false);
- script->set_constant("AREA",AREA,false);
- script->set_constant("AREA_WOS",AREA_WOS,false);
- script->set_constant("AREA_WOC",AREA_WOC,false);
- script->set_constant("AREA_WOSC",AREA_WOSC,false);
- script->set_constant("AREA_CHAT_WOC",AREA_CHAT_WOC,false);
- script->set_constant("CHAT",CHAT,false);
- script->set_constant("CHAT_WOS",CHAT_WOS,false);
- script->set_constant("PARTY",PARTY,false);
- script->set_constant("PARTY_WOS",PARTY_WOS,false);
- script->set_constant("PARTY_SAMEMAP",PARTY_SAMEMAP,false);
- script->set_constant("PARTY_SAMEMAP_WOS",PARTY_SAMEMAP_WOS,false);
- script->set_constant("PARTY_AREA",PARTY_AREA,false);
- script->set_constant("PARTY_AREA_WOS",PARTY_AREA_WOS,false);
- script->set_constant("GUILD",GUILD,false);
- script->set_constant("GUILD_WOS",GUILD_WOS,false);
- script->set_constant("GUILD_SAMEMAP",GUILD_SAMEMAP,false);
- script->set_constant("GUILD_SAMEMAP_WOS",GUILD_SAMEMAP_WOS,false);
- script->set_constant("GUILD_AREA",GUILD_AREA,false);
- script->set_constant("GUILD_AREA_WOS",GUILD_AREA_WOS,false);
- script->set_constant("GUILD_NOBG",GUILD_NOBG,false);
- script->set_constant("DUEL",DUEL,false);
- script->set_constant("DUEL_WOS",DUEL_WOS,false);
- script->set_constant("SELF",SELF,false);
- script->set_constant("BG",BG,false);
- script->set_constant("BG_WOS",BG_WOS,false);
- script->set_constant("BG_SAMEMAP",BG_SAMEMAP,false);
- script->set_constant("BG_SAMEMAP_WOS",BG_SAMEMAP_WOS,false);
- script->set_constant("BG_AREA",BG_AREA,false);
- script->set_constant("BG_AREA_WOS",BG_AREA_WOS,false);
- script->set_constant("BG_QUEUE",BG_QUEUE,false);
-
- /* Renewal */
+void script_hardcoded_constants(void)
+{
+ script->constdb_comment("Boolean");
+ script->set_constant("true", 1, false, false);
+ script->set_constant("false", 0, false, false);
+
+ script->constdb_comment("Server defines");
+ script->set_constant("PACKETVER",PACKETVER,false, false);
+ script->set_constant("MAX_LEVEL",MAX_LEVEL,false, false);
+ script->set_constant("MAX_STORAGE",MAX_STORAGE,false, false);
+ script->set_constant("MAX_GUILD_STORAGE",MAX_GUILD_STORAGE,false, false);
+ script->set_constant("MAX_CART",MAX_INVENTORY,false, false);
+ script->set_constant("MAX_INVENTORY",MAX_INVENTORY,false, false);
+ script->set_constant("MAX_ZENY",MAX_ZENY,false, false);
+ script->set_constant("MAX_BG_MEMBERS",MAX_BG_MEMBERS,false, false);
+ script->set_constant("MAX_CHAT_USERS",MAX_CHAT_USERS,false, false);
+ script->set_constant("MAX_REFINE",MAX_REFINE,false, false);
+
+ script->constdb_comment("status options");
+ script->set_constant("Option_Nothing",OPTION_NOTHING,false, false);
+ script->set_constant("Option_Sight",OPTION_SIGHT,false, false);
+ script->set_constant("Option_Hide",OPTION_HIDE,false, false);
+ script->set_constant("Option_Cloak",OPTION_CLOAK,false, false);
+ script->set_constant("Option_Falcon",OPTION_FALCON,false, false);
+ script->set_constant("Option_Riding",OPTION_RIDING,false, false);
+ script->set_constant("Option_Invisible",OPTION_INVISIBLE,false, false);
+ script->set_constant("Option_Orcish",OPTION_ORCISH,false, false);
+ script->set_constant("Option_Wedding",OPTION_WEDDING,false, false);
+ script->set_constant("Option_Chasewalk",OPTION_CHASEWALK,false, false);
+ script->set_constant("Option_Flying",OPTION_FLYING,false, false);
+ script->set_constant("Option_Xmas",OPTION_XMAS,false, false);
+ script->set_constant("Option_Transform",OPTION_TRANSFORM,false, false);
+ script->set_constant("Option_Summer",OPTION_SUMMER,false, false);
+ script->set_constant("Option_Dragon1",OPTION_DRAGON1,false, false);
+ script->set_constant("Option_Wug",OPTION_WUG,false, false);
+ script->set_constant("Option_Wugrider",OPTION_WUGRIDER,false, false);
+ script->set_constant("Option_Madogear",OPTION_MADOGEAR,false, false);
+ script->set_constant("Option_Dragon2",OPTION_DRAGON2,false, false);
+ script->set_constant("Option_Dragon3",OPTION_DRAGON3,false, false);
+ script->set_constant("Option_Dragon4",OPTION_DRAGON4,false, false);
+ script->set_constant("Option_Dragon5",OPTION_DRAGON5,false, false);
+ script->set_constant("Option_Hanbok",OPTION_HANBOK,false, false);
+ script->set_constant("Option_Oktoberfest",OPTION_OKTOBERFEST,false, false);
+
+ script->constdb_comment("status option compounds");
+ script->set_constant("Option_Dragon",OPTION_DRAGON,false, false);
+ script->set_constant("Option_Costume",OPTION_COSTUME,false, false);
+
+ script->constdb_comment("send_target");
+ script->set_constant("ALL_CLIENT",ALL_CLIENT,false, false);
+ script->set_constant("ALL_SAMEMAP",ALL_SAMEMAP,false, false);
+ script->set_constant("AREA",AREA,false, false);
+ script->set_constant("AREA_WOS",AREA_WOS,false, false);
+ script->set_constant("AREA_WOC",AREA_WOC,false, false);
+ script->set_constant("AREA_WOSC",AREA_WOSC,false, false);
+ script->set_constant("AREA_CHAT_WOC",AREA_CHAT_WOC,false, false);
+ script->set_constant("CHAT",CHAT,false, false);
+ script->set_constant("CHAT_WOS",CHAT_WOS,false, false);
+ script->set_constant("PARTY",PARTY,false, false);
+ script->set_constant("PARTY_WOS",PARTY_WOS,false, false);
+ script->set_constant("PARTY_SAMEMAP",PARTY_SAMEMAP,false, false);
+ script->set_constant("PARTY_SAMEMAP_WOS",PARTY_SAMEMAP_WOS,false, false);
+ script->set_constant("PARTY_AREA",PARTY_AREA,false, false);
+ script->set_constant("PARTY_AREA_WOS",PARTY_AREA_WOS,false, false);
+ script->set_constant("GUILD",GUILD,false, false);
+ script->set_constant("GUILD_WOS",GUILD_WOS,false, false);
+ script->set_constant("GUILD_SAMEMAP",GUILD_SAMEMAP,false, false);
+ script->set_constant("GUILD_SAMEMAP_WOS",GUILD_SAMEMAP_WOS,false, false);
+ script->set_constant("GUILD_AREA",GUILD_AREA,false, false);
+ script->set_constant("GUILD_AREA_WOS",GUILD_AREA_WOS,false, false);
+ script->set_constant("GUILD_NOBG",GUILD_NOBG,false, false);
+ script->set_constant("DUEL",DUEL,false, false);
+ script->set_constant("DUEL_WOS",DUEL_WOS,false, false);
+ script->set_constant("SELF",SELF,false, false);
+ script->set_constant("BG",BG,false, false);
+ script->set_constant("BG_WOS",BG_WOS,false, false);
+ script->set_constant("BG_SAMEMAP",BG_SAMEMAP,false, false);
+ script->set_constant("BG_SAMEMAP_WOS",BG_SAMEMAP_WOS,false, false);
+ script->set_constant("BG_AREA",BG_AREA,false, false);
+ script->set_constant("BG_AREA_WOS",BG_AREA_WOS,false, false);
+ script->set_constant("BG_QUEUE",BG_QUEUE,false, false);
+
+ script->constdb_comment("LOOK_ constants, use in setlook/changelook script commands");
+ script->set_constant("LOOK_BASE", LOOK_BASE, false, false);
+ script->set_constant("LOOK_HAIR", LOOK_HAIR, false, false);
+ script->set_constant("LOOK_WEAPON", LOOK_WEAPON, false, false);
+ script->set_constant("LOOK_HEAD_BOTTOM", LOOK_HEAD_BOTTOM, false, false);
+ script->set_constant("LOOK_HEAD_TOP", LOOK_HEAD_TOP, false, false);
+ script->set_constant("LOOK_HEAD_MID", LOOK_HEAD_MID, false, false);
+ script->set_constant("LOOK_HAIR_COLOR", LOOK_HAIR_COLOR, false, false);
+ script->set_constant("LOOK_CLOTHES_COLOR", LOOK_CLOTHES_COLOR, false, false);
+ script->set_constant("LOOK_SHIELD", LOOK_SHIELD, false, false);
+ script->set_constant("LOOK_SHOES", LOOK_SHOES, false, false);
+ script->set_constant("LOOK_BODY", LOOK_BODY, false, false);
+ script->set_constant("LOOK_FLOOR", LOOK_FLOOR, false, false);
+ script->set_constant("LOOK_ROBE", LOOK_ROBE, false, false);
+ script->set_constant("LOOK_BODY2", LOOK_BODY2, false, false);
+
+ script->constdb_comment("Equip Position in Bits, use with *getiteminfo type 5, or @inventorylist_equip");
+ script->set_constant("EQP_HEAD_LOW", EQP_HEAD_LOW, false, false);
+ script->set_constant("EQP_HEAD_MID", EQP_HEAD_MID, false, false);
+ script->set_constant("EQP_HEAD_TOP", EQP_HEAD_TOP, false, false);
+ script->set_constant("EQP_HAND_R", EQP_HAND_R, false, false);
+ script->set_constant("EQP_HAND_L", EQP_HAND_L, false, false);
+ script->set_constant("EQP_ARMOR", EQP_ARMOR, false, false);
+ script->set_constant("EQP_SHOES", EQP_SHOES, false, false);
+ script->set_constant("EQP_GARMENT", EQP_GARMENT, false, false);
+ script->set_constant("EQP_ACC_L", EQP_ACC_L, false, false);
+ script->set_constant("EQP_ACC_R", EQP_ACC_R, false, false);
+ script->set_constant("EQP_COSTUME_HEAD_TOP", EQP_COSTUME_HEAD_TOP, false, false);
+ script->set_constant("EQP_COSTUME_HEAD_MID", EQP_COSTUME_HEAD_MID, false, false);
+ script->set_constant("EQP_COSTUME_HEAD_LOW", EQP_COSTUME_HEAD_LOW, false, false);
+ script->set_constant("EQP_COSTUME_GARMENT", EQP_COSTUME_GARMENT, false, false);
+ script->set_constant("EQP_AMMO", EQP_AMMO, false, false);
+ script->set_constant("EQP_SHADOW_ARMOR", EQP_SHADOW_ARMOR, false, false);
+ script->set_constant("EQP_SHADOW_WEAPON", EQP_SHADOW_WEAPON, false, false);
+ script->set_constant("EQP_SHADOW_SHIELD", EQP_SHADOW_SHIELD, false, false);
+ script->set_constant("EQP_SHADOW_SHOES", EQP_SHADOW_SHOES, false, false);
+ script->set_constant("EQP_SHADOW_ACC_R", EQP_SHADOW_ACC_R, false, false);
+ script->set_constant("EQP_SHADOW_ACC_L", EQP_SHADOW_ACC_L, false, false);
+
+ script->constdb_comment("Renewal");
#ifdef RENEWAL
- script->set_constant("RENEWAL", 1, false);
+ script->set_constant("RENEWAL", 1, false, false);
#else
- script->set_constant("RENEWAL", 0, false);
+ script->set_constant("RENEWAL", 0, false, false);
#endif
#ifdef RENEWAL_CAST
- script->set_constant("RENEWAL_CAST", 1, false);
+ script->set_constant("RENEWAL_CAST", 1, false, false);
#else
- script->set_constant("RENEWAL_CAST", 0, false);
+ script->set_constant("RENEWAL_CAST", 0, false, false);
#endif
#ifdef RENEWAL_DROP
- script->set_constant("RENEWAL_DROP", 1, false);
+ script->set_constant("RENEWAL_DROP", 1, false, false);
#else
- script->set_constant("RENEWAL_DROP", 0, false);
+ script->set_constant("RENEWAL_DROP", 0, false, false);
#endif
#ifdef RENEWAL_EXP
- script->set_constant("RENEWAL_EXP", 1, false);
+ script->set_constant("RENEWAL_EXP", 1, false, false);
#else
- script->set_constant("RENEWAL_EXP", 0, false);
+ script->set_constant("RENEWAL_EXP", 0, false, false);
#endif
#ifdef RENEWAL_LVDMG
- script->set_constant("RENEWAL_LVDMG", 1, false);
+ script->set_constant("RENEWAL_LVDMG", 1, false, false);
#else
- script->set_constant("RENEWAL_LVDMG", 0, false);
+ script->set_constant("RENEWAL_LVDMG", 0, false, false);
#endif
#ifdef RENEWAL_EDP
- script->set_constant("RENEWAL_EDP", 1, false);
+ script->set_constant("RENEWAL_EDP", 1, false, false);
#else
- script->set_constant("RENEWAL_EDP", 0, false);
+ script->set_constant("RENEWAL_EDP", 0, false, false);
#endif
#ifdef RENEWAL_ASPD
- script->set_constant("RENEWAL_ASPD", 1, false);
+ script->set_constant("RENEWAL_ASPD", 1, false, false);
#else
- script->set_constant("RENEWAL_ASPD", 0, false);
+ script->set_constant("RENEWAL_ASPD", 0, false, false);
#endif
+ script->constdb_comment(NULL);
}
/**
@@ -21068,6 +21157,7 @@ void script_defaults(void) {
script->parse_expr = parse_expr;
script->parse_line = parse_line;
script->read_constdb = read_constdb;
+ script->constdb_comment = script_constdb_comment;
script->print_line = script_print_line;
script->errorwarning_sub = script_errorwarning_sub;
script->set_reg = set_reg;
diff --git a/src/map/script.h b/src/map/script.h
index 5f71662c6..351ccd02a 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -233,10 +233,8 @@ typedef enum c_op {
C_SUB_POST, // a--
C_ADD_PRE, // ++a
C_SUB_PRE, // --a
-#ifdef PCRE_SUPPORT
C_RE_EQ, // ~=
C_RE_NE, // ~!
-#endif // PCRE_SUPPORT
} c_op;
/// Script queue options
@@ -666,8 +664,8 @@ struct script_interface {
struct script_data* (*push_str) (struct script_stack* stack, enum c_op type, char* str);
struct script_data* (*push_copy) (struct script_stack* stack, int pos);
void (*pop_stack) (struct script_state* st, int start, int end);
- void (*set_constant) (const char* name, int value, bool isparameter);
- void (*set_constant2) (const char *name, int value, bool isparameter);
+ void (*set_constant) (const char *name, int value, bool is_parameter, bool is_deprecated);
+ void (*set_constant2) (const char *name, int value, bool is_parameter, bool is_deprecated);
bool (*get_constant) (const char* name, int* value);
void (*label_add)(int key, int pos);
void (*run) (struct script_code *rootscript, int pos, int rid, int oid);
@@ -726,6 +724,7 @@ struct script_interface {
const char* (*parse_expr) (const char *p);
const char* (*parse_line) (const char *p);
void (*read_constdb) (void);
+ void (*constdb_comment) (const char *comment);
const char* (*print_line) (StringBuf *buf, const char *p, const char *mark, int line);
void (*errorwarning_sub) (StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos);
int (*set_reg) (struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref);
diff --git a/src/map/skill.c b/src/map/skill.c
index 972e505cb..c70b94cd5 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -4374,7 +4374,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
clif->slide(src, x, y);
clif->fixpos(src); // the official server send these two packets.
skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
- if ( rnd() % 100 < 4 * skill_lv && skill_id == GC_DARKILLUSION )
+ if (rnd() % 100 < 4 * skill_lv && skill_id == GC_DARKILLUSION)
skill->castend_damage_id(src, bl, GC_CROSSIMPACT, skill_lv, tick, flag);
}
}
@@ -6047,7 +6047,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
case MC_CHANGECART:
- clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ break;
+
+ case MC_CARTDECORATE:
+ if (sd) {
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ clif->selectcart(sd);
+ }
break;
case TK_MISSION:
@@ -14881,7 +14888,7 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
}
if (sc->data[SC_MYSTICSCROLL])
VARCAST_REDUCTION(sc->data[SC_MYSTICSCROLL]->val1);
-
+
// Fixed cast reduction bonuses
if( sc->data[SC__LAZINESS] )
fixcast_r = max(fixcast_r, sc->data[SC__LAZINESS]->val2);
@@ -18121,7 +18128,7 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick)
return 0;
else {
int cursor;
- /** somehow, the timer vanished. (bugreport:8367) **/
+ /* somehow, the timer vanished. (bugreport:8367) */
ers_free(skill->cd_entry_ers, cd->entry[i]);
cd->entry[i] = NULL;
@@ -18833,7 +18840,7 @@ bool skill_parse_row_skilldb(char* split[], int columns, int current) {
safestrncpy(skill->dbs->db[idx].name, trim(split[15]), sizeof(skill->dbs->db[idx].name));
safestrncpy(skill->dbs->db[idx].desc, trim(split[16]), sizeof(skill->dbs->db[idx].desc));
strdb_iput(skill->name2id_db, skill->dbs->db[idx].name, skill_id);
- script->set_constant2(skill->dbs->db[idx].name,(int)skill_id,0);
+ script->set_constant2(skill->dbs->db[idx].name, (int)skill_id, false, false);
return true;
}
diff --git a/src/map/status.c b/src/map/status.c
index c755d8eb0..879f10efb 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -862,38 +862,38 @@ void initChangeTables(void) {
status->dbs->IconChangeTable[SC_M_LIFEPOTION] = SI_M_LIFEPOTION;
status->dbs->IconChangeTable[SC_G_LIFEPOTION] = SI_G_LIFEPOTION;
status->dbs->IconChangeTable[SC_MYSTICPOWDER] = SI_MYSTICPOWDER;
-
+
// Eden Crystal Synthesis
status->dbs->IconChangeTable[SC_QUEST_BUFF1] = SI_QUEST_BUFF1;
status->dbs->IconChangeTable[SC_QUEST_BUFF2] = SI_QUEST_BUFF2;
status->dbs->IconChangeTable[SC_QUEST_BUFF3] = SI_QUEST_BUFF3;
-
+
// Geffen Magic Tournament
status->dbs->IconChangeTable[SC_GEFFEN_MAGIC1] = SI_GEFFEN_MAGIC1;
status->dbs->IconChangeTable[SC_GEFFEN_MAGIC2] = SI_GEFFEN_MAGIC2;
status->dbs->IconChangeTable[SC_GEFFEN_MAGIC3] = SI_GEFFEN_MAGIC3;
status->dbs->IconChangeTable[SC_FENRIR_CARD] = SI_FENRIR_CARD;
-
+
// MVP Scrolls
status->dbs->IconChangeTable[SC_MVPCARD_TAOGUNKA] = SI_MVPCARD_TAOGUNKA;
status->dbs->IconChangeTable[SC_MVPCARD_MISTRESS] = SI_MVPCARD_MISTRESS;
status->dbs->IconChangeTable[SC_MVPCARD_ORCHERO] = SI_MVPCARD_ORCHERO;
status->dbs->IconChangeTable[SC_MVPCARD_ORCLORD] = SI_MVPCARD_ORCLORD;
-
+
// Mercenary Bonus Effects
status->dbs->IconChangeTable[SC_MER_FLEE] = SI_MER_FLEE;
status->dbs->IconChangeTable[SC_MER_ATK] = SI_MER_ATK;
status->dbs->IconChangeTable[SC_MER_HP] = SI_MER_HP;
status->dbs->IconChangeTable[SC_MER_SP] = SI_MER_SP;
status->dbs->IconChangeTable[SC_MER_HIT] = SI_MER_HIT;
-
+
// Warlock Spheres
status->dbs->IconChangeTable[SC_SUMMON1] = SI_SPHERE_1;
status->dbs->IconChangeTable[SC_SUMMON2] = SI_SPHERE_2;
status->dbs->IconChangeTable[SC_SUMMON3] = SI_SPHERE_3;
status->dbs->IconChangeTable[SC_SUMMON4] = SI_SPHERE_4;
status->dbs->IconChangeTable[SC_SUMMON5] = SI_SPHERE_5;
-
+
// Warlock Preserved spells
status->dbs->IconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1;
status->dbs->IconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2;
@@ -977,7 +977,7 @@ void initChangeTables(void) {
status->dbs->IconChangeTable[SC_REBOUND] = SI_REBOUND;
status->dbs->IconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING;
status->dbs->IconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM;
-
+
// Costumes
status->dbs->IconChangeTable[SC_MOONSTAR] = SI_MOONSTAR;
status->dbs->IconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR;
@@ -993,7 +993,7 @@ void initChangeTables(void) {
status->dbs->IconChangeTable[SC_TIME_ACCESSORY] = SI_TIME_ACCESSORY;
status->dbs->IconChangeTable[SC_MAGICAL_FEATHER] = SI_MAGICAL_FEATHER;
status->dbs->IconChangeTable[SC_BLOSSOM_FLUTTERING] = SI_BLOSSOM_FLUTTERING;
-
+
// Other SC which are not necessarily associated to skills.
status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION1] |= SCB_ASPD;
status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION2] |= SCB_ASPD;
@@ -1061,7 +1061,7 @@ void initChangeTables(void) {
status->dbs->ChangeFlagTable[SC_PHI_DEMON] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_MAGIC_CANDY] |= SCB_MATK | SCB_ALL;
status->dbs->ChangeFlagTable[SC_MYSTICPOWDER] |= SCB_FLEE | SCB_LUK;
-
+
// Cash Items
status->dbs->ChangeFlagTable[SC_FOOD_STR_CASH] |= SCB_STR;
status->dbs->ChangeFlagTable[SC_FOOD_AGI_CASH] |= SCB_AGI;
@@ -1069,14 +1069,14 @@ void initChangeTables(void) {
status->dbs->ChangeFlagTable[SC_FOOD_DEX_CASH] |= SCB_DEX;
status->dbs->ChangeFlagTable[SC_FOOD_INT_CASH] |= SCB_INT;
status->dbs->ChangeFlagTable[SC_FOOD_LUK_CASH] |= SCB_LUK;
-
+
// Mercenary Bonus Effects
status->dbs->ChangeFlagTable[SC_MER_FLEE] |= SCB_FLEE;
status->dbs->ChangeFlagTable[SC_MER_ATK] |= SCB_WATK;
status->dbs->ChangeFlagTable[SC_MER_HP] |= SCB_MAXHP;
status->dbs->ChangeFlagTable[SC_MER_SP] |= SCB_MAXSP;
status->dbs->ChangeFlagTable[SC_MER_HIT] |= SCB_HIT;
-
+
// Guillotine Cross Poison Effects
status->dbs->ChangeFlagTable[SC_PARALYSE] |= SCB_FLEE | SCB_SPEED | SCB_ASPD;
status->dbs->ChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP;
@@ -1084,11 +1084,11 @@ void initChangeTables(void) {
status->dbs->ChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
status->dbs->ChangeFlagTable[SC_PYREXIA] |= SCB_HIT | SCB_FLEE;
status->dbs->ChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN;
-
+
// Royal Guard status
status->dbs->ChangeFlagTable[SC_SHIELDSPELL_DEF] |= SCB_WATK;
status->dbs->ChangeFlagTable[SC_SHIELDSPELL_REF] |= SCB_DEF;
-
+
// Mechanic status
status->dbs->ChangeFlagTable[SC_STEALTHFIELD_MASTER] |= SCB_SPEED;
@@ -1116,7 +1116,7 @@ void initChangeTables(void) {
status->dbs->ChangeFlagTable[SC_STOMACHACHE] |= SCB_STR | SCB_AGI | SCB_VIT | SCB_INT | SCB_DEX | SCB_LUK | SCB_SPEED;
status->dbs->ChangeFlagTable[SC_PROMOTE_HEALTH_RESERCH] |= SCB_MAXHP | SCB_ALL;
status->dbs->ChangeFlagTable[SC_ENERGY_DRINK_RESERCH] |= SCB_MAXSP | SCB_ALL;
-
+
// Geffen Scrolls
status->dbs->ChangeFlagTable[SC_SKELSCROLL] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_DISTRUCTIONSCROLL] |= SCB_ALL;
@@ -1135,24 +1135,24 @@ void initChangeTables(void) {
status->dbs->ChangeFlagTable[SC_MTF_HITFLEE] |= SCB_HIT | SCB_FLEE;
status->dbs->ChangeFlagTable[SC_MTF_MHP] |= SCB_MAXHP;
status->dbs->ChangeFlagTable[SC_MTF_MSP] |= SCB_MAXSP;
-
+
// Eden Crystal Synthesis
status->dbs->ChangeFlagTable[SC_QUEST_BUFF1] |= SCB_BATK | SCB_MATK;
status->dbs->ChangeFlagTable[SC_QUEST_BUFF2] |= SCB_BATK | SCB_MATK;
status->dbs->ChangeFlagTable[SC_QUEST_BUFF3] |= SCB_BATK | SCB_MATK;
-
+
// Geffen Magic Tournament
status->dbs->ChangeFlagTable[SC_GEFFEN_MAGIC1] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_GEFFEN_MAGIC2] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_GEFFEN_MAGIC3] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_FENRIR_CARD] |= SCB_MATK | SCB_ALL;
-
+
// MVP Scrolls
status->dbs->ChangeFlagTable[SC_MVPCARD_TAOGUNKA] |= SCB_MAXHP | SCB_DEF | SCB_MDEF;
status->dbs->ChangeFlagTable[SC_MVPCARD_MISTRESS] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_MVPCARD_ORCHERO] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_MVPCARD_ORCLORD] |= SCB_ALL;
-
+
// Costumes
status->dbs->ChangeFlagTable[SC_MOONSTAR] |= SCB_NONE;
status->dbs->ChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE;
@@ -1192,7 +1192,7 @@ void initChangeTables(void) {
status->dbs->DisplayType[SC_BLOOD_SUCKER] = true;
status->dbs->DisplayType[SC__SHADOWFORM] = true;
status->dbs->DisplayType[SC_MONSTER_TRANSFORM] = true;
-
+
// Costumes
status->dbs->DisplayType[SC_MOONSTAR] = true;
status->dbs->DisplayType[SC_SUPER_STAR] = true;
@@ -2500,7 +2500,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
}
else if(sd->inventory_data[index]->type == IT_ARMOR) {
int r = sd->status.inventory[index].refine;
-
+
if ( (!battle_config.costume_refine_def && itemdb_is_costumeequip(sd->inventory_data[index]->equip)) ||
(!battle_config.shadow_refine_def && itemdb_is_shadowequip(sd->inventory_data[index]->equip))
)
@@ -3110,7 +3110,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->magic_addele[ELE_WIND] += 25;
if (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
sd->magic_addele[ELE_EARTH] += 25;
-
+
// Geffen Scrolls
if (sc->data[SC_SKELSCROLL]) {
#ifdef RENEWAL
@@ -3136,11 +3136,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
}
if (sc->data[SC_IMMUNITYSCROLL])
sd->subele[ELE_NEUTRAL] += sc->data[SC_IMMUNITYSCROLL]->val1;
-
+
// Geffen Magic Tournament
if (sc->data[SC_GEFFEN_MAGIC1]) {
sd->right_weapon.addrace[RC_DEMIHUMAN] += sc->data[SC_GEFFEN_MAGIC1]->val1;
- sd->left_weapon.addrace[RC_DEMIHUMAN] += sc->data[SC_GEFFEN_MAGIC1]->val1;
+ sd->left_weapon.addrace[RC_DEMIHUMAN] += sc->data[SC_GEFFEN_MAGIC1]->val1;
}
if (sc->data[SC_GEFFEN_MAGIC2])
sd->magic_addrace[RC_DEMIHUMAN] += sc->data[SC_GEFFEN_MAGIC2]->val1;
@@ -4190,10 +4190,14 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
if ( sd->status.shield )
amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class_)][MAX_WEAPON_TYPE];
switch ( sd->status.weapon ) {
- case W_BOW: case W_MUSICAL:
- case W_WHIP: case W_REVOLVER:
- case W_RIFLE: case W_GATLING:
- case W_SHOTGUN: case W_GRENADE:
+ case W_BOW:
+ case W_MUSICAL:
+ case W_WHIP:
+ case W_REVOLVER:
+ case W_RIFLE:
+ case W_GATLING:
+ case W_SHOTGUN:
+ case W_GRENADE:
temp = st->dex * st->dex / 7.0f + st->agi * st->agi * 0.5f;
break;
default:
@@ -4271,12 +4275,14 @@ unsigned short status_base_atk(const struct block_list *bl, const struct status_
str = (int)(dstr + (float)dex / 5 + (float)st->luk / 3 + (float)BL_UCCAST(BL_PC, bl)->status.base_level / 4);
else if (bl->type == BL_MOB)
str = dstr + BL_UCCAST(BL_MOB, bl)->level;
- //else if (bl->type == BL_MER) // FIXME: What should go here?
- // str = dstr + BL_UCCAST(BL_MER, bl)->level;
-#else
+#if 0
+ else if (bl->type == BL_MER) // FIXME: What should go here?
+ str = dstr + BL_UCCAST(BL_MER, bl)->level;
+#endif // 0
+#else // ! RENEWAL
if (bl->type == BL_PC)
str += dex / 5 + st->luk / 5;
-#endif
+#endif // RENEWAL
return cap_value(str, 0, USHRT_MAX);
}
@@ -4813,7 +4819,7 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc,
batk += 100 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1;
if (sc->data[SC_BATTLESCROLL])
batk += batk * sc->data[SC_BATTLESCROLL]->val1 / 100;
-
+
// Eden Crystal Synthesis
if (sc->data[SC_QUEST_BUFF1])
batk += sc->data[SC_QUEST_BUFF1]->val1;
@@ -4998,7 +5004,7 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc,
matk += sc->data[SC_MTF_MATK]->val1;
if (sc->data[SC_MYSTICSCROLL])
matk += matk * sc->data[SC_MYSTICSCROLL]->val1 / 100;
-
+
// Eden Crystal Synthesis
if (sc->data[SC_QUEST_BUFF1])
matk += sc->data[SC_QUEST_BUFF1]->val1;
@@ -5006,7 +5012,7 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc,
matk += sc->data[SC_QUEST_BUFF2]->val1;
if (sc->data[SC_QUEST_BUFF3])
matk += sc->data[SC_QUEST_BUFF3]->val1;
-
+
// Geffen Magic Tournament
if (sc->data[SC_FENRIR_CARD])
matk += sc->data[SC_FENRIR_CARD]->val1;
@@ -5115,7 +5121,7 @@ signed short status_calc_hit(struct block_list *bl, struct status_change *sc, in
hit += sc->data[SC_ACARAJE]->val1;
if (sc->data[SC_BUCHEDENOEL])
hit += sc->data[SC_BUCHEDENOEL]->val3;
-
+
return (short)cap_value(hit, 1, SHRT_MAX);
}
@@ -5536,8 +5542,10 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
if(sc->data[SC_FUSION]) {
val = 25;
} else if (sd) {
- if (pc_isridingpeco(sd) || pc_isridingdragon(sd) || sd->sc.data[SC_ALL_RIDING])
+ if (pc_isridingpeco(sd) || pc_isridingdragon(sd))
val = 25;//Same bonus
+ else if (sd->sc.data[SC_ALL_RIDING])
+ val = sd->sc.data[SC_ALL_RIDING]->val1;
else if (pc_isridingwug(sd))
val = 15 + 5 * pc->checkskill(sd, RA_WUGRIDER);
else if (pc_ismadogear(sd)) {
@@ -5616,10 +5624,8 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
val = max( val, sc->data[SC_MELON_BOMB]->val1 );
if (sc->data[SC_STOMACHACHE])
val = max(val, sc->data[SC_STOMACHACHE]->val2);
-
- if( sc->data[SC_MARSHOFABYSS] ) // It stacks to other statuses so always put this at the end.
- val = max( 50, val + 10 * sc->data[SC_MARSHOFABYSS]->val1 );
-
+ if (sc->data[SC_MARSHOFABYSS]) // It stacks to other statuses so always put this at the end.
+ val = max(50, val + 10 * sc->data[SC_MARSHOFABYSS]->val1);
if (sc->data[SC_MOVHASTE_POTION]) { // Doesn't affect the movement speed by Quagmire, Decrease Agi, Slow Grace [Frost]
if (sc->data[SC_DEC_AGI] || sc->data[SC_QUAGMIRE] || sc->data[SC_DONTFORGETME])
return 0;
@@ -8977,8 +8983,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
tick_time = 3000; // [GodLesZ] tick time
break;
case SC_CLOAKINGEXCEED:
- val2 = ( val1 + 1 ) / 2; // Hits
- val3 = 90 + val1 * 10; // Walk speed
+ val2 = (val1 + 1) / 2; // Hits
+ val3 = (val1 - 1) * 10; // Walk speed
if (bl->type == BL_PC)
val4 |= battle_config.pc_cloak_check_type&7;
else
@@ -12814,13 +12820,13 @@ bool status_readdb_sizefix(char* fields[], int columns, int current)
/**
* Processes a refine_db.conf entry.
*
- * @param *r Libconfig setting entry. It is expected to be valid and it
- * won't be freed (it is care of the caller to do so if
- * necessary)
- * @param n Ordinal number of the entry, to be displayed in case of
- * validation errors.
- * @param *source Source of the entry (file name), to be displayed in case of
- * validation errors.
+ * @param r Libconfig setting entry. It is expected to be valid and it
+ * won't be freed (it is care of the caller to do so if
+ * necessary)
+ * @param n Ordinal number of the entry, to be displayed in case of
+ * validation errors.
+ * @param source Source of the entry (file name), to be displayed in case of
+ * validation errors.
* @return # of the validated entry, or 0 in case of failure.
*/
int status_readdb_refine_libconfig_sub(config_setting_t *r, const char *name, const char *source)
@@ -12831,7 +12837,7 @@ int status_readdb_refine_libconfig_sub(config_setting_t *r, const char *name, co
nullpo_ret(r);
nullpo_ret(name);
nullpo_ret(source);
-
+
if (strncmp(name, "Armors", 6) == 0) {
type = REFINE_TYPE_ARMOR;
} else if (strncmp(name, "WeaponLevel", 11) != 0 || !strspn(&name[strlen(name)-1], "0123456789") || (type = atoi(strncpy(lv, name+11, 2))) == REFINE_TYPE_ARMOR) {
@@ -12920,14 +12926,14 @@ int status_readdb_refine_libconfig(const char *filename) {
config_setting_t *r;
char filepath[256];
int i = 0, count = 0,type = 0;
-
+
sprintf(filepath, "%s/%s", map->db_path, filename);
memset(&duplicate,0,sizeof(duplicate));
if( libconfig->read_file(&refine_db_conf, filepath) ) {
ShowError("can't read %s\n", filepath);
return 0;
}
-
+
while((r = libconfig->setting_get_elem(refine_db_conf.root,i++))) {
char *name = config_setting_name(r);
if((type=status->readdb_refine_libconfig_sub(r, name, filename))) {
@@ -12939,7 +12945,7 @@ int status_readdb_refine_libconfig(const char *filename) {
}
libconfig->destroy(&refine_db_conf);
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename);
-
+
return count;
}
diff --git a/src/map/status.h b/src/map/status.h
index 51ca1e78b..be6d4c209 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -758,13 +758,13 @@ typedef enum sc_type {
SC_MTF_MSP,
SC_MTF_PUMPKIN,
SC_MTF_HITFLEE,
-
+
SC_LJOSALFAR,
SC_MERMAID_LONGING,
-
+
SC_ACARAJE, // 590
SC_TARGET_ASPD,
-
+
// Geffen Scrolls
SC_SKELSCROLL,
SC_DISTRUCTIONSCROLL,
@@ -775,25 +775,25 @@ typedef enum sc_type {
SC_ARMORSCROLL,
SC_FREYJASCROLL,
SC_SOULSCROLL, // 600
-
+
// Eden Crystal Synthesis
SC_QUEST_BUFF1,
SC_QUEST_BUFF2,
SC_QUEST_BUFF3,
-
+
// Geffen Magic Tournament
SC_GEFFEN_MAGIC1,
SC_GEFFEN_MAGIC2,
SC_GEFFEN_MAGIC3,
SC_FENRIR_CARD,
-
+
SC_ATKER_ASPD,
SC_ATKER_MOVESPEED,
SC_FOOD_CRITICALSUCCESSVALUE, // 610
SC_CUP_OF_BOZA,
SC_OVERLAPEXPUP,
SC_MORA_BUFF,
-
+
// MVP Scrolls
SC_MVPCARD_TAOGUNKA,
SC_MVPCARD_MISTRESS,
diff --git a/src/map/unit.c b/src/map/unit.c
index 03334f7f3..bea0913d2 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -121,7 +121,7 @@ int unit_walktoxy_sub(struct block_list *bl)
#ifdef OFFICIAL_WALKPATH
if( !path->search_long(NULL, bl, bl->m, bl->x, bl->y, ud->to_x, ud->to_y, CELL_CHKNOPASS) // Check if there is an obstacle between
- && wpd.path_len > 14 // Official number of walkable cells is 14 if and only if there is an obstacle between. [malufett]
+ && wpd.path_len > 14 // Official number of walkable cells is 14 if and only if there is an obstacle between. [malufett]
&& (bl->type != BL_NPC) ) // If type is a NPC, please disregard.
return 0;
#endif
@@ -1976,6 +1976,7 @@ bool unit_can_reach_pos(struct block_list *bl,int x,int y, int easy)
bool unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range, int easy, short *x, short *y)
{
short dx,dy;
+ struct walkpath_data wpd;
nullpo_retr(false, bl);
nullpo_retr(false, tbl);
@@ -2005,7 +2006,20 @@ bool unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range,
if (x) *x = tbl->x-dx;
if (y) *y = tbl->y-dy;
- return path->search(NULL,bl,bl->m,bl->x,bl->y,tbl->x-dx,tbl->y-dy,easy,CELL_CHKNOREACH);
+
+ if (!path->search(&wpd,bl,bl->m,bl->x,bl->y,tbl->x-dx,tbl->y-dy,easy,CELL_CHKNOREACH))
+ return false;
+
+#ifdef OFFICIAL_WALKPATH
+ if( !path->search_long(NULL, bl, bl->m, bl->x, bl->y, tbl->x-dx, tbl->y-dy, CELL_CHKNOPASS) // Check if there is an obstacle between
+ && wpd.path_len > 14 // Official number of walkable cells is 14 if and only if there is an obstacle between. [malufett]
+ && (bl->type != BL_NPC) ) // If type is a NPC, please disregard.
+ return false;
+#endif
+
+ return true;
+
+
}
/*==========================================
* Calculates position of Pet/Mercenary/Homunculus/Elemental
diff --git a/src/map/vending.c b/src/map/vending.c
index 810e6b07a..6e74e6c3e 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -89,7 +89,7 @@ void vending_vendinglistreq(struct map_session_data* sd, unsigned int id) {
*------------------------------------------*/
void vending_purchasereq(struct map_session_data* sd, int aid, unsigned int uid, const uint8* data, int count) {
int i, j, cursor, w, new_ = 0, blank, vend_list[MAX_VENDING];
- double z;
+ int64 z;
struct s_vending vend[MAX_VENDING]; // against duplicate packets
struct map_session_data* vsd = map->id2sd(aid);
@@ -116,7 +116,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, unsigned int uid,
memcpy(&vend, &vsd->vending, sizeof(vsd->vending)); // copy vending list
// some checks
- z = 0.; // zeny counter
+ z = 0; // zeny counter
w = 0; // weight counter
for( i = 0; i < count; i++ ) {
short amount = *(uint16*)(data + 4*i + 0);
@@ -136,12 +136,12 @@ void vending_purchasereq(struct map_session_data* sd, int aid, unsigned int uid,
else
vend_list[i] = j;
- z += ((double)vsd->vending[j].value * (double)amount);
- if( z > (double)sd->status.zeny || z < 0. || z > (double)MAX_ZENY ) {
+ z += (int64)vsd->vending[j].value * amount;
+ if (z > sd->status.zeny || z < 0 || z > MAX_ZENY) {
clif->buyvending(sd, idx, amount, 1); // you don't have enough zeny
return;
}
- if( z + (double)vsd->status.zeny > (double)MAX_ZENY && !battle_config.vending_over_max ) {
+ if (z > MAX_ZENY - vsd->status.zeny && !battle_config.vending_over_max) {
clif->buyvending(sd, idx, vsd->vending[j].amount, 4); // too much zeny = overflow
return;
@@ -181,7 +181,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, unsigned int uid,
pc->payzeny(sd, (int)z, LOG_TYPE_VENDING, vsd);
if( battle_config.vending_tax )
- z -= z * (battle_config.vending_tax/10000.);
+ z -= apply_percentrate64(z, battle_config.vending_tax, 10000);
pc->getzeny(vsd, (int)z, LOG_TYPE_VENDING, sd);
for( i = 0; i < count; i++ ) {
diff --git a/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc
index 3a8bb2a5f..ce78fdd7e 100644
--- a/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc
@@ -314,6 +314,10 @@ struct {
struct HPMHookPoint *HP_login_parse_request_connection_post;
struct HPMHookPoint *HP_login_parse_login_pre;
struct HPMHookPoint *HP_login_parse_login_post;
+ struct HPMHookPoint *HP_login_config_set_defaults_pre;
+ struct HPMHookPoint *HP_login_config_set_defaults_post;
+ struct HPMHookPoint *HP_login_config_read_pre;
+ struct HPMHookPoint *HP_login_config_read_post;
struct HPMHookPoint *HP_iMalloc_init_pre;
struct HPMHookPoint *HP_iMalloc_init_post;
struct HPMHookPoint *HP_iMalloc_final_pre;
@@ -887,6 +891,10 @@ struct {
int HP_login_parse_request_connection_post;
int HP_login_parse_login_pre;
int HP_login_parse_login_post;
+ int HP_login_config_set_defaults_pre;
+ int HP_login_config_set_defaults_post;
+ int HP_login_config_read_pre;
+ int HP_login_config_read_post;
int HP_iMalloc_init_pre;
int HP_iMalloc_init_post;
int HP_iMalloc_final_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc
index 959bb076f..5be52d51e 100644
--- a/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc
@@ -175,6 +175,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(login->char_server_connection_status, HP_login_char_server_connection_status) },
{ HP_POP(login->parse_request_connection, HP_login_parse_request_connection) },
{ HP_POP(login->parse_login, HP_login_parse_login) },
+ { HP_POP(login->config_set_defaults, HP_login_config_set_defaults) },
+ { HP_POP(login->config_read, HP_login_config_read) },
/* iMalloc */
{ HP_POP(iMalloc->init, HP_iMalloc_init) },
{ HP_POP(iMalloc->final, HP_iMalloc_final) },
diff --git a/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc
index 2e2d9e619..670083e94 100644
--- a/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc
@@ -3914,6 +3914,59 @@ int HP_login_parse_login(int fd) {
}
return retVal___;
}
+void HP_login_config_set_defaults(void) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_login_config_set_defaults_pre ) {
+ void (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_login_config_set_defaults_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_login_config_set_defaults_pre[hIndex].func;
+ preHookFunc();
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.login.config_set_defaults();
+ }
+ if( HPMHooks.count.HP_login_config_set_defaults_post ) {
+ void (*postHookFunc) (void);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_login_config_set_defaults_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_login_config_set_defaults_post[hIndex].func;
+ postHookFunc();
+ }
+ }
+ return;
+}
+int HP_login_config_read(const char *cfgName) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if( HPMHooks.count.HP_login_config_read_pre ) {
+ int (*preHookFunc) (const char *cfgName);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_login_config_read_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_login_config_read_pre[hIndex].func;
+ retVal___ = preHookFunc(cfgName);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.login.config_read(cfgName);
+ }
+ if( HPMHooks.count.HP_login_config_read_post ) {
+ int (*postHookFunc) (int retVal___, const char *cfgName);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_login_config_read_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_login_config_read_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, cfgName);
+ }
+ }
+ return retVal___;
+}
/* iMalloc */
void HP_iMalloc_init(void) {
int hIndex = 0;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index e5ec573a9..2445074f6 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -1848,6 +1848,12 @@ struct {
struct HPMHookPoint *HP_clif_pHotkeyRowShift_post;
struct HPMHookPoint *HP_clif_dressroom_open_pre;
struct HPMHookPoint *HP_clif_dressroom_open_post;
+ struct HPMHookPoint *HP_clif_pOneClick_ItemIdentify_pre;
+ struct HPMHookPoint *HP_clif_pOneClick_ItemIdentify_post;
+ struct HPMHookPoint *HP_clif_selectcart_pre;
+ struct HPMHookPoint *HP_clif_selectcart_post;
+ struct HPMHookPoint *HP_clif_pSelectCart_pre;
+ struct HPMHookPoint *HP_clif_pSelectCart_post;
struct HPMHookPoint *HP_cmdline_init_pre;
struct HPMHookPoint *HP_cmdline_init_post;
struct HPMHookPoint *HP_cmdline_final_pre;
@@ -3474,6 +3480,8 @@ struct {
struct HPMHookPoint *HP_mob_lookup_const_post;
struct HPMHookPoint *HP_mob_get_const_pre;
struct HPMHookPoint *HP_mob_get_const_post;
+ struct HPMHookPoint *HP_mob_db_validate_entry_pre;
+ struct HPMHookPoint *HP_mob_db_validate_entry_post;
struct HPMHookPoint *HP_mob_read_libconfig_pre;
struct HPMHookPoint *HP_mob_read_libconfig_post;
struct HPMHookPoint *HP_mob_read_db_additional_fields_pre;
@@ -4318,6 +4326,8 @@ struct {
struct HPMHookPoint *HP_pc_check_job_name_post;
struct HPMHookPoint *HP_pc_update_idle_time_pre;
struct HPMHookPoint *HP_pc_update_idle_time_post;
+ struct HPMHookPoint *HP_pc_have_magnifier_pre;
+ struct HPMHookPoint *HP_pc_have_magnifier_post;
struct HPMHookPoint *HP_libpcre_compile_pre;
struct HPMHookPoint *HP_libpcre_compile_post;
struct HPMHookPoint *HP_libpcre_study_pre;
@@ -4620,6 +4630,8 @@ struct {
struct HPMHookPoint *HP_script_parse_line_post;
struct HPMHookPoint *HP_script_read_constdb_pre;
struct HPMHookPoint *HP_script_read_constdb_post;
+ struct HPMHookPoint *HP_script_constdb_comment_pre;
+ struct HPMHookPoint *HP_script_constdb_comment_post;
struct HPMHookPoint *HP_script_print_line_pre;
struct HPMHookPoint *HP_script_print_line_post;
struct HPMHookPoint *HP_script_errorwarning_sub_pre;
@@ -7685,6 +7697,12 @@ struct {
int HP_clif_pHotkeyRowShift_post;
int HP_clif_dressroom_open_pre;
int HP_clif_dressroom_open_post;
+ int HP_clif_pOneClick_ItemIdentify_pre;
+ int HP_clif_pOneClick_ItemIdentify_post;
+ int HP_clif_selectcart_pre;
+ int HP_clif_selectcart_post;
+ int HP_clif_pSelectCart_pre;
+ int HP_clif_pSelectCart_post;
int HP_cmdline_init_pre;
int HP_cmdline_init_post;
int HP_cmdline_final_pre;
@@ -9311,6 +9329,8 @@ struct {
int HP_mob_lookup_const_post;
int HP_mob_get_const_pre;
int HP_mob_get_const_post;
+ int HP_mob_db_validate_entry_pre;
+ int HP_mob_db_validate_entry_post;
int HP_mob_read_libconfig_pre;
int HP_mob_read_libconfig_post;
int HP_mob_read_db_additional_fields_pre;
@@ -10155,6 +10175,8 @@ struct {
int HP_pc_check_job_name_post;
int HP_pc_update_idle_time_pre;
int HP_pc_update_idle_time_post;
+ int HP_pc_have_magnifier_pre;
+ int HP_pc_have_magnifier_post;
int HP_libpcre_compile_pre;
int HP_libpcre_compile_post;
int HP_libpcre_study_pre;
@@ -10457,6 +10479,8 @@ struct {
int HP_script_parse_line_post;
int HP_script_read_constdb_pre;
int HP_script_read_constdb_post;
+ int HP_script_constdb_comment_pre;
+ int HP_script_constdb_comment_post;
int HP_script_print_line_pre;
int HP_script_print_line_post;
int HP_script_errorwarning_sub_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 67fb2ce19..4ec436d51 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -944,6 +944,9 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->add_random_options, HP_clif_add_random_options) },
{ HP_POP(clif->pHotkeyRowShift, HP_clif_pHotkeyRowShift) },
{ HP_POP(clif->dressroom_open, HP_clif_dressroom_open) },
+ { HP_POP(clif->pOneClick_ItemIdentify, HP_clif_pOneClick_ItemIdentify) },
+ { HP_POP(clif->selectcart, HP_clif_selectcart) },
+ { HP_POP(clif->pSelectCart, HP_clif_pSelectCart) },
/* cmdline */
{ HP_POP(cmdline->init, HP_cmdline_init) },
{ HP_POP(cmdline->final, HP_cmdline_final) },
@@ -1780,6 +1783,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(mob->readdb, HP_mob_readdb) },
{ HP_POP(mob->lookup_const, HP_mob_lookup_const) },
{ HP_POP(mob->get_const, HP_mob_get_const) },
+ { HP_POP(mob->db_validate_entry, HP_mob_db_validate_entry) },
{ HP_POP(mob->read_libconfig, HP_mob_read_libconfig) },
{ HP_POP(mob->read_db_additional_fields, HP_mob_read_db_additional_fields) },
{ HP_POP(mob->read_db_sub, HP_mob_read_db_sub) },
@@ -2209,6 +2213,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(pc->autotrade_final, HP_pc_autotrade_final) },
{ HP_POP(pc->check_job_name, HP_pc_check_job_name) },
{ HP_POP(pc->update_idle_time, HP_pc_update_idle_time) },
+ { HP_POP(pc->have_magnifier, HP_pc_have_magnifier) },
/* libpcre */
{ HP_POP(libpcre->compile, HP_libpcre_compile) },
{ HP_POP(libpcre->study, HP_libpcre_study) },
@@ -2364,6 +2369,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(script->parse_expr, HP_script_parse_expr) },
{ HP_POP(script->parse_line, HP_script_parse_line) },
{ HP_POP(script->read_constdb, HP_script_read_constdb) },
+ { HP_POP(script->constdb_comment, HP_script_constdb_comment) },
{ HP_POP(script->print_line, HP_script_print_line) },
{ HP_POP(script->errorwarning_sub, HP_script_errorwarning_sub) },
{ HP_POP(script->set_reg, HP_script_set_reg) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index d7e798637..f7b6ef056 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -24067,6 +24067,84 @@ void HP_clif_dressroom_open(struct map_session_data *sd, int view) {
}
return;
}
+void HP_clif_pOneClick_ItemIdentify(int fd, struct map_session_data *sd) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_clif_pOneClick_ItemIdentify_pre ) {
+ void (*preHookFunc) (int *fd, struct map_session_data *sd);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pOneClick_ItemIdentify_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_clif_pOneClick_ItemIdentify_pre[hIndex].func;
+ preHookFunc(&fd, sd);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.pOneClick_ItemIdentify(fd, sd);
+ }
+ if( HPMHooks.count.HP_clif_pOneClick_ItemIdentify_post ) {
+ void (*postHookFunc) (int *fd, struct map_session_data *sd);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pOneClick_ItemIdentify_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_clif_pOneClick_ItemIdentify_post[hIndex].func;
+ postHookFunc(&fd, sd);
+ }
+ }
+ return;
+}
+void HP_clif_selectcart(struct map_session_data *sd) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_clif_selectcart_pre ) {
+ void (*preHookFunc) (struct map_session_data *sd);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_selectcart_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_clif_selectcart_pre[hIndex].func;
+ preHookFunc(sd);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.selectcart(sd);
+ }
+ if( HPMHooks.count.HP_clif_selectcart_post ) {
+ void (*postHookFunc) (struct map_session_data *sd);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_selectcart_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_clif_selectcart_post[hIndex].func;
+ postHookFunc(sd);
+ }
+ }
+ return;
+}
+void HP_clif_pSelectCart(int fd, struct map_session_data *sd) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_clif_pSelectCart_pre ) {
+ void (*preHookFunc) (int *fd, struct map_session_data *sd);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pSelectCart_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_clif_pSelectCart_pre[hIndex].func;
+ preHookFunc(&fd, sd);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.pSelectCart(fd, sd);
+ }
+ if( HPMHooks.count.HP_clif_pSelectCart_post ) {
+ void (*postHookFunc) (int *fd, struct map_session_data *sd);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pSelectCart_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_clif_pSelectCart_post[hIndex].func;
+ postHookFunc(&fd, sd);
+ }
+ }
+ return;
+}
/* cmdline */
void HP_cmdline_init(void) {
int hIndex = 0;
@@ -46153,6 +46231,33 @@ bool HP_mob_get_const(const config_setting_t *it, int *value) {
}
return retVal___;
}
+int HP_mob_db_validate_entry(struct mob_db *entry, int n, const char *source) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if( HPMHooks.count.HP_mob_db_validate_entry_pre ) {
+ int (*preHookFunc) (struct mob_db *entry, int *n, const char *source);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_db_validate_entry_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_mob_db_validate_entry_pre[hIndex].func;
+ retVal___ = preHookFunc(entry, &n, source);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mob.db_validate_entry(entry, n, source);
+ }
+ if( HPMHooks.count.HP_mob_db_validate_entry_post ) {
+ int (*postHookFunc) (int retVal___, struct mob_db *entry, int *n, const char *source);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_db_validate_entry_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_mob_db_validate_entry_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, entry, &n, source);
+ }
+ }
+ return retVal___;
+}
int HP_mob_read_libconfig(const char *filename, bool ignore_missing) {
int hIndex = 0;
int retVal___ = 0;
@@ -46180,14 +46285,14 @@ int HP_mob_read_libconfig(const char *filename, bool ignore_missing) {
}
return retVal___;
}
-void HP_mob_read_db_additional_fields(struct mob_db *entry, int class_, config_setting_t *it, int n, const char *source) {
+void HP_mob_read_db_additional_fields(struct mob_db *entry, config_setting_t *it, int n, const char *source) {
int hIndex = 0;
if( HPMHooks.count.HP_mob_read_db_additional_fields_pre ) {
- void (*preHookFunc) (struct mob_db *entry, int *class_, config_setting_t *it, int *n, const char *source);
+ void (*preHookFunc) (struct mob_db *entry, config_setting_t *it, int *n, const char *source);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_additional_fields_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_mob_read_db_additional_fields_pre[hIndex].func;
- preHookFunc(entry, &class_, it, &n, source);
+ preHookFunc(entry, it, &n, source);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -46195,22 +46300,22 @@ void HP_mob_read_db_additional_fields(struct mob_db *entry, int class_, config_s
}
}
{
- HPMHooks.source.mob.read_db_additional_fields(entry, class_, it, n, source);
+ HPMHooks.source.mob.read_db_additional_fields(entry, it, n, source);
}
if( HPMHooks.count.HP_mob_read_db_additional_fields_post ) {
- void (*postHookFunc) (struct mob_db *entry, int *class_, config_setting_t *it, int *n, const char *source);
+ void (*postHookFunc) (struct mob_db *entry, config_setting_t *it, int *n, const char *source);
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_additional_fields_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_mob_read_db_additional_fields_post[hIndex].func;
- postHookFunc(entry, &class_, it, &n, source);
+ postHookFunc(entry, it, &n, source);
}
}
return;
}
-bool HP_mob_read_db_sub(config_setting_t *mobt, int id, const char *source) {
+int HP_mob_read_db_sub(config_setting_t *mobt, int id, const char *source) {
int hIndex = 0;
- bool retVal___ = false;
+ int retVal___ = 0;
if( HPMHooks.count.HP_mob_read_db_sub_pre ) {
- bool (*preHookFunc) (config_setting_t *mobt, int *id, const char *source);
+ int (*preHookFunc) (config_setting_t *mobt, int *id, const char *source);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_sub_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_mob_read_db_sub_pre[hIndex].func;
@@ -46225,7 +46330,7 @@ bool HP_mob_read_db_sub(config_setting_t *mobt, int id, const char *source) {
retVal___ = HPMHooks.source.mob.read_db_sub(mobt, id, source);
}
if( HPMHooks.count.HP_mob_read_db_sub_post ) {
- bool (*postHookFunc) (bool retVal___, config_setting_t *mobt, int *id, const char *source);
+ int (*postHookFunc) (int retVal___, config_setting_t *mobt, int *id, const char *source);
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_sub_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_mob_read_db_sub_post[hIndex].func;
retVal___ = postHookFunc(retVal___, mobt, &id, source);
@@ -46233,14 +46338,14 @@ bool HP_mob_read_db_sub(config_setting_t *mobt, int id, const char *source) {
}
return retVal___;
}
-void HP_mob_read_db_drops_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t) {
+void HP_mob_read_db_drops_sub(struct mob_db *entry, config_setting_t *t) {
int hIndex = 0;
if( HPMHooks.count.HP_mob_read_db_drops_sub_pre ) {
- void (*preHookFunc) (struct mob_db *entry, struct status_data *mstatus, int *class_, config_setting_t *t);
+ void (*preHookFunc) (struct mob_db *entry, config_setting_t *t);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_drops_sub_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_mob_read_db_drops_sub_pre[hIndex].func;
- preHookFunc(entry, mstatus, &class_, t);
+ preHookFunc(entry, t);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -46248,25 +46353,25 @@ void HP_mob_read_db_drops_sub(struct mob_db *entry, struct status_data *mstatus,
}
}
{
- HPMHooks.source.mob.read_db_drops_sub(entry, mstatus, class_, t);
+ HPMHooks.source.mob.read_db_drops_sub(entry, t);
}
if( HPMHooks.count.HP_mob_read_db_drops_sub_post ) {
- void (*postHookFunc) (struct mob_db *entry, struct status_data *mstatus, int *class_, config_setting_t *t);
+ void (*postHookFunc) (struct mob_db *entry, config_setting_t *t);
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_drops_sub_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_mob_read_db_drops_sub_post[hIndex].func;
- postHookFunc(entry, mstatus, &class_, t);
+ postHookFunc(entry, t);
}
}
return;
}
-void HP_mob_read_db_mvpdrops_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t) {
+void HP_mob_read_db_mvpdrops_sub(struct mob_db *entry, config_setting_t *t) {
int hIndex = 0;
if( HPMHooks.count.HP_mob_read_db_mvpdrops_sub_pre ) {
- void (*preHookFunc) (struct mob_db *entry, struct status_data *mstatus, int *class_, config_setting_t *t);
+ void (*preHookFunc) (struct mob_db *entry, config_setting_t *t);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_mvpdrops_sub_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_mob_read_db_mvpdrops_sub_pre[hIndex].func;
- preHookFunc(entry, mstatus, &class_, t);
+ preHookFunc(entry, t);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -46274,26 +46379,26 @@ void HP_mob_read_db_mvpdrops_sub(struct mob_db *entry, struct status_data *mstat
}
}
{
- HPMHooks.source.mob.read_db_mvpdrops_sub(entry, mstatus, class_, t);
+ HPMHooks.source.mob.read_db_mvpdrops_sub(entry, t);
}
if( HPMHooks.count.HP_mob_read_db_mvpdrops_sub_post ) {
- void (*postHookFunc) (struct mob_db *entry, struct status_data *mstatus, int *class_, config_setting_t *t);
+ void (*postHookFunc) (struct mob_db *entry, config_setting_t *t);
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_mvpdrops_sub_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_mob_read_db_mvpdrops_sub_post[hIndex].func;
- postHookFunc(entry, mstatus, &class_, t);
+ postHookFunc(entry, t);
}
}
return;
}
-int HP_mob_read_db_mode_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t) {
+int HP_mob_read_db_mode_sub(struct mob_db *entry, config_setting_t *t) {
int hIndex = 0;
int retVal___ = 0;
if( HPMHooks.count.HP_mob_read_db_mode_sub_pre ) {
- int (*preHookFunc) (struct mob_db *entry, struct status_data *mstatus, int *class_, config_setting_t *t);
+ int (*preHookFunc) (struct mob_db *entry, config_setting_t *t);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_mode_sub_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_mob_read_db_mode_sub_pre[hIndex].func;
- retVal___ = preHookFunc(entry, mstatus, &class_, t);
+ retVal___ = preHookFunc(entry, t);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -46301,25 +46406,25 @@ int HP_mob_read_db_mode_sub(struct mob_db *entry, struct status_data *mstatus, i
}
}
{
- retVal___ = HPMHooks.source.mob.read_db_mode_sub(entry, mstatus, class_, t);
+ retVal___ = HPMHooks.source.mob.read_db_mode_sub(entry, t);
}
if( HPMHooks.count.HP_mob_read_db_mode_sub_post ) {
- int (*postHookFunc) (int retVal___, struct mob_db *entry, struct status_data *mstatus, int *class_, config_setting_t *t);
+ int (*postHookFunc) (int retVal___, struct mob_db *entry, config_setting_t *t);
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_mode_sub_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_mob_read_db_mode_sub_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, entry, mstatus, &class_, t);
+ retVal___ = postHookFunc(retVal___, entry, t);
}
}
return retVal___;
}
-void HP_mob_read_db_stats_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t) {
+void HP_mob_read_db_stats_sub(struct mob_db *entry, config_setting_t *t) {
int hIndex = 0;
if( HPMHooks.count.HP_mob_read_db_stats_sub_pre ) {
- void (*preHookFunc) (struct mob_db *entry, struct status_data *mstatus, int *class_, config_setting_t *t);
+ void (*preHookFunc) (struct mob_db *entry, config_setting_t *t);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_stats_sub_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_mob_read_db_stats_sub_pre[hIndex].func;
- preHookFunc(entry, mstatus, &class_, t);
+ preHookFunc(entry, t);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -46327,13 +46432,13 @@ void HP_mob_read_db_stats_sub(struct mob_db *entry, struct status_data *mstatus,
}
}
{
- HPMHooks.source.mob.read_db_stats_sub(entry, mstatus, class_, t);
+ HPMHooks.source.mob.read_db_stats_sub(entry, t);
}
if( HPMHooks.count.HP_mob_read_db_stats_sub_post ) {
- void (*postHookFunc) (struct mob_db *entry, struct status_data *mstatus, int *class_, config_setting_t *t);
+ void (*postHookFunc) (struct mob_db *entry, config_setting_t *t);
for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_read_db_stats_sub_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_mob_read_db_stats_sub_post[hIndex].func;
- postHookFunc(entry, mstatus, &class_, t);
+ postHookFunc(entry, t);
}
}
return;
@@ -57571,6 +57676,33 @@ void HP_pc_update_idle_time(struct map_session_data *sd, enum e_battle_config_id
}
return;
}
+int HP_pc_have_magnifier(struct map_session_data *sd) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if( HPMHooks.count.HP_pc_have_magnifier_pre ) {
+ int (*preHookFunc) (struct map_session_data *sd);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_have_magnifier_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_pc_have_magnifier_pre[hIndex].func;
+ retVal___ = preHookFunc(sd);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.pc.have_magnifier(sd);
+ }
+ if( HPMHooks.count.HP_pc_have_magnifier_post ) {
+ int (*postHookFunc) (int retVal___, struct map_session_data *sd);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_have_magnifier_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_pc_have_magnifier_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, sd);
+ }
+ }
+ return retVal___;
+}
/* libpcre */
pcre* HP_libpcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr) {
int hIndex = 0;
@@ -60089,14 +60221,14 @@ void HP_script_pop_stack(struct script_state *st, int start, int end) {
}
return;
}
-void HP_script_set_constant(const char *name, int value, bool isparameter) {
+void HP_script_set_constant(const char *name, int value, bool is_parameter, bool is_deprecated) {
int hIndex = 0;
if( HPMHooks.count.HP_script_set_constant_pre ) {
- void (*preHookFunc) (const char *name, int *value, bool *isparameter);
+ void (*preHookFunc) (const char *name, int *value, bool *is_parameter, bool *is_deprecated);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_constant_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_script_set_constant_pre[hIndex].func;
- preHookFunc(name, &value, &isparameter);
+ preHookFunc(name, &value, &is_parameter, &is_deprecated);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -60104,25 +60236,25 @@ void HP_script_set_constant(const char *name, int value, bool isparameter) {
}
}
{
- HPMHooks.source.script.set_constant(name, value, isparameter);
+ HPMHooks.source.script.set_constant(name, value, is_parameter, is_deprecated);
}
if( HPMHooks.count.HP_script_set_constant_post ) {
- void (*postHookFunc) (const char *name, int *value, bool *isparameter);
+ void (*postHookFunc) (const char *name, int *value, bool *is_parameter, bool *is_deprecated);
for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_constant_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_script_set_constant_post[hIndex].func;
- postHookFunc(name, &value, &isparameter);
+ postHookFunc(name, &value, &is_parameter, &is_deprecated);
}
}
return;
}
-void HP_script_set_constant2(const char *name, int value, bool isparameter) {
+void HP_script_set_constant2(const char *name, int value, bool is_parameter, bool is_deprecated) {
int hIndex = 0;
if( HPMHooks.count.HP_script_set_constant2_pre ) {
- void (*preHookFunc) (const char *name, int *value, bool *isparameter);
+ void (*preHookFunc) (const char *name, int *value, bool *is_parameter, bool *is_deprecated);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_constant2_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_script_set_constant2_pre[hIndex].func;
- preHookFunc(name, &value, &isparameter);
+ preHookFunc(name, &value, &is_parameter, &is_deprecated);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -60130,13 +60262,13 @@ void HP_script_set_constant2(const char *name, int value, bool isparameter) {
}
}
{
- HPMHooks.source.script.set_constant2(name, value, isparameter);
+ HPMHooks.source.script.set_constant2(name, value, is_parameter, is_deprecated);
}
if( HPMHooks.count.HP_script_set_constant2_post ) {
- void (*postHookFunc) (const char *name, int *value, bool *isparameter);
+ void (*postHookFunc) (const char *name, int *value, bool *is_parameter, bool *is_deprecated);
for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_constant2_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_script_set_constant2_post[hIndex].func;
- postHookFunc(name, &value, &isparameter);
+ postHookFunc(name, &value, &is_parameter, &is_deprecated);
}
}
return;
@@ -61626,6 +61758,32 @@ void HP_script_read_constdb(void) {
}
return;
}
+void HP_script_constdb_comment(const char *comment) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_script_constdb_comment_pre ) {
+ void (*preHookFunc) (const char *comment);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_constdb_comment_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_script_constdb_comment_pre[hIndex].func;
+ preHookFunc(comment);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.script.constdb_comment(comment);
+ }
+ if( HPMHooks.count.HP_script_constdb_comment_post ) {
+ void (*postHookFunc) (const char *comment);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_constdb_comment_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_script_constdb_comment_post[hIndex].func;
+ postHookFunc(comment);
+ }
+ }
+ return;
+}
const char* HP_script_print_line(StringBuf *buf, const char *p, const char *mark, int line) {
int hIndex = 0;
const char* retVal___ = NULL;
diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in
index 6e8e3bfac..3fe38b6bc 100644
--- a/src/plugins/Makefile.in
+++ b/src/plugins/Makefile.in
@@ -102,7 +102,7 @@ Makefile: Makefile.in
../../plugins/%@DLLEXT@: %.c $(ALL_H) $$(shell ls %/* 2>/dev/null)
@echo " CC $<"
- @$(CC) $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @PLUGINSTATIC@ @DEFS@ @CFLAGS@ @PCRE_CFLAGS@ @CPPFLAGS@ @LDFLAGS@ @SOFLAGS@ -o $@ $<
+ @$(CC) $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @PLUGINSTATIC@ @DEFS@ @CFLAGS@ @CPPFLAGS@ @LDFLAGS@ @SOFLAGS@ -o $@ $<
../../plugins/HPMHooking_login@DLLEXT@: HPMHOOKINGTYPE = LOGIN
../../plugins/HPMHooking_char@DLLEXT@: HPMHOOKINGTYPE = CHAR
@@ -110,4 +110,4 @@ Makefile: Makefile.in
../../plugins/HPMHooking_%@DLLEXT@: HPMHooking.c $(ALL_H) $$(shell ls HPMHooking/*_%* HPMHooking/*_common* 2>/dev/null)
@echo " CC $< ($(HPMHOOKINGTYPE))"
- @$(CC) -DHPMHOOKING_$(HPMHOOKINGTYPE) $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @PLUGINSTATIC@ @DEFS@ @CFLAGS@ @PCRE_CFLAGS@ @CPPFLAGS@ @LDFLAGS@ @SOFLAGS@ -o $@ $<
+ @$(CC) -DHPMHOOKING_$(HPMHOOKINGTYPE) $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @PLUGINSTATIC@ @DEFS@ @CFLAGS@ @CPPFLAGS@ @LDFLAGS@ @SOFLAGS@ -o $@ $<
diff --git a/src/plugins/constdb2doc.c b/src/plugins/constdb2doc.c
new file mode 100644
index 000000000..1d5f37ad5
--- /dev/null
+++ b/src/plugins/constdb2doc.c
@@ -0,0 +1,197 @@
+/**
+ * This file is part of Hercules.
+ * http://herc.ws - http://github.com/HerculesWS/Hercules
+ *
+ * Copyright (C) 2016 Hercules Dev Team
+ * Copyright (C) 2016 Haru <haru@dotalux.com>
+ *
+ * Hercules is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/// db/constants.conf -> doc/constants.md generator plugin
+
+#include "common/hercules.h"
+//#include "common/memmgr.h"
+#include "common/nullpo.h"
+#include "common/strlib.h"
+#include "map/itemdb.h"
+#include "map/mob.h"
+#include "map/script.h"
+#include "map/skill.h"
+
+#include "common/HPMDataCheck.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#define OUTPUTFILENAME "doc" PATHSEP_STR "constants.md"
+
+HPExport struct hplugin_info pinfo = {
+ "constdb2doc", // Plugin name
+ SERVER_TYPE_MAP, // Which server types this plugin works with?
+ "0.1", // Plugin version
+ HPM_VERSION, // HPM Version (don't change, macro is automatically updated)
+};
+
+FILE *out_fp;
+bool torun = false;
+
+/// To override script_constdb_comment
+void constdb2doc_constdb_comment(const char *comment)
+{
+ nullpo_retv(out_fp);
+ if (comment == NULL)
+ fprintf(out_fp, "\n");
+ else
+ fprintf(out_fp, "\n### %s\n\n", comment);
+}
+
+/// To override script_set_constant, called by script_read_constdb
+void constdb2doc_script_set_constant(const char *name, int value, bool is_parameter, bool is_deprecated)
+{
+ nullpo_retv(out_fp);
+
+ if (is_parameter)
+ fprintf(out_fp, "- `%s`: [param]%s\n", name, is_deprecated ? " **(DEPRECATED)**" : "");
+ else
+ fprintf(out_fp, "- `%s`: %d%s\n", name, value, is_deprecated ? " **(DEPRECATED)**" : "");
+}
+
+void constdb2doc_constdb(void)
+{
+ void (*script_set_constant) (const char* name, int value, bool is_parameter, bool is_deprecated) = NULL;
+ void (*script_constdb_comment) (const char *comment) = NULL;
+
+ nullpo_retv(out_fp);
+
+ /* Link */
+ script_set_constant = script->set_constant;
+ script->set_constant = constdb2doc_script_set_constant;
+ script_constdb_comment = script->constdb_comment;
+ script->constdb_comment = constdb2doc_constdb_comment;
+
+ /* Run */
+ fprintf(out_fp, "## Constants (db/constants.conf)\n\n");
+ script->read_constdb();
+ fprintf(out_fp, "\n");
+
+ fprintf(out_fp, "## Hardcoded Constants (source)\n\n");
+ script->hardcoded_constants();
+ fprintf(out_fp, "\n");
+
+ /* Unlink */
+ script->set_constant = script_set_constant;
+ script->constdb_comment = script_constdb_comment;
+}
+
+void constdb2doc_skilldb(void)
+{
+ int i;
+
+ nullpo_retv(out_fp);
+
+ fprintf(out_fp, "## Skills (db/"DBPATH"skill_db.txt)\n\n");
+ for (i = 1; i < MAX_SKILL_DB; i++) {
+ if (skill->dbs->db[i].name[0] != '\0')
+ fprintf(out_fp, "- `%s`: %d\n", skill->dbs->db[i].name, skill->dbs->db[i].nameid);
+ }
+ fprintf(out_fp, "\n");
+}
+
+void constdb2doc_mobdb(void)
+{
+ int i;
+
+ nullpo_retv(out_fp);
+
+ fprintf(out_fp, "## Mobs (db/"DBPATH"mob_db.txt)\n\n");
+ for (i = 0; i < MAX_MOB_DB; i++) {
+ struct mob_db *md = mob->db(i);
+ if (md == mob->dummy || md->sprite[0] == '\0')
+ continue;
+ fprintf(out_fp, "- `%s`: %d\n", md->sprite, i);
+ }
+ fprintf(out_fp, "\n");
+}
+
+/// Cloned from itemdb_search
+struct item_data *constdb2doc_itemdb_search(int nameid)
+{
+ if (nameid >= 0 && nameid < ARRAYLENGTH(itemdb->array))
+ return itemdb->array[nameid];
+
+ return idb_get(itemdb->other, nameid);
+}
+
+void constdb2doc_itemdb(void)
+{
+ int i;
+
+ nullpo_retv(out_fp);
+
+ fprintf(out_fp, "## Items (db/"DBPATH"item_db.conf)\n");
+ for (i = 0; i < ARRAYLENGTH(itemdb->array); i++) {
+ struct item_data *id = constdb2doc_itemdb_search(i);
+ if (id == NULL || id->name[0] == '\0')
+ continue;
+ fprintf(out_fp, "- `%s`: %d\n", id->name, id->nameid);
+ }
+ fprintf(out_fp, "\n");
+}
+
+void do_constdb2doc(void)
+{
+ /* File Type Detector */
+ if ((out_fp = fopen(OUTPUTFILENAME, "wt+")) == NULL) {
+ ShowError("do_constdb2doc: Unable to open output file.\n");
+ return;
+ }
+
+ fprintf(out_fp,
+ "# Constants\n\n"
+ "> This document contains all the constants available to the script engine.\n\n");
+
+ constdb2doc_constdb();
+
+ constdb2doc_skilldb();
+
+ constdb2doc_mobdb();
+
+ constdb2doc_itemdb();
+
+ fprintf(out_fp, "> End of list\n");
+
+ fclose(out_fp);
+}
+CPCMD(constdb2doc) {
+ do_constdb2doc();
+}
+CMDLINEARG(constdb2doc)
+{
+ map->minimal = torun = true;
+ return true;
+}
+HPExport void server_preinit(void) {
+ addArg("--constdb2doc", false, constdb2doc, NULL);
+}
+HPExport void plugin_init(void) {
+ addCPCommand("server:tools:constdb2doc", constdb2doc);
+}
+HPExport void server_online(void) {
+ if (torun)
+ do_constdb2doc();
+}
diff --git a/src/plugins/db2sql.c b/src/plugins/db2sql.c
index 5b5d79bac..44e2bac3c 100644
--- a/src/plugins/db2sql.c
+++ b/src/plugins/db2sql.c
@@ -24,12 +24,12 @@
#include "common/conf.h"
#include "common/memmgr.h"
#include "common/mmo.h"
+#include "common/nullpo.h"
#include "common/strlib.h"
-#include "common/timer.h"
-#include "map/clif.h"
+#include "map/battle.h"
#include "map/itemdb.h"
+#include "map/mob.h"
#include "map/map.h"
-#include "map/pc.h"
#include "common/HPMDataCheck.h"
@@ -43,38 +43,102 @@ HPExport struct hplugin_info pinfo = {
HPM_VERSION, // HPM Version (don't change, macro is automatically updated)
};
+#ifdef RENEWAL
+#define DBSUFFIX "_re"
+#else // not RENEWAL
+#define DBSUFFIX ""
+#endif
+
+/// Conversion state tracking.
struct {
- FILE *fp;
+ FILE *fp; ///< Currently open file pointer
struct {
- char *p;
- size_t len;
- } buf[4];
- char *db_name;
+ char *p; ///< Buffer pointer
+ size_t len; ///< Buffer length
+ } buf[4]; ///< Output buffer
+ const char *db_name; ///< Database table name
} tosql;
-bool torun = false;
+/// Whether the item_db converter will automatically run.
+bool itemdb2sql_torun = false;
+/// Whether the mob_db converter will automatically run.
+bool mobdb2sql_torun = false;
+
+/// Backup of the original item_db parser function pointer.
int (*itemdb_readdb_libconfig_sub) (config_setting_t *it, int n, const char *source);
+/// Backup of the original mob_db parser function pointer.
+int (*mob_read_db_sub) (config_setting_t *it, int n, const char *source);
-void hstr(const char *str) {
- if( strlen(str) > tosql.buf[3].len ) {
+/**
+ * Normalizes and appends a string to the output buffer.
+ *
+ * @param str The string to append.
+ */
+void hstr(const char *str)
+{
+ if (strlen(str) > tosql.buf[3].len) {
tosql.buf[3].len = tosql.buf[3].len + strlen(str) + 1000;
RECREATE(tosql.buf[3].p,char,tosql.buf[3].len);
}
safestrncpy(tosql.buf[3].p,str,strlen(str));
normalize_name(tosql.buf[3].p,"\t\n ");
}
-int db2sql(config_setting_t *entry, int n, const char *source) {
+
+/**
+ * Prints a SQL file header for the current item_db file.
+ */
+void db2sql_fileheader(void)
+{
+ time_t t = time(NULL);
+ struct tm *lt = localtime(&t);
+ int year = lt->tm_year+1900;
+
+ fprintf(tosql.fp,
+ "-- This file is part of Hercules.\n"
+ "-- http://herc.ws - http://github.com/HerculesWS/Hercules\n"
+ "--\n"
+ "-- Copyright (C) 2013-%d Hercules Dev Team\n"
+ "--\n"
+ "-- Hercules is free software: you can redistribute it and/or modify\n"
+ "-- it under the terms of the GNU General Public License as published by\n"
+ "-- the Free Software Foundation, either version 3 of the License, or\n"
+ "-- (at your option) any later version.\n"
+ "--\n"
+ "-- This program is distributed in the hope that it will be useful,\n"
+ "-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "-- GNU General Public License for more details.\n"
+ "--\n"
+ "-- You should have received a copy of the GNU General Public License\n"
+ "-- along with this program. If not, see <http://www.gnu.org/licenses/>.\n\n"
+
+ "-- NOTE: This file was auto-generated and should never be manually edited,\n"
+ "-- as it will get overwritten. If you need to modify this file,\n"
+ "-- please consider modifying the corresponding .conf file inside\n"
+ "-- the db folder, and then re-run the db2sql plugin.\n"
+ "\n", year);
+}
+
+/**
+ * Converts an Item DB entry to SQL.
+ *
+ * @see itemdb_readdb_libconfig_sub.
+ */
+int itemdb2sql_sub(config_setting_t *entry, int n, const char *source)
+{
struct item_data *it = NULL;
- if( (it = itemdb->exists(itemdb_readdb_libconfig_sub(entry,n,source))) ) {
+ if ((it = itemdb->exists(itemdb_readdb_libconfig_sub(entry,n,source)))) {
char e_name[ITEM_NAME_LENGTH*2+1];
const char *bonus = NULL;
char *str;
int i32;
- unsigned int ui32;
+ uint32 ui32;
config_setting_t *t = NULL;
StringBuf buf;
+ nullpo_ret(entry);
+
StrBuf->Init(&buf);
// id
@@ -92,10 +156,10 @@ int db2sql(config_setting_t *entry, int n, const char *source) {
StrBuf->Printf(&buf, "'%u',", it->flag.delay_consume?IT_DELAYCONSUME:it->type);
// price_buy
- StrBuf->Printf(&buf, "'%u',", it->value_buy);
+ StrBuf->Printf(&buf, "'%d',", it->value_buy);
// price_sell
- StrBuf->Printf(&buf, "'%u',", it->value_sell);
+ StrBuf->Printf(&buf, "'%d',", it->value_sell);
// weight
StrBuf->Printf(&buf, "'%u',", it->weight);
@@ -116,15 +180,15 @@ int db2sql(config_setting_t *entry, int n, const char *source) {
StrBuf->Printf(&buf, "'%u',", it->slot);
// equip_jobs
- if( libconfig->setting_lookup_int(entry, "Job", &i32) ) // This is an unsigned value, do not check for >= 0
- ui32 = (unsigned int)i32;
+ if (libconfig->setting_lookup_int(entry, "Job", &i32)) // This is an unsigned value, do not check for >= 0
+ ui32 = (uint32)i32;
else
ui32 = UINT_MAX;
StrBuf->Printf(&buf, "'%u',", ui32);
// equip_upper
- if( libconfig->setting_lookup_int(entry, "Upper", &i32) && i32 >= 0 )
- ui32 = (unsigned int)i32;
+ if (libconfig->setting_lookup_int(entry, "Upper", &i32) && i32 >= 0)
+ ui32 = (uint32)i32;
else
ui32 = ITEMUPPER_ALL;
StrBuf->Printf(&buf, "'%u',", ui32);
@@ -142,7 +206,7 @@ int db2sql(config_setting_t *entry, int n, const char *source) {
StrBuf->Printf(&buf, "'%u',", it->elv);
// equip_level_max
- if( (t = libconfig->setting_get_member(entry, "EquipLv")) && config_setting_is_aggregate(t) && libconfig->setting_length(t) >= 2 )
+ if ((t = libconfig->setting_get_member(entry, "EquipLv")) && config_setting_is_aggregate(t) && libconfig->setting_length(t) >= 2)
StrBuf->Printf(&buf, "'%u',", it->elvmax);
else
StrBuf->AppendStr(&buf, "NULL,");
@@ -253,36 +317,15 @@ int db2sql(config_setting_t *entry, int n, const char *source) {
return it?it->nameid:0;
}
-void totable(void) {
- time_t t;
- struct tm *lt;
- t = time(NULL);
- lt = localtime(&t);
- int year = lt->tm_year+1900;
- fprintf(tosql.fp,
- "-- This file is part of Hercules.\n"
- "-- http://herc.ws - http://github.com/HerculesWS/Hercules\n"
- "--\n"
- "-- Copyright (C) 2013-%d Hercules Dev Team\n"
- "--\n"
- "-- Hercules is free software: you can redistribute it and/or modify\n"
- "-- it under the terms of the GNU General Public License as published by\n"
- "-- the Free Software Foundation, either version 3 of the License, or\n"
- "-- (at your option) any later version.\n"
- "--\n"
- "-- This program is distributed in the hope that it will be useful,\n"
- "-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- "-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
- "-- GNU General Public License for more details.\n"
- "--\n"
- "-- You should have received a copy of the GNU General Public License\n"
- "-- along with this program. If not, see <http://www.gnu.org/licenses/>.\n\n"
- "-- NOTE: This file was auto-generated and should never be manually edited,\n"
- "-- as it will get overwritten. If you need to modify this file,\n"
- "-- please consider modifying the corresponding .conf file inside\n"
- "-- the db folder, and then re-run the db2sql plugin.\n"
- "\n"
+/**
+ * Prints a SQL table header for the current item_db table.
+ */
+void itemdb2sql_tableheader(void)
+{
+ db2sql_fileheader();
+
+ fprintf(tosql.fp,
"--\n"
"-- Table structure for table `%s`\n"
"--\n"
@@ -326,79 +369,405 @@ void totable(void) {
" `unequip_script` text,\n"
" PRIMARY KEY (`id`)\n"
") ENGINE=MyISAM;\n"
- "\n", year, tosql.db_name,tosql.db_name,tosql.db_name);
+ "\n", tosql.db_name,tosql.db_name,tosql.db_name);
}
-void do_db2sql(void) {
+
+/**
+ * Item DB Conversion.
+ *
+ * Converts Item DB and Item DB2 to SQL scripts.
+ */
+void do_itemdb2sql(void)
+{
+ int i;
+ struct convert_db_files {
+ const char *name;
+ const char *source;
+ const char *destination;
+ } files[] = {
+ {"item_db", DBPATH"item_db.conf", "sql-files/item_db" DBSUFFIX ".sql"},
+ {"item_db2", "item_db2.conf", "sql-files/item_db2.sql"},
+ };
+
/* link */
itemdb_readdb_libconfig_sub = itemdb->readdb_libconfig_sub;
- itemdb->readdb_libconfig_sub = db2sql;
- /* */
+ itemdb->readdb_libconfig_sub = itemdb2sql_sub;
+
+ memset(&tosql.buf, 0, sizeof(tosql.buf));
+ itemdb->clear(false);
+
+ for (i = 0; i < ARRAYLENGTH(files); i++) {
+ if ((tosql.fp = fopen(files[i].destination, "wt+")) == NULL) {
+ ShowError("itemdb_tosql: File not found \"%s\".\n", files[i].destination);
+ return;
+ }
+
+ tosql.db_name = files[i].name;
+ itemdb2sql_tableheader();
+
+ itemdb->readdb_libconfig(files[i].source);
- if ((tosql.fp = fopen("sql-files/item_db_re.sql", "wt+")) == NULL) {
- ShowError("itemdb_tosql: File not found \"%s\".\n", "sql-files/item_db_re.sql");
- return;
+ fclose(tosql.fp);
}
- tosql.db_name = "item_db";
- totable();
+ /* unlink */
+ itemdb->readdb_libconfig_sub = itemdb_readdb_libconfig_sub;
- memset(&tosql.buf, 0, sizeof(tosql.buf) );
+ for (i = 0; i < ARRAYLENGTH(tosql.buf); i++) {
+ if (tosql.buf[i].p)
+ aFree(tosql.buf[i].p);
+ }
+}
- itemdb->clear(false);
- itemdb->readdb_libconfig("re/item_db.conf");
+/**
+ * Converts a Mob DB entry to SQL.
+ *
+ * @see mobdb_readdb_libconfig_sub.
+ */
+int mobdb2sql_sub(config_setting_t *mobt, int n, const char *source)
+{
+ struct mob_db *md = NULL;
+ nullpo_ret(mobt);
+
+ if ((md = mob->db(mob_read_db_sub(mobt, n, source))) != mob->dummy) {
+ char e_name[NAME_LENGTH*2+1];
+ StringBuf buf;
+ int card_idx = 9, i;
+
+ StrBuf->Init(&buf);
+
+ // id
+ StrBuf->Printf(&buf, "%u,", md->mob_id);
- fclose(tosql.fp);
+ // Sprite
+ SQL->EscapeString(NULL, e_name, md->sprite);
+ StrBuf->Printf(&buf, "'%s',", e_name);
+
+ // kName
+ SQL->EscapeString(NULL, e_name, md->name);
+ StrBuf->Printf(&buf, "'%s',", e_name);
- if ((tosql.fp = fopen("sql-files/item_db.sql", "wt+")) == NULL) {
- ShowError("itemdb_tosql: File not found \"%s\".\n", "sql-files/item_db.sql");
- return;
+ // iName
+ SQL->EscapeString(NULL, e_name, md->jname);
+ StrBuf->Printf(&buf, "'%s',", e_name);
+
+ // LV
+ StrBuf->Printf(&buf, "%u,", md->lv);
+
+ // HP
+ StrBuf->Printf(&buf, "%u,", md->status.max_hp);
+
+ // SP
+ StrBuf->Printf(&buf, "%u,", md->status.max_sp);
+
+ // EXP
+ StrBuf->Printf(&buf, "%u,", md->base_exp);
+
+ // JEXP
+ StrBuf->Printf(&buf, "%u,", md->job_exp);
+
+ // Range1
+ StrBuf->Printf(&buf, "%u,", md->status.rhw.range);
+
+ // ATK1
+ StrBuf->Printf(&buf, "%u,", md->status.rhw.atk);
+
+ // ATK2
+ StrBuf->Printf(&buf, "%u,", md->status.rhw.atk2);
+
+ // DEF
+ StrBuf->Printf(&buf, "%u,", md->status.def);
+
+ // MDEF
+ StrBuf->Printf(&buf, "%u,", md->status.mdef);
+
+ // STR
+ StrBuf->Printf(&buf, "%u,", md->status.str);
+
+ // AGI
+ StrBuf->Printf(&buf, "%u,", md->status.agi);
+
+ // VIT
+ StrBuf->Printf(&buf, "%u,", md->status.vit);
+
+ // INT
+ StrBuf->Printf(&buf, "%u,", md->status.int_);
+
+ // DEX
+ StrBuf->Printf(&buf, "%u,", md->status.dex);
+
+ // LUK
+ StrBuf->Printf(&buf, "%u,", md->status.luk);
+
+ // Range2
+ StrBuf->Printf(&buf, "%u,", md->range2);
+
+ // Range3
+ StrBuf->Printf(&buf, "%u,", md->range3);
+
+ // Scale
+ StrBuf->Printf(&buf, "%u,", md->status.size);
+
+ // Race
+ StrBuf->Printf(&buf, "%u,", md->status.race);
+
+ // Element
+ StrBuf->Printf(&buf, "%u,", md->status.def_ele + 20 * md->status.ele_lv);
+
+ // Mode
+ StrBuf->Printf(&buf, "0x%X,", md->status.mode);
+
+ // Speed
+ StrBuf->Printf(&buf, "%u,", md->status.speed);
+
+ // aDelay
+ StrBuf->Printf(&buf, "%u,", md->status.adelay);
+
+ // aMotion
+ StrBuf->Printf(&buf, "%u,", md->status.amotion);
+
+ // dMotion
+ StrBuf->Printf(&buf, "%u,", md->status.dmotion);
+
+ // MEXP
+ StrBuf->Printf(&buf, "%u,", md->mexp);
+
+ for (i = 0; i < 3; i++) {
+ // MVP{i}id
+ StrBuf->Printf(&buf, "%u,", md->mvpitem[i].nameid);
+ // MVP{i}per
+ StrBuf->Printf(&buf, "%u,", md->mvpitem[i].p);
+ }
+
+ // Scan for cards
+ for (i = 0; i < 10; i++) {
+ struct item_data *it = NULL;
+ if (md->dropitem[i].nameid != 0 && (it = itemdb->exists(md->dropitem[i].nameid)) != NULL && it->type == IT_CARD)
+ card_idx = i;
+ }
+
+ for (i = 0; i < 10; i++) {
+ if (card_idx == i)
+ continue;
+ // Drop{i}id
+ StrBuf->Printf(&buf, "%u,", md->dropitem[i].nameid);
+ // Drop{i}per
+ StrBuf->Printf(&buf, "%u,", md->dropitem[i].p);
+ }
+
+ // DropCardid
+ StrBuf->Printf(&buf, "%u,", md->dropitem[card_idx].nameid);
+ // DropCardper
+ StrBuf->Printf(&buf, "%u", md->dropitem[card_idx].p);
+
+ fprintf(tosql.fp, "REPLACE INTO `%s` VALUES (%s);\n", tosql.db_name, StrBuf->Value(&buf));
+
+ StrBuf->Destroy(&buf);
}
- tosql.db_name = "item_db";
- totable();
+ return md ? md->mob_id : 0;
+}
- itemdb->clear(false);
- itemdb->readdb_libconfig("pre-re/item_db.conf");
+/**
+ * Prints a SQL table header for the current mob_db table.
+ */
+void mobdb2sql_tableheader(void)
+{
+ db2sql_fileheader();
+
+ fprintf(tosql.fp,
+ "--\n"
+ "-- Table structure for table `%s`\n"
+ "--\n"
+ "\n"
+ "DROP TABLE IF EXISTS `%s`;\n"
+ "CREATE TABLE `%s` (\n"
+ " `ID` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Sprite` TEXT NOT NULL,\n"
+ " `kName` TEXT NOT NULL,\n"
+ " `iName` TEXT NOT NULL,\n"
+ " `LV` TINYINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `HP` INT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `SP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `EXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `JEXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Range1` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `ATK1` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `ATK2` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `DEF` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `MDEF` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `STR` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `AGI` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `VIT` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `INT` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `DEX` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `LUK` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Range2` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Range3` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Scale` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Race` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Element` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Mode` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Speed` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `aDelay` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `aMotion` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `dMotion` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `MEXP` MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `MVP1id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `MVP1per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `MVP2id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `MVP2per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `MVP3id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `MVP3per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop1id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop1per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop2id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop2per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop3id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop3per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop4id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop4per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop5id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop5per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop6id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop6per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop7id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop7per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop8id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop8per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop9id` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `Drop9per` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `DropCardid` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " `DropCardper` SMALLINT(9) UNSIGNED NOT NULL DEFAULT '0',\n"
+ " PRIMARY KEY (`ID`)\n"
+ ") ENGINE=MyISAM;\n"
+ "\n", tosql.db_name, tosql.db_name, tosql.db_name);
+}
- fclose(tosql.fp);
+/**
+ * Mob DB Conversion.
+ *
+ * Converts Mob DB and Mob DB2 to SQL scripts.
+ */
+void do_mobdb2sql(void)
+{
+ int i;
+ struct convert_db_files {
+ const char *name;
+ const char *source;
+ const char *destination;
+ } files[] = {
+ {"mob_db", DBPATH"mob_db.conf", "sql-files/mob_db" DBSUFFIX ".sql"},
+ {"mob_db2", "mob_db2.conf", "sql-files/mob_db2.sql"},
+ };
+
+ /* link */
+ mob_read_db_sub = mob->read_db_sub;
+ mob->read_db_sub = mobdb2sql_sub;
- if ((tosql.fp = fopen("sql-files/item_db2.sql", "wt+")) == NULL) {
- ShowError("itemdb_tosql: File not found \"%s\".\n", "sql-files/item_db2.sql");
- return;
+ if (map->minimal) {
+ // Set up modifiers
+ battle->config_set_defaults();
}
- tosql.db_name = "item_db2";
- totable();
+ memset(&tosql.buf, 0, sizeof(tosql.buf));
+ for (i = 0; i < ARRAYLENGTH(files); i++) {
+ if ((tosql.fp = fopen(files[i].destination, "wt+")) == NULL) {
+ ShowError("mobdb_tosql: File not found \"%s\".\n", files[i].destination);
+ return;
+ }
- itemdb->clear(false);
- itemdb->readdb_libconfig("item_db2.conf");
+ tosql.db_name = files[i].name;
+ mobdb2sql_tableheader();
- fclose(tosql.fp);
+ mob->read_libconfig(files[i].source, false);
+
+ fclose(tosql.fp);
+ }
/* unlink */
- itemdb->readdb_libconfig_sub = itemdb_readdb_libconfig_sub;
+ mob->read_db_sub = mob_read_db_sub;
+
+ for (i = 0; i < ARRAYLENGTH(tosql.buf); i++) {
+ if (tosql.buf[i].p)
+ aFree(tosql.buf[i].p);
+ }
+}
+
+/**
+ * Console command db2sql.
+ */
+CPCMD(db2sql)
+{
+ do_itemdb2sql();
+ do_mobdb2sql();
+}
- if( tosql.buf[0].p ) aFree(tosql.buf[0].p);
- if( tosql.buf[1].p ) aFree(tosql.buf[1].p);
- if( tosql.buf[2].p ) aFree(tosql.buf[2].p);
- if( tosql.buf[3].p ) aFree(tosql.buf[3].p);
+/**
+ * Console command itemdb2sql.
+ */
+CPCMD(itemdb2sql)
+{
+ do_itemdb2sql();
}
-CPCMD(db2sql) {
- do_db2sql();
+
+/**
+ * Console command mobdb2sql.
+ */
+CPCMD(mobdb2sql)
+{
+ do_mobdb2sql();
}
+
+/**
+ * Command line argument handler for --db2sql
+ */
CMDLINEARG(db2sql)
{
- map->minimal = torun = true;
+ map->minimal = true;
+ itemdb2sql_torun = true;
+ mobdb2sql_torun = true;
return true;
}
-HPExport void server_preinit(void) {
- addArg("--db2sql",false,db2sql,NULL);
+/**
+ * Command line argument handler for --itemdb2sql
+ */
+CMDLINEARG(itemdb2sql)
+{
+ map->minimal = true;
+ itemdb2sql_torun = true;
+ return true;
}
-HPExport void plugin_init(void) {
- addCPCommand("server:tools:db2sql",db2sql);
+
+/**
+ * Command line argument handler for --mobdb2sql
+ */
+CMDLINEARG(mobdb2sql)
+{
+ map->minimal = true;
+ mobdb2sql_torun = true;
+ return true;
+}
+
+HPExport void server_preinit(void)
+{
+ addArg("--db2sql", false, db2sql, NULL);
+ addArg("--itemdb2sql", false, itemdb2sql, NULL);
+ addArg("--mobdb2sql", false, mobdb2sql, NULL);
+}
+
+HPExport void plugin_init(void)
+{
+ addCPCommand("server:tools:db2sql", db2sql);
+ addCPCommand("server:tools:itemdb2sql", itemdb2sql);
+ addCPCommand("server:tools:mobdb2sql", mobdb2sql);
}
-HPExport void server_online(void) {
- if( torun )
- do_db2sql();
+
+HPExport void server_online(void)
+{
+ if (itemdb2sql_torun)
+ do_itemdb2sql();
+ if (mobdb2sql_torun)
+ do_mobdb2sql();
}
diff --git a/src/plugins/dbghelpplug.c b/src/plugins/dbghelpplug.c
index edd47814d..6c02b1a12 100644
--- a/src/plugins/dbghelpplug.c
+++ b/src/plugins/dbghelpplug.c
@@ -1581,7 +1581,7 @@ typedef BOOL (WINAPI *ISDEBUGGERPRESENT)(void);
///
/// @return TRUE is a debugger is present
static BOOL
-Dhp__IsDebuggerPresent()
+Dhp__IsDebuggerPresent(void)
{
HANDLE kernel32_dll;
ISDEBUGGERPRESENT IsDebuggerPresent_;
@@ -1606,7 +1606,7 @@ Dhp__IsDebuggerPresent()
///
/// @return TRUE is sucessfull
static BOOL
-Dhp__LoadDbghelpDll()
+Dhp__LoadDbghelpDll(void)
{
dbghelp_dll = LoadLibraryA(DBGHELP_DLL);
if( dbghelp_dll != INVALID_HANDLE_VALUE )
@@ -1663,7 +1663,7 @@ Dhp__LoadDbghelpDll()
/// Unloads the dbghelp.dll library.
static VOID
-Dhp__UnloadDbghlpDll()
+Dhp__UnloadDbghlpDll(void)
{
if( !SymCleanup_(GetCurrentProcess()) )
printf("Failed to cleanup symbols! Error: %u\n", GetLastError());
diff --git a/src/test/Makefile.in b/src/test/Makefile.in
index 29331cb0f..6d2187733 100644
--- a/src/test/Makefile.in
+++ b/src/test/Makefile.in
@@ -88,13 +88,13 @@ $(TESTS_ALL): test_%: ../../test_%@EXEEXT@
../../test_%@EXEEXT@: obj/test_%.o $(TEST_DEPENDS) Makefile
@echo " LD $(notdir $@)"
@$(CC) @STATIC@ @LDFLAGS@ -o $@ $< $(COMMON_D)/obj_sql/common_sql.a \
- $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
+ $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@
# object files
obj/%.o: %.c $(TEST_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj
@echo " CC $<"
- @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @PCRE_CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+ @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
# missing object files
$(COMMON_D)/obj_all/common.a: