summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorai4rei <ai4rei@54d463be-8e91-2dee-dedb-b68131a5f0ec>2011-07-10 06:17:06 +0000
committerai4rei <ai4rei@54d463be-8e91-2dee-dedb-b68131a5f0ec>2011-07-10 06:17:06 +0000
commit9ef634559f3cde232586b1dc6fd00bea3f3d8e53 (patch)
tree541295af8a6fbfe15b09da353680be6dd4d6b3ff /src/map
parent9c100697bf79604fcef8b7eedbadeed45c63b41b (diff)
downloadhercules-9ef634559f3cde232586b1dc6fd00bea3f3d8e53.tar.gz
hercules-9ef634559f3cde232586b1dc6fd00bea3f3d8e53.tar.bz2
hercules-9ef634559f3cde232586b1dc6fd00bea3f3d8e53.tar.xz
hercules-9ef634559f3cde232586b1dc6fd00bea3f3d8e53.zip
* Merged changes from trunk [14827:14894/trunk].
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/renewal@14895 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r--src/map/CMakeLists.txt12
-rw-r--r--src/map/Makefile.in30
-rw-r--r--src/map/atcommand.c22
-rw-r--r--src/map/battle.c6
-rw-r--r--src/map/battle.h27
-rw-r--r--src/map/battleground.c2
-rw-r--r--src/map/buyingstore.c2
-rw-r--r--src/map/chrif.c114
-rw-r--r--src/map/chrif.h2
-rw-r--r--src/map/clif.c160
-rw-r--r--src/map/clif.h8
-rw-r--r--src/map/guild.c10
-rw-r--r--src/map/homunculus.c6
-rw-r--r--src/map/instance.c63
-rw-r--r--src/map/instance.h11
-rw-r--r--src/map/map.c41
-rw-r--r--src/map/map.h16
-rw-r--r--src/map/mapreg_sql.c2
-rw-r--r--src/map/mapreg_txt.c2
-rw-r--r--src/map/mercenary.c2
-rw-r--r--src/map/mob.c57
-rw-r--r--src/map/mob.h4
-rw-r--r--src/map/npc.c38
-rw-r--r--src/map/npc.h2
-rw-r--r--src/map/party.c16
-rw-r--r--src/map/party.h2
-rw-r--r--src/map/pc.c139
-rw-r--r--src/map/pc.h12
-rw-r--r--src/map/pet.c17
-rw-r--r--src/map/pet.h8
-rw-r--r--src/map/quest.c2
-rw-r--r--src/map/script.c105
-rw-r--r--src/map/script.h2
-rw-r--r--src/map/skill.c133
-rw-r--r--src/map/skill.h83
-rw-r--r--src/map/sql/CMakeLists.txt110
-rw-r--r--src/map/status.c19
-rw-r--r--src/map/status.h78
-rw-r--r--src/map/txt/CMakeLists.txt110
-rw-r--r--src/map/unit.c18
40 files changed, 982 insertions, 511 deletions
diff --git a/src/map/CMakeLists.txt b/src/map/CMakeLists.txt
new file mode 100644
index 000000000..9199702be
--- /dev/null
+++ b/src/map/CMakeLists.txt
@@ -0,0 +1,12 @@
+
+#
+# setup
+#
+set( MAP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
+
+
+#
+# targets
+#
+add_subdirectory( txt )
+add_subdirectory( sql )
diff --git a/src/map/Makefile.in b/src/map/Makefile.in
index 7070a0a9d..09e92dde2 100644
--- a/src/map/Makefile.in
+++ b/src/map/Makefile.in
@@ -3,16 +3,22 @@ COMMON_OBJ = ../common/obj_all/core.o ../common/obj_all/socket.o ../common/obj_a
../common/obj_all/db.o ../common/obj_all/plugins.o ../common/obj_all/lock.o \
../common/obj_all/nullpo.o ../common/obj_all/malloc.o ../common/obj_all/showmsg.o \
../common/obj_all/utils.o ../common/obj_all/strlib.o ../common/obj_all/grfio.o \
- ../common/obj_all/mapindex.o ../common/obj_all/ers.o ../common/obj_all/md5calc.o
+ ../common/obj_all/mapindex.o ../common/obj_all/ers.o ../common/obj_all/md5calc.o \
+ ../common/obj_all/random.o
COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h \
../common/db.h ../common/plugins.h ../common/lock.h \
../common/nullpo.h ../common/malloc.h ../common/showmsg.h \
../common/utils.h ../common/strlib.h ../common/grfio.h \
- ../common/mapindex.h ../common/ers.h ../common/md5calc.h
+ ../common/mapindex.h ../common/ers.h ../common/md5calc.h \
+ ../common/random.h
COMMON_SQL_OBJ = ../common/obj_sql/sql.o
COMMON_SQL_H = ../common/sql.h
+MT19937AR_OBJ = ../../3rdparty/mt19937ar/mt19937ar.o
+MT19937AR_H = ../../3rdparty/mt19937ar/mt19937ar.h
+MT19937AR_INCLUDE = -I../../3rdparty/mt19937ar
+
MAP_OBJ = map.o chrif.o clif.o pc.o status.o npc.o \
npc_chat.o chat.o path.o itemdb.o mob.o script.o \
storage.o skill.o atcommand.o battle.o battleground.o \
@@ -38,6 +44,7 @@ else
ALL_TARGET=txt
SQL_DEPENDS=needs_mysql
endif
+TXT_DEPENDS=map-server
HAVE_PCRE=@HAVE_PCRE@
ifeq ($(HAVE_PCRE),yes)
@@ -53,7 +60,7 @@ endif
all: $(ALL_DEPENDS)
-txt: map-server
+txt: $(TXT_DEPENDS)
sql: $(SQL_DEPENDS)
@@ -87,21 +94,24 @@ obj_sql:
# executables
map-server: obj_txt $(MAP_TXT_OBJ) $(COMMON_OBJ)
- @CC@ @LDFLAGS@ -o ../../map-server@EXEEXT@ $(MAP_TXT_OBJ) $(COMMON_OBJ) @LIBS@ @PCRE_LIBS@
+ @CC@ @LDFLAGS@ -o ../../map-server@EXEEXT@ $(MAP_TXT_OBJ) $(COMMON_OBJ) $(MT19937AR_OBJ) @LIBS@ @PCRE_LIBS@
map-server_sql: obj_sql $(MAP_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ)
- @CC@ @LDFLAGS@ -o ../../map-server_sql@EXEEXT@ $(MAP_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
+ @CC@ @LDFLAGS@ -o ../../map-server_sql@EXEEXT@ $(MAP_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) $(MT19937AR_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
# map object files
-obj_txt/%.o: %.c $(MAP_H) $(COMMON_H)
- @CC@ @CFLAGS@ $(PCRE_CFLAGS) -DTXT_ONLY @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+obj_txt/%.o: %.c $(MAP_H) $(COMMON_H) $(MT19937AR_H)
+ @CC@ @CFLAGS@ $(MT19937AR_INCLUDE) $(PCRE_CFLAGS) -DTXT_ONLY @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
-obj_sql/%.o: %.c $(MAP_H) $(COMMON_H) $(COMMON_SQL_H)
- @CC@ @CFLAGS@ $(PCRE_CFLAGS) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+obj_sql/%.o: %.c $(MAP_H) $(COMMON_H) $(COMMON_SQL_H) $(MT19937AR_H)
+ @CC@ @CFLAGS@ $(MT19937AR_INCLUDE) $(PCRE_CFLAGS) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
-# missing common object files
+# missing object files
../common/obj_all/%.o:
@$(MAKE) -C ../common txt
../common/obj_sql/%.o:
@$(MAKE) -C ../common sql
+
+MT19937AR_OBJ:
+ @$(MAKE) -C ../../3rdparty/mt19937ar
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 664430b18..32c2cabf7 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -3988,23 +3988,9 @@ ACMD_FUNC(agitend2)
*------------------------------------------*/
ACMD_FUNC(mapexit)
{
- struct map_session_data* pl_sd;
- struct s_mapiterator* iter;
-
nullpo_retr(-1, sd);
- iter = mapit_getallusers();
- for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
- if (sd->status.account_id != pl_sd->status.account_id)
- clif_GM_kick(NULL, pl_sd);
- mapit_free(iter);
-
- clif_GM_kick(NULL, sd);
-
- flush_fifos();
-
- runflag = 0;
-
+ do_shutdown();
return 0;
}
@@ -7098,9 +7084,9 @@ ACMD_FUNC(mobinfo)
if (mob->mvpitem[i].p > 0) {
j++;
if (j == 1)
- sprintf(atcmd_output2, " %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100);
+ sprintf(atcmd_output2, " %s %02.02f%%", item_data->jname, (float)mob->mvpitem[i].p / 100);
else
- sprintf(atcmd_output2, " - %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100);
+ sprintf(atcmd_output2, " - %s %02.02f%%", item_data->jname, (float)mob->mvpitem[i].p / 100);
strcat(atcmd_output, atcmd_output2);
}
}
@@ -7117,7 +7103,7 @@ ACMD_FUNC(mobinfo)
* @showmobs by KarLaeda
* => For 5 sec displays the mobs on minimap
*------------------------------------------*/
-int atshowmobs_timer(int tid, unsigned int tick, int id, intptr data)
+int atshowmobs_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data* sd = map_id2sd(id);
if( sd == NULL )
diff --git a/src/map/battle.c b/src/map/battle.c
index aea2f2da4..ca5662dd7 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -154,7 +154,7 @@ struct delay_damage {
unsigned short attack_type;
};
-int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr data)
+int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data)
{
struct delay_damage *dat = (struct delay_damage *)data;
struct block_list *target = map_id2bl(dat->target);
@@ -208,7 +208,7 @@ int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src,
dat->distance = distance_bl(src, target)+10; //Attack should connect regardless unless you teleported.
if (src->type != BL_PC && amotion > 1000)
amotion = 1000; //Aegis places a damage-delay cap of 1 sec to non player attacks. [Skotlex]
- add_timer(tick+amotion, battle_delay_damage_sub, src->id, (intptr)dat);
+ add_timer(tick+amotion, battle_delay_damage_sub, src->id, (intptr_t)dat);
return 0;
}
@@ -1620,7 +1620,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
case AS_SPLASHER:
skillratio += 400+50*skill_lv;
if(sd)
- skillratio += 30 * pc_checkskill(sd,AS_POISONREACT);
+ skillratio += 20 * pc_checkskill(sd,AS_POISONREACT);
break;
case ASC_BREAKER:
skillratio += 100*skill_lv-100;
diff --git a/src/map/battle.h b/src/map/battle.h
index 8d014c5f9..d54d49c0a 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -72,20 +72,19 @@ struct block_list* battle_getenemy(struct block_list *target, int type, int rang
int battle_gettarget(struct block_list *bl);
int battle_getcurrentskill(struct block_list *bl);
-//New definitions [Skotlex]
-#define BCT_ENEMY 0x020000
-//This should be (~BCT_ENEMY&BCT_ALL)
-#define BCT_NOENEMY 0x1d0000
-#define BCT_PARTY 0x040000
-//This should be (~BCT_PARTY&BCT_ALL)
-#define BCT_NOPARTY 0x1b0000
-#define BCT_GUILD 0x080000
-//This should be (~BCT_GUILD&BCT_ALL)
-#define BCT_NOGUILD 0x170000
-#define BCT_ALL 0x1f0000
-#define BCT_NOONE 0x000000
-#define BCT_SELF 0x010000
-#define BCT_NEUTRAL 0x100000
+enum e_battle_check_target
+{//New definitions [Skotlex]
+ BCT_ENEMY = 0x020000,
+ BCT_NOENEMY = 0x1d0000, //This should be (~BCT_ENEMY&BCT_ALL)
+ BCT_PARTY = 0x040000,
+ BCT_NOPARTY = 0x1b0000, //This should be (~BCT_PARTY&BCT_ALL)
+ BCT_GUILD = 0x080000,
+ BCT_NOGUILD = 0x170000, //This should be (~BCT_GUILD&BCT_ALL)
+ BCT_ALL = 0x1f0000,
+ BCT_NOONE = 0x000000,
+ BCT_SELF = 0x010000,
+ BCT_NEUTRAL = 0x100000,
+};
#define is_boss(bl) (status_get_mode(bl)&MD_BOSS) // Can refine later [Aru]
diff --git a/src/map/battleground.c b/src/map/battleground.c
index 13f62a042..b456a868a 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -236,7 +236,7 @@ int bg_send_xy_timer_sub(DBKey key, void *data, va_list ap)
return 0;
}
-int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr data)
+int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
bg_team_db->foreach(bg_team_db, bg_send_xy_timer_sub, tick);
return 0;
diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c
index 5b9734819..94f390c10 100644
--- a/src/map/buyingstore.c
+++ b/src/map/buyingstore.c
@@ -145,7 +145,7 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
if( i )
{// duplicate check. as the client does this too, only malicious intent should be caught here
- ARR_FIND( 0, i, listidx, sd->buyingstore.items[i].nameid == nameid );
+ ARR_FIND( 0, i, listidx, sd->buyingstore.items[listidx].nameid == nameid );
if( listidx != i )
{// duplicate
ShowWarning("buyingstore_create: Found duplicate item on buying list (nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", nameid, amount, sd->status.account_id, sd->status.char_id);
diff --git a/src/map/chrif.c b/src/map/chrif.c
index c4eeea3d9..a14200a36 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -31,6 +31,8 @@
#include <sys/types.h>
#include <time.h>
+static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data);
+
static struct eri *auth_db_ers; //For reutilizing player login structures.
static DBMap* auth_db; // int id -> struct auth_node*
@@ -94,7 +96,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2b27: Incoming, chrif_authfail -> 'client authentication failed'
int chrif_connected = 0;
-int char_fd = 0; //Using 0 instead of -1 is safer against crashes. [Skotlex]
+int char_fd = -1;
int srvinfo;
static char char_ip_str[128];
static uint32 char_ip = 0;
@@ -110,6 +112,28 @@ int other_mapserver_count=0; //Holds count of how many other map servers are onl
//This define should spare writing the check in every function. [Skotlex]
#define chrif_check(a) { if(!chrif_isconnected()) return a; }
+
+/// Resets all the data.
+void chrif_reset(void)
+{
+ // TODO kick everyone out and reset everything [FlavioJS]
+ exit(EXIT_FAILURE);
+}
+
+
+/// Checks the conditions for the server to stop.
+/// Releases the cookie when all characters are saved.
+/// If all the conditions are met, it stops the core loop.
+void chrif_check_shutdown(void)
+{
+ if( runflag != MAPSERVER_ST_SHUTDOWN )
+ return;
+ if( auth_db->size(auth_db) > 0 )
+ return;
+ runflag = CORE_ST_STOP;
+}
+
+
struct auth_node* chrif_search(int account_id)
{
return (struct auth_node*)idb_get(auth_db, account_id);
@@ -244,9 +268,8 @@ int chrif_save(struct map_session_data *sd, int flag)
{
nullpo_retr(-1, sd);
- if (!flag) //The flag check is needed to prevent 'nosave' taking effect when a jailed player logs out.
- pc_makesavestatus(sd);
-
+ pc_makesavestatus(sd);
+
if (flag && sd->state.active) //Store player data which is quitting.
{
//FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex]
@@ -363,6 +386,7 @@ int chrif_removemap(int fd)
static void chrif_save_ack(int fd)
{
chrif_auth_delete(RFIFOL(fd,2), RFIFOL(fd,6), ST_LOGOUT);
+ chrif_check_shutdown();
}
// request to move a character between mapservers
@@ -472,19 +496,13 @@ static int chrif_reconnect(DBKey key,void *data,va_list ap)
return 0;
}
-/*==========================================
- *
- *------------------------------------------*/
-int chrif_sendmapack(int fd)
-{
- if (RFIFOB(fd,2)) {
- ShowFatalError("chrif : send map list to char server failed %d\n", RFIFOB(fd,2));
- exit(EXIT_FAILURE);
- }
- memcpy(wisp_server_name, RFIFOP(fd,3), NAME_LENGTH);
- ShowStatus("Map sending complete. Map Server is now online.\n");
+/// Called when all the connection steps are completed.
+void chrif_on_ready(void)
+{
+ ShowStatus("Map Server is now online.\n");
chrif_state = 2;
+ chrif_check_shutdown();
//If there are players online, send them to the char-server. [Skotlex]
send_users_tochar();
@@ -494,7 +512,21 @@ int chrif_sendmapack(int fd)
//Re-save any storages that were modified in the disconnection time. [Skotlex]
do_reconnect_storage();
+}
+
+/*==========================================
+ *
+ *------------------------------------------*/
+int chrif_sendmapack(int fd)
+{
+ if (RFIFOB(fd,2)) {
+ ShowFatalError("chrif : send map list to char server failed %d\n", RFIFOB(fd,2));
+ exit(EXIT_FAILURE);
+ }
+
+ memcpy(wisp_server_name, RFIFOP(fd,3), NAME_LENGTH);
+ chrif_on_ready();
return 0;
}
@@ -592,7 +624,8 @@ void chrif_authok(int fd)
}
sd = node->sd;
- if(node->char_dat == NULL &&
+ if( runflag == MAPSERVER_ST_RUNNING &&
+ node->char_dat == NULL &&
node->account_id == account_id &&
node->char_id == char_id &&
node->login_id1 == login_id1 )
@@ -661,7 +694,7 @@ int auth_db_cleanup_sub(DBKey key,void *data,va_list ap)
return 0;
}
-int auth_db_cleanup(int tid, unsigned int tick, int id, intptr data)
+int auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
if(!chrif_isconnected()) return 0;
auth_db->foreach(auth_db, auth_db_cleanup_sub);
@@ -838,7 +871,7 @@ int chrif_changedsex(int fd)
if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
// remove specifical skills of Bard classes
for(i = 315; i <= 322; i++) {
- if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) {
+ if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[i].lv;
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
@@ -846,7 +879,7 @@ int chrif_changedsex(int fd)
}
// remove specifical skills of Dancer classes
for(i = 323; i <= 330; i++) {
- if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) {
+ if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[i].lv;
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
@@ -1292,22 +1325,22 @@ int chrif_char_online(struct map_session_data *sd)
return 0;
}
-int chrif_disconnect(int fd)
+
+/// Called when the connection to Char Server is disconnected.
+void chrif_on_disconnect(void)
{
- if(fd == char_fd) {
- char_fd = 0;
- ShowWarning("Map Server disconnected from Char Server.\n\n");
- chrif_connected = 0;
-
- other_mapserver_count=0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
- map_eraseallipport();
+ if( chrif_connected != 1 )
+ ShowWarning("Connection to Char Server lost.\n\n");
+ chrif_connected = 0;
+
+ other_mapserver_count = 0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
+ map_eraseallipport();
- //Attempt to reconnect in a second. [Skotlex]
- add_timer(gettick() + 1000, check_connect_char_server, 0, 0);
- }
- return 0;
+ //Attempt to reconnect in a second. [Skotlex]
+ add_timer(gettick() + 1000, check_connect_char_server, 0, 0);
}
+
void chrif_update_ip(int fd)
{
uint32 new_ip;
@@ -1352,10 +1385,9 @@ int chrif_parse(int fd)
if (session[fd]->flag.eof)
{
- if (chrif_connected == 1)
- chrif_disconnect(fd);
-
do_close(fd);
+ char_fd = -1;
+ chrif_on_disconnect();
return 0;
}
@@ -1393,7 +1425,7 @@ int chrif_parse(int fd)
case 0x2afb: chrif_sendmapack(fd); break;
case 0x2afd: chrif_authok(fd); break;
case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break;
- case 0x2b03: clif_charselectok(RFIFOL(fd,2)); break;
+ case 0x2b03: clif_charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break;
case 0x2b04: chrif_recvmap(fd); break;
case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break;
case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
@@ -1423,7 +1455,7 @@ int chrif_parse(int fd)
return 0;
}
-int ping_char_server(int tid, unsigned int tick, int id, intptr data)
+int ping_char_server(int tid, unsigned int tick, int id, intptr_t data)
{
chrif_check(-1);
chrif_keepalive(char_fd);
@@ -1431,7 +1463,7 @@ int ping_char_server(int tid, unsigned int tick, int id, intptr data)
}
// unused
-int send_usercount_tochar(int tid, unsigned int tick, int id, intptr data)
+int send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data)
{
chrif_check(-1);
@@ -1476,7 +1508,7 @@ int send_users_tochar(void)
* timer関数
* char鯖との接続を確認し、もし切れていたら再度接続する
*------------------------------------------*/
-int check_connect_char_server(int tid, unsigned int tick, int id, intptr data)
+static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data)
{
static int displayed = 0;
if (char_fd <= 0 || session[char_fd] == NULL)
@@ -1491,7 +1523,6 @@ int check_connect_char_server(int tid, unsigned int tick, int id, intptr data)
char_fd = make_connection(char_ip, char_port);
if (char_fd == -1)
{ //Attempt to connect later. [Skotlex]
- char_fd = 0;
return 0;
}
@@ -1532,8 +1563,11 @@ int auth_db_final(DBKey k,void *d,va_list ap)
*------------------------------------------*/
int do_final_chrif(void)
{
- if (char_fd > 0)
+ if( char_fd != -1 )
+ {
do_close(char_fd);
+ char_fd = -1;
+ }
auth_db->destroy(auth_db, auth_db_final);
ers_destroy(auth_db_ers);
diff --git a/src/map/chrif.h b/src/map/chrif.h
index 9ff5b9a0e..1f11cc6f2 100644
--- a/src/map/chrif.h
+++ b/src/map/chrif.h
@@ -25,6 +25,7 @@ int chrif_setip(const char* ip);
void chrif_setport(uint16 port);
int chrif_isconnected(void);
+void chrif_check_shutdown(void);
extern int chrif_connected;
extern int other_mapserver_count;
@@ -55,7 +56,6 @@ int send_users_tochar(void);
int chrif_char_online(struct map_session_data *sd);
int chrif_changesex(struct map_session_data *sd);
int chrif_chardisconnect(struct map_session_data *sd);
-int check_connect_char_server(int tid, unsigned int tick, int id, intptr data);
int chrif_divorce(int partner_id1, int partner_id2);
int do_final_chrif(void);
diff --git a/src/map/clif.c b/src/map/clif.c
index 81ab49799..8d2159823 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -581,10 +581,10 @@ int clif_authfail_fd(int fd, int type)
return 0;
}
-/*==========================================
- *
- *------------------------------------------*/
-int clif_charselectok(int id)
+/// Reply from char-server.
+/// Tells the player if it can connect to the char-server to select a character.
+/// ok=1 : client disconnects and tries to connect to the char-server
+int clif_charselectok(int id, uint8 ok)
{
struct map_session_data* sd;
int fd;
@@ -595,7 +595,7 @@ int clif_charselectok(int id)
fd = sd->fd;
WFIFOHEAD(fd,packet_len(0xb3));
WFIFOW(fd,0) = 0xb3;
- WFIFOB(fd,2) = 1;
+ WFIFOB(fd,2) = ok;
WFIFOSET(fd,packet_len(0xb3));
return 0;
@@ -700,7 +700,7 @@ int clif_clearunit_area(struct block_list* bl, clr_type type)
return 0;
}
-static int clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr data)
+static int clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list *bl = (struct block_list *)data;
clif_clearunit_area(bl, CLR_OUTSIGHT);
@@ -713,7 +713,7 @@ int clif_clearunit_delayed(struct block_list* bl, unsigned int tick)
struct block_list *tbl;
tbl = (struct block_list*)aMalloc(sizeof (struct block_list));
memcpy (tbl, bl, sizeof (struct block_list));
- add_timer(tick, clif_clearunit_delayed_sub, 0, (intptr)tbl);
+ add_timer(tick, clif_clearunit_delayed_sub, 0, (intptr_t)tbl);
return 0;
}
@@ -1376,6 +1376,12 @@ static void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_
clif_specialeffect(&md->bl,421,AREA);
}
break;
+ case BL_PET:
+ if( vd->head_bottom )
+ {// needed to display pet equip properly
+ clif_pet_equip_area((TBL_PET*)bl);
+ }
+ break;
}
return;
}
@@ -1415,7 +1421,7 @@ void clif_move(struct unit_data *ud)
/*==========================================
* Delays the map_quit of a player after they are disconnected. [Skotlex]
*------------------------------------------*/
-static int clif_delayquit(int tid, unsigned int tick, int id, intptr data)
+static int clif_delayquit(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd = NULL;
@@ -4192,7 +4198,7 @@ int clif_skillinfoblock(struct map_session_data *sd)
WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv);
WFIFOW(fd,len+10)= skill_get_range2(&sd->bl, id,sd->status.skill[i].lv);
safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
- if(sd->status.skill[i].flag == 0)
+ if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
WFIFOB(fd,len+36) = (sd->status.skill[i].lv < skill_tree_get_max(id, sd->status.class_))? 1:0;
else
WFIFOB(fd,len+36) = 0;
@@ -4229,7 +4235,7 @@ int clif_addskill(struct map_session_data *sd, int id )
WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[id].lv);
WFIFOW(fd,12)= skill_get_range2(&sd->bl, id,sd->status.skill[id].lv);
safestrncpy((char*)WFIFOP(fd,14), skill_get_name(id), NAME_LENGTH);
- if( sd->status.skill[id].flag == 0 )
+ if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
WFIFOB(fd,38) = (sd->status.skill[id].lv < skill_tree_get_max(id, sd->status.class_))? 1:0;
else
WFIFOB(fd,38) = 0;
@@ -4279,38 +4285,49 @@ int clif_skillup(struct map_session_data *sd,int skill_num)
return 0;
}
-/*==========================================
- * スキル詠唱エフェクトを送信する
- * pl:
- * 0 = Yellow cast aura
- * 1 = Water elemental cast aura
- * 2 = Earth elemental cast aura
- * 3 = Fire elemental cast aura
- * 4 = Wind elemental cast aura
- * 5 = Poison elemental cast aura
- * 6 = White cast aura
- * ? = like 0
- *------------------------------------------*/
-int clif_skillcasting(struct block_list* bl,
- int src_id,int dst_id,int dst_x,int dst_y,int skill_num,int pl, int casttime)
+
+/// Notifies clients, that an object is about to use a skill (ZC_USESKILL_ACK/ZC_USESKILL_ACK2)
+/// 013e <src id>.L <dst id>.L <x pos>.W <y pos>.W <skill id>.W <property>.L <delaytime>.L
+/// 07fb <src id>.L <dst id>.L <x pos>.W <y pos>.W <skill id>.W <property>.L <delaytime>.L <is disposable>.B
+/// property:
+/// 0 = Yellow cast aura
+/// 1 = Water elemental cast aura
+/// 2 = Earth elemental cast aura
+/// 3 = Fire elemental cast aura
+/// 4 = Wind elemental cast aura
+/// 5 = Poison elemental cast aura
+/// 6 = Holy elemental cast aura
+/// ? = like 0
+/// is disposable:
+/// 0 = yellow chat text "[src name] will use skill [skill name]."
+/// 1 = no text
+void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, int skill_num, int property, int casttime)
{
+#if PACKETVER < 20091124
+ const int cmd = 0x13e;
+#else
+ const int cmd = 0x7fb;
+#endif
unsigned char buf[32];
- WBUFW(buf,0) = 0x13e;
+
+ WBUFW(buf,0) = cmd;
WBUFL(buf,2) = src_id;
WBUFL(buf,6) = dst_id;
WBUFW(buf,10) = dst_x;
WBUFW(buf,12) = dst_y;
WBUFW(buf,14) = skill_num;
- WBUFL(buf,16) = pl<0?0:pl; //Avoid sending negatives as element [Skotlex]
+ WBUFL(buf,16) = property<0?0:property; //Avoid sending negatives as element [Skotlex]
WBUFL(buf,20) = casttime;
+#if PACKETVER >= 20091124
+ WBUFB(buf,24) = 1; // isDisposable
+#endif
+
if (disguised(bl)) {
- clif_send(buf,packet_len(0x13e), bl, AREA_WOS);
+ clif_send(buf,packet_len(cmd), bl, AREA_WOS);
WBUFL(buf,2) = -src_id;
- clif_send(buf,packet_len(0x13e), bl, SELF);
+ clif_send(buf,packet_len(cmd), bl, SELF);
} else
- clif_send(buf,packet_len(0x13e), bl, AREA);
-
- return 0;
+ clif_send(buf,packet_len(cmd), bl, AREA);
}
/*==========================================
@@ -5821,28 +5838,32 @@ void clif_partyinvitationstate(struct map_session_data* sd)
WFIFOSET(fd, packet_len(0x2c9));
}
-/*==========================================
- * パーティ勧誘
- *------------------------------------------*/
-int clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd)
+/// Party invitation request (ZC_REQ_JOIN_GROUP/ZC_PARTY_JOIN_REQ)
+/// 00fe <party id>.L <party name>.24B
+/// 02c6 <party id>.L <party name>.24B
+void clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd)
{
+#if PACKETVER < 20070821
+ const int cmd = 0xfe;
+#else
+ const int cmd = 0x2c6;
+#endif
int fd;
struct party_data *p;
- nullpo_ret(sd);
- nullpo_ret(tsd);
+ nullpo_retv(sd);
+ nullpo_retv(tsd);
fd=tsd->fd;
if( (p=party_search(sd->status.party_id))==NULL )
- return 0;
+ return;
- WFIFOHEAD(fd,packet_len(0xfe));
- WFIFOW(fd,0)=0xfe;
- WFIFOL(fd,2)=sd->status.account_id; // FIXME: This is party_id
+ WFIFOHEAD(fd,packet_len(cmd));
+ WFIFOW(fd,0)=cmd;
+ WFIFOL(fd,2)=sd->status.party_id;
memcpy(WFIFOP(fd,6),p->party.name,NAME_LENGTH);
- WFIFOSET(fd,packet_len(0xfe));
- return 0;
+ WFIFOSET(fd,packet_len(cmd));
}
/*==========================================
@@ -7643,6 +7664,8 @@ int clif_refresh(struct map_session_data *sd)
clif_weather_check(sd);
if( sd->chatID )
chat_leavechat(sd,0);
+ if( sd->state.vending )
+ clif_openvending(sd, sd->bl.id, sd->vending);
if( pc_issit(sd) )
clif_sitting(&sd->bl); // FIXME: just send to self, not area
if( pc_isdead(sd) ) //When you refresh, resend the death packet.
@@ -7650,6 +7673,9 @@ int clif_refresh(struct map_session_data *sd)
else
clif_changed_dir(&sd->bl, SELF);
+ // unlike vending, resuming buyingstore crashes the client.
+ buyingstore_close(sd);
+
#ifndef TXT_ONLY
mail_clear(sd);
#endif
@@ -8371,6 +8397,12 @@ void clif_parse_WantToConnection(int fd, TBL_PC* sd)
return;
}
+ if( runflag != MAPSERVER_ST_RUNNING )
+ {// not allowed
+ clif_authfail_fd(fd,1);// server closed
+ return;
+ }
+
//Check for double login.
bl = map_id2bl(account_id);
if(bl && bl->type != BL_PC) {
@@ -10620,12 +10652,12 @@ void clif_parse_PartyInvite2(int fd, struct map_session_data *sd)
party_invite(sd, t_sd);
}
-/*==========================================
- * Party invitation reply
- * S 00ff <account ID>.L <flag>.L
- * S 02c7 <account ID>.L <flag>.B
- * flag: 0-reject, 1-accept
- *------------------------------------------*/
+/// Party invitation reply (CZ_JOIN_GROUP/CZ_PARTY_JOIN_REQ_ACK)
+/// 00ff <party id>.L <flag>.L
+/// 02c7 <party id>.L <flag>.B
+/// flag:
+/// 0 = reject
+/// 1 = accept
void clif_parse_ReplyPartyInvite(int fd,struct map_session_data *sd)
{
party_reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6));
@@ -11995,6 +12027,11 @@ void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd)
return;
}
+ if( sd->bl.id == f_sd->bl.id )
+ {// adding oneself as friend
+ return;
+ }
+
// @noask [LuzZza]
if(f_sd->state.noask) {
clif_noask_sub(sd, f_sd, 5);
@@ -12037,6 +12074,11 @@ void clif_parse_FriendsListReply(int fd, struct map_session_data *sd)
char_id = RFIFOL(fd,6);
reply = RFIFOB(fd,10);
+ if( sd->bl.id == account_id )
+ {// adding oneself as friend
+ return;
+ }
+
f_sd = map_id2sd(account_id); //The account id is the same as the bl.id of players.
if (f_sd == NULL)
return;
@@ -12305,10 +12347,8 @@ void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd)
sd->menuskill_val = sd->menuskill_id = 0;
}
-/*==========================================
- * Question about Star Glaldiator save map [Komurka]
- *------------------------------------------*/
-void clif_parse_ReqFeel(int fd, struct map_session_data *sd, int skilllv)
+/// Star Gladiator's Feeling map confirmation prompt (ZC_STARPLACE)
+void clif_feel_req(int fd, struct map_session_data *sd, int skilllv)
{
WFIFOHEAD(fd,packet_len(0x253));
WFIFOW(fd,0)=0x253;
@@ -13957,11 +13997,11 @@ int clif_instance(int instance_id, int type, int flag)
switch( type )
{
case 1:
- // S 0x2cb <Instance name>.63B <Standby Position>.W
+ // S 0x2cb <Instance name>.61B <Standby Position>.W
// Required to start the instancing information window on Client
// This window re-appear each "refresh" of client automatically until type 4 is send to client.
WBUFW(buf,0) = 0x02CB;
- memcpy(WBUFP(buf,2),instance[instance_id].name,61);
+ memcpy(WBUFP(buf,2),instance[instance_id].name,INSTANCE_NAME_LENGTH);
WBUFW(buf,63) = flag;
clif_send(buf,packet_len(0x02CB),&sd->bl,PARTY);
break;
@@ -13989,14 +14029,16 @@ int clif_instance(int instance_id, int type, int flag)
}
clif_send(buf,packet_len(0x02CD),&sd->bl,PARTY);
break;
- case 5: // R 02CE <message ID>.L
+ case 5:
// S 0x2ce <Message ID>.L
+ // 0 = Notification (EnterLimitDate update?)
// 1 = The Memorial Dungeon expired; it has been destroyed
// 2 = The Memorial Dungeon's entry time limit expired; it has been destroyed
// 3 = The Memorial Dungeon has been removed.
- // 4 = Just remove the window, maybe party/guild leave
+ // 4 = Create failure (removes the instance window)
WBUFW(buf,0) = 0x02CE;
WBUFL(buf,2) = flag;
+ //WBUFL(buf,6) = EnterLimitDate;
clif_send(buf,packet_len(0x02CE),&sd->bl,PARTY);
break;
}
@@ -14911,7 +14953,7 @@ static int packetdb_readdb(void)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85, -1, -1,107, 6, -1, 7, 7, 22,191, 0, 0, 0, 0, 0, 0,
//#0x02C0
- 0, 0, 0, 0, 0, 30, 0, 0, 0, 3, 0, 65, 4, 71, 10, 0,
+ 0, 0, 0, 0, 0, 30, 30, 0, 0, 3, 0, 65, 4, 71, 10, 0,
0, 0, 0, 0, 29, 0, 6, -1, 10, 10, 3, 0, -1, 32, 6, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 59, 60, 8,
10, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -15018,7 +15060,7 @@ static int packetdb_readdb(void)
6, 2, -1, 4, 4, 4, 4, 8, 8,268, 6, 8, 6, 54, 30, 54,
#endif
0, 0, 0, 0, 0, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 14, -1, -1, -1, 8, 0, 0, 0, 26, 0,
+ 0, 0, 0, 0, 0, 0, 14, -1, -1, -1, 8, 25, 0, 0, 26, 0,
//#0x0800
#if PACKETVER < 20091229
-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 20,
diff --git a/src/map/clif.h b/src/map/clif.h
index 70a7fdce8..0feeb22b5 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -220,7 +220,7 @@ uint16 clif_getport(void);
int clif_authok(struct map_session_data *);
int clif_authfail_fd(int fd,int type);
-int clif_charselectok(int);
+int clif_charselectok(int id, uint8 ok);
int clif_dropflooritem(struct flooritem_data *);
int clif_clearflooritem(struct flooritem_data *,int);
@@ -326,7 +326,7 @@ int clif_skillup(struct map_session_data *sd,int skill_num);
int clif_addskill(struct map_session_data *sd, int skill);
int clif_deleteskill(struct map_session_data *sd, int skill);
-int clif_skillcasting(struct block_list* bl,int src_id,int dst_id,int dst_x,int dst_y,int skill_num,int pl,int casttime);
+void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, int skill_num, int property, int casttime);
int clif_skillcastcancel(struct block_list* bl);
int clif_skill_fail(struct map_session_data *sd,int skill_id,int type,int btype);
int clif_skill_cooldown(struct map_session_data *sd, int skillid, unsigned int tick);
@@ -404,7 +404,7 @@ int clif_movetoattack(struct map_session_data *sd,struct block_list *bl);
int clif_party_created(struct map_session_data *sd,int result);
int clif_party_member_info(struct party_data *p, struct map_session_data *sd);
int clif_party_info(struct party_data *p, struct map_session_data *sd);
-int clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd);
+void clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd);
void clif_party_inviteack(struct map_session_data* sd, const char* nick, int flag);
int clif_party_option(struct party_data *p,struct map_session_data *sd,int flag);
int clif_party_withdraw(struct party_data* p, struct map_session_data* sd, int account_id, const char* name, int flag);
@@ -515,7 +515,7 @@ void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, un
int clif_party_xy_remove(struct map_session_data *sd); //Fix for minimap [Kevin]
void clif_gospel_info(struct map_session_data *sd, int type);
-void clif_parse_ReqFeel(int fd, struct map_session_data *sd, int skilllv);
+void clif_feel_req(int fd, struct map_session_data *sd, int skilllv);
void clif_starskill(struct map_session_data* sd, const char* mapname, int monster_id, unsigned char star, unsigned char result);
void clif_feel_info(struct map_session_data *sd, unsigned char feel_level, unsigned char type);
void clif_hate_info(struct map_session_data *sd, unsigned char hate_level,int class_, unsigned char type);
diff --git a/src/map/guild.c b/src/map/guild.c
index c80b124ef..0b77aa9a1 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -61,8 +61,8 @@ struct{
}need[6];
} guild_skill_tree[MAX_GUILDSKILL];
-int guild_payexp_timer(int tid, unsigned int tick, int id, intptr data);
-static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr data);
+int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data);
+static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
/*==========================================
* Retrieves and validates the sd pointer for this guild member [Skotlex]
@@ -308,7 +308,7 @@ int guild_payexp_timer_sub(DBKey dataid, void *data, va_list ap)
return 0;
}
-int guild_payexp_timer(int tid, unsigned int tick, int id, intptr data)
+int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data)
{
guild_expcache_db->clear(guild_expcache_db,guild_payexp_timer_sub);
return 0;
@@ -336,7 +336,7 @@ int guild_send_xy_timer_sub(DBKey key,void *data,va_list ap)
}
//Code from party_send_xy_timer [Skotlex]
-static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr data)
+static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
guild_db->foreach(guild_db,guild_send_xy_timer_sub,tick);
return 0;
@@ -1840,7 +1840,7 @@ int guild_castlealldataload(int len,struct guild_castle *gc)
}
// update mapserver castle data with new info
- memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - ((uintptr)&c->guild_id - (uintptr)c));
+ memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - ((uintptr_t)&c->guild_id - (uintptr_t)c));
if( c->guild_id )
{
diff --git a/src/map/homunculus.c b/src/map/homunculus.c
index 7bfb6081d..50b7c2c7a 100644
--- a/src/map/homunculus.c
+++ b/src/map/homunculus.c
@@ -45,7 +45,7 @@
struct s_homunculus_db homunculus_db[MAX_HOMUNCULUS_CLASS]; //[orn]
struct skill_tree_entry hskill_tree[MAX_HOMUNCULUS_CLASS][MAX_SKILL_TREE];
-static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr data);
+static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr_t data);
static unsigned int hexptbl[MAX_LEVEL];
@@ -196,7 +196,7 @@ void merc_hom_skillup(struct homun_data *hd,int skillnum)
i = skillnum - HM_SKILLBASE;
if(hd->homunculus.skillpts > 0 &&
hd->homunculus.hskill[i].id &&
- hd->homunculus.hskill[i].flag == 0 && //Don't allow raising while you have granted skills. [Skotlex]
+ hd->homunculus.hskill[i].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
hd->homunculus.hskill[i].lv < merc_skill_tree_get_max(skillnum, hd->homunculus.class_)
)
{
@@ -480,7 +480,7 @@ int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
return 0;
}
-static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr data)
+static int merc_hom_hungry(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
struct homun_data *hd;
diff --git a/src/map/instance.c b/src/map/instance.c
index e9ff2b409..d533a0188 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -28,6 +28,24 @@
int instance_start = 0; // To keep the last index + 1 of normal map inserted in the map[ARRAY]
struct s_instance instance[MAX_INSTANCE];
+
+/// Checks whether given instance id is valid or not.
+static bool instance_is_valid(int instance_id)
+{
+ if( instance_id < 1 || instance_id >= ARRAYLENGTH(instance) )
+ {// out of range
+ return false;
+ }
+
+ if( instance[instance_id].state == INSTANCE_FREE )
+ {// uninitialized/freed instance slot
+ return false;
+ }
+
+ return true;
+}
+
+
/*--------------------------------------
* name : instance name
* Return value could be
@@ -62,13 +80,13 @@ int instance_create(int party_id, const char *name)
instance[i].idle_timer = INVALID_TIMER;
instance[i].idle_timeout = instance[i].idle_timeoutval = 0;
instance[i].progress_timer = INVALID_TIMER;
- instance[i].progress_timeout = instance[i].progress_timeoutval = 0;
+ instance[i].progress_timeout = 0;
instance[i].users = 0;
instance[i].party_id = party_id;
instance[i].ivar = NULL;
instance[i].svar = NULL;
- memcpy( instance[i].name, name, sizeof(instance[i].name) );
+ safestrncpy( instance[i].name, name, sizeof(instance[i].name) );
memset( instance[i].map, 0x00, sizeof(instance[i].map) );
p->instance_id = i;
@@ -88,7 +106,7 @@ int instance_add_map(const char *name, int instance_id, bool usebasename)
if( m < 0 )
return -1; // source map not found
- if( instance[instance_id].state == INSTANCE_FREE )
+ if( !instance_is_valid(instance_id) )
{
ShowError("instance_add_map: trying to attach '%s' map to non-existing instance %d.\n", name, instance_id);
return -1;
@@ -158,6 +176,12 @@ int instance_add_map(const char *name, int instance_id, bool usebasename)
int instance_map2imap(int m, int instance_id)
{
int i;
+
+ if( !instance_is_valid(instance_id) )
+ {
+ return -1;
+ }
+
for( i = 0; i < instance[instance_id].num_map; i++ )
{
if( instance[instance_id].map[i] && map[instance[instance_id].map[i]].instance_src_map == m )
@@ -173,7 +197,6 @@ int instance_map2imap(int m, int instance_id)
*--------------------------------------*/
int instance_mapid2imapid(int m, int instance_id)
{
- int i, max;
if( map[m].flag.src4instance == 0 )
return m; // not instances found for this map
else if( map[m].instance_id )
@@ -182,16 +205,10 @@ int instance_mapid2imapid(int m, int instance_id)
return -1;
}
- if( instance_id <= 0 )
+ if( !instance_is_valid(instance_id) )
return -1;
- max = instance[instance_id].num_map;
-
- for( i = 0; i < max; i++ )
- if( map[instance[instance_id].map[i]].instance_src_map == m )
- return instance[instance_id].map[i];
-
- return -1;
+ return instance_map2imap(m, instance_id);
}
/*--------------------------------------
@@ -214,13 +231,13 @@ void instance_init(int instance_id)
{
int i;
- if( !instance_id )
+ if( !instance_is_valid(instance_id) )
return; // nothing to do
for( i = 0; i < instance[instance_id].num_map; i++ )
map_foreachinmap(instance_map_npcsub, map[instance[instance_id].map[i]].instance_src_map, BL_NPC, instance[instance_id].map[i]);
- instance[instance_id].state = INSTANCE_BUSSY;
+ instance[instance_id].state = INSTANCE_BUSY;
ShowInfo("[Instance] Initialized %s.\n", instance[instance_id].name);
}
@@ -294,7 +311,7 @@ void instance_destroy_freesvar(void *key, void *data, va_list args)
/*--------------------------------------
* Timer to destroy instance by process or idle
*--------------------------------------*/
-int instance_destroy_timer(int tid, unsigned int tick, int id, intptr data)
+int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
instance_destroy(id);
return 0;
@@ -309,7 +326,7 @@ void instance_destroy(int instance_id)
struct party_data *p;
time_t now = time(NULL);
- if( !instance_id || instance[instance_id].state == INSTANCE_FREE )
+ if( !instance_is_valid(instance_id) )
return; // nothing to do
if( instance[instance_id].progress_timeout && instance[instance_id].progress_timeout <= now )
@@ -361,7 +378,7 @@ void instance_check_idle(int instance_id)
bool idle = true;
time_t now = time(NULL);
- if( !instance_id || instance[instance_id].idle_timeoutval == 0 )
+ if( !instance_is_valid(instance_id) || instance[instance_id].idle_timeoutval == 0 )
return;
if( instance[instance_id].users )
@@ -389,7 +406,7 @@ void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsign
{
time_t now = time(0);
- if( !instance_id )
+ if( !instance_is_valid(instance_id) )
return;
if( instance[instance_id].progress_timer != INVALID_TIMER )
@@ -399,13 +416,11 @@ void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsign
if( progress_timeout )
{
- instance[instance_id].progress_timeoutval = progress_timeout;
instance[instance_id].progress_timeout = now + progress_timeout;
instance[instance_id].progress_timer = add_timer( gettick() + progress_timeout * 1000, instance_destroy_timer, instance_id, 0);
}
else
{
- instance[instance_id].progress_timeoutval = 0;
instance[instance_id].progress_timeout = 0;
instance[instance_id].progress_timer = INVALID_TIMER;
}
@@ -444,6 +459,14 @@ void instance_check_kick(struct map_session_data *sd)
}
}
+void do_final_instance(void)
+{
+ int i;
+
+ for( i = 1; i < MAX_INSTANCE; i++ )
+ instance_destroy(i);
+}
+
void do_init_instance(void)
{
memset(instance, 0x00, sizeof(instance));
diff --git a/src/map/instance.h b/src/map/instance.h
index c663503f5..e2b0354f9 100644
--- a/src/map/instance.h
+++ b/src/map/instance.h
@@ -7,10 +7,12 @@
#define MAX_MAP_PER_INSTANCE 10
#define MAX_INSTANCE 500
-typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSSY } instance_state;
+#define INSTANCE_NAME_LENGTH (60+1)
+
+typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSY } instance_state;
struct s_instance {
- char name[61]; // Instance Name - required for clif functions.
+ char name[INSTANCE_NAME_LENGTH]; // Instance Name - required for clif functions.
instance_state state;
short instance_id;
int party_id;
@@ -22,7 +24,7 @@ struct s_instance {
struct linkdb_node *ivar, *svar; // Instance Variable for scripts
int progress_timer;
- time_t progress_timeout, progress_timeoutval;
+ time_t progress_timeout;
int idle_timer;
time_t idle_timeout, idle_timeoutval;
@@ -43,6 +45,7 @@ void instance_check_idle(int instance_id);
void instance_check_kick(struct map_session_data *sd);
void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout);
-void do_init_instance();
+void do_final_instance(void);
+void do_init_instance(void);
#endif
diff --git a/src/map/map.c b/src/map/map.c
index c086b73c0..bc9465781 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -240,7 +240,7 @@ int map_freeblock_unlock (void)
// この関数は、do_timer() のトップレベルから呼ばれるので、
// block_free_lock を直接いじっても支障無いはず。
-int map_freeblock_timer(int tid, unsigned int tick, int id, intptr data)
+int map_freeblock_timer(int tid, unsigned int tick, int id, intptr_t data)
{
if (block_free_lock > 0) {
ShowError("map_freeblock_timer: block_free_lock(%d) is invalid.\n", block_free_lock);
@@ -1217,7 +1217,7 @@ int map_get_new_object_id(void)
* 後者は、map_clearflooritem(id)へ
* map.h?で#defineしてある
*------------------------------------------*/
-int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr data)
+int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct flooritem_data* fitem = (struct flooritem_data*)idb_get(id_db, id);
if( fitem==NULL || fitem->bl.type!=BL_ITEM || (!data && fitem->cleartimer != tid) )
@@ -2146,7 +2146,7 @@ int map_removemobs_sub(struct block_list *bl, va_list ap)
return 1;
}
-int map_removemobs_timer(int tid, unsigned int tick, int id, intptr data)
+int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data)
{
int count;
const int m = id;
@@ -2727,7 +2727,7 @@ int map_readfromcache(struct map_data *m, char *buffer, char *decode_buffer)
}
// TO-DO: Maybe handle the scenario, if the decoded buffer isn't the same size as expected? [Shinryo]
- uncompress(decode_buffer, &size, p+sizeof(struct map_cache_map_info), info->len);
+ decode_zip(decode_buffer, &size, p+sizeof(struct map_cache_map_info), info->len);
CREATE(m->cell, struct mapcell, size);
@@ -3436,9 +3436,6 @@ void do_final(void)
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
map_quit(sd);
mapit_free(iter);
-
- for( i = 0; i < MAX_INSTANCE; i++ )
- instance_destroy(i);
id_db->foreach(id_db,cleanup_db_sub);
chrif_char_reset_offline();
@@ -3449,6 +3446,7 @@ void do_final(void)
do_final_chrif();
do_final_npc();
do_final_script();
+ do_final_instance();
do_final_itemdb();
do_final_storage();
do_final_guild();
@@ -3491,7 +3489,7 @@ void do_final(void)
#ifndef TXT_ONLY
map_sql_close();
#endif /* not TXT_ONLY */
- ShowStatus("Successfully terminated.\n");
+ ShowStatus("Finished.\n");
}
static int map_abort_sub(struct map_session_data* sd, va_list ap)
@@ -3573,6 +3571,27 @@ void set_server_type(void)
SERVER_TYPE = ATHENA_SERVER_MAP;
}
+
+/// Called when a terminate signal is received.
+void do_shutdown(void)
+{
+ if( runflag != MAPSERVER_ST_SHUTDOWN )
+ {
+ runflag = MAPSERVER_ST_SHUTDOWN;
+ ShowStatus("Shutting down...\n");
+ {
+ struct map_session_data* sd;
+ struct s_mapiterator* iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+ clif_GM_kick(NULL, sd);
+ mapit_free(iter);
+ flush_fifos();
+ }
+ chrif_check_shutdown();
+ }
+}
+
+
int do_init(int argc, char *argv[])
{
int i;
@@ -3710,6 +3729,12 @@ int do_init(int argc, char *argv[])
ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n");
ShowStatus("Server is '"CL_GREEN"ready"CL_RESET"' and listening on port '"CL_WHITE"%d"CL_RESET"'.\n\n", map_port);
+
+ if( runflag != CORE_ST_STOP )
+ {
+ shutdown_callback = do_shutdown;
+ runflag = MAPSERVER_ST_RUNNING;
+ }
return 0;
}
diff --git a/src/map/map.h b/src/map/map.h
index d572cec4c..36496280e 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -4,9 +4,8 @@
#ifndef _MAP_H_
#define _MAP_H_
-#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
-#endif
+#include "../common/core.h" // CORE_ST_LAST
#include "../common/mmo.h"
#include "../common/mapindex.h"
#include "../common/db.h"
@@ -16,6 +15,13 @@
struct npc_data;
struct item_data;
+enum E_MAPSERVER_ST
+{
+ MAPSERVER_ST_RUNNING = CORE_ST_LAST,
+ MAPSERVER_ST_SHUTDOWN,
+ MAPSERVER_ST_LAST
+};
+
//Uncomment to enable the Cell Stack Limit mod.
//It's only config is the battle_config cell_stack_limit.
//Only chars affected are those defined in BL_CHAR (mobs and players currently)
@@ -615,8 +621,8 @@ int map_quit(struct map_session_data *);
bool map_addnpc(int,struct npc_data *);
// 床アイテム関連
-int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr data);
-int map_removemobs_timer(int tid, unsigned int tick, int id, intptr data);
+int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data);
+int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data);
#define map_clearflooritem(id) map_clearflooritem_timer(0,0,id,1)
int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,int first_charid,int second_charid,int third_charid,int flags);
@@ -739,4 +745,6 @@ extern char mob_db2_db[32];
#endif /* not TXT_ONLY */
+void do_shutdown(void);
+
#endif /* _MAP_H_ */
diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c
index f80be56a2..455da0f49 100644
--- a/src/map/mapreg_sql.c
+++ b/src/map/mapreg_sql.c
@@ -184,7 +184,7 @@ static void script_save_mapreg(void)
mapreg_dirty = false;
}
-static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr data)
+static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr_t data)
{
if( mapreg_dirty )
script_save_mapreg();
diff --git a/src/map/mapreg_txt.c b/src/map/mapreg_txt.c
index 555b773ee..95be201e2 100644
--- a/src/map/mapreg_txt.c
+++ b/src/map/mapreg_txt.c
@@ -151,7 +151,7 @@ static void script_save_mapreg(void)
mapreg_dirty = false;
}
-static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr data)
+static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr_t data)
{
if( mapreg_dirty )
script_save_mapreg();
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index 8300628d5..f6fa6bdaa 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -215,7 +215,7 @@ int mercenary_save(struct mercenary_data *md)
return 1;
}
-static int merc_contract_end(int tid, unsigned int tick, int id, intptr data)
+static int merc_contract_end(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
struct mercenary_data *md;
diff --git a/src/map/mob.c b/src/map/mob.c
index 4c8fa685a..5fb440b4f 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -81,7 +81,7 @@ const int mob_splendide[5] = { 1991, 1992, 1993, 1994, 1995 };
* Local prototype declaration (only required thing)
*------------------------------------------*/
static int mob_makedummymobdb(int);
-static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr data);
+static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data);
int mob_skillid2skillidx(int class_,int skillid);
/*==========================================
@@ -507,7 +507,7 @@ int mob_once_spawn_area(struct map_session_data* sd,int m,int x0,int y0,int x1,i
/*==========================================
* Set a Guardian's guild data [Skotlex]
*------------------------------------------*/
-static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr data)
+static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data)
{ //Needed because the guild_data may not be available at guardian spawn time.
struct block_list* bl = map_id2bl(id);
struct mob_data* md;
@@ -766,7 +766,7 @@ int mob_linksearch(struct block_list *bl,va_list ap)
/*==========================================
* mob spawn with delay (timer function)
*------------------------------------------*/
-int mob_delayspawn(int tid, unsigned int tick, int id, intptr data)
+int mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list* bl = map_id2bl(id);
struct mob_data* md = BL_CAST(BL_MOB, bl);
@@ -1636,7 +1636,7 @@ static int mob_ai_sub_lazy(struct mob_data *md, va_list args)
/*==========================================
* Negligent processing for mob outside PC field of view (interval timer function)
*------------------------------------------*/
-static int mob_ai_lazy(int tid, unsigned int tick, int id, intptr data)
+static int mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data)
{
map_foreachmob(mob_ai_sub_lazy,tick);
return 0;
@@ -1645,7 +1645,7 @@ static int mob_ai_lazy(int tid, unsigned int tick, int id, intptr data)
/*==========================================
* Serious processing for mob in PC field of view (interval timer function)
*------------------------------------------*/
-static int mob_ai_hard(int tid, unsigned int tick, int id, intptr data)
+static int mob_ai_hard(int tid, unsigned int tick, int id, intptr_t data)
{
if (battle_config.mob_ai&0x20)
@@ -1684,7 +1684,7 @@ static struct item_drop* mob_setlootitem(struct item* item)
/*==========================================
* item drop with delay (timer function)
*------------------------------------------*/
-static int mob_delay_item_drop(int tid, unsigned int tick, int id, intptr data)
+static int mob_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data)
{
struct item_drop_list *list;
struct item_drop *ditem, *ditem_prev;
@@ -1744,7 +1744,7 @@ static void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, str
dlist->item = ditem;
}
-int mob_timer_delete(int tid, unsigned int tick, int id, intptr data)
+int mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list* bl = map_id2bl(id);
struct mob_data* md = BL_CAST(BL_MOB, bl);
@@ -1791,7 +1791,7 @@ int mob_deleteslave(struct mob_data *md)
return 0;
}
// Mob respawning through KAIZEL or NPC_REBIRTH [Skotlex]
-int mob_respawn(int tid, unsigned int tick, int id, intptr data)
+int mob_respawn(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list *bl = map_id2bl(id);
@@ -2296,7 +2296,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000, homkillonly);
}
if (dlist->item) //There are drop items.
- add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr)dlist);
+ add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr_t)dlist);
else //No drops
ers_free(item_drop_list_ers, dlist);
} else if (md->lootitem && md->lootitem_count) { //Loot MUST drop!
@@ -2310,7 +2310,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
dlist->item = NULL;
for(i = 0; i < md->lootitem_count; i++)
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitem[i]), 1, 10000, homkillonly);
- add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr)dlist);
+ add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr_t)dlist);
}
if(mvp_sd && md->db->mexp > 0 && !md->special_state.ai)
@@ -3407,7 +3407,7 @@ static unsigned int mob_drop_adjust(int baserate, int rate_adjust, unsigned shor
*------------------------------------------*/
static bool mob_parse_dbrow(char** str)
{
- struct mob_db *db;
+ struct mob_db *db, entry;
struct status_data *status;
int class_, i, k;
double exp, maxhp;
@@ -3416,29 +3416,28 @@ static bool mob_parse_dbrow(char** str)
class_ = atoi(str[0]);
if (class_ <= 1000 || class_ > MAX_MOB_DB) {
- ShowWarning("Mob with ID: %d not loaded. ID must be in range [%d-%d]\n", class_, 1000, MAX_MOB_DB);
+ ShowError("mob_parse_dbrow: Invalid monster ID %d, must be in range %d-%d.\n", class_, 1000, MAX_MOB_DB);
return false;
}
if (pcdb_checkid(class_)) {
- ShowWarning("Mob with ID: %d not loaded. That ID is reserved for player classes.\n", class_);
+ ShowError("mob_parse_dbrow: Invalid monster ID %d, reserved for player classes.\n", class_);
return false;
}
if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END) {
- ShowWarning("Mob with ID: %d not loaded. 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);
+ ShowError("mob_parse_dbrow: 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 (mob_db_data[class_] == NULL)
- mob_db_data[class_] = (struct mob_db*)aCalloc(1, sizeof (struct mob_db));
+ memset(&entry, 0, sizeof(entry));
- db = mob_db_data[class_];
+ db = &entry;
status = &db->status;
db->vd.class_ = class_;
- strncpy(db->sprite, str[1], NAME_LENGTH);
- strncpy(db->jname, str[2], NAME_LENGTH);
- strncpy(db->name, str[3], NAME_LENGTH);
+ safestrncpy(db->sprite, str[1], sizeof(db->sprite));
+ safestrncpy(db->jname, str[2], sizeof(db->jname));
+ safestrncpy(db->name, str[3], sizeof(db->name));
db->lv = atoi(str[4]);
db->lv = cap_value(db->lv, 1, USHRT_MAX);
status->max_hp = atoi(str[5]);
@@ -3489,12 +3488,12 @@ static bool mob_parse_dbrow(char** str)
status->def_ele = i%10;
status->ele_lv = i/20;
if (status->def_ele >= ELE_MAX) {
- ShowWarning("Mob with ID: %d has invalid element type %d (max element is %d)\n", class_, status->def_ele, ELE_MAX-1);
- status->def_ele = ELE_NEUTRAL;
+ ShowError("mob_parse_dbrow: Invalid element type %d for monster ID %d (max=%d).\n", status->def_ele, class_, ELE_MAX-1);
+ return false;
}
if (status->ele_lv < 1 || status->ele_lv > 4) {
- ShowWarning("Mob with ID: %d has invalid element level %d (max is 4)\n", class_, status->ele_lv);
- status->ele_lv = 1;
+ ShowError("mob_parse_dbrow: Invalid element level %d for monster ID %d, must be in range 1-4.\n", status->ele_lv, class_);
+ return false;
}
status->mode = (int)strtol(str[25], NULL, 0);
@@ -3512,7 +3511,8 @@ static bool mob_parse_dbrow(char** str)
status->dmotion = atoi(str[29]);
if(battle_config.monster_damage_delay_rate != 100)
status->dmotion = status->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 = db->lv;
memcpy(&data.status, status, sizeof(struct status_data));
@@ -3632,7 +3632,12 @@ static bool mob_parse_dbrow(char** str)
id->mob[k].id = class_;
}
}
-
+
+ // Finally insert monster's data into the database.
+ if (mob_db_data[class_] == NULL)
+ mob_db_data[class_] = (struct mob_db*)aCalloc(1, sizeof(struct mob_db));
+
+ memcpy(mob_db_data[class_], db, sizeof(struct mob_db));
return true;
}
diff --git a/src/map/mob.h b/src/map/mob.h
index 605439f12..9e86b8d63 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -239,7 +239,7 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist);
int mob_unlocktarget(struct mob_data *md, unsigned int tick);
struct mob_data* mob_spawn_dataset(struct spawn_data *data);
int mob_spawn(struct mob_data *md);
-int mob_delayspawn(int tid, unsigned int tick, int id, intptr data);
+int mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data);
int mob_setdelayspawn(struct mob_data *md);
int mob_parse_dataset(struct spawn_data *data);
void mob_log_damage(struct mob_data *md, struct block_list *src, int damage);
@@ -256,7 +256,7 @@ void mob_clear_spawninfo();
int do_init_mob(void);
int do_final_mob(void);
-int mob_timer_delete(int tid, unsigned int tick, int id, intptr data);
+int mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data);
int mob_deleteslave(struct mob_data *md);
int mob_random_class (int *value, size_t count);
diff --git a/src/map/npc.c b/src/map/npc.c
index d070b6886..dd3a671b0 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -356,7 +356,7 @@ bool npc_event_isspecial(const char* eventname)
/*==========================================
* 時計イベント実行
*------------------------------------------*/
-int npc_event_do_clock(int tid, unsigned int tick, int id, intptr data)
+int npc_event_do_clock(int tid, unsigned int tick, int id, intptr_t data)
{
static struct tm ev_tm_b; // tracks previous execution time
time_t timer;
@@ -455,7 +455,7 @@ struct timer_event_data {
/*==========================================
* triger 'OnTimerXXXX' events
*------------------------------------------*/
-int npc_timerevent(int tid, unsigned int tick, int id, intptr data)
+int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data)
{
int next;
int old_rid, old_timer;
@@ -498,9 +498,9 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr data)
next = nd->u.scr.timer_event[ ted->next ].timer - nd->u.scr.timer_event[ ted->next - 1 ].timer;
ted->time += next;
if( sd )
- sd->npc_timer_id = add_timer(tick+next,npc_timerevent,id,(intptr)ted);
+ sd->npc_timer_id = add_timer(tick+next,npc_timerevent,id,(intptr_t)ted);
else
- nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,(intptr)ted);
+ nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,(intptr_t)ted);
}
else
{
@@ -570,13 +570,13 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
if( sd )
{
ted->rid = sd->bl.id; // Attach only the player if attachplayerrid was used.
- sd->npc_timer_id = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr)ted);
+ sd->npc_timer_id = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr_t)ted);
}
else
{
ted->rid = 0;
nd->u.scr.timertick = tick; // Set when timer is started
- nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr)ted);
+ nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr_t)ted);
}
return 0;
@@ -1164,8 +1164,8 @@ static int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* i
// save list of bought items
for( i = 0; i < n; i++ )
{
- script_setarray_pc(sd, "@bought_nameid", i, (void*)(intptr)item_list[i*2+1], &key_nameid);
- script_setarray_pc(sd, "@bought_quantity", i, (void*)(intptr)item_list[i*2], &key_amount);
+ script_setarray_pc(sd, "@bought_nameid", i, (void*)(intptr_t)item_list[i*2+1], &key_nameid);
+ script_setarray_pc(sd, "@bought_quantity", i, (void*)(intptr_t)item_list[i*2], &key_amount);
}
// invoke event
@@ -1369,8 +1369,9 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
// custom merchant shop exp bonus
if( battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_DISCOUNT)) > 0 )
{
- if( sd->status.skill[MC_DISCOUNT].flag != 0 )
- skill = sd->status.skill[MC_DISCOUNT].flag - 2;
+ if( sd->status.skill[MC_DISCOUNT].flag >= SKILL_FLAG_REPLACED_LV_0 )
+ skill = sd->status.skill[MC_DISCOUNT].flag - SKILL_FLAG_REPLACED_LV_0;
+
if( skill > 0 )
{
z = z * (double)skill * (double)battle_config.shop_exp/10000.;
@@ -1401,8 +1402,8 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short*
{
idx = item_list[i*2]-2;
- script_setarray_pc(sd, "@sold_nameid", i, (void*)(intptr)sd->status.inventory[idx].nameid, &key_nameid);
- script_setarray_pc(sd, "@sold_quantity", i, (void*)(intptr)item_list[i*2+1], &key_amount);
+ script_setarray_pc(sd, "@sold_nameid", i, (void*)(intptr_t)sd->status.inventory[idx].nameid, &key_nameid);
+ script_setarray_pc(sd, "@sold_quantity", i, (void*)(intptr_t)item_list[i*2+1], &key_amount);
}
// invoke event
@@ -1505,8 +1506,9 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list)
// custom merchant shop exp bonus
if( battle_config.shop_exp > 0 && z > 0 && ( skill = pc_checkskill(sd,MC_OVERCHARGE) ) > 0)
{
- if( sd->status.skill[MC_OVERCHARGE].flag != 0 )
- skill = sd->status.skill[MC_OVERCHARGE].flag - 2;
+ if( sd->status.skill[MC_OVERCHARGE].flag >= SKILL_FLAG_REPLACED_LV_0 )
+ skill = sd->status.skill[MC_OVERCHARGE].flag - SKILL_FLAG_REPLACED_LV_0;
+
if( skill > 0 )
{
z = z * (double)skill * (double)battle_config.shop_exp/10000.;
@@ -2734,13 +2736,13 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
// check monster ID if exists!
if( mobdb_checkid(class_) == 0 )
{
- ShowError("npc_parse_mob: Unknown mob ID : %s %s (file '%s', line '%d').\n", w3, w4, filepath, strline(buffer,start-buffer));
+ ShowError("npc_parse_mob: Unknown mob ID %d (file '%s', line '%d').\n", class_, filepath, strline(buffer,start-buffer));
return strchr(start,'\n');// skip and continue
}
if( num < 1 || num > 1000 )
{
- ShowError("npc_parse_mob: Invalid number of monsters (must be inside the range [1,1000]) : %s %s (file '%s', line '%d').\n", w3, w4, filepath, strline(buffer,start-buffer));
+ ShowError("npc_parse_mob: Invalid number of monsters %d, must be inside the range [1,1000] (file '%s', line '%d').\n", num, filepath, strline(buffer,start-buffer));
return strchr(start,'\n');// skip and continue
}
@@ -2786,7 +2788,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
}
if(mob.delay1>0xfffffff || mob.delay2>0xfffffff) {
- ShowError("npc_parse_mob: wrong monsters spawn delays : %s %s (file '%s', line '%d').\n", w3, w4, filepath, strline(buffer,start-buffer));
+ ShowError("npc_parse_mob: Invalid spawn delays %u %u (file '%s', line '%d').\n", mob.delay1, mob.delay2, filepath, strline(buffer,start-buffer));
return strchr(start,'\n');// skip and continue
}
@@ -2801,7 +2803,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c
//Verify dataset.
if( !mob_parse_dataset(&mob) )
{
- ShowError("npc_parse_mob: Invalid dataset : %s %s (file '%s', line '%d').\n", w3, w4, filepath, strline(buffer,start-buffer));
+ ShowError("npc_parse_mob: Invalid dataset for monster ID %d (file '%s', line '%d').\n", class_, filepath, strline(buffer,start-buffer));
return strchr(start,'\n');// skip and continue
}
diff --git a/src/map/npc.h b/src/map/npc.h
index 6e7c7cbeb..29e3d79cb 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -77,7 +77,7 @@ struct npc_data {
#define MAX_NPC_CLASS 1000
//Checks if a given id is a valid npc id. [Skotlex]
//Since new npcs are added all the time, the max valid value is the one before the first mob (Scorpion = 1001)
-#define npcdb_checkid(id) ((id >= 46 && id <= 125) || id == 139 || (id >= 400 && id <= MAX_NPC_CLASS) || id == INVISIBLE_CLASS)
+#define npcdb_checkid(id) ( ( (id) >= 46 && (id) <= 125) || (id) == 139 || ( (id) > 400 && (id) < MAX_NPC_CLASS ) || (id) == INVISIBLE_CLASS )
#ifdef PCRE_SUPPORT
void npc_chat_finalize(struct npc_data* nd);
diff --git a/src/map/party.c b/src/map/party.c
index 47dba49e9..88f53bcb0 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -32,7 +32,7 @@ static DBMap* party_db; // int party_id -> struct party_data*
static DBMap* party_booking_db; // Party Booking [Spiria]
static unsigned long party_booking_nextid = 1;
-int party_send_xy_timer(int tid, unsigned int tick, int id, intptr data);
+int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
/*==========================================
* Fills the given party_member structure according to the sd provided.
@@ -369,11 +369,19 @@ int party_invite(struct map_session_data *sd,struct map_session_data *tsd)
return 1;
}
-void party_reply_invite(struct map_session_data *sd,int account_id,int flag)
+void party_reply_invite(struct map_session_data *sd,int party_id,int flag)
{
- struct map_session_data *tsd= map_id2sd(account_id);
+ struct map_session_data* tsd;
struct party_member member;
+ if( sd->party_invite != party_id )
+ {// forged
+ sd->party_invite = 0;
+ sd->party_invite_account = 0;
+ return;
+ }
+ tsd = map_id2sd(sd->party_invite_account);
+
if( flag == 1 && !sd->party_creating && !sd->party_joining )
{// accepted and allowed
sd->party_joining = true;
@@ -832,7 +840,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, int skillid, in
return 0;
}
-int party_send_xy_timer(int tid, unsigned int tick, int id, intptr data)
+int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct party_data* p;
diff --git a/src/map/party.h b/src/map/party.h
index 31e46f5ec..1c59197b3 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -62,7 +62,7 @@ int party_member_added(int party_id,int account_id,int char_id,int flag);
int party_leave(struct map_session_data *sd);
int party_removemember(struct map_session_data *sd,int account_id,char *name);
int party_member_withdraw(int party_id,int account_id,int char_id);
-void party_reply_invite(struct map_session_data *sd,int account_id,int flag);
+void party_reply_invite(struct map_session_data *sd,int party_id,int flag);
int party_recv_noinfo(int party_id);
int party_recv_info(struct party *sp);
int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv);
diff --git a/src/map/pc.c b/src/map/pc.c
index 6d4002599..a9d798ade 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -85,7 +85,7 @@ int pc_isGM(struct map_session_data* sd)
return sd->gmlevel;
}
-static int pc_invincible_timer(int tid, unsigned int tick, int id, intptr data)
+static int pc_invincible_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
@@ -123,7 +123,7 @@ void pc_delinvincibletimer(struct map_session_data* sd)
}
}
-static int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr data)
+static int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
int i;
@@ -295,7 +295,7 @@ int pc_setrestartvalue(struct map_session_data *sd,int type)
/*==========================================
Rental System
*------------------------------------------*/
-static int pc_inventory_rental_end(int tid, unsigned int tick, int id, intptr data)
+static int pc_inventory_rental_end(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd = map_id2sd(id);
if( sd == NULL )
@@ -695,7 +695,7 @@ bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd
return false;
}
- if( !(b_sd->status.class_ >= JOB_NOVICE && b_sd->status.class_ <= JOB_THIEF) )
+ if( !( ( b_sd->status.class_ >= JOB_NOVICE && b_sd->status.class_ <= JOB_THIEF ) || b_sd->status.class_ == JOB_SUPER_NOVICE ) )
return false;
return true;
@@ -1061,9 +1061,9 @@ int pc_reg_received(struct map_session_data *sd)
if (sd->cloneskill_id > 0) {
sd->status.skill[sd->cloneskill_id].id = sd->cloneskill_id;
sd->status.skill[sd->cloneskill_id].lv = pc_readglobalreg(sd,"CLONE_SKILL_LV");
- if (i < sd->status.skill[sd->cloneskill_id].lv)
+ if (sd->status.skill[sd->cloneskill_id].lv > i)
sd->status.skill[sd->cloneskill_id].lv = i;
- sd->status.skill[sd->cloneskill_id].flag = 13; //cloneskill flag
+ sd->status.skill[sd->cloneskill_id].flag = SKILL_FLAG_PLAGIARIZED;
}
}
@@ -1124,11 +1124,11 @@ static int pc_calc_skillpoint(struct map_session_data* sd)
if((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
!(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Do not count wedding/link skills. [Skotlex]
) {
- if(!sd->status.skill[i].flag)
+ if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT)
skill_point += skill;
- else if(sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13) {
- skill_point += (sd->status.skill[i].flag - 2);
- }
+ else
+ if(sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0)
+ skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
}
}
}
@@ -1157,16 +1157,16 @@ int pc_calc_skilltree(struct map_session_data *sd)
for( i = 0; i < MAX_SKILL; i++ )
{
- if( sd->status.skill[i].flag != 13 ) //Don't touch plagiarized skills
+ if( sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED ) //Don't touch plagiarized skills
sd->status.skill[i].id = 0; //First clear skills.
}
for( i = 0; i < MAX_SKILL; i++ )
{
- if( sd->status.skill[i].flag && sd->status.skill[i].flag != 13 )
+ if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED )
{ // Restore original level of skills after deleting earned skills.
- sd->status.skill[i].lv = (sd->status.skill[i].flag == 1)?0:sd->status.skill[i].flag-2;
- sd->status.skill[i].flag = 0;
+ sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
+ sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
}
if( sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && i >= DC_HUMMING && i<= DC_SERVICEFORYOU )
@@ -1177,7 +1177,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
continue;
sd->status.skill[i].id = i;
sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
- sd->status.skill[i].flag = 1; // Tag it as a non-savable, non-uppable, bonus skill
+ sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
}
else
{ //Link bard skills to dancer.
@@ -1185,7 +1185,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
continue;
sd->status.skill[i-8].id = i - 8;
sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
- sd->status.skill[i-8].flag = 1; // Tag it as a non-savable, non-uppable, bonus skill
+ sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
}
}
}
@@ -1216,10 +1216,11 @@ int pc_calc_skilltree(struct map_session_data *sd)
for(j = 0; j < MAX_PC_SKILL_REQUIRE; j++) {
if((k=skill_tree[c][i].need[j].id))
{
- if (!sd->status.skill[k].id || sd->status.skill[k].flag == 13)
+ if (sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED)
k = 0; //Not learned.
- else if (sd->status.skill[k].flag) //Real lerned level
- k = sd->status.skill[skill_tree[c][i].need[j].id].flag-2;
+ else
+ if (sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
+ k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
else
k = pc_checkskill(sd,k);
if (k < skill_tree[c][i].need[j].lv)
@@ -1249,7 +1250,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
if(inf2&INF2_SPIRIT_SKILL)
{ //Spirit skills cannot be learned, they will only show up on your tree when you get buffed.
sd->status.skill[id].lv = 1; // need to manually specify a skill level
- sd->status.skill[id].flag = 1; //So it is not saved, and tagged as a "bonus" skill.
+ sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill.
}
flag = 1; // skill list has changed, perform another pass
}
@@ -1273,10 +1274,12 @@ int pc_calc_skilltree(struct map_session_data *sd)
if( sd->status.skill[id].id == 0 )
{
sd->status.skill[id].id = id;
- sd->status.skill[id].flag = 1; // So it is not saved, and tagged as a "bonus" skill.
+ sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill.
}
else
- sd->status.skill[id].flag = sd->status.skill[id].lv+2;
+ {
+ sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Remember original level
+ }
sd->status.skill[id].lv = skill_tree_get_max(id, sd->status.class_);
}
@@ -1314,10 +1317,11 @@ static void pc_check_skilltree(struct map_session_data *sd, int skill)
{
if( (k = skill_tree[c][i].need[j].id) )
{
- if( !sd->status.skill[k].id || sd->status.skill[k].flag == 13 )
+ if( sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED )
k = 0; //Not learned.
- else if( sd->status.skill[k].flag ) //Real lerned level
- k = sd->status.skill[skill_tree[c][i].need[j].id].flag - 2;
+ else
+ if( sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level
+ k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0;
else
k = pc_checkskill(sd,k);
if( k < skill_tree[c][i].need[j].lv )
@@ -1352,13 +1356,15 @@ int pc_clean_skilltree(struct map_session_data *sd)
{
int i;
for (i = 0; i < MAX_SKILL; i++){
- if (sd->status.skill[i].flag == 13 || sd->status.skill[i].flag == 1)
+ if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED)
{
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
sd->status.skill[i].flag = 0;
- } else if (sd->status.skill[i].flag){
- sd->status.skill[i].lv = sd->status.skill[i].flag-2;
+ }
+ else
+ if (sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0){
+ sd->status.skill[i].lv = sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
sd->status.skill[i].flag = 0;
}
}
@@ -1716,14 +1722,14 @@ int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus)
script_run_autobonus(autobonus->other_script,sd->bl.id,sd->equip_index[j]);
}
- autobonus->active = add_timer(gettick()+autobonus->duration, pc_endautobonus, sd->bl.id, (intptr)autobonus);
+ autobonus->active = add_timer(gettick()+autobonus->duration, pc_endautobonus, sd->bl.id, (intptr_t)autobonus);
sd->state.autobonus |= autobonus->pos;
status_calc_pc(sd,0);
return 0;
}
-int pc_endautobonus(int tid, unsigned int tick, int id, intptr data)
+int pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd = map_id2sd(id);
struct s_autobonus *autobonus = (struct s_autobonus *)data;
@@ -2321,8 +2327,8 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
sd->right_weapon.hp_drain[RC_BOSS].value += val;
}
else if(sd->state.lr_flag == 1) {
- sd->right_weapon.hp_drain[RC_NONBOSS].value += val;
- sd->right_weapon.hp_drain[RC_BOSS].value += val;
+ sd->left_weapon.hp_drain[RC_NONBOSS].value += val;
+ sd->left_weapon.hp_drain[RC_BOSS].value += val;
}
break;
case SP_SP_DRAIN_VALUE:
@@ -3060,8 +3066,8 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag)
case 0: //Set skill data overwriting whatever was there before.
sd->status.skill[id].id = id;
sd->status.skill[id].lv = level;
- sd->status.skill[id].flag = 0;
- if( !level ) //Remove skill.
+ sd->status.skill[id].flag = SKILL_FLAG_PERMANENT;
+ if( level == 0 ) //Remove skill.
{
sd->status.skill[id].id = 0;
clif_deleteskill(sd,id);
@@ -3075,21 +3081,21 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag)
if( sd->status.skill[id].id == id ){
if( sd->status.skill[id].lv >= level )
return 0;
- if( !sd->status.skill[id].flag ) //Non-granted skill, store it's level.
- sd->status.skill[id].flag = sd->status.skill[id].lv + 2;
+ if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT ) //Non-granted skill, store it's level.
+ sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv;
} else {
sd->status.skill[id].id = id;
- sd->status.skill[id].flag = 1;
+ sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY;
}
sd->status.skill[id].lv = level;
break;
case 2: //Add skill bonus on top of what you had.
if( sd->status.skill[id].id == id ){
- if( !sd->status.skill[id].flag ) // Store previous level.
- sd->status.skill[id].flag = sd->status.skill[id].lv + 2;
+ if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
+ sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Store previous level.
} else {
sd->status.skill[id].id = id;
- sd->status.skill[id].flag = 1; //Set that this is a bonus skill.
+ sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill.
}
sd->status.skill[id].lv += level;
break;
@@ -4789,7 +4795,8 @@ const char* job_name(int class_)
case JOB_WEDDING:
case JOB_SUPER_NOVICE:
-
+ case JOB_GUNSLINGER:
+ case JOB_NINJA:
case JOB_XMAS:
return msg_txt(570 - JOB_WEDDING+class_);
@@ -4870,11 +4877,6 @@ const char* job_name(int class_)
return msg_txt(617);
case JOB_SOUL_LINKER:
return msg_txt(618);
-
- case JOB_GUNSLINGER:
- return msg_txt(619);
- case JOB_NINJA:
- return msg_txt(620);
case JOB_RUNE_KNIGHT:
case JOB_WARLOCK:
@@ -4958,7 +4960,7 @@ const char* job_name(int class_)
}
}
-int pc_follow_timer(int tid, unsigned int tick, int id, intptr data)
+int pc_follow_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
struct block_list *tbl;
@@ -5507,7 +5509,7 @@ int pc_skillup(struct map_session_data *sd,int skill_num)
if( sd->status.skill_point > 0 &&
sd->status.skill[skill_num].id &&
- sd->status.skill[skill_num].flag == 0 && //Don't allow raising while you have granted skills. [Skotlex]
+ sd->status.skill[skill_num].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex]
sd->status.skill[skill_num].lv < skill_tree_get_max(skill_num, sd->status.class_) )
{
sd->status.skill[skill_num].lv++;
@@ -5537,11 +5539,11 @@ int pc_allskillup(struct map_session_data *sd)
nullpo_ret(sd);
for(i=0;i<MAX_SKILL;i++){
- if (sd->status.skill[i].flag && sd->status.skill[i].flag != 13){
- sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2;
- sd->status.skill[i].flag=0;
- if (!sd->status.skill[i].lv)
- sd->status.skill[i].id=0;
+ if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) {
+ sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
+ sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
+ if (sd->status.skill[i].lv == 0)
+ sd->status.skill[i].id = 0;
}
}
@@ -5771,7 +5773,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
if( i == NV_BASIC && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE && (sd->class_&MAPID_UPPERMASK) != MAPID_BABY )
{ // Official server does not include Basic Skill to be resetted. [Jobbie]
sd->status.skill[i].lv = 9;
- sd->status.skill[i].flag = 0;
+ sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
continue;
}
@@ -5784,13 +5786,14 @@ int pc_resetskill(struct map_session_data* sd, int flag)
}
continue;
}
- if( !sd->status.skill[i].flag )
+ if( sd->status.skill[i].flag == SKILL_FLAG_PERMANENT )
skill_point += lv;
- else if( sd->status.skill[i].flag > 2 && sd->status.skill[i].flag != 13 )
- skill_point += (sd->status.skill[i].flag - 2);
+ else
+ if( sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0 )
+ skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0);
if( !(flag&2) )
- {
+ {// reset
sd->status.skill[i].lv = 0;
sd->status.skill[i].flag = 0;
}
@@ -5896,7 +5899,7 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype)
clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
}
-static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr data)
+static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd = map_id2sd(id);
if( sd != NULL )
@@ -6602,6 +6605,12 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
}
if(sd->cloneskill_id) {
+ if( sd->status.skill[sd->cloneskill_id].flag == SKILL_FLAG_PLAGIARIZED ) {
+ sd->status.skill[sd->cloneskill_id].id = 0;
+ sd->status.skill[sd->cloneskill_id].lv = 0;
+ sd->status.skill[sd->cloneskill_id].flag = 0;
+ clif_deleteskill(sd,sd->cloneskill_id);
+ }
sd->cloneskill_id = 0;
pc_setglobalreg(sd, "CLONE_SKILL", 0);
pc_setglobalreg(sd, "CLONE_SKILL_LV", 0);
@@ -7261,7 +7270,7 @@ int pc_setregistry_str(struct map_session_data *sd,const char *reg,const char *v
/*==========================================
* イベントタイマ??理
*------------------------------------------*/
-static int pc_eventtimer(int tid, unsigned int tick, int id, intptr data)
+static int pc_eventtimer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=map_id2sd(id);
char *p = (char *)data;
@@ -7295,7 +7304,7 @@ int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
if( i == MAX_EVENTTIMER )
return 0;
- sd->eventtimer[i] = add_timer(gettick()+tick, pc_eventtimer, sd->bl.id, (intptr)aStrdup(name));
+ sd->eventtimer[i] = add_timer(gettick()+tick, pc_eventtimer, sd->bl.id, (intptr_t)aStrdup(name));
sd->eventcount++;
return 1;
@@ -7761,7 +7770,7 @@ int pc_calc_pvprank(struct map_session_data *sd)
/*==========================================
* PVP順位計算(timer)
*------------------------------------------*/
-int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr data)
+int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=NULL;
@@ -7960,7 +7969,7 @@ int pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y)
/*==========================================
* 自動セ?ブ (timer??)
*------------------------------------------*/
-int pc_autosave(int tid, unsigned int tick, int id, intptr data)
+int pc_autosave(int tid, unsigned int tick, int id, intptr_t data)
{
int interval;
struct s_mapiterator* iter;
@@ -8014,7 +8023,7 @@ static int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap)
* timer to do the day [Yor]
* data: 0 = called by timer, 1 = gmcommand/script
*------------------------------------------------*/
-int map_day_timer(int tid, unsigned int tick, int id, intptr data)
+int map_day_timer(int tid, unsigned int tick, int id, intptr_t data)
{
char tmp_soutput[1024];
@@ -8035,7 +8044,7 @@ int map_day_timer(int tid, unsigned int tick, int id, intptr data)
* timer to do the night [Yor]
* data: 0 = called by timer, 1 = gmcommand/script
*------------------------------------------------*/
-int map_night_timer(int tid, unsigned int tick, int id, intptr data)
+int map_night_timer(int tid, unsigned int tick, int id, intptr_t data)
{
char tmp_soutput[1024];
diff --git a/src/map/pc.h b/src/map/pc.h
index 271b3f6b0..fdf4094a1 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -582,8 +582,8 @@ int pc_calc_skilltree(struct map_session_data *sd);
int pc_calc_skilltree_normalize_job(struct map_session_data *sd);
int pc_clean_skilltree(struct map_session_data *sd);
-#define pc_checkoverhp(sd) (sd->battle_status.hp == sd->battle_status.max_hp)
-#define pc_checkoversp(sd) (sd->battle_status.sp == sd->battle_status.max_sp)
+#define pc_checkoverhp(sd) ((sd)->battle_status.hp == (sd)->battle_status.max_hp)
+#define pc_checkoversp(sd) ((sd)->battle_status.sp == (sd)->battle_status.max_sp)
int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype);
int pc_setsavepoint(struct map_session_data*,short,int,int);
@@ -621,7 +621,7 @@ int pc_updateweightstatus(struct map_session_data *sd);
int pc_addautobonus(struct s_autobonus *bonus,char max,const char *script,short rate,unsigned int dur,short atk_type,const char *o_script,unsigned short pos,bool onskill);
int pc_exeautobonus(struct map_session_data* sd,struct s_autobonus *bonus);
-int pc_endautobonus(int tid, unsigned int tick, int id, intptr data);
+int pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data);
int pc_delautobonus(struct map_session_data* sd,struct s_autobonus *bonus,char max,bool restore);
int pc_bonus(struct map_session_data*,int,int);
@@ -715,7 +715,7 @@ int pc_cleareventtimer(struct map_session_data *sd);
int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick);
int pc_calc_pvprank(struct map_session_data *sd);
-int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr data);
+int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr_t data);
int pc_ismarried(struct map_session_data *sd);
int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd);
@@ -779,8 +779,8 @@ enum {ADDITEM_EXIST,ADDITEM_NEW,ADDITEM_OVERAMOUNT};
// timer for night.day
extern int day_timer_tid;
extern int night_timer_tid;
-int map_day_timer(int tid, unsigned int tick, int id, intptr data); // by [yor]
-int map_night_timer(int tid, unsigned int tick, int id, intptr data); // by [yor]
+int map_day_timer(int tid, unsigned int tick, int id, intptr_t data); // by [yor]
+int map_night_timer(int tid, unsigned int tick, int id, intptr_t data); // by [yor]
// Rental System
void pc_inventory_rentals(struct map_session_data *sd);
diff --git a/src/map/pet.c b/src/map/pet.c
index 1f350ec4b..a0f652f2b 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -189,7 +189,7 @@ int pet_sc_check(struct map_session_data *sd, int type)
return 0;
}
-static int pet_hungry(int tid, unsigned int tick, int id, intptr data)
+static int pet_hungry(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
struct pet_data *pd;
@@ -858,6 +858,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
if (pd->ud.walktimer != INVALID_TIMER)
return 0; //Wait until the pet finishes walking back to master.
pd->status.speed = pd->petDB->speed;
+ pd->ud.state.change_walk_target = pd->ud.state.speed_changed = 1;
}
if (pd->target_id) {
@@ -934,7 +935,7 @@ static int pet_ai_sub_foreachclient(struct map_session_data *sd,va_list ap)
return 0;
}
-static int pet_ai_hard(int tid, unsigned int tick, int id, intptr data)
+static int pet_ai_hard(int tid, unsigned int tick, int id, intptr_t data)
{
map_foreachpc(pet_ai_sub_foreachclient,tick);
@@ -968,7 +969,7 @@ static int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap)
return 0;
}
-static int pet_delay_item_drop(int tid, unsigned int tick, int id, intptr data)
+static int pet_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data)
{
struct item_drop_list *list;
struct item_drop *ditem, *ditem_prev;
@@ -1029,7 +1030,7 @@ int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd)
pd->ud.canact_tick = gettick()+10000; // 10*1000msの間拾わない
if (dlist->item)
- add_timer(gettick()+540,pet_delay_item_drop,0,(intptr)dlist);
+ add_timer(gettick()+540,pet_delay_item_drop,0,(intptr_t)dlist);
else
ers_free(item_drop_list_ers, dlist);
return 1;
@@ -1038,7 +1039,7 @@ int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd)
/*==========================================
* pet bonus giving skills [Valaris] / Rewritten by [Skotlex]
*------------------------------------------*/
-int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr data)
+int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=map_id2sd(id);
struct pet_data *pd;
@@ -1080,7 +1081,7 @@ int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr data)
/*==========================================
* pet recovery skills [Valaris] / Rewritten by [Skotlex]
*------------------------------------------*/
-int pet_recovery_timer(int tid, unsigned int tick, int id, intptr data)
+int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=map_id2sd(id);
struct pet_data *pd;
@@ -1108,7 +1109,7 @@ int pet_recovery_timer(int tid, unsigned int tick, int id, intptr data)
return 0;
}
-int pet_heal_timer(int tid, unsigned int tick, int id, intptr data)
+int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=map_id2sd(id);
struct status_data *status;
@@ -1146,7 +1147,7 @@ int pet_heal_timer(int tid, unsigned int tick, int id, intptr data)
/*==========================================
* pet support skills [Skotlex]
*------------------------------------------*/
-int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr data)
+int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd=map_id2sd(id);
struct pet_data *pd;
diff --git a/src/map/pet.h b/src/map/pet.h
index 729fdeb92..52f4999df 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -121,10 +121,10 @@ int pet_change_name_ack(struct map_session_data *sd, char* name, int flag);
int pet_equipitem(struct map_session_data *sd,int index);
int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd);
int pet_attackskill(struct pet_data *pd, int target_id);
-int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr data); // [Skotlex]
-int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr data); // [Valaris]
-int pet_recovery_timer(int tid, unsigned int tick, int id, intptr data); // [Valaris]
-int pet_heal_timer(int tid, unsigned int tick, int id, intptr data); // [Valaris]
+int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data); // [Skotlex]
+int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data); // [Valaris]
+int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data); // [Valaris]
+int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data); // [Valaris]
#define pet_stop_walking(pd, type) unit_stop_walking(&(pd)->bl, type)
#define pet_stop_attack(pd) unit_stop_attack(&(pd)->bl)
diff --git a/src/map/quest.c b/src/map/quest.c
index 4960d8a93..4c890ce9e 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -85,7 +85,7 @@ int quest_add(TBL_PC * sd, int quest_id)
i = sd->avail_quests;
memmove(&sd->quest_log[i+1], &sd->quest_log[i], sizeof(struct quest)*(sd->num_quests-sd->avail_quests));
- memmove(sd->quest_index+i+1, sd->quest_log+i, sizeof(int)*(sd->num_quests-sd->avail_quests));
+ memmove(sd->quest_index+i+1, sd->quest_index+i, sizeof(int)*(sd->num_quests-sd->avail_quests));
memset(&sd->quest_log[i], 0, sizeof(struct quest));
sd->quest_log[i].quest_id = quest_db[j].id;
diff --git a/src/map/script.c b/src/map/script.c
index bf0b4f652..632dc0e14 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -246,9 +246,13 @@ enum curly_type {
TYPE_ARGLIST // function argument list
};
-#define ARGLIST_UNDEFINED 0
-#define ARGLIST_NO_PAREN 1
-#define ARGLIST_PAREN 2
+enum e_arglist
+{
+ ARGLIST_UNDEFINED = 0,
+ ARGLIST_NO_PAREN = 1,
+ ARGLIST_PAREN = 2,
+};
+
static struct {
struct {
enum curly_type type;
@@ -3315,7 +3319,7 @@ struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n)
/*==========================================
* sleep用タイマー関数
*------------------------------------------*/
-int run_script_timer(int tid, unsigned int tick, int id, intptr data)
+int run_script_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct script_state *st = (struct script_state *)data;
struct linkdb_node *node = (struct linkdb_node *)sleep_db;
@@ -3512,7 +3516,7 @@ void run_script_main(struct script_state *st)
sd = map_id2sd(st->rid); // Get sd since script might have attached someone while running. [Inkfish]
st->sleep.charid = sd?sd->status.char_id:0;
st->sleep.timer = add_timer(gettick()+st->sleep.tick,
- run_script_timer, st->sleep.charid, (intptr)st);
+ run_script_timer, st->sleep.charid, (intptr_t)st);
linkdb_insert(&sleep_db, (void*)st->oid, st);
}
else if(st->state != END && st->rid){
@@ -4550,7 +4554,7 @@ BUILDIN_FUNC(warpchar)
*------------------------------------------*/
BUILDIN_FUNC(warpparty)
{
- TBL_PC *sd;
+ TBL_PC *sd = NULL;
TBL_PC *pl_sd;
struct party_data* p;
int type;
@@ -4565,22 +4569,21 @@ BUILDIN_FUNC(warpparty)
if ( script_hasdata(st,6) )
str2 = script_getstr(st,6);
- sd=script_rid2sd(st);
- if( sd == NULL )
- return 0;
p = party_search(p_id);
if(!p)
return 0;
- if(map[sd->bl.m].flag.noreturn || map[sd->bl.m].flag.nowarpto)
- return 0;
-
type = ( strcmp(str,"Random")==0 ) ? 0
: ( strcmp(str,"SavePointAll")==0 ) ? 1
: ( strcmp(str,"SavePoint")==0 ) ? 2
: ( strcmp(str,"Leader")==0 ) ? 3
: 4;
+ if( type == 2 && ( sd = script_rid2sd(st) ) == NULL )
+ {// "SavePoint" uses save point of the currently attached player
+ return 0;
+ }
+
for (i = 0; i < MAX_PARTY; i++)
{
if( !(pl_sd = p->data[i].sd) || pl_sd->status.party_id != p_id )
@@ -4638,7 +4641,7 @@ BUILDIN_FUNC(warpparty)
*------------------------------------------*/
BUILDIN_FUNC(warpguild)
{
- TBL_PC *sd;
+ TBL_PC *sd = NULL;
TBL_PC *pl_sd;
struct guild* g;
struct s_mapiterator* iter;
@@ -4649,21 +4652,20 @@ BUILDIN_FUNC(warpguild)
int y = script_getnum(st,4);
int gid = script_getnum(st,5);
- sd=script_rid2sd(st);
- if( sd == NULL )
- return 0;
g = guild_search(gid);
if( g == NULL )
return 0;
- if(map[sd->bl.m].flag.noreturn || map[sd->bl.m].flag.nowarpto)
- return 0;
-
type = ( strcmp(str,"Random")==0 ) ? 0
: ( strcmp(str,"SavePointAll")==0 ) ? 1
: ( strcmp(str,"SavePoint")==0 ) ? 2
: 3;
+ if( type == 2 && ( sd = script_rid2sd(st) ) == NULL )
+ {// "SavePoint" uses save point of the currently attached player
+ return 0;
+ }
+
iter = mapit_getallusers();
for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
{
@@ -11682,6 +11684,62 @@ BUILDIN_FUNC(gethominfo)
return 0;
}
+/// Retrieves information about character's mercenary
+/// getmercinfo <type>[,<char id>];
+BUILDIN_FUNC(getmercinfo)
+{
+ int type, char_id;
+ struct map_session_data* sd;
+ struct mercenary_data* md;
+
+ type = script_getnum(st,2);
+
+ if( script_hasdata(st,3) )
+ {
+ char_id = script_getnum(st,3);
+
+ if( ( sd = map_charid2sd(char_id) ) == NULL )
+ {
+ ShowError("buildin_getmercinfo: No such character (char_id=%d).\n", char_id);
+ script_pushnil(st);
+ return 1;
+ }
+ }
+ else
+ {
+ if( ( sd = script_rid2sd(st) ) == NULL )
+ {
+ script_pushnil(st);
+ return 0;
+ }
+ }
+
+ md = ( sd->status.mer_id && sd->md ) ? sd->md : NULL;
+
+ switch( type )
+ {
+ case 0: script_pushint(st,md ? md->mercenary.mercenary_id : 0); break;
+ case 1: script_pushint(st,md ? md->mercenary.class_ : 0); break;
+ case 2:
+ if( md )
+ script_pushstrcopy(st,md->db->name);
+ else
+ script_pushconststr(st,"");
+ break;
+ case 3: script_pushint(st,md ? mercenary_get_faith(md) : 0); break;
+ case 4: script_pushint(st,md ? mercenary_get_calls(md) : 0); break;
+ case 5: script_pushint(st,md ? md->mercenary.kill_count : 0); break;
+ case 6: script_pushint(st,md ? mercenary_get_lifetime(md) : 0); break;
+ case 7: script_pushint(st,md ? md->db->lv : 0); break;
+ default:
+ ShowError("buildin_getmercinfo: Invalid type %d (char_id=%d).\n", type, sd->status.char_id);
+ script_pushnil(st);
+ return 1;
+ }
+
+ return 0;
+}
+
/*==========================================
* Shows wether your inventory(and equips) contain
selected card or not.
@@ -11788,7 +11846,7 @@ BUILDIN_FUNC(movenpc)
return -1;
if (script_hasdata(st,5))
- nd->ud.dir = script_getnum(st,5);
+ nd->ud.dir = script_getnum(st,5) % 8;
npc_movenpc(nd, x, y);
return 0;
}
@@ -12871,7 +12929,7 @@ BUILDIN_FUNC(npcshopitem)
int n, i;
int amount;
- if( !nd || nd->subtype != SHOP )
+ if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) )
{ //Not found.
script_pushint(st,0);
return 0;
@@ -12900,7 +12958,7 @@ BUILDIN_FUNC(npcshopadditem)
int n, i;
int amount;
- if( !nd || nd->subtype != SHOP )
+ if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) )
{ //Not found.
script_pushint(st,0);
return 0;
@@ -12931,7 +12989,7 @@ BUILDIN_FUNC(npcshopdelitem)
int amount;
int size;
- if( !nd || nd->subtype != SHOP )
+ if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) )
{ //Not found.
script_pushint(st,0);
return 0;
@@ -15141,6 +15199,7 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(recovery,""),
BUILDIN_DEF(getpetinfo,"i"),
BUILDIN_DEF(gethominfo,"i"),
+ BUILDIN_DEF(getmercinfo,"i?"),
BUILDIN_DEF(checkequipedcard,"i"),
BUILDIN_DEF(jump_zero,"il"), //for future jA script compatibility
BUILDIN_DEF(globalmes,"s?"),
diff --git a/src/map/script.h b/src/map/script.h
index c272f2d32..2ed163a0f 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -153,7 +153,7 @@ void run_script(struct script_code*,int,int,int);
int set_var(struct map_session_data *sd, char *name, void *val);
int conv_num(struct script_state *st,struct script_data *data);
const char* conv_str(struct script_state *st,struct script_data *data);
-int run_script_timer(int tid, unsigned int tick, int id, intptr data);
+int run_script_timer(int tid, unsigned int tick, int id, intptr_t data);
void run_script_main(struct script_state *st);
void script_stop_sleeptimers(int id);
diff --git a/src/map/skill.c b/src/map/skill.c
index d95d04134..d33d35d6e 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -43,11 +43,11 @@
// ranges reserved for mapping skill ids to skilldb offsets
#define GD_SKILLRANGEMIN 900
-#define GD_SKILLRANGEMAX GD_SKILLRANGEMIN+MAX_GUILDSKILL
+#define GD_SKILLRANGEMAX (GD_SKILLRANGEMIN+MAX_GUILDSKILL)
#define MC_SKILLRANGEMIN 800
-#define MC_SKILLRANGEMAX MC_SKILLRANGEMIN+MAX_MERCSKILL
+#define MC_SKILLRANGEMAX (MC_SKILLRANGEMIN+MAX_MERCSKILL)
#define HM_SKILLRANGEMIN 700
-#define HM_SKILLRANGEMAX HM_SKILLRANGEMIN+MAX_HOMUNSKILL
+#define HM_SKILLRANGEMAX (HM_SKILLRANGEMIN+MAX_HOMUNSKILL)
static struct eri *skill_unit_ers = NULL; //For handling skill_unit's [Skotlex]
static struct eri *skill_timer_ers = NULL; //For handling skill_timerskills [Skotlex]
@@ -1820,11 +1820,11 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
&& (!sc || !sc->data[SC_PRESERVE])
&& damage < tsd->battle_status.hp)
{ //Updated to not be able to copy skills if the blow will kill you. [Skotlex]
- if ((!tsd->status.skill[skillid].id || tsd->status.skill[skillid].flag >= 13) &&
+ if ((tsd->status.skill[skillid].id == 0 || tsd->status.skill[skillid].flag == SKILL_FLAG_PLAGIARIZED) &&
can_copy(tsd,skillid,bl)) // Split all the check into their own function [Aru]
{
int lv = skilllv;
- if (tsd->cloneskill_id && tsd->status.skill[tsd->cloneskill_id].flag == 13){
+ if (tsd->cloneskill_id && tsd->status.skill[tsd->cloneskill_id].flag == SKILL_FLAG_PLAGIARIZED){
tsd->status.skill[tsd->cloneskill_id].id = 0;
tsd->status.skill[tsd->cloneskill_id].lv = 0;
tsd->status.skill[tsd->cloneskill_id].flag = 0;
@@ -1840,7 +1840,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
tsd->status.skill[skillid].id = skillid;
tsd->status.skill[skillid].lv = lv;
- tsd->status.skill[skillid].flag = 13;//cloneskill flag
+ tsd->status.skill[skillid].flag = SKILL_FLAG_PLAGIARIZED;
clif_addskill(tsd,skillid);
}
}
@@ -2277,7 +2277,7 @@ int skill_area_sub_count (struct block_list *src, struct block_list *target, int
/*==========================================
*
*------------------------------------------*/
-static int skill_timerskill(int tid, unsigned int tick, int id, intptr data)
+static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list *src = map_id2bl(id),*target;
struct unit_data *ud = unit_bl2ud(src);
@@ -3958,51 +3958,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case KN_BRANDISHSPEAR:
case ML_BRANDISH:
- {
- int c,n=4;
- int dir = map_calc_dir(src,bl->x,bl->y);
- struct square tc;
- int x=bl->x,y=bl->y;
- skill_brandishspear_first(&tc,dir,x,y);
- skill_brandishspear_dir(&tc,dir,4);
- skill_area_temp[1] = bl->id;
-
- if(skilllv > 9){
- for(c=1;c<4;c++){
- map_foreachincell(skill_area_sub,
- bl->m,tc.val1[c],tc.val2[c],BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|n,
- skill_castend_damage_id);
- }
- }
- if(skilllv > 6){
- skill_brandishspear_dir(&tc,dir,-1);
- n--;
- }else{
- skill_brandishspear_dir(&tc,dir,-2);
- n-=2;
- }
-
- if(skilllv > 3){
- for(c=0;c<5;c++){
- map_foreachincell(skill_area_sub,
- bl->m,tc.val1[c],tc.val2[c],BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|n,
- skill_castend_damage_id);
- if(skilllv > 6 && n==3 && c==4){
- skill_brandishspear_dir(&tc,dir,-1);
- n--;c=-1;
- }
- }
- }
- for(c=0;c<10;c++){
- if(c==0||c==5) skill_brandishspear_dir(&tc,dir,-1);
- map_foreachincell(skill_area_sub,
- bl->m,tc.val1[c%5],tc.val2[c%5],BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
- }
- }
+ skill_brandishspear(src, bl, skillid, skilllv, tick, flag);
break;
case WZ_SIGHTRASHER:
@@ -5531,7 +5487,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
//AuronX reported you CAN memorize the same map as all three. [Skotlex]
if (sd) {
if(!sd->feel_map[skilllv-1].index)
- clif_parse_ReqFeel(sd->fd,sd, skilllv);
+ clif_feel_req(sd->fd,sd, skilllv);
else
clif_feel_info(sd, skilllv-1, 1);
}
@@ -5726,7 +5682,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
/*==========================================
*
*------------------------------------------*/
-int skill_castend_id(int tid, unsigned int tick, int id, intptr data)
+int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list *target, *src;
struct map_session_data *sd;
@@ -6016,7 +5972,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data)
/*==========================================
*
*------------------------------------------*/
-int skill_castend_pos(int tid, unsigned int tick, int id, intptr data)
+int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list* src = map_id2bl(id);
int maxcount;
@@ -9149,7 +9105,12 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
/*=========================================
*
*-----------------------------------------*/
-void skill_brandishspear_first (struct square *tc, int dir, int x, int y)
+struct square {
+ int val1[5];
+ int val2[5];
+};
+
+static void skill_brandishspear_first (struct square *tc, int dir, int x, int y)
{
nullpo_retv(tc);
@@ -9252,10 +9213,7 @@ void skill_brandishspear_first (struct square *tc, int dir, int x, int y)
}
-/*=========================================
- *
- *-----------------------------------------*/
-void skill_brandishspear_dir (struct square* tc, int dir, int are)
+static void skill_brandishspear_dir (struct square* tc, int dir, int are)
{
int c;
nullpo_retv(tc);
@@ -9276,6 +9234,53 @@ void skill_brandishspear_dir (struct square* tc, int dir, int are)
}
}
+void skill_brandishspear(struct block_list* src, struct block_list* bl, int skillid, int skilllv, unsigned int tick, int flag)
+{
+ int c,n=4;
+ int dir = map_calc_dir(src,bl->x,bl->y);
+ struct square tc;
+ int x=bl->x,y=bl->y;
+ skill_brandishspear_first(&tc,dir,x,y);
+ skill_brandishspear_dir(&tc,dir,4);
+ skill_area_temp[1] = bl->id;
+
+ if(skilllv > 9){
+ for(c=1;c<4;c++){
+ map_foreachincell(skill_area_sub,
+ bl->m,tc.val1[c],tc.val2[c],BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|n,
+ skill_castend_damage_id);
+ }
+ }
+ if(skilllv > 6){
+ skill_brandishspear_dir(&tc,dir,-1);
+ n--;
+ }else{
+ skill_brandishspear_dir(&tc,dir,-2);
+ n-=2;
+ }
+
+ if(skilllv > 3){
+ for(c=0;c<5;c++){
+ map_foreachincell(skill_area_sub,
+ bl->m,tc.val1[c],tc.val2[c],BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|n,
+ skill_castend_damage_id);
+ if(skilllv > 6 && n==3 && c==4){
+ skill_brandishspear_dir(&tc,dir,-1);
+ n--;c=-1;
+ }
+ }
+ }
+ for(c=0;c<10;c++){
+ if(c==0||c==5) skill_brandishspear_dir(&tc,dir,-1);
+ map_foreachincell(skill_area_sub,
+ bl->m,tc.val1[c%5],tc.val2[c%5],BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ }
+}
+
/*==========================================
* Weapon Repair [Celest/DracoRPG]
*------------------------------------------*/
@@ -10485,7 +10490,7 @@ static int skill_unit_timer_sub (DBKey key, void* data, va_list ap)
/*==========================================
* Executes on all skill units every SKILLUNITTIMER_INTERVAL miliseconds.
*------------------------------------------*/
-int skill_unit_timer(int tid, unsigned int tick, int id, intptr data)
+int skill_unit_timer(int tid, unsigned int tick, int id, intptr_t data)
{
map_freeblock_lock();
@@ -11181,7 +11186,7 @@ int skill_arrow_create (struct map_session_data *sd, int nameid)
/*==========================================
*
*------------------------------------------*/
-int skill_blockpc_end(int tid, unsigned int tick, int id, intptr data)
+int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd = map_id2sd(id);
if (data <= 0 || data >= MAX_SKILL)
@@ -11212,7 +11217,7 @@ int skill_blockpc_start(struct map_session_data *sd, int skillid, int tick)
return 0;
}
-int skill_blockhomun_end(int tid, unsigned int tick, int id, intptr data) //[orn]
+int skill_blockhomun_end(int tid, unsigned int tick, int id, intptr_t data) //[orn]
{
struct homun_data *hd = (TBL_HOM*) map_id2bl(id);
if (data <= 0 || data >= MAX_SKILL)
@@ -11238,7 +11243,7 @@ int skill_blockhomun_start(struct homun_data *hd, int skillid, int tick) //[orn]
return add_timer(gettick() + tick, skill_blockhomun_end, hd->bl.id, skillid);
}
-int skill_blockmerc_end(int tid, unsigned int tick, int id, intptr data) //[orn]
+int skill_blockmerc_end(int tid, unsigned int tick, int id, intptr_t data) //[orn]
{
struct mercenary_data *md = (TBL_MER*)map_id2bl(id);
if( data <= 0 || data >= MAX_SKILL )
diff --git a/src/map/skill.h b/src/map/skill.h
index 6f55af7ec..1ad6ea25a 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -22,51 +22,61 @@ struct status_change_entry;
#define MAX_SKILL_LEVEL 100
//Constants to identify the skill's inf value:
-#define INF_ATTACK_SKILL 1
-#define INF_GROUND_SKILL 2
-// Skills casted on self where target is automatically chosen:
-#define INF_SELF_SKILL 4
-#define INF_SUPPORT_SKILL 16
-#define INF_TARGET_TRAP 32
+enum e_skill_inf
+{
+ INF_ATTACK_SKILL = 0x01,
+ INF_GROUND_SKILL = 0x02,
+ INF_SELF_SKILL = 0x04, // Skills casted on self where target is automatically chosen
+ // 0x08 not assigned
+ INF_SUPPORT_SKILL = 0x10,
+ INF_TARGET_TRAP = 0x20,
+};
//Constants to identify a skill's nk value (damage properties)
//The NK value applies only to non INF_GROUND_SKILL skills
//when determining skill castend function to invoke.
-#define NK_NO_DAMAGE 0x01
-#define NK_SPLASH (0x02|0x04) // 0x4 = splash & split
-#define NK_SPLASHSPLIT 0x04
-#define NK_NO_CARDFIX_ATK 0x08
-#define NK_NO_ELEFIX 0x10
-#define NK_IGNORE_DEF 0x20
-#define NK_IGNORE_FLEE 0x40
-#define NK_NO_CARDFIX_DEF 0x80
+enum e_skill_nk
+{
+ NK_NO_DAMAGE = 0x01,
+ NK_SPLASH = 0x02|0x04, // 0x4 = splash & split
+ NK_SPLASHSPLIT = 0x04,
+ NK_NO_CARDFIX_ATK = 0x08,
+ NK_NO_ELEFIX = 0x10,
+ NK_IGNORE_DEF = 0x20,
+ NK_IGNORE_FLEE = 0x40,
+ NK_NO_CARDFIX_DEF = 0x80,
+};
//A skill with 3 would be no damage + splash: area of effect.
//Constants to identify a skill's inf2 value.
-#define INF2_QUEST_SKILL 1
-//NPC skills are those that players can't have in their skill tree.
-#define INF2_NPC_SKILL 0x2
-#define INF2_WEDDING_SKILL 0x4
-#define INF2_SPIRIT_SKILL 0x8
-#define INF2_GUILD_SKILL 0x10
-#define INF2_SONG_DANCE 0x20
-#define INF2_ENSEMBLE_SKILL 0x40
-#define INF2_TRAP 0x80
-//Refers to ground placed skills that will target the caster as well (like Grandcross)
-#define INF2_TARGET_SELF 0x100
-#define INF2_NO_TARGET_SELF 0x200
-#define INF2_PARTY_ONLY 0x400
-#define INF2_GUILD_ONLY 0x800
-#define INF2_NO_ENEMY 0x1000
+enum e_skill_inf2
+{
+ INF2_QUEST_SKILL = 0x0001,
+ INF2_NPC_SKILL = 0x0002, //NPC skills are those that players can't have in their skill tree.
+ INF2_WEDDING_SKILL = 0x0004,
+ INF2_SPIRIT_SKILL = 0x0008,
+ INF2_GUILD_SKILL = 0x0010,
+ INF2_SONG_DANCE = 0x0020,
+ INF2_ENSEMBLE_SKILL = 0x0040,
+ INF2_TRAP = 0x0080,
+ INF2_TARGET_SELF = 0x0100, //Refers to ground placed skills that will target the caster as well (like Grandcross)
+ INF2_NO_TARGET_SELF = 0x0200,
+ INF2_PARTY_ONLY = 0x0400,
+ INF2_GUILD_ONLY = 0x0800,
+ INF2_NO_ENEMY = 0x1000,
+};
//Walk intervals at which chase-skills are attempted to be triggered.
#define WALK_SKILL_INTERVAL 5
// Flags passed to skill_attack/skill_area_sub
-#define SD_LEVEL 0x1000 // skill_attack will send -1 instead of skill level (affects display of some skills)
-#define SD_ANIMATION 0x2000 // skill_attack will use '5' instead of the skill's 'type' (this makes skills show an animation)
-#define SD_SPLASH 0x4000 // skill_area_sub will count targets in skill_area_temp[2]
-#define SD_PREAMBLE 0x8000 // skill_area_sub will transmit a 'magic' damage packet (-30000 dmg) for the first target selected
+enum e_skill_display
+{
+ SD_LEVEL = 0x1000, // skill_attack will send -1 instead of skill level (affects display of some skills)
+ SD_ANIMATION = 0x2000, // skill_attack will use '5' instead of the skill's 'type' (this makes skills show an animation)
+ SD_SPLASH = 0x4000, // skill_area_sub will count targets in skill_area_temp[2]
+ SD_PREAMBLE = 0x8000, // skill_area_sub will transmit a 'magic' damage packet (-30000 dmg) for the first target selected
+};
#define MAX_SKILL_ITEM_REQUIRE 10
struct skill_condition {
@@ -253,8 +263,8 @@ const char* skill_get_desc( int id ); // [Skotlex]
int skill_name2id(const char* name);
int skill_isammotype(struct map_session_data *sd, int skill);
-int skill_castend_id(int tid, unsigned int tick, int id, intptr data);
-int skill_castend_pos(int tid, unsigned int tick, int id, intptr data);
+int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data);
+int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data);
int skill_castend_map( struct map_session_data *sd,short skill_num, const char *map);
int skill_cleartimerskill(struct block_list *src);
@@ -305,8 +315,7 @@ int skill_guildaura_sub (struct block_list *bl,va_list ap);
int skill_castcancel(struct block_list *bl,int type);
int skill_sit (struct map_session_data *sd, int type);
-void skill_brandishspear_first(struct square *tc,int dir,int x,int y);
-void skill_brandishspear_dir(struct square *tc,int dir,int are);
+void skill_brandishspear(struct block_list* src, struct block_list* bl, int skillid, int skilllv, unsigned int tick, int flag);
void skill_repairweapon(struct map_session_data *sd, int idx);
void skill_identify(struct map_session_data *sd,int idx);
void skill_weaponrefine(struct map_session_data *sd,int idx); // [Celest]
diff --git a/src/map/sql/CMakeLists.txt b/src/map/sql/CMakeLists.txt
new file mode 100644
index 000000000..74598423a
--- /dev/null
+++ b/src/map/sql/CMakeLists.txt
@@ -0,0 +1,110 @@
+
+#
+# map sql
+#
+if( HAVE_common_sql )
+message( STATUS "Creating target map-server_sql" )
+set( SQL_MAP_HEADERS
+ "${MAP_SOURCE_DIR}/atcommand.h"
+ "${MAP_SOURCE_DIR}/battle.h"
+ "${MAP_SOURCE_DIR}/battleground.h"
+ "${MAP_SOURCE_DIR}/buyingstore.h"
+ "${MAP_SOURCE_DIR}/chat.h"
+ "${MAP_SOURCE_DIR}/chrif.h"
+ "${MAP_SOURCE_DIR}/clif.h"
+ "${MAP_SOURCE_DIR}/date.h"
+ "${MAP_SOURCE_DIR}/duel.h"
+ "${MAP_SOURCE_DIR}/guild.h"
+ "${MAP_SOURCE_DIR}/homunculus.h"
+ "${MAP_SOURCE_DIR}/instance.h"
+ "${MAP_SOURCE_DIR}/intif.h"
+ "${MAP_SOURCE_DIR}/itemdb.h"
+ "${MAP_SOURCE_DIR}/log.h"
+ "${MAP_SOURCE_DIR}/mail.h"
+ "${MAP_SOURCE_DIR}/map.h"
+ "${MAP_SOURCE_DIR}/mapreg.h"
+ "${MAP_SOURCE_DIR}/mercenary.h"
+ "${MAP_SOURCE_DIR}/mob.h"
+ "${MAP_SOURCE_DIR}/npc.h"
+ "${MAP_SOURCE_DIR}/party.h"
+ "${MAP_SOURCE_DIR}/path.h"
+ "${MAP_SOURCE_DIR}/pc.h"
+ "${MAP_SOURCE_DIR}/pet.h"
+ "${MAP_SOURCE_DIR}/quest.h"
+ "${MAP_SOURCE_DIR}/script.h"
+ "${MAP_SOURCE_DIR}/searchstore.h"
+ "${MAP_SOURCE_DIR}/skill.h"
+ "${MAP_SOURCE_DIR}/status.h"
+ "${MAP_SOURCE_DIR}/storage.h"
+ "${MAP_SOURCE_DIR}/trade.h"
+ "${MAP_SOURCE_DIR}/unit.h"
+ "${MAP_SOURCE_DIR}/vending.h"
+ )
+set( SQL_MAP_SOURCES
+ "${MAP_SOURCE_DIR}/atcommand.c"
+ "${MAP_SOURCE_DIR}/battle.c"
+ "${MAP_SOURCE_DIR}/battleground.c"
+ "${MAP_SOURCE_DIR}/buyingstore.c"
+ "${MAP_SOURCE_DIR}/chat.c"
+ "${MAP_SOURCE_DIR}/chrif.c"
+ "${MAP_SOURCE_DIR}/clif.c"
+ "${MAP_SOURCE_DIR}/date.c"
+ "${MAP_SOURCE_DIR}/duel.c"
+ "${MAP_SOURCE_DIR}/guild.c"
+ "${MAP_SOURCE_DIR}/homunculus.c"
+ "${MAP_SOURCE_DIR}/instance.c"
+ "${MAP_SOURCE_DIR}/intif.c"
+ "${MAP_SOURCE_DIR}/itemdb.c"
+ "${MAP_SOURCE_DIR}/log.c"
+ "${MAP_SOURCE_DIR}/mail.c"
+ "${MAP_SOURCE_DIR}/map.c"
+ "${MAP_SOURCE_DIR}/mapreg_sql.c"
+ "${MAP_SOURCE_DIR}/mercenary.c"
+ "${MAP_SOURCE_DIR}/mob.c"
+ "${MAP_SOURCE_DIR}/npc.c"
+ "${MAP_SOURCE_DIR}/npc_chat.c"
+ "${MAP_SOURCE_DIR}/party.c"
+ "${MAP_SOURCE_DIR}/path.c"
+ "${MAP_SOURCE_DIR}/pc.c"
+ "${MAP_SOURCE_DIR}/pet.c"
+ "${MAP_SOURCE_DIR}/quest.c"
+ "${MAP_SOURCE_DIR}/script.c"
+ "${MAP_SOURCE_DIR}/searchstore.c"
+ "${MAP_SOURCE_DIR}/skill.c"
+ "${MAP_SOURCE_DIR}/status.c"
+ "${MAP_SOURCE_DIR}/storage.c"
+ "${MAP_SOURCE_DIR}/trade.c"
+ "${MAP_SOURCE_DIR}/unit.c"
+ "${MAP_SOURCE_DIR}/vending.c"
+ )
+set( DEPENDENCIES common_sql )
+set( LIBRARIES ${GLOBAL_LIBRARIES} )
+set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
+set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+if( WITH_PCRE )
+ message( STATUS "Using PCRE" )
+ list( APPEND LIBRARIES ${PCRE_LIBRARIES} )
+ list( APPEND INCLUDE_DIRS ${PCRE_INCLUDE_DIRS} )
+ list( APPEND DEFINITIONS PCRE_SUPPORT )
+endif()
+set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} ${SQL_MAP_HEADERS} ${SQL_MAP_SOURCES} )
+source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} )
+source_group( map FILES ${SQL_MAP_HEADERS} ${SQL_MAP_SOURCES} )
+include_directories( ${INCLUDE_DIRS} )
+add_executable( map-server_sql ${SOURCE_FILES} )
+add_dependencies( map-server_sql ${DEPENDENCIES} )
+target_link_libraries( map-server_sql ${LIBRARIES} ${DEPENDENCIES} )
+set_target_properties( map-server_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
+if( WITH_COMPONENT_RUNTIME )
+ cpack_add_component( Runtime_mapserver_sql DESCRIPTION "map-server (sql version)" DISPLAY_NAME "map-server_sql" GROUP Runtime )
+ install( TARGETS map-server_sql
+ DESTINATION "."
+ COMPONENT Runtime_mapserver_sql )
+endif()
+message( STATUS "Creating target map-server_sql - done" )
+set( HAVE_map-server_sql ON CACHE BOOL "map-server_sql target is available" )
+mark_as_advanced( HAVE_map-server_sql )
+else()
+message( STATUS "Skipping target map-server_sql (requires common_sql; optional PCRE)" )
+unset( HAVE_map-server_sql CACHE )
+endif()
diff --git a/src/map/status.c b/src/map/status.c
index e68ebd291..37dad30b9 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -38,10 +38,13 @@
//Regen related flags.
-#define RGN_HP 0x01
-#define RGN_SP 0x02
-#define RGN_SHP 0x04
-#define RGN_SSP 0x08
+enum e_regen
+{
+ RGN_HP = 0x01,
+ RGN_SP = 0x02,
+ RGN_SHP = 0x04,
+ RGN_SSP = 0x08,
+};
static int max_weight_base[CLASS_COUNT];
static int hp_coefficient[CLASS_COUNT];
@@ -6961,7 +6964,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
return 1;
}
-int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr data)
+int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list *bl;
struct status_change *sc;
@@ -6998,7 +7001,7 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr data)
/*==========================================
* ステータス異常終了タイマー
*------------------------------------------*/
-int status_change_timer(int tid, unsigned int tick, int id, intptr data)
+int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
{
enum sc_type type = (sc_type)data;
struct block_list *bl;
@@ -7258,7 +7261,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr data)
case SC_BERSERK:
// 5% every 10 seconds [DracoRPG]
- if(--(sce->val3)>0 && status_charge(bl, sce->val2, 0))
+ if( --( sce->val3 ) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100 )
{
sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
return 0;
@@ -7689,7 +7692,7 @@ static int status_natural_heal(struct block_list* bl, va_list args)
}
//Natural heal main timer.
-static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr data)
+static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
{
natural_heal_diff_tick = DIFF_TICK(tick,natural_heal_prev_tick);
map_foreachregen(status_natural_heal);
diff --git a/src/map/status.h b/src/map/status.h
index 45eaa5c8d..abaeff75e 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -915,13 +915,16 @@ enum si_type {
};
// JOINTBEAT stackable ailments
-#define BREAK_ANKLE 0x01 // MoveSpeed reduced by 50%
-#define BREAK_WRIST 0x02 // ASPD reduced by 25%
-#define BREAK_KNEE 0x04 // MoveSpeed reduced by 30%, ASPD reduced by 10%
-#define BREAK_SHOULDER 0x08 // DEF reduced by 50%
-#define BREAK_WAIST 0x10 // DEF reduced by 25%, ATK reduced by 25%
-#define BREAK_NECK 0x20 // current attack does 2x damage, inflicts 'bleeding' for 30 seconds
-#define BREAK_FLAGS ( BREAK_ANKLE | BREAK_WRIST | BREAK_KNEE | BREAK_SHOULDER | BREAK_WAIST | BREAK_NECK )
+enum e_joint_break
+{
+ BREAK_ANKLE = 0x01, // MoveSpeed reduced by 50%
+ BREAK_WRIST = 0x02, // ASPD reduced by 25%
+ BREAK_KNEE = 0x04, // MoveSpeed reduced by 30%, ASPD reduced by 10%
+ BREAK_SHOULDER = 0x08, // DEF reduced by 50%
+ BREAK_WAIST = 0x10, // DEF reduced by 25%, ATK reduced by 25%
+ BREAK_NECK = 0x20, // current attack does 2x damage, inflicts 'bleeding' for 30 seconds
+ BREAK_FLAGS = BREAK_ANKLE | BREAK_WRIST | BREAK_KNEE | BREAK_SHOULDER | BREAK_WAIST | BREAK_NECK,
+};
extern int current_equip_item_index;
extern int current_equip_card_id;
@@ -929,22 +932,25 @@ extern int current_equip_card_id;
extern int percentrefinery[5][MAX_REFINE+1]; //The last slot always has a 0% success chance [Skotlex]
//Mode definitions to clear up code reading. [Skotlex]
-#define MD_CANMOVE 0x0001
-#define MD_LOOTER 0x0002
-#define MD_AGGRESSIVE 0x0004
-#define MD_ASSIST 0x0008
-#define MD_CASTSENSOR_IDLE 0x0010
-#define MD_BOSS 0x0020
-#define MD_PLANT 0x0040
-#define MD_CANATTACK 0x0080
-#define MD_DETECTOR 0x0100
-#define MD_CASTSENSOR_CHASE 0x0200
-#define MD_CHANGECHASE 0x0400
-#define MD_ANGRY 0x0800
-#define MD_CHANGETARGET_MELEE 0x1000
-#define MD_CHANGETARGET_CHASE 0x2000
-#define MD_TARGETWEAK 0x4000
-#define MD_MASK 0xFFFF
+enum e_mode
+{
+ MD_CANMOVE = 0x0001,
+ MD_LOOTER = 0x0002,
+ MD_AGGRESSIVE = 0x0004,
+ MD_ASSIST = 0x0008,
+ MD_CASTSENSOR_IDLE = 0x0010,
+ MD_BOSS = 0x0020,
+ MD_PLANT = 0x0040,
+ MD_CANATTACK = 0x0080,
+ MD_DETECTOR = 0x0100,
+ MD_CASTSENSOR_CHASE = 0x0200,
+ MD_CHANGECHASE = 0x0400,
+ MD_ANGRY = 0x0800,
+ MD_CHANGETARGET_MELEE = 0x1000,
+ MD_CHANGETARGET_CHASE = 0x2000,
+ MD_TARGETWEAK = 0x4000,
+ MD_MASK = 0xFFFF,
+};
//Status change option definitions (options are what makes status changes visible to chars
//who were not on your field of sight when it happened)
@@ -1026,19 +1032,21 @@ enum {
OPTION_DRAGON3 = 0x01000000,
OPTION_DRAGON4 = 0x02000000,
OPTION_DRAGON5 = 0x04000000,
+ // compound constants
+ OPTION_CART = OPTION_CART1|OPTION_CART2|OPTION_CART3|OPTION_CART4|OPTION_CART5,
+ OPTION_DRAGON = OPTION_DRAGON1|OPTION_DRAGON2|OPTION_DRAGON3|OPTION_DRAGON4|OPTION_DRAGON5,
+ OPTION_MASK = ~OPTION_INVISIBLE,
};
-#define OPTION_CART (OPTION_CART1|OPTION_CART2|OPTION_CART3|OPTION_CART4|OPTION_CART5)
-#define OPTION_DRAGON (OPTION_DRAGON1|OPTION_DRAGON2|OPTION_DRAGON3|OPTION_DRAGON4|OPTION_DRAGON5)
-
-#define OPTION_MASK ~0x40
-
//Defines for the manner system [Skotlex]
-#define MANNER_NOCHAT 0x01
-#define MANNER_NOSKILL 0x02
-#define MANNER_NOCOMMAND 0x04
-#define MANNER_NOITEM 0x08
-#define MANNER_NOROOM 0x10
+enum manner_flags
+{
+ MANNER_NOCHAT = 0x01,
+ MANNER_NOSKILL = 0x02,
+ MANNER_NOCOMMAND = 0x04,
+ MANNER_NOITEM = 0x08,
+ MANNER_NOROOM = 0x10,
+};
//Define flags for the status_calc_bl function. [Skotlex]
enum scb_flag
@@ -1278,8 +1286,8 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag);
int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line);
#define status_change_end(bl,type,tid) status_change_end_(bl,type,tid,__FILE__,__LINE__)
-int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr data);
-int status_change_timer(int tid, unsigned int tick, int id, intptr data);
+int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data);
+int status_change_timer(int tid, unsigned int tick, int id, intptr_t data);
int status_change_timer_sub(struct block_list* bl, va_list ap);
int status_change_clear(struct block_list* bl, int type);
int status_change_clear_buffs(struct block_list* bl, int type);
diff --git a/src/map/txt/CMakeLists.txt b/src/map/txt/CMakeLists.txt
new file mode 100644
index 000000000..d58866f96
--- /dev/null
+++ b/src/map/txt/CMakeLists.txt
@@ -0,0 +1,110 @@
+
+#
+# map txt
+#
+if( HAVE_common_base )
+message( STATUS "Creating target map-server" )
+set( TXT_MAP_HEADERS
+ "${MAP_SOURCE_DIR}/atcommand.h"
+ "${MAP_SOURCE_DIR}/battle.h"
+ "${MAP_SOURCE_DIR}/battleground.h"
+ "${MAP_SOURCE_DIR}/buyingstore.h"
+ "${MAP_SOURCE_DIR}/chat.h"
+ "${MAP_SOURCE_DIR}/chrif.h"
+ "${MAP_SOURCE_DIR}/clif.h"
+ "${MAP_SOURCE_DIR}/date.h"
+ "${MAP_SOURCE_DIR}/duel.h"
+ "${MAP_SOURCE_DIR}/guild.h"
+ "${MAP_SOURCE_DIR}/homunculus.h"
+ "${MAP_SOURCE_DIR}/instance.h"
+ "${MAP_SOURCE_DIR}/intif.h"
+ "${MAP_SOURCE_DIR}/itemdb.h"
+ "${MAP_SOURCE_DIR}/log.h"
+ "${MAP_SOURCE_DIR}/mail.h"
+ "${MAP_SOURCE_DIR}/map.h"
+ "${MAP_SOURCE_DIR}/mapreg.h"
+ "${MAP_SOURCE_DIR}/mercenary.h"
+ "${MAP_SOURCE_DIR}/mob.h"
+ "${MAP_SOURCE_DIR}/npc.h"
+ "${MAP_SOURCE_DIR}/party.h"
+ "${MAP_SOURCE_DIR}/path.h"
+ "${MAP_SOURCE_DIR}/pc.h"
+ "${MAP_SOURCE_DIR}/pet.h"
+ "${MAP_SOURCE_DIR}/quest.h"
+ "${MAP_SOURCE_DIR}/script.h"
+ "${MAP_SOURCE_DIR}/searchstore.h"
+ "${MAP_SOURCE_DIR}/skill.h"
+ "${MAP_SOURCE_DIR}/status.h"
+ "${MAP_SOURCE_DIR}/storage.h"
+ "${MAP_SOURCE_DIR}/trade.h"
+ "${MAP_SOURCE_DIR}/unit.h"
+ "${MAP_SOURCE_DIR}/vending.h"
+ )
+set( TXT_MAP_SOURCES
+ "${MAP_SOURCE_DIR}/atcommand.c"
+ "${MAP_SOURCE_DIR}/battle.c"
+ "${MAP_SOURCE_DIR}/battleground.c"
+ "${MAP_SOURCE_DIR}/buyingstore.c"
+ "${MAP_SOURCE_DIR}/chat.c"
+ "${MAP_SOURCE_DIR}/chrif.c"
+ "${MAP_SOURCE_DIR}/clif.c"
+ "${MAP_SOURCE_DIR}/date.c"
+ "${MAP_SOURCE_DIR}/duel.c"
+ "${MAP_SOURCE_DIR}/guild.c"
+ "${MAP_SOURCE_DIR}/homunculus.c"
+ "${MAP_SOURCE_DIR}/instance.c"
+ "${MAP_SOURCE_DIR}/intif.c"
+ "${MAP_SOURCE_DIR}/itemdb.c"
+ "${MAP_SOURCE_DIR}/log.c"
+ "${MAP_SOURCE_DIR}/mail.c"
+ "${MAP_SOURCE_DIR}/map.c"
+ "${MAP_SOURCE_DIR}/mapreg_txt.c"
+ "${MAP_SOURCE_DIR}/mercenary.c"
+ "${MAP_SOURCE_DIR}/mob.c"
+ "${MAP_SOURCE_DIR}/npc.c"
+ "${MAP_SOURCE_DIR}/npc_chat.c"
+ "${MAP_SOURCE_DIR}/party.c"
+ "${MAP_SOURCE_DIR}/path.c"
+ "${MAP_SOURCE_DIR}/pc.c"
+ "${MAP_SOURCE_DIR}/pet.c"
+ "${MAP_SOURCE_DIR}/quest.c"
+ "${MAP_SOURCE_DIR}/script.c"
+ "${MAP_SOURCE_DIR}/searchstore.c"
+ "${MAP_SOURCE_DIR}/skill.c"
+ "${MAP_SOURCE_DIR}/status.c"
+ "${MAP_SOURCE_DIR}/storage.c"
+ "${MAP_SOURCE_DIR}/trade.c"
+ "${MAP_SOURCE_DIR}/unit.c"
+ "${MAP_SOURCE_DIR}/vending.c"
+ )
+set( DEPENDENCIES common_base )
+set( LIBRARIES ${GLOBAL_LIBRARIES} )
+set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
+set( DEFINITIONS ${GLOBAL_DEFINITIONS} TXT_ONLY )
+if( WITH_PCRE )
+ message( STATUS "Using PCRE" )
+ list( APPEND LIBRARIES ${PCRE_LIBRARIES} )
+ list( APPEND INCLUDE_DIRS ${PCRE_INCLUDE_DIRS} )
+ list( APPEND DEFINITIONS PCRE_SUPPORT )
+endif()
+set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${TXT_MAP_HEADERS} ${TXT_MAP_SOURCES} )
+source_group( common FILES ${COMMON_BASE_HEADERS} )
+source_group( map FILES ${TXT_MAP_HEADERS} ${TXT_MAP_SOURCES} )
+include_directories( ${INCLUDE_DIRS} )
+add_executable( map-server ${SOURCE_FILES} )
+add_dependencies( map-server ${DEPENDENCIES} )
+target_link_libraries( map-server ${LIBRARIES} ${DEPENDENCIES} )
+set_target_properties( map-server PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
+if( WITH_COMPONENT_RUNTIME )
+ cpack_add_component( Runtime_mapserver_txt DESCRIPTION "map-server (txt version)" DISPLAY_NAME "map-server" GROUP Runtime )
+ install( TARGETS map-server
+ DESTINATION "."
+ COMPONENT Runtime_mapserver_txt )
+endif()
+message( STATUS "Creating target map-server - done" )
+set( HAVE_map-server ON CACHE BOOL "map-server target is available" )
+mark_as_advanced( HAVE_map-server )
+else()
+message( STATUS "Skipping target map-server (requires common_base; optional PCRE)" )
+unset( HAVE_map-server CACHE )
+endif()
diff --git a/src/map/unit.c b/src/map/unit.c
index 3cec43f70..2165532b4 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -51,8 +51,8 @@ struct unit_data* unit_bl2ud(struct block_list *bl)
return NULL;
}
-static int unit_attack_timer(int tid, unsigned int tick, int id, intptr data);
-static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr data);
+static int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data);
+static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data);
int unit_walktoxy_sub(struct block_list *bl)
{
@@ -106,7 +106,7 @@ int unit_walktoxy_sub(struct block_list *bl)
return 1;
}
-static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr data)
+static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
int i;
int x,y,dx,dy;
@@ -263,7 +263,7 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr data)
return 0;
}
-static int unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr data)
+static int unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list *bl = map_id2bl(id);
@@ -327,7 +327,7 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag)
if((bl)->type == BL_MOB && (flag)) \
((TBL_MOB*)(bl))->state.skillstate = ((TBL_MOB*)(bl))->state.aggressive?MSS_FOLLOW:MSS_RUSH;
-static int unit_walktobl_sub(int tid, unsigned int tick, int id, intptr data)
+static int unit_walktobl_sub(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list *bl = map_id2bl(id);
struct unit_data *ud = bl?unit_bl2ud(bl):NULL;
@@ -847,7 +847,7 @@ int unit_can_move(struct block_list *bl)
* Resume running after a walk delay
*------------------------------------------*/
-int unit_resume_running(int tid, unsigned int tick, int id, intptr data)
+int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data)
{
struct unit_data *ud = (struct unit_data *)data;
@@ -891,7 +891,7 @@ int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int
//Resume running after can move again [Kevin]
if(ud->state.running)
{
- add_timer(ud->canmove_tick, unit_resume_running, bl->id, (intptr)ud);
+ add_timer(ud->canmove_tick, unit_resume_running, bl->id, (intptr_t)ud);
}
else
{
@@ -1655,7 +1655,7 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t
return 1;
}
-static int unit_attack_timer(int tid, unsigned int tick, int id, intptr data)
+static int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list *bl;
bl = map_id2bl(id);
@@ -1881,7 +1881,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
storage_guild_storage_quit(sd,0);
sd->state.storage_flag = 0; //Force close it when being warped.
if(sd->party_invite>0)
- party_reply_invite(sd,sd->party_invite_account,0);
+ party_reply_invite(sd,sd->party_invite,0);
if(sd->guild_invite>0)
guild_reply_invite(sd,sd->guild_invite,0);
if(sd->guild_alliance>0)